上一篇文章一个汽车跟踪问题的滑模控制实例,已经从理论上证明了可以使用滑模变结构控制策略来解决汽车跟踪问题。

下面分别采用指数趋近律、等速趋近律、准滑模控制的方法完成车辆跟随问题的仿真

import matplotlib.pyplot as plt

'''
指数趋近律、等速趋近律、准滑模控制的车辆跟随问题仿真, 运行结果以图片形式保存在同目录下。
''' # q1, q2分别是切换函数ei1, ei2前面的系数
q1, q2 = 2, 1
# lan是指数趋近律前面的系数
lan = 0.5
# 设定期望车间距均为12
l1, l2, l3, l4 = 12, 12, 12, 12
# 设定汽车质量均为1000
m1, m2, m3, m4 = 1000, 1000, 1000, 1000
# 设定动力学模型分子的速度平方项前的系数ci均为0.5(按照模型符号是负的)
c1, c2, c3, c4 = 0.5, 0.5, 0.5, 0.5
# 设定动力学模型分子的常数项系数Fi均为200(按照模型符号是负的)
f1, f2, f3, f4 = 200, 200, 200, 200
# 设定五辆车汽车的位移、速度、加速度
x0, x1, x2, x3, x4 = [100.], [90.], [79.5], [68.5], [57.]
v0, v1, v2, v3, v4 = [20.], [19.], [18.], [17.], [16.]
a1, a2, a3, a4 = [0.], [0.], [0.], [0.] # 设定趋近律
def reaching_law(m:int , s:float, q2:int, mode='exponential'):
'''
mode: 指数趋近律exponential| 等速趋近律uniform| 准滑模控制quasi_sliding
'''
if mode == 'exponential':
return -m * lan * s / q2
if mode == 'uniform':
epslion = 0.3
if s > 0:
return -m * epslion / q2
if s == 0:
return 0
if s < 0:
return m * epslion / q2
if mode == 'quasi_sliding':
delta, epslion = 0.8, 2.
if s < -delta:
return m * epslion / q2
if s > delta:
return -m * epslion / q2
else:
return -m * epslion * s / (delta * q2) # 设定第一辆车的加速度(分段函数), 要注意t的长度和a0的长度相等
def get_a0(t:list):
a0 = []
for i in t:
if i < 4:
a0.append(0)
continue
if i >= 4 and i < 7:
a0.append(-0.25*(i-4))
continue
if i >= 7 and i < 10:
a0.append(-0.75)
continue
if i >= 10 and i < 16:
a0.append(0.25*(i-10)-0.75)
continue
if i >= 16 and i < 19:
a0.append(0.75)
continue
if i >= 19 and i < 22:
a0.append(0.25*(19-i)+0.75)
continue
if i >= 22 and i <= 30: # 注意i=30, 所以是取两端, 故为301份
a0.append(0)
return a0 if __name__ == "__main__": t = [float(i/10) for i in range(301)] # 将30秒划分成301份, [0, 0.1, 0.2, ..., 29.9, 30]
a0 = get_a0(t) # 四辆车的车间距误差ei1列表
e11 = [x1[0] - x0[0] + l1]
e21 = [x2[0] - x1[0] + l2]
e31 = [x3[0] - x2[0] + l3]
e41 = [x4[0] - x3[0] + l4] # 四辆车的车间距误差导数ei2的列表
e12 = [v1[0] - v0[0]]
e22 = [v2[0] - v1[0]]
e32 = [v3[0] - v2[0]]
e42 = [v4[0] - v3[0]] # 四辆车切换函数的列表
s1 = [q1 * e11[0] + q2 * e12[0]]
s2 = [q1 * e21[0] + q2 * e22[0]]
s3 = [q1 * e31[0] + q2 * e32[0]]
s4 = [q1 * e41[0] + q2 * e42[0]] # 四辆车控制律的列表
u1, u2, u3, u4 = [0], [0], [0], [0] for i in range(1, 301):
# 最前车0的速度、加速度更新,可以看出更新时用了直线等效, 0.1指的是时间标度(列表t划分的, 也是之后绘图打印的x轴)
v0.append(v0[i-1] + 0.1 * (a0[i] + a0[i - 1]) * 0.5)
x0.append(x0[i-1] + 0.1 * (v0[i] + v0[i - 1]) * 0.5) # 车1的车间距误差及导数更新
e11.append(x1[i-1] - x0[i-1]+l1)
e12.append(v1[i-1] - v0[i-1])
# 车1的切换函数更新
s1.append(q1 * e11[i] + q2 * e12[i])
# 等效控制
u1equ = c1 * (e12[i] + v0[i]) * (e12[i] + v0[i]) - m1 * q1 * e12[i] / q2 + m1 * a0[i] + f1
# 反馈控制(指数趋近律)
u1n = reaching_law(m1, s1[i], q2) # 默认采用指数趋近律, 下同
# u1n = reaching_law(m1, s1[i], q2, mode='uniform') # 采用等速趋近律
# u1n = reaching_law(m1, s1[i], q2, mode='quasi_sliding') # 采用准滑模控制
# 更新控制律
u1.append(u1equ + u1n)
# 利用控制律更新车1的加速度、速度、位移, 加速度是利用动力学模型得到的
a1.append((-c1 * v1[i-1] * v1[i-1] + u1[i] - f1) / m1)
v1.append(v1[i-1] + 0.1 * (a1[i] + a1[i - 1]) * 0.5)
x1.append(x1[i-1] + 0.1 * (v1[i] + v1[i - 1]) * 0.5) # 车2、3、4过程同车1
e21.append(x2[i-1] - x1[i-1]+l2)
e22.append(v2[i-1] - v1[i-1])
s2.append(q1 * e21[i] + q2 * e22[i])
u2equ = c2 * (e22[i] + v1[i]) * (e22[i] + v1[i]) - m2 * q1 * e22[i] / q2 + m2 * a1[i] + f2
u2n = reaching_law(m2, s2[i], q2) # 默认采用指数趋近律
# u2n = reaching_law(m2, s2[i], q2, mode='uniform') # 采用等速趋近律
# u2n = reaching_law(m2, s2[i], q2, mode='quasi_sliding') # 采用准滑模控制 u2.append(u2equ + u2n)
a2.append((-c2 * v2[i-1] * v2[i-1] + u2[i] -f2) / m2)
v2.append(v2[i-1] + 0.1 * (a2[i] + a2[i - 1]) * 0.5)
x2.append(x2[i-1] + 0.1 * (v2[i] + v2[i - 1]) * 0.5) e31.append(x3[i-1] - x2[i-1]+l3)
e32.append(v3[i-1] - v2[i-1])
s3.append(q1 * e31[i] + q2 * e32[i])
u3equ = c3 * (e32[i] + v2[i]) * (e32[i] + v2[i]) - m3 * q1 * e32[i] / q2 + m3 * a2[i] + f3
u3n = reaching_law(m3, s3[i], q2)
# u3n = reaching_law(m3, s3[i], q2, mode='uniform')
# u3n = reaching_law(m3, s3[i], q2, mode='quasi_sliding')
u3.append(u3equ + u3n)
a3.append((-c3 * v3[i-1] * v3[i-1] + u3[i] -f3) / m3)
v3.append(v3[i-1] + 0.1 * (a3[i] + a3[i - 1]) * 0.5)
x3.append(x3[i-1] + 0.1 * (v3[i] + v3[i - 1]) * 0.5) e41.append(x4[i-1] - x3[i-1]+l4)
e42.append(v4[i-1] - v3[i-1])
s4.append(q1 * e41[i] + q2 * e42[i])
u4equ = c4 * (e42[i] + v3[i]) * (e42[i] + v3[i]) - m4 * q1 * e42[i] / q2 + m4 * a3[i] + f4
u4n = reaching_law(m4, s4[i], q2)
# u4n = reaching_law(m4, s4[i], q2, mode='uniform')
# u4n = reaching_law(m4, s4[i], q2, mode='quasi_sliding')
u4.append(u4equ + u4n)
a4.append((-c4 * v4[i-1] * v4[i-1] + u4[i] -f4) / m4)
v4.append(v4[i-1] + 0.1 * (a4[i] + a4[i - 1]) * 0.5)
x4.append(x4[i-1] + 0.1 * (v4[i] + v4[i - 1]) * 0.5) # 开始绘图
# 绘制加速度曲线
plt.figure() # 设置画布
plt.plot(t, a0, label='car 0') # :是指绘制点划线
plt.plot(t, a1, label='car 1')
plt.plot(t, a2, label='car 2')
plt.plot(t, a3, label='car 3')
plt.plot(t, a4, label='car 4')
plt.xlabel("Time(s)",fontsize=13)
plt.ylabel("Acceleration(m/s^2)",fontsize=13)
plt.xlim(0, 30)
plt.legend()
plt.savefig('./acceleration.png') # 保存图像 # 绘制速度曲线
plt.clf() # 清空画布,不然会前后图像会重叠
plt.plot(t, v0, ':', label='car 0')
plt.plot(t, v1, ':', label='car 1')
plt.plot(t, v2, ':', label='car 2')
plt.plot(t, v3, ':', label='car 3')
plt.plot(t, v4, ':', label='car 4')
plt.xlabel("Time(s)",fontsize=13)
plt.ylabel("velocity(m/s)",fontsize=13)
plt.xlim(0, 30)
plt.legend()
plt.savefig('./velocity.png') # 保存图像 # 绘制位置曲线
plt.clf()
plt.plot(t, x0, ':', label='car 0')
plt.plot(t, x1, ':', label='car 1')
plt.plot(t, x2, ':', label='car 2')
plt.plot(t, x3, ':', label='car 3')
plt.plot(t, x4, ':', label='car 4')
plt.xlabel("Time(s)",fontsize=13)
plt.ylabel("position(m)",fontsize=13)
plt.xlim(0, 30)
plt.legend()
plt.savefig('./position.png') # 绘制车间距误差ei1曲线
plt.clf()
plt.plot(t, e11, label='car 1')
plt.plot(t, e21, label='car 2')
plt.plot(t, e31, label='car 3')
plt.plot(t, e41, label='car 4')
plt.xlabel("Time(s)",fontsize=13)
plt.ylabel("space error(m)",fontsize=13)
plt.xlim(0, 30)
plt.legend()
plt.savefig('./space_error.png') # 绘制车间距误差导数ei2曲线
plt.clf()
plt.plot(t, e12, ':', label='car 1')
plt.plot(t, e22, ':', label='car 2')
plt.plot(t, e32, ':', label='car 3')
plt.plot(t, e42, ':', label='car 4')
plt.xlabel("Time(s)",fontsize=13)
plt.ylabel("space_error_derivative(m)",fontsize=13)
plt.xlim(0, 30)
plt.legend()
plt.savefig('./space_error_derivative.png') # 绘制切换函数曲线
plt.clf()
plt.plot(t, s1, label='car 1')
plt.plot(t, s2, label='car 2')
plt.plot(t, s3, label='car 3')
plt.plot(t, s4, label='car 4')
plt.xlabel("Time(s)",fontsize=13)
plt.ylabel("Switching Function",fontsize=13)
plt.xlim(0, 30)
plt.legend()
plt.savefig('./Switching_Function.png') # 绘制控制输入U曲线
plt.clf()
plt.plot(t, u1, label='car 1')
plt.plot(t, u2, label='car 2')
plt.plot(t, u3, label='car 3')
plt.plot(t, u4, label='car 4')
plt.xlabel("Time(s)",fontsize=13)
plt.ylabel("Control Input",fontsize=13)
plt.xlim(0, 30)
plt.legend()
plt.savefig('./Control_Input.png')

