铁子:你不是建前向模型吗?咋反着来。
帅气的老王:Emmmm……把这个杠精拖出去!
我们前面提到,在前向仿真中,车辆模块作为数据流的终端模块。由传动系对电机扭矩降速增扭后输入给车轮,车轮将驱动扭矩转化成车轮驱动力,车辆模块接收到驱动力后将其处理成车速的响应,并反馈给驾驶员模块。
这里的驱动力是个泛概念,车辆行驶除了驱动状态外还有制动状态,所以这里的驱动力指的是轮端力,其包含了制动力。
有疑问先保留,等我更新到车轱辘模块的时候你就清楚了。
所以车辆模块的基本的输入、输出接口就明确了。
输入:
【1】驱动力
输出:
【1】车速
车速的计算我们在系列的第一篇文章中介绍过,有了驱动力我们还需要车辆阻力以及车重等参数,这样模块的功能也就明确了。
车辆模块的主要功能可以看作是:模拟车辆行驶阻力,并根据车辆驱动力的输入计算车辆动态响应。
理论搞清楚了,下面需要实践了。
建立模型变量
模型变量我们通过脚本进行管理,打开Matlab软件,在电脑中新建一个模型存放位置,并设置为软件的当前路径。
新建脚本,命名为”Data.m”,用于模型变量的管理。
变量定义通过赋值语句(A=B;)定义即可,在脚本中定义以下变量,并运行。定义变量时注意以“;”结尾。
运行后,定义的变量会出现在软件的工作区。
定义完变量就可以开始搞模型了。由于是基础教程,所以介绍建模时照顾下刚开始学习simulink的铁子,对于建模过程中第一次使用的模块会标记在模型库中的位置,以及模块参数的设置方法。所以这部分会稍显冗繁。
模型建立
打开simulink,创建一个空白模型,并命名为“EV_Model.sxl”。
点击“建模”-“模型设置”,打开“模型配置参数管理器”。
将模型求解器设置为“定步长”,步长设置为0.01,其他保持不变。
通过库浏览器向模块中添加三个“Constant”模块以及一个“Product”模块,双击“Constant”模块,将模块的常量值分别设置为“VehMass”、“g”、“f”。
双击Product模块,将输入数目设为3,并将端口分别连接至三个constant模块,这样就完成了滚动阻力的计算。
向模型中添加一个输入模块“In”,并命名为“VehSpd”。
再次向模型中添加三个“Constant”模块及一个“Product”模块,如下图设置“Constant”变量值。并将“Product”模块的输入数目按下图设置。
最后将Constant模块与In模块如下图所示连接至Product模块。
这样我们空气阻力计算部分也完成了。
向模型中添加三个“Constant”模块,一个”Product”模块,一个三角函数计算模块,设置“Constant”模块变量值为“VehMass”、“g”、“Grad”。
Grad在模型中设置的是坡度值,单位为%,计算时我们需要先将其转换为弧度值。
模型中添加一个增益模块,和一个三角函数计算模块。设置增益系数为0.01,设置计算函数为atan。增益模块可以看做是将输入信号乘以设置的增益系数后输出。
最后将各参数按下图连接。
这样就完成了坡道阻力的计算。
最后添加一个“Add”模块,将以上三个阻力相加这样就完成了阻力模型的构建。
全选模型,右键选择“基于所选内容创建子系统”(或者直接按快捷键Ctrl+G),将阻力模型建立为子系统,方便模型的界面管理。
建立完成后,模型如下图所示。这样车辆阻力部分就处理好了。
驱动力是输入项,所以求得车辆阻力后,我们根据前面介绍的公式,即可求得车辆加速度。
在模型中添加一个Add模块、Product模块、Constant模块及Gain模块,分别按下图设置及连接即可。
Simulink的Math Operations库中对于加减法运算有三个模块,其实没什么区别,都可以通过符号列表控制端口属性。
求得车辆加速度后,对其进行积分即可得到车速,再次对车速积分即可得到车辆的行驶里程。
我们再回到前面计算的车辆阻力模块,在计算车辆阻力时需要用到车速,然后我们现在还求出个车速来,这两个车速等同吗?
当然,一个模型里不可能存在两个车速。
那可以直接接到一起吗?不可以。
铁子:我知道,因为单位不一样!
是,除此之外还有代数环的问题。
当输入信号直接取决于输出信号,同时输出信号也直接取决于输入信号时,由于数字计算的时序性,而出现的由于没有输入无法计算输出,没有输出也无法得到输入的“ 死锁环” ,称之为代数环。
就像你女朋友不理你的原因是你不理她,你不理她的原因是她不理你,这就是个代数环。
模型这里也同样,计算车辆阻力需要用到车速,车速的计算又需要用到车辆阻力,如果我们直接将这两个信号相连,就完美的形成了一个代数环。
出现代数环后如何解决呢?既然代数环是由于计算的时序性导致的,所以处理好计算顺序就可以了。我们在车辆阻力计算模块的车速输入端口前增加一个“Memory”或“Unit Delay”模块,使用上一时刻的车速计算车辆阻力即可。注意我们计算得到的车速需要进行单位转换。
在计算续航时,我们需要观测续航里程,所以可以在此处增加一个Display模块。注意我们通过积分计算的里程单位是m,需要进行单位转换。
最终完成的模型如下图所示。
再次将模型建立为子系统,添加一个“Constant”模块及一个示波器模块。“Constant”模块的常量值设置为2000。
将仿真停止时间设置为100s,点击运行仿真。
运行完成后打开scope模块,输出曲线如下图所示。
这样车辆模块模型就完成了……吗?
你如果回答是,那你的车又开始往沟里跑了,赶紧踩刹车。
为什么?我们将驱动力设为0,再次运行仿真结果。你猜车速会有什么变化?
纳尼?车速为什么变成负的了,不应该是0吗?问题出在哪里?
我们再回顾一下车辆行驶阻力的计算公式。
假设现在道路坡度为0,车速为0,那么此时坡道阻力等于0,空气阻力也等于0。滚动阻力呢,很明显不为0。所以问题就出在这里。
我猜有铁子肯定会问:当把滚动阻力系数视为常数的时候,滚动阻力是与车速无关的,车速为0的时候不应该有滚动阻力吗?
那你翻的这个沟挺深的。阻力是什么,是阻碍物体运动的力。滚动阻力是由车轮滚动时弹性迟滞产生的,车辆都不动哪来的滚动阻力。
所以当车速为0的时候,车辆的阻力应该为0。
所以我们要对车辆阻力模块进行以下处理:
当车速绝对值大于等于0.1时,正常输出计算的阻力;否则,将阻力置为0。
车速判断部分可以通过如下方式实现,然后将逻辑值与计算的阻力相乘即可。
此部分用到的两个模块分别是对输入取绝对值Abs模块和比较模块(当输入满足比较条件输出为1,否则输出为0),其在模块库中位置分别如下。
这时候,我们再去运行模型,当驱动力为0的时候,车速就正常保持为0了。