云计算百科
云计算领域专业知识百科平台

在MATLAB命令行执行ros2node 和 ros2subscriber后,执行ros2 topic list,MATLAB卡死

提问

setenv(‘ROS_DOMAIN_ID’,‘5’) node = ros2node(“test_node”); sub = ros2subscriber(node, “/topic_state”, “pid_interfaces/Command”);

我执行上面的命令,都是正常的,直到紧接着执行下面的命令:

ros2 topic list

然后MATLAB就一直处于busy。 无法完成。 这是为什么?

回答

你现在遇到的是一个MATLAB 在调用 ROS 2 相关 API 时陷入卡死(busy 状态)的问题,这类问题通常与 DDS 通信层阻塞或冲突 有关,下面是针对你情况的深度分析:


🧠 现象分析:

你成功执行了:

setenv('ROS_DOMAIN_ID','5');
node = ros2node("test_node");
sub = ros2subscriber(node, "/topic_state", "pid_interfaces/Command");

然后一旦执行:

ros2 topic list

MATLAB 卡住,进入 busy,甚至必须强制终止。


✅ 初步结论:

这是一个 DDS 节点/发现层阻塞死锁或资源竞争 问题。

✔ 为什么会这样?
  • ros2node 和 ros2subscriber 都会初始化 ROS 2 runtime 和底层 DDS 实例(Fast DDS)

  • ros2 topic list 调用又试图初始化 另一个节点或访问 ROS graph

  • 如果:

    • DDS participant 互相冲突(共享资源)
    • 底层 DDS 实现(如 FastDDS)有线程死锁风险
    • 自定义消息未正确定义或未注册(特别是 pid_interfaces/Command)
    • 端口/资源(如 multicast 地址)已被占用或绑定异常 那么在调用 ros2 topic list 时,DDS discovery 阶段就会阻塞,造成 MATLAB 卡死

✅ 对策建议:

✅ 一:避免混用 ros2subscriber 和 ros2 topic list

你已经创建了一个 ros2node 和 ros2subscriber,这些已经启动了一个 DDS 会话。 此时不要再用 ros2 topic list 命令去触发另一个 DDS Graph API 操作,建议调试过程只使用一类 API,否则会出现 DDS 死锁。

❗️推荐做法是:先用 ros2 topic list,再构建 ros2subscriber


✅ 二:换一种方式验证话题是否收到

比如你已经建立了 subscriber,那就直接:

msg = receive(sub, 5);

  • 如果 5 秒内能收到消息,说明连接一切正常
  • 如果 5 秒后报超时(Timeout while receiving),说明订阅建立但没有实际收到消息(要么发太慢,要么消息类型不匹配)

✅ 三:建议你执行以下测试脚本

把下面的操作流程当作“黄金验证路径”,只使用一次 DDS 初始化,避免混用 MATLAB API 和 CLI 命令:

% 确保环境变量设置正确
setenv('ROS_DOMAIN_ID','5');

% 创建节点
node = ros2node("sim_debug");

% 列出话题(推荐先做这个)
disp(ros2topic("list")); % 如果这里不卡死,说明 DDS OK

% 创建订阅者
sub = ros2subscriber(node, "/topic_state", "pid_interfaces/Command");

% 接收消息
msg = receive(sub, 5);
disp(msg);


✅ 四:防止卡死建议

