做机器人算法验证时,我经常要在 ROS 环境里跑感知、规划,又想在 MATLAB/Simulink 里快速调参、分析数据。两套工具链各有优势:ROS 生态丰富,传感器驱动、导航框架、可视化工具基本开箱即用;MATLAB 在矩阵运算、控制系统设计、Simulink 建模和数据分析上效率极高。但把它们接到一起,很多刚入门的人会卡在环境搭建、消息类型不匹配、网络不通这些细节上。这篇教程把 ROS 与 MATLAB 通信及仿真这条路完整走一遍,包含可复制的示例代码、典型报错和排查思路,适合正在做机器人仿真、课程设计、算法预研或想用 Simulink 做硬件在环测试的读者。
1. 背景与核心概念
1.1 ROS 和 MATLAB 各自解决什么问题
ROS(Robot Operating System,机器人操作系统)本质是一套分布式通信框架,它提供节点之间的话题、服务、参数等通信机制,方便多进程、多语言、多主机协作。机器人项目里,激光雷达驱动、SLAM、导航、机械臂控制都可以封装成独立节点,通过话题传递消息。
MATLAB 则是一个数值计算和算法开发环境,Simulink 是多域物理建模与仿真平台。它们的强项是快速验证控制算法、处理传感器数据、做可视化分析和自动化测试。尤其在做控制器设计时,Simulink 的框图模型比手写 C++ 更容易调整增益、切换算法、生成代码。
1.2 ROS 与 MATLAB 通信解决什么问题
两者结合最典型的场景有三种:
- 算法快速验证:感知或控制算法先用 MATLAB 写出来,通过 ROS 接收真实传感器数据,验证后再移植到 C++。
- 联合仿真:Gazebo 或真实机器人运行 ROS 环境,MATLAB/Simulink 作为外部节点发送控制指令、接收状态反馈,形成闭环。
- 数据采集与分析:用 ROS 录制 rosbag,再放进 MATLAB 做离线分析、标定和特征提取。
这种模式下,MATLAB 不是独立软件,而是 ROS 网络中的一个普通节点。只是这个节点运行在 Windows、Mac 或 Linux 上,通过 ROS 标准协议与其他节点通信。
1.3 核心概念扫盲
在继续之前,需要先理解几个常见词:
- 节点(Node):一个独立进程,负责某类功能,比如 /cmd_vel 发布节点。
- 话题(Topic):发布订阅式单向数据流,适合高频传感器数据。
- 服务(Service):请求响应式双向通信,适合调用一次、等待结果的逻辑。
- 动作(Action):带反馈的长时间任务,比如导航到目标点。
- 消息(Message):话题和服务传输的数据结构,例如 geometry_msgs/Twist。
MATLAB 通过 ROS Toolbox 与 ROS 通信,你可以完全不用写 C++,也能发布和订阅这些消息。Simulink 中甚至有专门的消息收发模块,可以直接和 Gazebo、真实机器人联调。
2. 环境准备与版本说明
2.1 推荐环境组合
目前最常见的组合是:
- 操作系统:Ubuntu 20.04 或 Ubuntu 22.04
- ROS 版本:ROS 1 Noetic 或 ROS 2 Humble
- MATLAB 版本:R2021a 及以上,并安装 ROS Toolbox
- 仿真工具:Gazebo(或 Gazebo Classic)
如果你希望在 MATLAB 和 ROS 之间做联合仿真,ROS 主机建议是 Ubuntu,因为绝大多数机器人驱动、Gazebo 仿真和 ROS 包都在 Linux 下发布。MATLAB 可以装在同一个 Linux 系统里,也可以装在 Windows 宿主机上通过网络连接。后者需要保证两端处于同一局域网,并正确配置 ROS_MASTER_URI 和 ROS_IP。
关于版本支持,我建议你以 MATLAB 官网对 ROS Toolbox 的支持矩阵为准,不要只凭别人一句话就定版本。比如某些 MATLAB 版本对 ROS 2 Dashing/Foxy/Humble 的支持范围不同,升级 ROS 版本后可能导致 ros2genmsg 等工具失效。示例项目里,我们以 ROS 1 Noetic 为例,如果使用 ROS 2,Matlab 侧函数名会变为 ros2init、ros2subscriber、ros2publisher,整体思路一致。
2.2 安装 ROS
Ubuntu 20.04 下安装 ROS Noetic,官方步骤是设置 sources.list、添加密钥、apt 更新、安装 ros-noetic-desktop-full,然后初始化 rosdep 和 environment。如果网络不稳定,可以通过国内镜像源安装,也可以借助社区经常提到的一键安装脚本,比如“鱼香ROS”工具。使用一键脚本前建议先阅读脚本内容,确认安装动作符合预期。
安装完成后,检查环境:
source /opt/ros/noetic/setup.bash roscore如果能看到started core service [/rosout],说明 ROS 主节点正常启动。
2.3 安装 MATLAB ROS Toolbox
在 MATLAB 中检查是否已经安装 ROS Toolbox:
ver('ros')如果显示找不到该工具箱,可以在 MATLAB 的 Add-On Explorer 中搜索 ROS Toolbox 并安装。需要注意,MATLAB 安装包体积大,Linux 环境下要确保磁盘空间充足,并给 MATLAB 启动脚本matlab添加可执行权限。
安装完成后,可以在 MATLAB 里运行:
rosinit它会尝试连接当前环境变量ROS_MASTER_URI指向的 ROS Master。如果本机没有启动 roscore,会提示连接失败。
2.4 网络配置
当 MATLAB 与 ROS 不在同一台机器时,网络配置是最容易出错的点。
- ROS 主机:使用
hostname -I查看 IP,设置export ROS_MASTER_URI=http://<ros主机IP>:11311和export ROS_IP=<ros主机IP>。 - MATLAB 主机:在连接前设置环境变量,或在 MATLAB 中使用
rosinit('http://<ros主机IP>:11311')手动指定 Master 地址。 - 虚拟机场景下,建议把网络模式改成桥接(Bridged)模式,否则宿主机和虚拟机之间的 IP 可能不在同一子网,连接不稳定。
3. ROS 与 MATLAB 通信原理拆解
3.1 ROS 通信机制回顾
ROS 中最常用的是话题。发布者把消息发到话题上,订阅者接收消息。这种模式适合连续数据流,比如 /scan 激光数据、/odom 里程计数据、/camera/image_raw 图像数据。
服务则适合一次性调用。例如机器人清空地图、切换导航目标点。客户端发送请求,服务端返回响应,是一问一答的模式。
动作是服务的增强版,适合需要取消、需要实时反馈的长任务。例如导航到目标点、机械臂执行轨迹。
MATLAB ROS Toolbox 对三种方式都有支持:话题可以用rospublisher、rossubscriber、send、receive;服务可以用rossvcclient;动作主要通过rosactionclient实现。
3.2 MATLAB 如何成为 ROS 节点
调用rosinit后,MATLAB 会启动一个内部 ROS 节点并连接到 ROS Master。此时你可以用rostopic list查看当前所有话题,这个命令在 MATLAB 命令行里也能执行。
rosinit rostopic listrosinit实际上做了什么?它会创建一个节点句柄,注册到 Master,并运行一个后台订阅线程。这样后续rossubscriber能持续接收消息,而不会阻塞 MATLAB 主线程。
如果你使用 ROS 2,对应的初始化函数是:
ros2init ros2 topic list3.3 MATLAB 发布与订阅的本质
MATLAB 发布话题时,需要先创建发布者:
pub = rospublisher('/cmd_vel', 'geometry_msgs/Twist'); msg = rosmessage(pub); msg.Linear.X = 0.2; msg.Angular.Z = 0.0; send(pub, msg);这段代码的逻辑是:创建一个发布到 /cmd_vel 的发布者,然后构造一个 geometry_msgs/Twist 消息,设置线速度和角速度,最后 send 发布。注意,rosmessage(pub)会根据发布者的消息类型自动生成一个空消息结构,方便直接赋值。
订阅时,常见写法有两种。一种是阻塞接收:
sub = rossubscriber('/odom', 'nav_msgs/Odometry'); odomMsg = receive(sub, 10);receive会阻塞等待最多 10 秒,直到收到消息。另一种是回调函数方式,适合持续数据处理:
sub = rossubscriber('/scan', @scanCallback);当新消息到达时,MATLAB 会自动调用scanCallback函数,并把消息对象传进去。
3.4 Simulink 中的 ROS 模块
Simulink 里也有 ROS 相关模块,位于 Simulink Library Browser 的 Robotics System Toolbox 或 ROS Toolbox 分类下。
常用模块包括:
- Publish:往指定话题发布消息。
- Subscribe:订阅指定话题,输出消息内容。
- Call Service:调用 ROS 服务。
这些模块适合搭建控制闭环。例如在 Simulink 中读取 /odom 位置信息,计算期望速度,再通过 Publish 模块发到 /cmd_vel,就能形成 Gazebo 中的自动控制回路。Simulink 还可以生成 C++ 代码,编译成独立 ROS 节点,不过这一步对编译器版本、ROS 版本和 MATLAB 版本都有要求,建议先从外部节点模式开始。
4. 完整实战案例
下面通过两个完整案例,演示 ROS 与 MATLAB 通信和联合仿真的核心流程。
4.1 案例一:MATLAB 订阅 ROS 话题
这个案例中,我们先用 Python 写一个 ROS 发布者节点,模拟机器人速度数据,然后在 MATLAB 里订阅并绘图。
4.1.1 创建 ROS 工作区
在 Ubuntu 主机上创建功能包:
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_create_pkg ros_matlab_demo rospy std_msgs geometry_msgs cd ~/catkin_ws catkin_make source devel/setup.bash这里我们创建了一个名为 ros_matlab_demo 的功能包,依赖 rospy 和消息包。功能包路径为~/catkin_ws/src/ros_matlab_demo。
4.1.2 编写 Python 发布节点
在~/catkin_ws/src/ros_matlab_demo/scripts/下新建vel_publisher.py:
#!/usr/bin/env python # -*- coding: utf-8 -*- import rospy from geometry_msgs.msg import Twist def main(): rospy.init_node('matlab_demo_vel_publisher', anonymous=True) pub = rospy.Publisher('/demo_vel', Twist, queue_size=10) rate = rospy.Rate(10) # 10 Hz vel_msg = Twist() vel_msg.linear.x = 0.5 vel_msg.angular.z = 0.1 while not rospy.is_shutdown(): pub.publish(vel_msg) rate.sleep() if __name__ == '__main__': try: main() except rospy.ROSInterruptException: pass给脚本添加执行权限:
chmod +x ~/catkin_ws/src/ros_matlab_demo/scripts/vel_publisher.py4.1.3 启动 ROS Master 和发布节点
终端一:
source /opt/ros/noetic/setup.bash roscore终端二:
source /opt/ros/noetic/setup.bash source ~/catkin_ws/devel/setup.bash rosrun ros_matlab_demo vel_publisher.py可以用rostopic echo /demo_vel验证话题是否有数据持续输出。
4.1.4 MATLAB 侧订阅并绘制
在 MATLAB 中新建脚本subscribe_demo.m:
clear; clc; % 连接 ROS Master,把 IP 换成你的 ROS 主机 IP rosinit('http://localhost:11311'); % 创建订阅者 sub = rossubscriber('/demo_vel', 'geometry_msgs/Twist'); % 接收 100 条消息,记录线速度 numSamples = 100; linearVel = zeros(1, numSamples); for i = 1:numSamples msg = receive(sub, 10); linearVel(i) = msg.Linear.X; pause(0.1); end % 绘制线速度时序 figure; plot(linearVel, 'LineWidth', 1.5); xlabel('Sample'); ylabel('Linear Velocity (m/s)'); title('MATLAB Subscribed /demo_vel'); grid on; % 关闭 ROS 连接 rosshutdown;运行后,MATLAB 会画出 100 个采样点上的线速度变化。如果 ROS 节点发布的是固定值 0.5,图像会是一条接近 0.5 的水平线。
这里有几个关键点:
rosinit('http://localhost:11311')指定 Master 地址,如果是远程主机,要写成对应 IP。rossubscriber第三个参数是消息类型,这里必须和发布端一致。receive(sub, 10)表示最多等 10 秒,超时会报错。
4.1.5 结果说明
预期结果是 MATLAB 能正常收到来自 Python 节点的 Twist 消息。如果收不到,优先检查rostopic list是否能看到 /demo_vel,以及两端 ROS_MASTER_URI 配置是否一致。
4.2 案例二:MATLAB 控制 Gazebo 中的机器人
这个案例演示真实联合仿真:Gazebo 里运行一个差速驱动机器人,MATLAB 发布速度指令,并订阅里程计数据形成闭环。
4.2.1 启动 Gazebo 仿真环境
以 TurtleBot3 为例,需要先安装相关功能包。启动命令如下:
source /opt/ros/noetic/setup.bash export TURTLEBOT3_MODEL=burger roslaunch turtlebot3_gazebo turtlebot3_world.launch启动后,Gazebo 会加载一个包含小车的仿真环境。/cmd_vel话题用于发布速度指令,/odom话题用于获取里程计信息。
检查话题:
rostopic list正常情况下可以看到/cmd_vel和/odom。
4.2.2 MATLAB 发布速度并订阅里程计
新建 MATLAB 脚本gazebo_control_demo.m:
clear; clc; rosinit('http://localhost:11311'); % 发布 /cmd_vel velPub = rospublisher('/cmd_vel', 'geometry_msgs/Twist'); velMsg = rosmessage(velPub); % 订阅 /odom odomSub = rossubscriber('/odom', 'nav_msgs/Odometry'); % 控制参数 simTime = 5.0; % 仿真时长 dt = 0.1; % 控制周期 steps = simTime / dt; % 记录轨迹 x_log = zeros(1, steps); y_log = zeros(1, steps); for i = 1:steps % 读取当前里程计 odomMsg = receive(odomSub, 2); x_log(i) = odomMsg.Pose.Pose.Position.X; y_log(i) = odomMsg.Pose.Pose.Position.Y; % 设定速度:先前进,后转弯 if i * dt < 2.0 velMsg.Linear.X = 0.2; velMsg.Angular.Z = 0.0; elseif i * dt < 3.0 velMsg.Linear.X = 0.0; velMsg.Angular.Z = 0.5; else velMsg.Linear.X = 0.2; velMsg.Angular.Z = 0.0; end send(velPub, velMsg); pause(dt); end % 停止机器人 velMsg.Linear.X = 0.0; velMsg.Angular.Z = 0.0; send(velPub, velMsg); % 绘制轨迹 figure; plot(x_log, y_log, 'LineWidth', 1.5); xlabel('X (m)'); ylabel('Y (m)'); title('Robot Trajectory in Gazebo'); axis equal; grid on; rosshutdown;运行这个脚本后,可以看到 Gazebo 中的小车先直线前进、再左转、再前进,MATLAB 中则画出完整的二维轨迹。
4.2.3 为什么用 receive 而不是回调
在这个脚本里,我们使用receive按控制周期主动获取里程计。好处是代码简单,逻辑顺序清晰,适合固定步长控制。如果使用回调函数,消息到达时间与发送指令的循环可能不同步,需要借助事件驱动逻辑,对新手不够直观。
4.2.4 结果说明
如果一切正常,Gazebo 小车运动轨迹和 MATLAB 绘制的轨迹基本一致。如果轨迹异常或小车不动,可以从以下几个方面检查:
/cmd_vel是否有效:在终端运行rostopic echo /cmd_vel,看是否有数据。- 小车是否有电池或控制模式限制:仿真环境下一般没有,但真实机器人需要注意。
- 里程计是否发布:运行
rostopic echo /odom检查数据频率。
4.3 案例三:Simulink 与 ROS 联合仿真
除了脚本方式,Simulink 也能直接和 ROS 交互。下面是一个最简单的例子:用 Simulink 发布正弦波速度指令,并订阅 Gazebo 的里程计。
4.3.1 创建 Simulink 模型
在 MATLAB 命令窗口输入simulink,新建空白模型。打开 Library Browser,添加以下模块:
- Signal Generator(Sources)
- Publish(ROS Toolbox)
- Subscribe(ROS Toolbox)
- Scope(Sinks)
4.3.2 配置 Publish 和 Subscribe 模块
Publish 模块配置:
- Topic:
/cmd_vel - Message type:
geometry_msgs/Twist - Sample time:0.1
由于 Publish 模块需要 Twist 结构体输入,我们可以用一个 Bus Assignment 或 MATLAB Function 模块构造消息。最简单的方法是添加一个 MATLAB Function:
function twist = buildTwist(speed) twist.Linear.X = speed; twist.Linear.Y = 0; twist.Linear.Z = 0; twist.Angular.X = 0; twist.Angular.Y = 0; twist.Angular.Z = 0; end将 Signal Generator 输出连接到这个函数的 speed 输入,再把 twist 输出接到 Publish 模块。
Subscribe 模块配置:
- Topic:
/odom - Message type:
nav_msgs/Odometry - Sample time:0.1
Subscribe 模块输出整个 Odometry 消息,你可以用 Selector 或 Bus Selector 取出 Position.X 和 Position.Y,再连接到 Scope 查看轨迹。
4.3.3 运行模型
在模型配置中,不需要额外设置,直接点击 Run。只要 MATLAB 已经rosinit,Simulink 就会通过同一个 ROS 网络收发数据。
需要注意的是,Simulink 模型运行时会占用 MATLAB 主线程,如果你还要在命令行执行其他操作,会不方便。建议把 Simulink 运行模式设置为外部模式(External),或者在单独 MATLAB 进程中运行模型。
5. 常见问题与排查思路
ROS 与 MATLAB 通信过程中,高频问题往往集中在网络配置、消息类型、版本兼容三方面。下面用表格汇总。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| rosinit 报错:Connection refused | ROS Master 没有启动 | 在 ROS 主机执行 roscore,确认 11311 端口 |
| rosinit 连接远程 Master 失败 | ROS_MASTER_URI 指向了 localhost | 在 MATLAB 中使用rosinit('http://<IP>:11311') |
| MATLAB 能连接,但 receive 超时 | 两端网络隔离或防火墙 | 检查 ros_IP、ping 连通性,虚拟机改用桥接模式 |
| rostopic list 看不到自定义话题 | MATLAB 和 ROS 不在同一 ROS 网络 | 确保 ROS_MASTER_URI 一致,且都在同一局域网 |
| MATLAB 识别不了自定义消息 | 自定义消息还没有生成 MATLAB 接口 | 使用 rosgenmsg 生成消息接口 |
| Simulink Publish 模块输入结构不匹配 | Twist 消息字段不全 | 用 Bus Assignment 或者 MATLAB Function 构造完整结构体 |
| Gazebo 中小车不动 | /cmd_vel 发布频率过低或消息全零 | 检查速度数值和输出频率,必要时用 rostopic echo 验证 |
| MATLAB 在 Ubuntu 上打开很慢 | 缺少图形驱动或字体渲染问题 | 设置 MATLAB_JAVA,或使用软件 OpenGL |
| ROS 2 下 rosinit 不可用 | 使用了 ROS 2 环境 | 改用 ros2init、ros2subscriber、ros2publisher |
5.1 rosinit 连接失败排查步骤
- 在 ROS 主机运行
hostname -I查看 IP。 - 检查
echo $ROS_MASTER_URI,默认应该是http://localhost:11311。 - 在 MATLAB 主机用浏览器或
ping测试能否访问该 IP。 - 如果是虚拟机,确认网络模式是桥接而不是 NAT。
- 在 MATLAB 中用
rosinit('http://192.168.1.100:11311')明确指定 Master 地址。
5.2 自定义消息处理
当 ROS 工程中有自定义消息,比如my_msgs/ControlCmd,MATLAB 默认无法直接识别。解决办法是使用 ROS Toolbox 的rosgenmsg函数:
rosgenmsg('/path/to/catkin_ws/src')执行后,MATLAB 会生成对应的消息接口,并在当前路径下生成一个matlab_gen文件夹。你需要把该文件夹添加到 MATLAB 路径,然后重新rosshutdown和rosinit,才能正常使用自定义消息。
注意:rosgenmsg生成的接口和 ROS 版本强相关。如果以后升级了 ROS 功能包里的消息定义,需要重新生成一次,否则容易出现字段对不上或类型冲突。
6. 最佳实践与工程建议
6.1 版本定好后不要轻易漂移
ROS 和 MATLAB 版本都比较“挑剔”。建议在项目里记录一份环境清单,包括 Ubuntu 版本、ROS 发行版、Gazebo 版本、MATLAB 版本、ROS Toolbox 版本,以及是否使用了 Docker。每次重新部署环境时,按照清单复现,可以省去大量排错时间。
6.2 网络配置固定化
在联合仿真实战里,最好把 ROS 主机和 MATLAB 主机的 IP 固定下来。DHCP 可能导致 IP 漂移,rosinit 和 roslaunch 配置里写死的地址会失效。你可以在 Ubuntu 的 Netplan 或 NetworkManager 里配置静态 IP,并把两台机器放到同一网段。
如果 MATLAB 和 ROS 跑在同一台电脑上,问题会简单很多,直接用rosinit默认连接 localhost 即可。第一轮学习建议先单机跑通,再扩展到远程。
6.3 优先使用标准消息类型
ROS 已经提供了非常丰富的标准消息,比如 geometry_msgs、nav_msgs、sensor_msgs、std_msgs。在设计接口时,优先复用这些消息,能减少rosgenmsg的额外开销。只有业务逻辑确实需要特殊字段时,再定义自定义消息。
自定义消息设计上要注意:
- 字段命名使用可读性强的下划线风格。
- 单位写清楚,比如长度一律用米,角度用弧度。
- 增加时间戳字段
std_msgs/Header header,方便下游同步。
6.4 Simulink 联调时注意时间同步
Simulink 仿真时间和 ROS 时间默认是独立的。如果你要严格同步,比如用 rosbag 录制仿真数据做回放,需要配置 Simulink 的 Sample Time 和 ROS 端时间源一致。常见做法是在 Simulink 中使能simulation time与 ROS Clock 同步。
对于大多数控制场景,真随机延迟有几十毫秒也能接受,但如果你在做里程计融合或高精度控制,一定要考虑时间戳对齐。
6.5 安全边界:先仿真,再真机
用 MATLAB 控制真实机器人前,必须先在 Gazebo 中完整验证。原因很简单,MATLAB 脚本里一个符号错误,可能导致机器人猛冲或反转。真实机器人上应当设置速度上限、使能急停、监控状态反馈。
如果你要发布真实机器人的 cmd_vel,务必做到:
- 在代码里限制最大线速度和角速度。
- 增加 watchdog,超过指定时间没有收到新指令就停止。
- 先以极低速度测试,比如 0.05 m/s。
- 手动断开急停开关,确保随时能停车。
6.6 日志与数据回放
联合仿真时,记录数据非常重要。你可以用 rosbag 记录整个 ROS 网络数据:
rosbag record -O matlab_demo.bag /cmd_vel /odom然后在 MATLAB 中离线处理这个 bag 文件:
bag = rosbag('matlab_demo.bag'); odomSel = select(bag, 'Topic', '/odom'); odomStruct = readMessages(odomSel, 'DataFormat', 'struct');这样做的好处是,即使仿真环境已经被关闭,你仍然可以反复调整算法参数,不需要重新跑一遍仿真。
6.7 代码组织建议
MATLAB 脚本不要全堆在一个文件里。建议按功能拆分模块:
ros_utils/存放 rosinit、rosshutdown 等连接管理函数。controllers/存放控制算法。plotters/存放数据可视化函数。scripts/存放一次性的演示脚本。
这样当你从 MATLAB 迁移到 C++ 节点时,模块边界已经清晰,可以直接参考算法部分的输入输出接口。
7. 总结与学习路线
本文从 ROS 与 MATLAB 通信的原理出发,梳理了环境准备、消息类型、话题订阅发布、Simulink 联合仿真等关键内容,并给出了三个可运行的实战案例。
你现在可以动手做以下练习:
- 在 Ubuntu 安装 ROS Noetic,在 MATLAB 安装 ROS Toolbox,执行一次
rosinit。 - 用 Python 编写一个话题发布节点,让 MATLAB 订阅并绘图。
- 启动 Gazebo 的 TurtleBot3 仿真,用 MATLAB 控制小车走一个方形轨迹。
- 尝试将 PID 控制器放进 Simulink,订阅 /odom,发布 /cmd_vel,形成闭环。
继续深入,可以学习这些方向:
- ROS 2 与 MATLAB 的 ros2 系列接口。
- Simulink Coder 自动生成 ROS C++ 节点。
- MATLAB 的 Robotics System Toolbox 与运动规划算法。
- 用 rosbag 做数据集采集,再用 MATLAB 做感知算法评测。
如果你在实战中遇到“版本不兼容”“消息类型不识别”“网络连接失败”这些问题,多回到第 5 节的排查表格,大概率能快速定位。机器人开发路很长,先把 ROS 和 MATLAB 这条通信链路打通,后面做感知、规划、控制都会顺手很多。