车辆跟随滑模控制的python实现的更多相关文章

  1. 使用滑模控制对sin(t)曲线追踪

    结合:[Matlab]简单的滑模控制程序及Simulink仿真本片文章观看,此篇文章是在这篇文章的基础上进行修改的 输出u的推导过程 如果不明白控制量输出u的推到过成请看:[控制理论]滑模控制最强解析 ...

  2. 【Matlab】简单的滑模控制程序及Simulink仿真

    文章: [控制理论]滑模控制最强解析 滑模控制程序及Simulink仿真 这篇文章仿真和输出U的推到有些问题,博主根据此篇文章进行修改进行对sin(t)曲线的追踪(使用滑模控制) 使用滑模控制对sin ...

  3. [github项目]基于百度地图二次开发实现的车辆监管(包含车辆定位、车辆图片和方向控制,电子围栏,图形绘制等功能)前端实现(不包含后端实现)

    前言:基于百度地图javascript版本开发,百度地图中所用的key已承诺仅用于测试,不用于商业用途 注:本文所有代码可以到github上进行下载,github地址:http://map.eguid ...

  4. TCP/IP详细说明--滑模、拥塞窗口、慢启动、Negle算法

    TCP的数据流大致能够分为两类,交互数据流与成块的数据流. 交互数据流就是发送控制命令的数据流.比方relogin,telnet.ftp命令等等.成块数据流是用来发送数据的包,网络上大部分的TCP包都 ...

  5. python基础之打/解包及运算符与控制流程

    python基础之打/解包及运算符与控制流程 python中的解压缩(即序列类型的打包和解包) python提供了两个设计元祖和其他序列类型的处理的便利,也就是自动打包与自动解包功能,比如: data ...

  6. Python小白的数学建模课-A3.12 个新冠疫情数模竞赛赛题与点评

    新冠疫情深刻和全面地影响着社会和生活,已经成为数学建模竞赛的背景帝. 本文收集了与新冠疫情相关的的数学建模竞赛赛题,供大家参考,欢迎收藏关注. 『Python小白的数学建模课 @ Youcans』带你 ...

  7. Python学习--04条件控制与循环结构

    Python学习--04条件控制与循环结构 条件控制 在Python程序中,用if语句实现条件控制. 语法格式: if <条件判断1>: <执行1> elif <条件判断 ...

  8. python应用-使用python控制win2003服务器

    经调研和测试,服务端可通过ansible控制各linux服务器(容器),进行各类操作,且支持远程控制windows服务器,但windows操作系统中,需安装.net及powershell3.0及以上版 ...

  9. Python数模笔记-StatsModels 统计回归(4)可视化

    1.如何认识可视化? 图形总是比数据更加醒目.直观.解决统计回归问题,无论在分析问题的过程中,还是在结果的呈现和发表时,都需要可视化工具的帮助和支持. 需要指出的是,虽然不同绘图工具包的功能.效果会有 ...

