ROS2与Matlab入门教程-在Simulink中使用ROS2消息
说明:
- 如何在Simulink中处理复杂的ROS2消息,例如具有嵌套子消息和可变长度数组的消息
介绍
在ROS2 Simulink模型中,总线信号表示ROS2消息。ROS2消息的每个字段对应于Simulink总线中的一个字段,具有以下限制:
常量不受支持,并且被排除在 Simulink 总线之外。
64 位整数(ROS 类型int64和uint64)在 Simulink 总线中转换为双精度,因为 Simulink 本身不支持 64 位整数数据类型。
可变长度数组(ROS 类型...[])转换为具有可定制最大长度的固定长度数组。默认情况下,对于原始类型(例如,,),固定长度为 128,uint8[]对于float32[]嵌套消息数组(例如,geometry_msgs/Point[]),固定长度为 16。
字符串(ROS 类型string)转换为uint8具有可自定义最大长度的固定长度数组,默认最大长度为 128 个字符。
字符串数组(ROS 类型string[])转换为std_msgs/String具有可自定义最大长度的固定长度数组。默认最大长度为 16 个字符串。
当 Simulink 总线转换为 ROS 2 消息时,消息字段将恢复为其原生 ROS 2 类型。例如,ROS 消息类型std_msgs/Header有一个字段frame_id,它是一个字符串。在对应的 Simulink 总线中,frame_id字段是一个uint8数组。当总线转换为 ROS 消息时,frame_id转换回字符串
以下模型有几个在 Simulink 中处理复杂 ROS 2 消息的示例。此示例中的其余任务侧重于特定场景
open_system( 'robotROS2MessageUsageExample' );
访问可变长度数组中的数据
ROS 2 消息可以包含长度(元素数量)无法预先确定的数组。例如,消息中的 position字段sensor_msgs/JointState是一个 64 位浮点数的可变长度数组。
在任何给定sensor_msgs/JointState的消息中,position数组可以没有元素,也可以有任意数量的元素。在 Simulink 中,此类数组需要具有最大长度
打开示例模型并探索如何在 Simulink 中按以下步骤处理 ROS 消息中的可变长度数组
open_system( 'robotROS2MessageUsageExample/使用可变长度数组' );
双击Work with Variable-length Arrays子系统。请注意,订阅块被配置为接收/my_joint_topic作为消息类型发送到主题的消息,sensor_msgs/JointState
在建模选项卡下,单击更新模型
双击Bus Selector模块。消息中有三个可变长度数组(position、velocity和effort)
观察总线中有一个 aposition_SL_Info场。p保存原始收到的 ROS 2 消息osition_SL_Info.ReceivedLength中数组的长度。Position这个值可以任意大。p保存Simulink 总线信号中osition_SL_Info.CurrentLengthp 数组的长度。osition这可以在 0 和数组的最大长度(在本例中为 128)之间变化
配置 ROS 2 网络
在Simulation选项卡下,从Prepare部分中选择ROS Network 。如果您没有看到 ROS 工具箱,请在控制系统下的应用程序选项卡上选择机器人操作系统 (ROS)。在打开的对话框中,从ROS Network下拉菜单中选择Robot Operating System 2 (ROS 2)
将Domain ID和RMW Implementation设置为所需的值
运行模拟
在 Simulation 选项卡下,将Stop Time设置为Inf,然后单击Play开始仿真
在 MATLAB 命令行中执行以下命令
node = ros2node("/my_node");
[pub, msg] = ros2publisher(node,"/my_joint_state", "sensor_msgs/JointState",Durability="transientlocal");
msg.position = [11:2:25]; % array of length 8
send(pub, msg);
观察使用可变长度数组子系统中的显示输出。注意和是相等的。Current LengthReceived Length
在 MATLAB 命令行中执行以下命令
msg.position = 1:130; % array of length 130
send(pub, msg);
观察发出警告,表明发生了截断
在“调试”选项卡下,选择“诊断” > “诊断查看器” 。警告通常在此处路由到 Simulink 诊断查看器(请参阅查看诊断(Simulink))
修改可变长度数组的最大大小
在 Simulink 中更改可变长度数组的最大大小。消息类型中Position数组的默认最大值是。您将此限制更改为.sensor_msgs/JointState128256
打开示例模型,然后双击Work with Variable-length Arrays子系统
从Simulation选项卡中,选择ROS Toolbox > Variable Size Messages
在左侧的列表框中,单击sensor_msgs/JointState。然后,取消选中使用此消息类型的默认限制复选框。最后,在 p数组属性256的行中输入新值 ,然后单击OK关闭对话框
单击“播放”开始模拟
在 MATLAB 命令行中运行以下命令。观察诊断查看器中没有发出警告
msg.position = 1:200; % array of length 200
send(pub, msg);
- 在 MATLAB 命令行中运行以下命令。观察诊断查看器中发出警告
msg.position = 1:300; % array of length 300
send(pub, msg);
关闭模型而不保存
最大大小信息适用于sensor_msgs/JointState消息类型的所有实例。例如,如果模型中使用的其他消息包含sensor_msgs/JointState消息,则更新的限制也256将适用于所有这些嵌套实例
最大尺寸信息特定于模型,并与模型一起保存。您可以打开两个使用sensor_msgs/JointState的模型,一个模型使用默认限制128,另一个使用自定义限制256
使用 MATLAB Function 模块处理消息
Simulink 中的 Bus Assignment 模块不支持分配给总线数组中的元素
例如,一条geometry_msgs/PoseArray消息有一个Poses属性,它必须是一个geometry_msgs/Pose消息数组。如果要分配给Poses数组的特定元素,则无法使用 Bus Assignment 块
探索如何使用 MATLAB Function 模块进行高级消息操作,例如分配嵌套消息
打开示例模型。选择Work with Nested Arrays of Messages子系统并复制
打开一个新的 Simulink 模型。将新模型粘贴并保存到临时位置,名称为FunctionTest.slx
clear关闭所有模型,并通过在 MATLAB 命令行中键入来清除基础工作区
配置 MATLAB 分配模块
打开 FunctionTest.slx 模型,双击Work with Nested Arrays of Messages子系统,然后打开MATLAB Function - Assign模块。请注意,它使用 MATLAB 表示法在嵌套数组中分配值
msg功能块需要明确指定总线输出的数据类型(在本例中为)。通过在 MATLAB 命令行中键入以下内容来创建此模型所需的所有总线。请注意,总线对象是使用名称创建的,SL_Bus_<messageType>并存储在 Simulink 数据字典ros2lib中。您可以在Model Explorer的External Data > From Libraries下找到此数据字典
ros.ros2.createSimulinkBus(gcs)
双击MATLAB Function - Assign模块。双击MATLAB Function - Assign模块。在 MATLAB Editor 工具条中的Modeling选项卡下,单击Symbols Pane。然后右键单击msg,选择检查并将其类型设置为SL_Bus_geometry_msgs_PoseArray。单击应用并关闭端口和数据管理器
如果您没有在Type下拉列表中看到SL_Bus_geometry_msgs_PoseArray作为选项列出,请选择Refresh data types
运行模拟
在Simulation选项卡下,将Stop Time设置为1.0,然后单击Play运行仿真。验证Display块中的值是否等于pi/2和pi/2 + 1
ros.ros2.createSimulinkBus(gcs)每次加载模型或清除工作空间时都必须重新运行该语句。为避免这些问题,请将此语句包含在模型的InitFcn回调中
使用字符串数组
ROS 消息中的字符串数组在 Simulink 中表示为std_msgs/String消息数组。每条std_msgs/String消息都有一个data属性,该属性包含字符串中的实际字符。每个字符串都表示为一个uint8值数组
默认情况下,std_msgs/String字符串数组中的最大消息数为16,单个字符串的最大长度为128字符。以下步骤显示了如何更改这些默认值:
打开示例模型,然后双击Work with Strings and String Arrays子系统
更改最大数组长度
从Simulation选项卡中,选择ROS Toolbox > Variable Size Messages
在模型中的消息类型列中,单击sensor_msgs/JointState条目。请注意,右侧窗格显示的Name属性是 的数组std_msgs/String,最大长度为16。要更改 中的最大字符串数Name,请取消选中使用此消息类型的默认限制复选框并输入所需的值
在模型中的消息类型列中,单击std_msgs/String条目。请注意,右侧窗格显示的 adata属性是一个 数组uint8,最大长度为128。要更改字符串的最大长度,请取消选中使用此消息类型的默认限制复选框并输入所需的值
更改默认值后,打开Work with Strings and String Arrays子系统并仿真模型。显示块现在应该反映更新的最大值
注意: d 的最大长度ata适用于std_msgs/String模型中的所有实例。例如,Work with Strings and String Arrays子系统中的Blank String模块使用消息,因此这些消息将继承更新后的最大长度。同样,如果模型具有另一个具有字符串数组属性的 ROS 消息类型,则该数组中的各个字符串也将继承更新后的最大长度
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号