如果你已经卡死过,建议你执行以下清理动作后重试:

  • 重启 MATLAB

  • 关闭所有后台的 ros2 daemon(Linux 端执行 ros2 daemon stop)

  • 删除 DDS 缓存:

    • Windows: %LocalAppData%\\Temp\\fastrtps* 等缓存文件
    • Linux: ~/.ros 或 ~/.dds 相关缓存
  • 确保 Linux 和 Windows 使用相同的 RMW 实现(如都是 rmw_fastrtps_cpp)

  • 确保 Windows 防火墙彻底关闭,或者明确放通 UDP 多播端口(7400/7410)


  • ✅ 五:参考已知问题

    • MathWorks 已知问题报告
    • 官方建议在某些版本中避免在 node active 时使用 ros2 CLI 命令
    • 或者通过 clear all 清除所有 ROS 节点,再执行 ros2 topic list 也可避免冲突

    ✅ 总结

    结论说明
    不建议在已有 ros2node 和 ros2subscriber 的会话中使用 ros2 topic list 会触发 DDS 层冲突或阻塞
    建议先使用 ros2 topic list,再初始化节点/订阅者 避免 DDS 冲突
    你当前问题极可能是 DDS participant 重复或线程资源死锁 并非 Simulink 问题,而是底层通信资源未正确释放

    是否需要我帮你写个自动化测试脚本(自动初始化节点、订阅、接收并打印消息),方便你以后排查这类问题?

    继续提问

    为什么使用了 setenv(‘ROS_DOMAIN_ID’,‘5’) node = ros2node(“test_node”); sub = ros2subscriber(node, “/topic_state”, “pid_interfaces/Command”);

    以后,连打开simulink都变得很慢?如何取消节点?

    回答

    你发现 使用了 ros2node 和 ros2subscriber 后,连打开 Simulink 都变得很慢,这个现象确实存在,并且是可以解释的:


    🧠 问题根源:ROS 2 节点阻塞 DDS 网络线程资源

    执行:

    setenv('ROS_DOMAIN_ID','5')
    node = ros2node("test_node");
    sub = ros2subscriber(node, "/topic_state", "pid_interfaces/Command");

    实际上会常驻启动一个 ROS 2 节点,这个节点:

    • 会开启底层 DDS participant(Fast DDS)
    • 会占用线程、UDP端口、多播资源
    • 会持续尝试“发现”远程参与者,尤其如果远端不回应,就会不断重试,消耗 CPU + 网络堆栈资源

    于是就导致:

    现象原因
    Simulink 打开慢 Simulink 在启动时也会尝试初始化 ROS 2 子系统,结果被当前 DDS participant 阻塞
    MATLAB 运行慢 ROS2 节点内部有 I/O 线程和 discovery loop,持续占资源
    多次运行 ros2node 后卡死 participant 没有及时释放,堆积成“幽灵节点”

    ✅ 如何释放和取消节点

    你可以使用下面命令立即释放所有 ROS 2 资源:

    clear node sub

    如果你还用了多个变量:

    clear all

    然后再执行:

    ros2 reset

    这将彻底清除 MATLAB 当前会话中的所有 ROS 2 DDS participant 和缓存。


    ✅ 补充推荐操作

    如果你已经执行过 ros2node 等命令,建议在打开 Simulink 前先做这两件事:

    clear all
    ros2 reset

    然后再打开 Simulink,速度会明显恢复。


    ✅ 持久优化建议

    1. 养成习惯:测试完 ROS2 后清理资源

    clear node sub
    ros2 reset

    2. 避免在 MATLAB 启动后立即执行多个 ROS2 节点(会拖慢初始化)

    3. 如果你调试频繁,可写个“清理小脚本”:

    function cleanup_ros2()
    try
    clear all;
    ros2 reset;
    disp("✅ 已清理 ROS2 节点和 DDS participant");
    catch
    disp("⚠️ 无 ROS2 节点正在运行");
    end
    end


    ✅ 总结

    你做了什么?发生了什么?
    执行 ros2node 和 ros2subscriber 启动 ROS 2 DDS 节点,抢占资源
    之后打开 Simulink Simulink 内部初始化 ROS 2,发生阻塞冲突
    MATLAB 很慢 DDS participant 没释放,持续发现网络节点
    如何解决 clear node sub,然后 ros2 reset 即可

    需要我帮你写一个一键测试 + 自动清理的 ROS2 脚本模板吗?这样你每次调试完就不会拖慢 MATLAB 或 Simulink。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 在MATLAB命令行执行ros2node 和 ros2subscriber后,执行ros2 topic list,MATLAB卡死
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!