随机推荐

  1. 学习FastDfs(二)

    分布式文件系统(DFS) 指文件系统管理的物理存储资源不一定直接连接在本地节点上 而是通过计算机网络与节点相连 分布式文件系统的设计基于客户机/服务器模式 一个典型的网络可能包括多个多个用户访问的服务 ...

  2. 【Linux-vim】vim文件:查看某几行,把某几行复制到另一个文件中

    一.查看文件的某几行1.使用cat命令(1)查看文件的前10行: cat filename |head -n 10(2)查看文件后10行: cat filename |tail -n 10(3)查看文 ...

  3. CAN总线系列讲座第六讲——SJA1000的滤波器设置

    CAN总线的滤波器设置就像给总线上的节点设置了一层过滤网,只有符合要求的CAN信息帧才可以通过,其余的一概滤除. 在验收滤波器的帮助下,只有当接收信息中的识别位和验收滤波器预定义的值相等时,CAN 控 ...

  4. Linux基础学习 | 目录及文件

    一.目录结构 Linux目录采用树形结构,以根目录/向下延伸呈一个倒置的树的形状. 每个目录下都有其相对应的子目录,而子目录中又有其子目录的存在,就像一棵树的树枝分叉,所有的目录层次结构分明,每个目录 ...

  5. RESTful API/Web API

    Microsoft REST API Guidelines Are Not RESTful White House Web API Standards Microsoft REST API Guide ...

  6. 安装Backstage.io应用

    Backstage介绍 What's Backstage? Backstage is an open platform for building developer portals. Powered ...

  7. Vue3生命周期的理解

    beforeCreate():在实例生成之前 created():在实例生成之后 beforeMount():在模板已经被编译成函数之后,组件内容被渲染到页面之前 mounted():在组件内容被渲染 ...

  8. jboss7学习3-jboss安装 访问(外网)添加用户

    一.下载安装 1.下载地址: http://www.jboss.org/jbossas/downloads ,下载Certified Java EE 6 Full Profile版本. 2.解压 jb ...

  9. css过渡效果和盒子缩放大小的结合

    给盒子一个鼠标经过时放大里面的图片效果在css中使用过渡效果transition结合 <html lang="en"> <head> <meta ch ...

  10. Linux上部署net6应用

    前言 ​ .net6都出来了,作为一名.net搬砖工却一直都在windows下部署应用,还未尝试过linux环境下部署应用.参考福禄网络研发团队的相关博客,学习一下如何将应用部署到linux系统. . ...