大作业
📖 阅读信息
阅读时间:5 分钟 | 中文字符:2081 | 有效代码行数:67
数学建模¶
控制模型的建立¶
这里的控制模型分为内环(航向角)和外环(横向偏差)两个部分
外环¶
- \(y_{ref}\) : 参考轨迹的横向位置
- \(y{: }\) 车辆当前横向位置
- \(e_y:\) 横向偏差
就是现在的车的位置离目标位置多远
这一部分的偏差使用 PID 控制,得到了第一个航向修正量 \(\Delta \theta\):
含义
根据横向偏差,生成一个应该额外补偿的航向角修正量 \(\Delta \theta\)。
内环¶
- \(θ_{ref}\) : 参考航向角
- \(θ\) : 车辆当前实际航向角
- \(e_θ\) : 航向角误差
总的航向角修正¶
就是结合上面的两个偏差:
前轮转角部分¶
前轮转角由前馈和后馈两个部分组成:\(\delta=\delta_{ff}+\delta_{fb}\)
前馈¶
就是轴距乘以参考的轨迹曲率,在汽车理论中
这里的前轮转角也是近似的,在二自由度稳态中的公式为:\(\delta_{ff}=\frac{L}{R}+LKa_y\)
反馈¶

使用的是上述的 总的航向角修正
一个 PD + 横摆角速度反馈
- 第一项:航向角误差比例控制
- 第二项:“D 微分抑制”,意思是抑制快速变化,减少振荡
- 如果车辆当前横摆角速度太大,就反向抑制一下,避免转向过猛、摆振太强。
以上就是控制模型的建立
被控对象的建立¶
这一部分可以使用 carsim 代替
实际上就是几个物理量之间的关系:
对应的传递函数关系就是图中的:
但是上述的公式是比较近似的,实际上的横摆加速度与前轮转角的公式为:
- 二自由度稳态:
- 二自由度非稳态:
总的来说:¶
参数的修改¶
首先是外部的 PID 参数¶
优化之后的参数¶
函数:¶
主函数:提取 pid 中的参数,调用方法优化参数
patternsearch(模式搜索算法)
从初始点开始,从上下左右试探参数
找到更好的就过去
步子从大到小,越调越精细
损失函数:
联合仿真¶
输入输出部分¶
- 首先我们要新建我们自己的 simulink 的 dataset

- 在内部,我们要将这个 dataset 链接到我们的本地的文件中:

- 在左侧,我们要打开一个选项:

✅ 勾选 Set time step here 复选框 3,(设置方法和时间步长)
✅ 设置积分方法 4(如 AB-2、Euler 等),
✅ 并明确指定时间步长或频率 6。
此外还有一个与数值积分方法相关的选项:对于每步仅计算一次的显式方法(如 AB-2 或 Euler),可以选择调整 CarSim 内部变量的计算时机,使其与 Simulink 的计算节奏对齐 5。(就是同步的作用)- 7:定义哪些变量将从 Simulink 导入到 CarSim(即 Simulink → CarSim);
- 8:定义哪些变量将从 CarSim 导出到 Simulink(即 CarSim → Simulink)。
- Run parallel VS Math Models
中文:并行运行 VehicleSim 数学模型。
作用:允许多个模型在多核 CPU 上同时计算,用于加速复杂的联合仿真或参数扫描。
- 我们现在定义一下自己的输入和输出
- 输入是前轮的转向角:
选择 import channels,然后进入数据集中进行设置(这个数据集就是要选择 simulink 输入到 carsim 中的数据是个什么数据)

