Python解决控制问题系列之二:线性连续系统最优控制问题

文章目录

  • Python解决控制问题系列之二:线性连续系统最优控制问题
    • 1. 前言
    • 2. 线性系统问题描述
    • 3. Python 编程
      • 3.1 仿真状态模型构造
      • 3.2 黎卡提方程求解
      • 3.3 构造反馈控制器的I/O系统描述
      • 3.4 闭环系统构造
    • 4 结语

1. 前言

线性系统是控制问题的最常见状态空间表达式模型,也是各类物理运动系统在平衡点处线性化后的标准模型。本文是在研究如何利用python编程复现Lewis1科研团队在2009年Automatica发表的一篇有关“reinforcement learning control”的算法时,衍生出来的基础线性系统模型构造、代数黎卡提方程(ARE)求解以及状态反馈闭环系统的轨迹数值解求解实现方案。

2. 线性系统问题描述

线性系统的模型如下式:
x˙=Ax+Bu(1)\dot x = Ax + Bu\quad (1) x˙=Ax+Bu(1)
最优控制的价值函数为无穷时间尺度,要求找到最优控制u∗u^*u∗,使得下列价值函数取得最小值,同时保证系统稳定。
J=∫t0∞xT(τ)Qx(τ)+uT(τ)Ru(τ)dτ(2)J = \int^{\infin}_{t_0} x^T(\tau)Qx(\tau)+u^T(\tau)Ru(\tau)d\tau \quad (2) J=∫t0​∞​xT(τ)Qx(τ)+uT(τ)Ru(τ)dτ(2)
通过最优控制的基本理论分析可知,为例保证(2)取得最小值,必须保证从代数黎卡提方程中求得对称正定阵点P,即:
ATP+PA−PBR−1BTP+Q=0(3)A^TP+PA-PBR^{-1}B^TP + Q = 0 \quad (3) ATP+PA−PBR−1BTP+Q=0(3)
此时最优控制律u*可以表示为:
u∗(t)=−Kx(t)=−R−1BTPx(t)(4)u^*(t) = - K x(t) = -R^{-1}B^TPx(t)\quad (4) u∗(t)=−Kx(t)=−R−1BTPx(t)(4)
从上述(4)式可知,问题的核心就是求解代数黎卡提方程ARE和构建闭环控制系统。

3. Python 编程

由于scipy.integrate.solve_ivp()函数只适用于一维的微分方程数值求解,这样当面对多维的线性系统状态方程时,就必续将系统状态方程人为转化为每个变量的一维微分方程,非常不方便,也无法利用后续的矩阵特性求解。因此,采用python-control功能包中的若干函数API来完成状态方程的构造、控制器的构造、输入输出轨迹响应数值求解的构造。

3.1 仿真状态模型构造

仿真系统来源于文献【1】中提到的能量系统在关键操作点的简化数学模型,即:
A=(−0.066511.5000−2.52.50−9.50−13.736−13.7360.6000)B=(0013.7360)TA = \begin{pmatrix} -0.0665 & 11.5 & 0 & 0 \\ 0 & -2.5 & 2.5 & 0 \\ -9.5 & 0 & -13.736 & -13.736\\ 0.6 & 0 & 0 & 0 \end{pmatrix}\\ B = \begin{pmatrix}0 & 0 & 13.736 & 0\end{pmatrix}^T A=⎝⎜⎜⎛​−0.06650−9.50.6​11.5−2.500​02.5−13.7360​00−13.7360​⎠⎟⎟⎞​B=(0​0​13.736​0​)T
通过control.ss函数实现状态空间表达式的构建,将C设置为单位矩阵,保证输出为全状态,D设置为0矩阵(不考虑输入对输出的影响)。当状态方程构建完成后,再加线性系统状态方程转化为I/O系统描述,方便后续调用control.input_output_response API接口函数实现轨迹的数值解求解。具体的代码为:

# 引入必要的功能包和API接口
import numpy as np
import control as ct
import matplotlib.pyplot as plt
# 科学计数法, 小数精度控制在小数点后3位
np.set_printoptions(precision=4,suppress=True)
#构造线性系统 \dot x = Ax+Bu
A = np.array([[-0.0665, 11.5, 0, 0],[0, -2.5, 2.5, 0],[-9.5, 0, -13.736, -13.736],[0.6, 0, 0, 0]
])
B = np.array([[0], [0], [13.736], [0]])
C = np.diag([1.0, 1.0, 1.0, 1.0])
D = np.zeros((4, 1))
#构造出状态方程
sys = ct.ss(A, B, C, D)
# 将状态方程转化为I/O系统描述,定义输入名为controller,输出为四个状态。
state_sys = ct.LinearIOSystem(sys, name='state_sys', inputs=('controller'), outputs=('x[0]', 'x[1]','x[2]','x[3]'), states=4 )

