首页 > 编程问答 >迟滞建模作为 Python GEKKO 中 MPC 的控制约束

迟滞建模作为 Python GEKKO 中 MPC 的控制约束

时间:2024-07-31 06:15:45浏览次数:14  
标签:python optimization nonlinear-optimization gekko

我试图使用 Python GEKKO 在用于控制信号调度的 MPC 优化问题中引入滞后约束。这已成为一项艰巨的任务,因为我无法将以下问题转换为 GEKKO 理解的方程。 问题:

  • 如果开启时间 < 最短开启时间,则给定资产的控制调度不应将其关闭。

  • 如果关闭时间 < 最小关闭时间,则同一资产的控制调度不应能够将其关闭将其打开。

我正在尝试做的一个示例

其中:

engine = GEKKO(remote = False)

control = engine.Param(value = control_signal)

key        = engine.MV(value = 0)
key.STATUS =  1
key.LOWER  = -1
key.UPPER  =  1

engine.Equation(hysteresis_equation(key))

在这种情况下,操纵变量是称为“关键”的控制信号的调度百分位数,它将影响问题动态。| ||其中键是操纵变量,而 hysteresis_equation 是键值的函数,应模拟时间相关的滞后。我没有提供更多细节,因为没有意义,问题在于 GEKKO 模型中非线性磁滞约束的实现。

我尝试过查看二进制变量,但是,我不明白如何获得它们在整个优化过程中使用 GEKKO 更改值。

尝试调用返回 True 或 False 的外部函数不受支持并产生 @error:方程定义 没有等式 (=) 或不等式 (>,<)

的方程我还尝试在类似于 power == (can_on * key + (1-can_on) *b0 + can_off * 0 + (1 -can_off) * 键)/2。布尔值是 hysteresis_equation 中的受控变量,根据滞后状态设置为 1 或 0,但不是 GEKKO 变量。

提前感谢您的帮助。

Thank you in advance for your help.


以下是使用 Python GEKKO 实现磁滞控制的两种方法:

方法 1:互补约束

此方法使用互补约束来强制执行磁滞逻辑。

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt

m = GEKKO(remote=False)
m.time = np.linspace(0, 20, 101)

# 参数
on_time_min = 2  # 最小开启时间
off_time_min = 3  # 最小关闭时间

# 变量
control = m.MV(value=0, lb=-1, ub=1)  # 控制信号(假设范围为 -1 到 1)
control.STATUS = 1

on_state = m.Var(value=0, lb=0, ub=1) # 开启状态(二进制)
off_state = m.Var(value=1, lb=0, ub=1) # 关闭状态(二进制)
on_timer = m.Var(value=0)  # 开启时间计数器
off_timer = m.Var(value=0)  # 关闭时间计数器

# 方程
m.Equation(on_state + off_state == 1)  # 始终处于开启或关闭状态之一

# 开启/关闭逻辑
m.Equation(on_timer.dt() == m.if3(control - 0.5, 1, 0))  # 如果 control > 0.5,则增加 on_timer
m.Equation(off_timer.dt() == m.if3(0.5 - control, 1, 0))  # 如果 control < 0.5,则增加 off_timer

# 磁滞约束
m.Equation(on_state * on_time_min <= on_timer)  # 在切换到关闭状态之前保持开启至少 on_time_min
m.Equation(off_state * off_time_min <= off_timer)  # 在切换到开启状态之前保持关闭至少 off_time_min

# 互补约束
m.Equation(on_state * (control.dt() - 1) <= 0) # 如果 on_state=1,则 control 必须增加(开启)
m.Equation(off_state * (control.dt() + 1) >= 0) # 如果 off_state=1,则 control 必须减少(关闭)

# 模拟
m.options.IMODE = 6
m.solve(disp=False)

# 绘制结果
plt.figure(figsize=(10, 6))
plt.plot(m.time, control.value, label='Control Signal')
plt.plot(m.time, on_state.value, label='On State')
plt.plot(m.time, off_state.value, label='Off State')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Value')
plt.title('Hysteresis Control with GEKKO')
plt.show()

方法 2:状态机

此方法使用状态机框架来表示磁滞行为。

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt

m = GEKKO(remote=False)
m.time = np.linspace(0, 20, 101)

# 参数
on_time_min = 2  # 最小开启时间
off_time_min = 3  # 最小关闭时间

# 变量
control = m.MV(value=0, lb=-1, ub=1)  # 控制信号(假设范围为 -1 到 1)
control.STATUS = 1

# 状态:关闭=1,开启=2
state = m.Var(value=1, lb=1, ub=2, integer=True)

# 时间计数器
time_in_state = m.Var(value=0)

# 方程
m.Equation(time_in_state.dt() == 1)

