目录
1. 引言
上一篇文章我们介绍了单摆模型的建立以及其在重力场中的运动。有两个比较关键的问题没有提到,那就是如何测量模型的输出以及如何驱动模型运动。这篇文章即围绕这两个问题展开。
2 信号测量
我们先从信号的测量开始说起,作为一个完备的多体机器人仿真环境,Multibody提供了非常方便地信号测量方法。我们还是以单摆为例来进行说明。首先需要搭建一个单摆模型,如果你还不清楚如何搭建单摆模型,请参考我的上一篇博客SimMechanics/Multibody入门。搭建好的单摆模型如下图所示。
双击Revolute Joint 模块打开属性配置窗口,浏览至Z Revolute Primitive(Rz) --> Sensing 。在这里勾选你想要测量的数据。窗口中显示我们可以测量关节的位置,速度,加速度及关节驱动力矩。在这里我们勾选位置和速度,如下图所示。
点击Apply应用修改。你会发现在Revolute Joint模块的右侧多出了两个输出端子,q对应了关节的位置输出,w对应了关节速度输出。我们只需要连接示波器就可以查看相应的信号。不过在信号进入示波器之前,我们需要添加一个物理信号到仿真信号的接口模块,在Simulink Library Browser中浏览至Simscape --> Utilities,选择PS-Simulink Converter模块添加到模型中,在PS-Simulink Converter模块后面连接一个示波器,连接完成后如下图所示。
运行仿真,XY Graph输出的位置,速度相平面图如下图所示。
在控制科学中这种相平面图有一个专有的名字,叫做极限环,是一种不稳定状态。对应到这里就是说理想状态下(忽略阻尼),单摆将一直摆动下去,不会停止。
当然,你可能希望将输出信号导出到Matlab的工作空间中以进行进一步处理。这个时候你可以用一个To Workspace模块替代示波器,如下图所示。
输出到工作空间后q是一个结构体,你可以通过q.Time和q.Data访问时间以及对应的关节角数据。
你可能觉得这样的单摆并不真实,在实际中总是会有阻尼存在,单摆不可能一直摆动下去。为了使仿真更加接近实际的物理系统,需要对Revolute Joint进行一些额外的配置。双击Revolute Joint,浏览至Z Revolute Primitive(Rz) --> Internal Mechanics 。在这里你可以配置驱动器的线性弹簧阻尼和粘滞阻尼。我们为驱动器添加一些粘滞阻尼,如下图所示。
粘滞阻尼系数设置得越大,单摆停止得就越快,阻尼系数为0.003时的相平面图如下图所示。
3. 关节驱动
前面单摆之所以会运动是因为重力的作用,在实际中我们通常在机器的活动关节处安装驱动装置如电机等驱动连杆运动。Multibody中提供了驱动关节运动的接口,即关节的Actuation属性。双击Revolute Joint,浏览到Z Revolute Primitive(Rz) --> Actuation 。你会发现,这个关节支持力矩和位置两种驱动方式,在Motion中选择Provided by Input,Torque选择Automatically Computed,这个配置就是说我们输入信号是位置,至于这样运动需要多大的力让系统自己计算。点击OK保存修改之后,在Revolute Joint模块的左侧会出现一个新的关节驱动端子。如下图所示。
在这一端上你可以输入任意的信号对关节进行位置控制,同时在测量端以及3D视图中可以看到相应的输出。这里我们先加一个正弦信号,与输出信号类似,驱动信号在进入Revolute Joint之前需要添加一个仿真信号转物理信号的接口模块,即Simulink-PS Converter模块,这个模块也在Simulink Library Browser中的Simscape --> Utilities目录下。驱动信号添加之后如下图所示。
在Sine Wave中设置信号的幅值和频率。这里选择默认的幅值为1,频率为1。此时运行仿真你可能会得到如下错误提示。
大概意思就是Simulink-PS模块的输入信号是连续信号,但是ode15s求解器需要的是离散信号。同时提示我们可以设置输入滤波来解决这个问题。双击Simulink-PS Converter模块,在属性配置中切换到Input Handling标签页。Filtering and derivatives选择Filter input,derivatives calculated。Input filtering order选择Second-order filtering。再进行仿真就不会有问题了。
有的时候我们可能希望自定义模型的驱动信号,这个时候就不能简单地利用Simulink中内置的模块来实现了,通常可以利用两个模块实现Simulink功能的扩展,一个是Matlab Function,一个是Matlab System。相对而言Matlab Function的使用比较简单,只需要我们了解Matlab的编程即可。在Simulink Library Browser中浏览到Simulink --> User-Defined Functions,在其中找到MATLAB Function模块添加到模型中。在Simulink Library Browser中浏览到Simulink --> Sources,在其中找到Clock模块添加到模型中。进行如下图所示的连接。
我们希望添加的这两个模块能够取代原来的正弦波发生模块。Clock模块用于产生时间,保持默认配置。MATLAB Function模块双击会打开m文件编辑器。编写这个函数就可以实现自定义信号输出。在这里我们希望生成一个正弦波,编写代码如下:
function y = fcn(u)
y = sin(u);
还是比较简单的吧~。
另外还有一种情况,你希望基于现有的驱动信号和反馈信号设计自己的控制算法,这个时候也可以通过MATLAB Function模块实现。添加一个新的MATLAB Function模块到仿真模型中。双击该模块编辑对应的函数代码如下(注意这不是我们常说的PID控制器,实际上是一个前馈加一个误差的比例控制):
function y = pid(u, q)
y = u + 10 * (u - q);
保存编辑之后,这个模块就有两个输入信号了。进行如下图所示连接。
图中已经将期望信号和输出信号导出到工作空间,你可以将两个信号作差查看误差随时间变化的情况,会发现添加了这个控制器之后,误差有所下降。
相关的模型已上传至github: https://github.com/hitgavin/simmechanics/tree/master/model_driver_measure,感兴趣可以下载下来跑一下。
4. 总结
这篇文章主要介绍了Matlab SimMechanics/Multibody进行模型驱动以及信号测量的方法。由于个人能力有限,所述内容难免存在疏漏,欢迎指出,欢迎讨论。