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

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

  1. import matplotlib.pyplot as plt
  2. '''
  3. 指数趋近律、等速趋近律、准滑模控制的车辆跟随问题仿真, 运行结果以图片形式保存在同目录下。
  4. '''
  5. # q1, q2分别是切换函数ei1, ei2前面的系数
  6. q1, q2 = 2, 1
  7. # lan是指数趋近律前面的系数
  8. lan = 0.5
  9. # 设定期望车间距均为12
  10. l1, l2, l3, l4 = 12, 12, 12, 12
  11. # 设定汽车质量均为1000
  12. m1, m2, m3, m4 = 1000, 1000, 1000, 1000
  13. # 设定动力学模型分子的速度平方项前的系数ci均为0.5(按照模型符号是负的)
  14. c1, c2, c3, c4 = 0.5, 0.5, 0.5, 0.5
  15. # 设定动力学模型分子的常数项系数Fi均为200(按照模型符号是负的)
  16. f1, f2, f3, f4 = 200, 200, 200, 200
  17. # 设定五辆车汽车的位移、速度、加速度
  18. x0, x1, x2, x3, x4 = [100.], [90.], [79.5], [68.5], [57.]
  19. v0, v1, v2, v3, v4 = [20.], [19.], [18.], [17.], [16.]
  20. a1, a2, a3, a4 = [0.], [0.], [0.], [0.]
  21. # 设定趋近律
  22. def reaching_law(m:int , s:float, q2:int, mode='exponential'):
  23. '''
  24. mode: 指数趋近律exponential| 等速趋近律uniform| 准滑模控制quasi_sliding
  25. '''
  26. if mode == 'exponential':
  27. return -m * lan * s / q2
  28. if mode == 'uniform':
  29. epslion = 0.3
  30. if s > 0:
  31. return -m * epslion / q2
  32. if s == 0:
  33. return 0
  34. if s < 0:
  35. return m * epslion / q2
  36. if mode == 'quasi_sliding':
  37. delta, epslion = 0.8, 2.
  38. if s < -delta:
  39. return m * epslion / q2
  40. if s > delta:
  41. return -m * epslion / q2
  42. else:
  43. return -m * epslion * s / (delta * q2)
  44. # 设定第一辆车的加速度(分段函数), 要注意t的长度和a0的长度相等
  45. def get_a0(t:list):
  46. a0 = []
  47. for i in t:
  48. if i < 4:
  49. a0.append(0)
  50. continue
  51. if i >= 4 and i < 7:
  52. a0.append(-0.25*(i-4))
  53. continue
  54. if i >= 7 and i < 10:
  55. a0.append(-0.75)
  56. continue
  57. if i >= 10 and i < 16:
  58. a0.append(0.25*(i-10)-0.75)
  59. continue
  60. if i >= 16 and i < 19:
  61. a0.append(0.75)
  62. continue
  63. if i >= 19 and i < 22:
  64. a0.append(0.25*(19-i)+0.75)
  65. continue
  66. if i >= 22 and i <= 30: # 注意i=30, 所以是取两端, 故为301份
  67. a0.append(0)
  68. return a0
  69. if __name__ == "__main__":
  70. t = [float(i/10) for i in range(301)] # 将30秒划分成301份, [0, 0.1, 0.2, ..., 29.9, 30]
  71. a0 = get_a0(t)
  72. # 四辆车的车间距误差ei1列表
  73. e11 = [x1[0] - x0[0] + l1]
  74. e21 = [x2[0] - x1[0] + l2]
  75. e31 = [x3[0] - x2[0] + l3]
  76. e41 = [x4[0] - x3[0] + l4]
  77. # 四辆车的车间距误差导数ei2的列表
  78. e12 = [v1[0] - v0[0]]
  79. e22 = [v2[0] - v1[0]]
  80. e32 = [v3[0] - v2[0]]
  81. e42 = [v4[0] - v3[0]]
  82. # 四辆车切换函数的列表
  83. s1 = [q1 * e11[0] + q2 * e12[0]]
  84. s2 = [q1 * e21[0] + q2 * e22[0]]
  85. s3 = [q1 * e31[0] + q2 * e32[0]]
  86. s4 = [q1 * e41[0] + q2 * e42[0]]
  87. # 四辆车控制律的列表
  88. u1, u2, u3, u4 = [0], [0], [0], [0]
  89. for i in range(1, 301):
  90. # 最前车0的速度、加速度更新,可以看出更新时用了直线等效, 0.1指的是时间标度(列表t划分的, 也是之后绘图打印的x轴)
  91. v0.append(v0[i-1] + 0.1 * (a0[i] + a0[i - 1]) * 0.5)
  92. x0.append(x0[i-1] + 0.1 * (v0[i] + v0[i - 1]) * 0.5)
  93. # 车1的车间距误差及导数更新
  94. e11.append(x1[i-1] - x0[i-1]+l1)
  95. e12.append(v1[i-1] - v0[i-1])
  96. # 车1的切换函数更新
  97. s1.append(q1 * e11[i] + q2 * e12[i])
  98. # 等效控制
  99. u1equ = c1 * (e12[i] + v0[i]) * (e12[i] + v0[i]) - m1 * q1 * e12[i] / q2 + m1 * a0[i] + f1
  100. # 反馈控制(指数趋近律)
  101. u1n = reaching_law(m1, s1[i], q2) # 默认采用指数趋近律, 下同
  102. # u1n = reaching_law(m1, s1[i], q2, mode='uniform') # 采用等速趋近律
  103. # u1n = reaching_law(m1, s1[i], q2, mode='quasi_sliding') # 采用准滑模控制
  104. # 更新控制律
  105. u1.append(u1equ + u1n)
  106. # 利用控制律更新车1的加速度、速度、位移, 加速度是利用动力学模型得到的
  107. a1.append((-c1 * v1[i-1] * v1[i-1] + u1[i] - f1) / m1)
  108. v1.append(v1[i-1] + 0.1 * (a1[i] + a1[i - 1]) * 0.5)
  109. x1.append(x1[i-1] + 0.1 * (v1[i] + v1[i - 1]) * 0.5)
  110. # 车2、3、4过程同车1
  111. e21.append(x2[i-1] - x1[i-1]+l2)
  112. e22.append(v2[i-1] - v1[i-1])
  113. s2.append(q1 * e21[i] + q2 * e22[i])
  114. u2equ = c2 * (e22[i] + v1[i]) * (e22[i] + v1[i]) - m2 * q1 * e22[i] / q2 + m2 * a1[i] + f2
  115. u2n = reaching_law(m2, s2[i], q2) # 默认采用指数趋近律
  116. # u2n = reaching_law(m2, s2[i], q2, mode='uniform') # 采用等速趋近律
  117. # u2n = reaching_law(m2, s2[i], q2, mode='quasi_sliding') # 采用准滑模控制
  118. u2.append(u2equ + u2n)
  119. a2.append((-c2 * v2[i-1] * v2[i-1] + u2[i] -f2) / m2)
  120. v2.append(v2[i-1] + 0.1 * (a2[i] + a2[i - 1]) * 0.5)
  121. x2.append(x2[i-1] + 0.1 * (v2[i] + v2[i - 1]) * 0.5)
  122. e31.append(x3[i-1] - x2[i-1]+l3)
  123. e32.append(v3[i-1] - v2[i-1])
  124. s3.append(q1 * e31[i] + q2 * e32[i])
  125. u3equ = c3 * (e32[i] + v2[i]) * (e32[i] + v2[i]) - m3 * q1 * e32[i] / q2 + m3 * a2[i] + f3
  126. u3n = reaching_law(m3, s3[i], q2)
  127. # u3n = reaching_law(m3, s3[i], q2, mode='uniform')
  128. # u3n = reaching_law(m3, s3[i], q2, mode='quasi_sliding')
  129. u3.append(u3equ + u3n)
  130. a3.append((-c3 * v3[i-1] * v3[i-1] + u3[i] -f3) / m3)
  131. v3.append(v3[i-1] + 0.1 * (a3[i] + a3[i - 1]) * 0.5)
  132. x3.append(x3[i-1] + 0.1 * (v3[i] + v3[i - 1]) * 0.5)
  133. e41.append(x4[i-1] - x3[i-1]+l4)
  134. e42.append(v4[i-1] - v3[i-1])
  135. s4.append(q1 * e41[i] + q2 * e42[i])
  136. u4equ = c4 * (e42[i] + v3[i]) * (e42[i] + v3[i]) - m4 * q1 * e42[i] / q2 + m4 * a3[i] + f4
  137. u4n = reaching_law(m4, s4[i], q2)
  138. # u4n = reaching_law(m4, s4[i], q2, mode='uniform')
  139. # u4n = reaching_law(m4, s4[i], q2, mode='quasi_sliding')
  140. u4.append(u4equ + u4n)
  141. a4.append((-c4 * v4[i-1] * v4[i-1] + u4[i] -f4) / m4)
  142. v4.append(v4[i-1] + 0.1 * (a4[i] + a4[i - 1]) * 0.5)
  143. x4.append(x4[i-1] + 0.1 * (v4[i] + v4[i - 1]) * 0.5)
  144. # 开始绘图
  145. # 绘制加速度曲线
  146. plt.figure() # 设置画布
  147. plt.plot(t, a0, label='car 0') # :是指绘制点划线
  148. plt.plot(t, a1, label='car 1')
  149. plt.plot(t, a2, label='car 2')
  150. plt.plot(t, a3, label='car 3')
  151. plt.plot(t, a4, label='car 4')
  152. plt.xlabel("Time(s)",fontsize=13)
  153. plt.ylabel("Acceleration(m/s^2)",fontsize=13)
  154. plt.xlim(0, 30)
  155. plt.legend()
  156. plt.savefig('./acceleration.png') # 保存图像
  157. # 绘制速度曲线
  158. plt.clf() # 清空画布,不然会前后图像会重叠
  159. plt.plot(t, v0, ':', label='car 0')
  160. plt.plot(t, v1, ':', label='car 1')
  161. plt.plot(t, v2, ':', label='car 2')
  162. plt.plot(t, v3, ':', label='car 3')
  163. plt.plot(t, v4, ':', label='car 4')
  164. plt.xlabel("Time(s)",fontsize=13)
  165. plt.ylabel("velocity(m/s)",fontsize=13)
  166. plt.xlim(0, 30)
  167. plt.legend()
  168. plt.savefig('./velocity.png') # 保存图像
  169. # 绘制位置曲线
  170. plt.clf()
  171. plt.plot(t, x0, ':', label='car 0')
  172. plt.plot(t, x1, ':', label='car 1')
  173. plt.plot(t, x2, ':', label='car 2')
  174. plt.plot(t, x3, ':', label='car 3')
  175. plt.plot(t, x4, ':', label='car 4')
  176. plt.xlabel("Time(s)",fontsize=13)
  177. plt.ylabel("position(m)",fontsize=13)
  178. plt.xlim(0, 30)
  179. plt.legend()
  180. plt.savefig('./position.png')
  181. # 绘制车间距误差ei1曲线
  182. plt.clf()
  183. plt.plot(t, e11, label='car 1')
  184. plt.plot(t, e21, label='car 2')
  185. plt.plot(t, e31, label='car 3')
  186. plt.plot(t, e41, label='car 4')
  187. plt.xlabel("Time(s)",fontsize=13)
  188. plt.ylabel("space error(m)",fontsize=13)
  189. plt.xlim(0, 30)
  190. plt.legend()
  191. plt.savefig('./space_error.png')
  192. # 绘制车间距误差导数ei2曲线
  193. plt.clf()
  194. plt.plot(t, e12, ':', label='car 1')
  195. plt.plot(t, e22, ':', label='car 2')
  196. plt.plot(t, e32, ':', label='car 3')
  197. plt.plot(t, e42, ':', label='car 4')
  198. plt.xlabel("Time(s)",fontsize=13)
  199. plt.ylabel("space_error_derivative(m)",fontsize=13)
  200. plt.xlim(0, 30)
  201. plt.legend()
  202. plt.savefig('./space_error_derivative.png')
  203. # 绘制切换函数曲线
  204. plt.clf()
  205. plt.plot(t, s1, label='car 1')
  206. plt.plot(t, s2, label='car 2')
  207. plt.plot(t, s3, label='car 3')
  208. plt.plot(t, s4, label='car 4')
  209. plt.xlabel("Time(s)",fontsize=13)
  210. plt.ylabel("Switching Function",fontsize=13)
  211. plt.xlim(0, 30)
  212. plt.legend()
  213. plt.savefig('./Switching_Function.png')
  214. # 绘制控制输入U曲线
  215. plt.clf()
  216. plt.plot(t, u1, label='car 1')
  217. plt.plot(t, u2, label='car 2')
  218. plt.plot(t, u3, label='car 3')
  219. plt.plot(t, u4, label='car 4')
  220. plt.xlabel("Time(s)",fontsize=13)
  221. plt.ylabel("Control Input",fontsize=13)
  222. plt.xlim(0, 30)
  223. plt.legend()
  224. 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. POI Excel索引是从0还是1开始??

    this.workbook.getSheetAt(1).getFirstRowNum() // == 0 this.workbook.getSheetAt(1).getLastRowNum() // ...

  2. 如何实现数组与List的相互转换?在 Queue 中 poll()和 remove()有什么区别?哪些集合类是线程安全的?

    如何实现数组与List的相互转换? List转数组:toArray(arraylist.size()方法 数组转List:Arrays的asList(a)方法 /** * 〈一句话功能简述〉; * 〈 ...

  3. kafka中的回调函数

    kafka客户端中使用了很多的回调方式处理请求.基本思路是将回调函数暂存到ClientRequest中,而ClientRequest会暂存到inFlightRequests中,当返回response的 ...

  4. Mybatis 的一级、二级缓存?

    1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 C ...

  5. MATLAB与Carsim联合仿真时提示matlab not found的解决方法(CarSim在联合仿真时提示找不到MATLAB的解决方法)

    CarSim8.02并没有提供选择联合仿真的MATLAB/Simulink的版本的功能,CarSim总是与最后安装的MATLAB/Simulink进行联合仿真,如果安装有多个matlab版本则只打开最 ...

  6. 结合Vue.js的前端压缩图片方案

    这是一个很简单的方案.嗯,是真的. 为什么要这么做? 在移动Web蓬勃发展的今天,有太多太多的应用需要让用户在移动Web上传图片文件了,正因如此,我们有些困难必须去攻克: 低网速下上传进度缓慢,用户体 ...

  7. 【Weex笔记】-- Animate.css的使用

    animate.css是一个使用CSS3的animation制作的动画效果的CSS集合,里面预设了很多种常用的动画,且使用非常简单.本文将详细介绍animate.css的使用. 一,安装辅助依赖 np ...

  8. web.xml 配置 contextConfigLocation

    web.xml中classpath:和classpath*:  有什么区别? classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件 ...

  9. macos停止MySQL服务

    1.命令行中 使用 find /usr  -name mysql 查找自己电脑中MySQL的安装位置 例如我查找到我电脑MySQL安装位置是 /usr/local/Cellar/mysql@5.6/5 ...

  10. shiro之第一个程序认证

    有关shiro的介绍请访问https://blog.csdn.net/Kevinnsm/article/details/111823268 三个核心组件:Subject, SecurityManage ...