• 问题与报错

在使用moveit2中的getCurrentPose()接口函数时出现报错:

[moveit2_ik_demo-1] [INFO] [1761290240.162356682] [moveit_ros.current_state_monitor]: Listening to joint states on topic 'joint_states'
[moveit2_ik_demo-1] [INFO] [1761290243.188118174] [moveit_ros.current_state_monitor]: Didn't received robot state (joint angles) with recent timestamp within 1.000000 seconds.
[moveit2_ik_demo-1] Check clock synchronization if your are running ROS across multiple machines!
[moveit2_ik_demo-1] [ERROR] [1761290243.188158369] [move_group_interface]: Failed to fetch current robot state
[moveit2_ik_demo-1] [INFO] [1761290244.188528379] [moveit_ros.current_state_monitor]: Didn't received robot state (joint angles) with recent timestamp within 1.000000 seconds.
[moveit2_ik_demo-1] Check clock synchronization if your are running ROS across multiple machines!
[moveit2_ik_demo-1] [ERROR] [1761290244.188567393] [move_group_interface]: Failed to fetch current robot state

报错里写了什么时间戳错误,我排查了很多比如系统时间戳、命名空间、话题发布顺序......但都没有解决问题,排查了两天终于发现是线程调度问题。

  • 真正的报错原因

MoveIt2 的 current_state_monitor通过订阅 /joint_states来更新内部的当前机器人状态。这个更新发生在订阅回调(callback)里。如果程序没有在某个线程里 spin() 或者运行 executor,那么这些回调就不会被执行,因此内部状态一直不能最新更新。

  • 解决方式

创建线程池来并行执行订阅/服务/定时器的回调:

executor_ = std::make_shared<rclcpp::executors::MultiThreadedExecutor>();
executor_->add_node(node_);
executor_thread_ = std::thread([this]() { executor_->spin(); });

只要把 node 加到 executor 并让 executor 在后台 spin(), 订阅到的消息回调就能被真正执行,MoveIt 的 current_state_monitor 就能更新它的内部状态(joint angles 和时间戳)。

随后在析构或退出时停止executor:executor_->cancel() 并 join() 线程,避免程序退出时出现悬挂或内存问题。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