# 状态转换逻辑
m.Equation(m.if3(state - 1.5,  # 如果处于关闭状态
                   m.if3(time_in_state - off_time_min,  # 如果 off_time_min 已经过去
                         m.if3(control - 0.5, 2, 1),  # 如果 control > 0.5,则转换到开启,否则保持在关闭
                         1),  # 保持在关闭
                   m.if3(time_in_state - on_time_min,  # 如果处于开启状态且 on_time_min 已经过去
                         m.if3(0.5 - control, 1, 2),  # 如果 control < 0.5,则转换到关闭,否则保持在开启
                         2)) - state == 0)  # 保持在开启

# 模拟
m.options.IMODE = 6
m.solve(disp=False)

# 绘制结果
plt.figure(figsize=(10, 6))
plt.plot(m.time, control.value, label='Control Signal')
plt.plot(m.time, state.value, label='State (1=Off, 2=On)')
plt.legend()
plt.xlabel('Time')
plt.ylabel('Value')
plt.title('Hysteresis Control with GEKKO (State Machine)')
plt.show()

这两种方法都实现了磁滞控制,但它们使用不同的方法。第一种方法更简洁,使用互补约束直接强制执行磁滞逻辑。第二种方法更明确,使用状态机框架来模拟系统行为。可以选择最适合的需求和编码风格的一种。

标签:python,optimization,nonlinear-optimization,gekko
From: 78798267

相关文章

  • 在 Lambda Python 中获取 errorMessage": "期望值: 第 1 行第 1 列 (char 0)"
    我正在尝试使用slackapi和awslambda函数创建一个slack机器人。现在我只希望每当用户说“你好”时它就响应“你好”。当我在Lambda代码编辑器中测试代码时,出现此错误。我对Lambda很陌生,并且已经被困在这个问题上有一段时间了。非常感谢任何帮助!完整错误:Response......
  • 具有 Python lambda 函数的 QTimer 使用先前的数据运行
    我有一个GUI项目,它使用PySide2和Python3.8,它在QThread中执行一些后台任务。在该QThread中,我有QTimer成员对象,该对象必须定期运行一个函数,每次向其传递不同的数据。我没有使用QTimer.singleShot静态函数,因为如果需要某些特定场景,我需要......
  • 我如何在 python 上使用 spire.pdf 修复此错误
    我使用spirepdf,但出现以下错误:“DllNotFound_Windows,libSkiaSharp,Nosepuedeencontrarelmóduloespecificado.:....”defextract_text_from_pdf(file_path,output_file):#LoadaPDFdocumentdoc=PdfDocument()doc.LoadFromFile(file_path)ex......
  • C++ 函数返回极其缓慢,远慢于功能等效的 python 代码
    我有一个在我编写的脚本中使用的函数,用于从列表中删除多余的阻塞关键字。基本上,输入(以任何顺序):{"apple","bapple","banana","cherry","bananaman","sweetherrypie","sweet","b"}它应该输出一个缩小的字符串数组(以任何顺序):......
  • 在预定时间从 python telegram bot 发起对话
    对于没有提供代码,我提前表示歉意。我明天会尝试添加它,但我现在还没有接近它,思考如何解决这个问题让我一直在思考。我已经为一个机器人创建了一个程序,该程序的数据帧充满了之前请求的用户添加到机器人的消息列表中。现在,机器人使用job_queue在一天中的随机时间向每个用户发......
  • python函数:带星号的参数一个接一个
    我想知道为什么定义以下函数被认为是好的。deffoo(*x,y):pass据我所知,现在有调用此函数的方法,因为它总是缺少y的值。(如果我错了,请纠正我。)这有什么我不知道的用处吗?你说得对,在Python中定义一个像deffoo(*x,y):...这样的函数,在试图以常规方......
  • 基于遗传(GA)、粒子群(PSO)、模拟退火(SA)、禁忌搜索(ST)、蚁群算法(ACO)、自自组织神
        ......
  • 10个append()函数在Python程序开发中的创新应用
    文末赠免费精品编程资料~~在Python编程的世界里,append()函数是列表操作中最常见的方法之一。它允许我们在列表的末尾添加一个元素,这一简单的功能却能激发无限的创造力。今天,我们将探讨append()函数在Python程序开发中的10种创新应用,从基本用法到高级技巧,逐步深入。1.构......
  • 全网最适合入门的面向对象编程教程:28 类和对象的Python实现-Python编程原则、哲学和规
    全网最适合入门的面向对象编程教程:28类和对象的Python实现-Python编程原则、哲学和规范大汇总摘要:本文主要介绍了在使用Python进行面向对象编程时,Python异常处理的原则-“请求谅解,而非许可”,以及软件设计和Python的编程原则,同时介绍了PEP8规范。原文链接:FreakStud......
  • python生成器
    一前言环境:python3.10win10二生成器1关于生成器先看一个例子    定义了一个函数,当我们运行该函数时,并未像普通函数那样执行函数体内的代码    从其中的英文可知,执行函数得到了一个生成器对象,这个生成器对象也叫做generatoriterator(生成器迭代器),generatorit......