如上图所示,这个数据集中的子数据集就是主页的车辆模型的数据集(也就是控制这个车辆的什么部分)
我们现在需要输入的就是 IMP_STEER_SW(deg)注意单位
我们使用 replace 的模式,也就是直接使用 simulink 控制转角,而不是在驾驶员的基础上叠加 - 我们的输出是 export channels:
也是先新建一个数据集,选择这个新建的数据集
同样,输出的数据集中的子数据集也是主页数据集
我们输出选择的参数为:Lat_Veh ——车辆到参考路径的横向距离,单位是米(m)(这个直接就是我们的误差量了)(双击可以添加或者删除)
还有 Rho_Road(驾驶员参考路径曲率)
Vx:纵向形式速度
Ay:横向加速度
Beta:侧偏角(车辆的)
X、Y_Design:参考路径的 x、y 坐标(可以计算航向角)
- 输入是前轮的转向角:
- 之后我们进入 procedure 中进行车辆控制,还有道路的设置
- 我们可以修改运行的车速
- 还有下面的 3D 道路:修改道路的形状、道路的附着系数
- 在内部,我们要将这个 dataset 链接到我们的本地的文件中:
一些需要调整的点¶
- 横摆角速度反馈的系数增大一点,增加阻尼项
- 横向的误差比例增益减小(可以将其余与速度关联起来:\(k_{pg}(V)=\frac{k_0}{1+V}\))
- 加一个前瞻的距离:\(e_y+L_d\cdot e_\theta\)(就是将后面的 \(e_{\theta}\) 的部分提前了 )
- 这里的 \(L_d\) 可以取一个与速度相关的项(实际上和前馈部分的曲率比较像,所以曲率部分的系数也可以与速度相关)
模糊 PID 控制¶
几种常见的隶属函数¶
高斯和三角形最常用
模糊语句¶
if A and B then C
上面就是模糊语句的形式

就是精确的离散值,经过隶属函数之后的模糊集合
我们现在介绍的是模糊 PID,所以有着二输入(误差、误差变化率),三输出(pid 参数)
模糊控制器的组成¶
对于一个模糊输入变量 e,其模糊自己通常可以按照下面的三种方式划分:
| 序号 | 模糊输入变量 \(e\) 的划分 |
|---|---|
| 1 | \(e = \{ \text{负大}, \text{负小}, \text{零}, \text{正小}, \text{正大} \} = \{ NB, NS, ZO, PS, PB \}\) |
| 2 | \(e = \{ \text{负大}, \text{负中}, \text{负小}, \text{零}, \text{正小}, \text{正大} \} = \{ NB, NM, NS, ZO, PS, PM, PB \}\) |
| 3 | \(e = \{ \text{负大}, \text{负中}, \text{负小}, \text{零负}, \text{零正}, \text{正小}, \text{正中}, \text{正大} \} = \{ NB, NM, NS, NZ, PZ, PS, PM, PB \}\) |
通过 E,EC 的输入,将其模糊、语言化
数据库和规则库¶
- 数据库:隶属函数(论域为连续)
- 规则库:
模糊控制系统输出变量为 e 和 ec,对应的语言变量为 A',B'
就可以得出一组模糊规则
模糊控制器的设计基本步骤¶
以下是将图片中内容转换为 Markdown 格式的结果,保留了原有的结构和信息:
- 定义输入、输出模糊集
对误差 \(E\)、误差变化 \(EC\) 及控制量 \(u\) 的模糊集及其论域定义如下:- \(E\) 、\(EC\) 和 \(U\) (pid)的模糊集均为:
{NB, NM, NS, ZO, PS, PM, PB} - \(E\)、\(EC\) 的论域均为:
{-3, -2, -1, 0, 1, 2, 3} - \(U\) 的论域为:
{-4.5, -3, -1.5, 0, 1, 3, 4.5}
- \(E\) 、\(EC\) 和 \(U\) (pid)的模糊集均为:
- 定义输入输出隶属函数
- 建立模糊控制规则
- 建立模糊控制表
- 模糊推理
- 反模糊化(常用重心法)
实操¶
使用 from、goto 的模块进行输入输出的区分

这样,相同名称(就是方框中的名字)的信号就是同一个信号,就不同连成一个很大的圈了
- 在 matlab 中输入 fuzzy 并且运行就可以得到我们的模糊控制器设置窗口

我们可以在 edit 中增加输入和输出的数量:改成两个输出的隶属函数和一个输出的隶属函数 - 都设置好之后,我们就点击文件 ->输出 ->输出到 workspace->命名即可

- 之后我们打开我们的 simulink,双击模糊控制的模块,在名字中填入我们保存的名字

- 选择 PID(z) 作为控制器,双击,改为从外部输入
之后调节的目标是控制器,不是被控对象