构造出的state_sys I/O系统画成方框图表示即为:

3.2 黎卡提方程求解

control功能包提供了一个函数接口control.care来方便计算标准的代数黎卡提方程,如(3)式。具体的API接口使用说明再次不在赘述,可以参考control包的使用说明。与文献【1】中的设置相同,将对称阵Q和R均设置为单位矩阵,从而通过求解代数黎卡提方程,得到三个返回值,分别是解P,闭环系统的特征值L,状态反馈增益K,这就为后续构造状态反馈控制器做好了准备。具体代码为:

# 初始化Q
Q = np.diag([1.0, 1.0, 1.0 , 1.0])
# 解标准的代数黎卡提方程,R=None时,默认R为单位阵
P, L, K = ct.care(A, B, Q, R=None)

3.3 构造反馈控制器的I/O系统描述

接下去就是将基于全状态反馈的控制器构造成I/O系统,方便和之前构造的state_sys I/O系统进行反馈链接,实现初值状态下闭环系统的构建。控制器不涉及到微分方程,所以在使用control.NonlinearIOSystem接口时,第一项参数填为None,第二项参数作为I/O系统的输出项,即反馈控制器的表达式 u = -kx。值得注意的是,在设置输入端口时,需要多设置一个控制输入(这个控制输入在实际运行中不起任何作用,设置的原因是因为在使用control.input_output_response时必须设置初始闭环系统的输入,在这里你可以把它当作一个启动触发信号,对状态的轨迹无任何影响)。具体代码如下:

# 定义反馈控制器ctrl = -Kx,其中参数u为5维列向量,前4维为四个状态,最后1维为启动触发信号ref
def control_output(t, x, u, params={'control gain': np.zeros((1, 4))}):k = params['control gain']  #默认K为0,开环控制x = u[:4]ctrl = -k @ x return ctrl
# 构造控制器 I/O 系统
control_sys = ct.NonlinearIOSystem(None, control_output, params={'control gain': K}, name='control_sys', inputs=('x[0]', 'x[1]','x[2]','x[3]', 'ref'),outputs = 'u')

control_sys 构造成的I/O系统化程方框图为:

3.4 闭环系统构造

通过control.interconnect API接口实现将控制对象state_sys I/O系统的输入输出端与控制器control_sys I/O 系统的输入输出端相连接,构成闭环控制系统。即:

对于闭环系统closed_loop系统来说,它的输入即ref信号,作为仿真启动信号,取值为0即可,对具体轨迹变化无影响。输出为所需的四位状态轨迹x[0],…, x[3]。系统状态的初始值取为:
x0=[0,0.1,0,0]x_0 = [0, 0.1, 0, 0] x0​=[0,0.1,0,0]
具体的代码为:

#构造闭环系统
closed_loop = ct.interconnect((state_sys, control_sys), connections=(['state_sys.controller', 'control_sys.u'],['control_sys.x[0]', 'state_sys.x[0]'],['control_sys.x[1]', 'state_sys.x[1]'],['control_sys.x[2]', 'state_sys.x[2]'],['control_sys.x[3]', 'state_sys.x[3]']),inplist=['control_sys.ref'],inputs=['start'], outlist=['state_sys.x[0]','state_sys.x[1]','state_sys.x[2]','state_sys.x[3]'],outputs=['x[0]','x[1]','x[2]','x[3]']
)#计算轨迹响应
t = np.array([i * 0.5 for i in range(100)]) #每隔0.5取一个点进行数值计算
tp = np.linspace(0, 50, 200)
tout, yout = ct.input_output_response(sys, tp, 0, [0, 0.1, 0, 0], t_eval = t) #开环控制的轨迹,按照t的采用分布取值
t1, y1 = ct.input_output_response(closed_loop, tp, 0, [0, 0.1, 0, 0], t_eval = t) #闭环控制的轨迹
plt.plot(tout, yout[1,:])
plt.plot(t1, y1[1, :])
print(t1)

最终得到的效果图为:

蓝色线为x[1]状态的开环控制轨迹变化情况,橙色线为x[1]状态在闭环最优控制下轨迹变化情况,收敛到平衡点的速度明显加快。

4 结语

查了很多资料,网上显有python实现线性系统控制的程序范例,大都都是matlab实现。后续,如果攻破了文献【1】的算法复现的话,还会共享出来。


  1. D. Vrabie, O. Pastravanu, M. Abu-khalaf, F.L. Lewis. Adaptive optimal control for continuous-time linear systems based on policy iteration. Automatica, 2009(45): 477-484 ↩︎

