相机和毫米波雷达数据融合3--Simulink解析Can信号
参考文章
simulink中CAN PACK和CAN UNPACK模块的使用
Simulink CAN PACK Message总线解包及处理
这些参考文章都写的很好很详细。如果我在这篇文章中没讲清楚的可以参考这几篇。但是最好先看我的之后看他们的,因为他们的不会完美契合这个项目,如果跟着搞到后面发现出了问题就是在浪费时间。
pack和unpack模块认识
高版本的matlab和低版本的matlab有明显不同,最明显的就是高版本需要将CAN_MESSAGE_BUS创建在工作空间中,而低版本不需要。我也是在写文章的时候才摸索出来两个版本的成功操作。
低版本以2016a为例
pack模块
这是一个pack模块,里面有一个Gear_A1_param,在simulink里这是一个bus信号,生成c++代码之后他就是一个类了。首先你需要在matlab工作空间里创建这个bus信号。如下:
matlab窗口输入buseditor,在弹出串口中点击2,3可以添加bus和该bus的element。比如这个Gear_A1_param类:
bus element需要在右边设置名称和类型,一般都是double型。如果你想创建那种复合类,注意要先创建出里面的类,再创建外面的类,像下面这种can0_Input_Param里还包含很多控制参数类:
创建好bus之后,我们创建一个In1输入模块设置他的Data type,选择你需要的bus。如果找不到点击Refresh data type就好了。
然后利用一个busSelector模块,选择出需要的信号,然后输入到pack模块中。pack模块设置如下:
输入信号的方式,第一个和另外两个有明显区别,第一个你得输入和can信号每一位的数值,一般来说can信号有8位,所以你得提供八个数据。raw data原始数据的意思,这个方式这里用不上。
第二个和第三个输入方式,都是输入参数物理值,不同的是第二个你可以自己定义,当你选择了第二个后,你会发现signals那一行的add signal和delete signal可以进行选择了,也就是可以自己操作这个can的解析方式了。在pack中不常用,因为改变了解析方式,最后pack出来的can信号是要发送给硬件设备的,硬件是理解不了这种can信号的。一般pack的话就选择第三种。
然后继续选择dbc文件的路径,还有你需要pack的那个can信号,然后ok就好了。
最后连接一个Out1输出模块,由于是低版本matlab不用设置成canmessage的类型,他会自动识别。记住输入输出的名字很重要,这个就是生产代码里的类的名字。
unpack模块
这时输入是canMessage,不需要设置输入数据类型,然后连接unpack模块,unpack模块如下:
unpack模块与pack模块类似,不同点在于:
- 你可以选第二种输入方式,这样可以选择你需要的信号进行解析,使得模型和代码看起来更简洁,或者输出之后连接到terminator。
- 可以勾选下面的Output ports,选择canmessage的一些状态信息。
之后连接一个busCreator模块,让输出的参数合成一个类输入到Out1模块,Out1模块需要设置bus数据类型,和pack模块那部分类似。
高版本以2021a为例
想要完成和上文一样的内容,需要你提前创建一个canMessage的bus,你可以在matlab窗口输入“canMessageBusType”即可创建。
在搭建模块时,所有Out1和In1模块(不管是子系统还是外面的)如果和can_Msg连接,数据类型都要选择你创建的CAN_MESSAGE_BUS。而且要勾选output as a non-virtual bus signal。
所有的pack模块都要勾选output as bus ,如下:
生成代码
搭建好解析模型后就可以生成代码,注意你的输入输出模块,还有子系统的命名,这都将在后面生成的代码中得到体现。
生成代码的步骤可以参考这个,写的很好:
生成代码
如果你高版本没有找到生成代码口在哪?
点击1,然后在2中搜code,然后选择Embedded Coder,会看到出现4,在4里你就会看到Quick start了。如果生成代码不成功,看他的报错,一般是这几个问题:
- dbc文件路径改变了
- 数据格式没设置好
- bus没有设置好,output as bus啥的没勾上
按照报错去修改就好了。生成代码后按照链接文章里去好好看看怎么理解生成的代码,这会帮助后面的编程。
融合项目的can解析
下面我将介绍我的解析框架,我的工控机一共有三个can口接入了硬件设备,分别是can0接车辆底盘,can1接摄像头,can2接毫米波雷达ESR。
你可以把需要交互的信息在模型里连上,比如相机需要本车的制动信号,那我直接把底盘can解析之后的档位反馈信息,直接输入到相机解析模块里。意思就是只要我这个模型收到了底盘的档位can信号就可以自动解析车的档位状态,然后输入到相机pack模块中,最后生成一条表示档位状态的,相机需要的can信号给相机。
图中你还可以继续优化,再用busCreator把同一个can输出的param做成一个类,这样会更简洁方便一些。
can0模块
can0中C_Msg是车辆的状态反馈信号,解析之后有C_param,我们可以得到车辆当前的前轮转角,转矩,档位状态等等。A_param是控制参数,我们可传入档位,转向,驱动,制动,驻车等参数,来控制车辆。
can1模块
can1接入的摄像头,我们不需要控制摄像头,关注输出就好了,738主要输出摄像头探测到的所有目标数量。要知道这个数量是在不停变化的,摄像头的报文数量也在不停变化,摄像头最多可以同时探测到10个目标,难道我们要设置好所有目标的解析吗???
输出的参数A1_739,B1_73A是摄像头探测到的一个目标的信息。还有A2,B2;A3,B3;目标多的时候还有A9,B9。但其实他们的解析方式是一样的,所以我们这里只选择一个作为代表。在后面代码编写中,我们只要含有目标总数的738can信号,还有和739一类的A信号,73A一类的B信号,A信号10个,B信号10个,加一个738,一共21个信号。
也就是我们只获取这些id的can信号,之后我们在解析代码中进行处理,解析代码后面会详细讲,我们提前来看看:
通过判断对3取余之后的结果来选择将receive_msg输入到解析模型的哪个输入口,至于为啥对3取余,这是这个相机can信号的规律,其实每个目标的信息由三条can组成,ABC,但C没啥有用的信息所以我就不解析C信号了。
can2模块
can2接入的是毫米波雷达ESR,需要输入一些本车状态量(后文会介绍到)。重点看输出,有500和540两个param。ESR每个周期会发送64个目标的信息,不管是否有这么多目标被探测到,都会发送64条can信号,和上文摄像头一样,只需要选择一个can,然后进行取余判断。从500-53f一共64个目标,然后我们还需要从540里获得一些信息(虽然这些信息后面发现并没有啥用)。
这是540的can解析的数据,这一条can中包含了64个目标的某些信息,信息太多,而且有相似性。我们在设置的时候不要把输出设置成bus了,auto就好了,这样在代码中就是数组了,我们可以通过索引去获取相关目标的信息,由于这部分后面也没用到,就不细讲了,有兴趣可以自己去试。
总结
终于把这部分讲完了,看的时候把这篇文章和参考文章结合着看,有些东西我也没有试,比如高版本生成的代码在ROS中是什么样的,所以欢迎大家在评论区交流。