不使用planning_scene接口发布collision_object后Rviz无可视化显示
我之前在做MoveIt项目时也踩过这个坑——放弃用planning_scene.addCollisionObjects(),自己手动发布话题添加碰撞物体,但RViz里就是没动静。后来排查出几个容易忽略的关键点,给你梳理一下:
一定要设置正确的坐标系ID
CollisionObject消息的header.frame_id必须和RViz中使用的固定坐标系一致(比如常用的base_link或world)。如果填成了机器人的某个活动连杆坐标系,TF变换没跟上的话,物体就会“隐身”。举个正确的写法:collision_object.header.frame_id = "base_link"; collision_object.header.stamp = ros::Time::now();别漏了操作类型(operation)
MoveIt需要明确知道你对碰撞物体做什么操作——是添加、移除还是替换。如果没设置collision_object.operation,planning scene节点会直接忽略这条消息。添加物体的话要写:collision_object.operation = moveit_msgs::CollisionObject::ADD;等订阅者连上再发消息
刚创建publisher就立刻发消息,很可能此时planning_scene_monitor还没完成订阅,导致消息直接丢失。给publisher加个等待逻辑:// 等待collision_object话题的订阅者 while (pub_co.getNumSubscribers() == 0 && ros::ok()) { ROS_INFO("Waiting for collision_object subscribers..."); ros::Duration(0.5).sleep(); } // attached_collision_object同理 while (pub_aco.getNumSubscribers() == 0 && ros::ok()) { ROS_INFO("Waiting for attached_collision_object subscribers..."); ros::Duration(0.5).sleep(); }检查物体的形状和位置是否合理
有时候不是没显示,而是物体太小或者藏在机器人模型里了。可以先把物体放在显眼的位置,比如机器人前方0.5米处,尺寸设大一点:shape_msgs::SolidPrimitive box; box.type = box.BOX; box.dimensions = {0.2, 0.2, 0.2}; // 长宽高各20cm geometry_msgs::Pose box_pose; box_pose.orientation.w = 1.0; box_pose.position.x = 0.5; box_pose.position.y = 0.0; box_pose.position.z = 0.5;附着物体的特殊注意事项
如果是发布AttachedCollisionObject,要确保attached_collision_object.link_name是机器人的有效连杆(比如夹爪的gripper_finger_link),并且物体的位姿是相对于这个连杆的坐标系。同时别忘了设置attached_collision_object.object.operation = moveit_msgs::CollisionObject::ADD;。查看MoveIt的日志找线索
启动MoveIt的时候,看看终端输出的日志,有没有类似“Invalid frame ID 'xxx' passed to lookupTransform”或者“Collision object not processed: no operation specified”的警告,这些日志能直接帮你定位问题。
你可以按照上面的步骤逐一排查,应该就能解决RViz不显示的问题了。
内容的提问来源于stack exchange,提问作者MostafaBakr