Python解决控制问题系列之二:线性连续系统最优控制问题相关推荐

  1. 控制系统仿真技术(二)-连续系统的数字仿真二

    太原理工大学控制系统仿真技术实验报告 连续系统的数字仿真 1.分别利用欧拉法和预估-校正法求下图所示系统的阶跃响应,并对其结果进行比较. %欧拉法求阶跃响应 r=2;num0=8;den0=[1 3 ...

  2. 信号系统笔记(二)连续系统的时域分析

    信号系统笔记(二)连续系统的时域分析 2 连续系统的时域分析 2.1 连续系统的响应 2.1.1 连续系统建立微分方程 2.1.2 微分方程的模拟框图 2.1.3 微分方程的经典解法 2.1.4 连续 ...

  3. 状态空间离散化matlab,现代控制理论:3.4g 线性连续系统状态空间模型的离散化...

    <现代控制理论:3.4g 线性连续系统状态空间模型的离散化>由会员分享,可在线阅读,更多相关<现代控制理论:3.4g 线性连续系统状态空间模型的离散化(24页珍藏版)>请在人人 ...

  4. 状态空间离散化matlab,线性连续系统状态空间模型的离散化.ppt

    线性连续系统状态空间模型的离散化 * * * * * * * * * * * * * * * * * * * * Ch.3 线性系统的时域分析 目录(1/1) 目 录 概述 3.1 线性定常连续系统状 ...

  5. 关于线性连续系统转换到离散系统的方法

    关于线性连续系统转换到离散系统的方法 虽然通常在分析设计控制器时,总是针对连续系统设计的.但是若要将其在实际工程中应用起来,则免不了需要将它转换为离散的形式.本文主要对连续系统转换到离散系统的几种方法 ...

  6. 线性连续系统matlab仿真,东大20秋学期《控制系统 Simulink 仿真》在线平时作业【答案满分】...

    20秋学期<控制系统 Simulink 仿真>在线平时作业1 试卷总分:100  得分:100 一.单选题 (共 10 道试题,共 50 分) 1.下列对仿真步长的理解正确的是 A.仿真起 ...

  7. 【Python】Flask框架系列(二):安装、配置文件、增删改查

    MySQL-python中间件的安装 打开这里链接:https://www.lfd.uci.edu/~gohlke/pythonlibs/ 这里32与64的选择不是看操作系统的位数,而是看python ...

  8. 【 I.MX6U-ALPHA 】嵌入式Linux Ubuntu系统入门系列(二)Ubuntu 系统入门

    目录 1.Ubuntu系统初体验 1.1.开启Ubuntu虚拟机 1.2.系统设置 1.3.中文输入法 1.4.Ubuntu终端操作 2.Shell操作 2.1 Shell基本操作 2.2.常用She ...

  9. SCCM 2012系列之二 Operations Manager系统要求

    版本: System Center 2012 SP1 - Operations Manager 系统要求主题: 一. 服务器操作系统要求 Windows Server 2008 R2 SP1 Stan ...

最新文章

  1. HP Webinspect 10 访问wap的url
  2. ffmpeg4编解码例子
  3. Python 字典类型的使用
  4. 【转自CDDN】随笔:sysobjects.Xtype
  5. VTK:图片之DotProduct
  6. px4官网调参指南 多旋翼无人机PID调参指南
  7. 垂直居中及容器内图片垂直居中的CSS解决方法
  8. 双向重定向指令 tee
  9. redis分布式锁简单总结
  10. 现在连U盘都不兼容性了?
  11. java编译jni错误_JNI开发的常见错误
  12. matlab使用xlsread报错,matlab的IO操作复习
  13. openproj centos安装及其输入中文变方块乱码解决
  14. 学环境艺术设计的 考计算机,环境艺术设计专业升本要考哪些科目?
  15. NLP比赛-小布助手对话短文本语义匹配
  16. python 之 del() 函数
  17. 蓝桥 卷“兔”来袭编程竞赛专场-07明码加密 题解
  18. GeneMark-ES:真核生物编码基因预测软件
  19. 农夫养牛问题怎么用java实现,经典的农夫养牛问题(Java实现)
  20. Qt - WPS文本编辑器(WPS字体格式)

热门文章

  1. 计算机网络:期中考试2020年
  2. 手机热点或者在家-连接实验室服务器
  3. Android开发艺术探索——第九章:四大组件的工作过程(下)
  4. 『Java面经』Java中 == 和 equals() 的区别
  5. 55个提高你CSS开发效率的必备片段
  6. java实现第五届蓝桥杯猜字母
  7. 苹果屏幕上的小圆点_iPhone点2下屏幕就能截屏,你还在用按键截屏?不会花30秒学...
  8. 三星note2+android8.0,三星note8有可能搭配android8.0吗
  9. ios分屏_iPadOS 全新侧拉和分屏浏览功能怎么用?
  10. ThreadLocal线程池使用和TransmittableThreadLocal值传递