@@ -152,6 +152,10 @@ class StageNode
152152 const char *mapName (const char *name, size_t robotID, Stg::Model* mod) const ;
153153 const char *mapName (const char *name, size_t robotID, size_t deviceID, Stg::Model* mod) const ;
154154
155+ // Append robot name to a tf message. This is for multi-robot simulation with arc.
156+ const char *mapTfName (const char *name, size_t robotID, Stg::Model* mod) const ;
157+ const char *mapTfName (const char *name, size_t robotID, size_t deviceID, Stg::Model* mod) const ;
158+
155159 tf::TransformBroadcaster tf;
156160
157161 // Last time that we received a velocity command
@@ -203,6 +207,33 @@ class StageNode
203207 Stg::World* world;
204208};
205209
210+ // since stageros is single-threaded, this is OK. revisit if that changes!
211+ const char *
212+ StageNode::mapTfName (const char *name, size_t robotID, Stg::Model* mod) const
213+ {
214+ // ROS_INFO("Robot %lu: Device %s", robotID, name);
215+ bool umn = this ->use_model_names ;
216+
217+ if ((positionmodels.size () > 1 ) || umn)
218+ {
219+ static char buf[100 ];
220+ std::size_t found = std::string (((Stg::Ancestor *) mod)->Token ()).find (" :" );
221+
222+ if ((found==std::string::npos) && umn)
223+ {
224+ snprintf (buf, sizeof (buf), " /%s/%s" , ((Stg::Ancestor *) mod)->Token (), name);
225+ }
226+ else
227+ {
228+ snprintf (buf, sizeof (buf), " /robot_%u/%s" , (unsigned int )robotID, name);
229+ }
230+
231+ return buf;
232+ }
233+ else
234+ return name;
235+ }
236+
206237// since stageros is single-threaded, this is OK. revisit if that changes!
207238const char *
208239StageNode::mapName (const char *name, size_t robotID, Stg::Model* mod) const
@@ -275,6 +306,36 @@ StageNode::mapName(const char *name, size_t robotID, size_t deviceID, Stg::Model
275306 }
276307}
277308
309+ const char *
310+ StageNode::mapTfName (const char *name, size_t robotID, size_t deviceID, Stg::Model* mod) const
311+ {
312+ // ROS_INFO("Robot %lu: Device %s:%lu", robotID, name, deviceID);
313+ bool umn = this ->use_model_names ;
314+
315+ if ((positionmodels.size () > 1 ) || umn)
316+ {
317+ static char buf[100 ];
318+ std::size_t found = std::string (((Stg::Ancestor *) mod)->Token ()).find (" :" );
319+
320+ if ((found==std::string::npos) && umn)
321+ {
322+ snprintf (buf, sizeof (buf), " /%s/%s_%u" , ((Stg::Ancestor *) mod)->Token (), name, (unsigned int )deviceID);
323+ }
324+ else
325+ {
326+ snprintf (buf, sizeof (buf), " /robot_%u/%s_%u" , (unsigned int )robotID, name, (unsigned int )deviceID);
327+ }
328+
329+ return buf;
330+ }
331+ else
332+ {
333+ static char buf[100 ];
334+ snprintf (buf, sizeof (buf), " /%s_%u" , name, (unsigned int )deviceID);
335+ return buf;
336+ }
337+ }
338+
278339void
279340StageNode::ghfunc (Stg::Model* mod, StageNode* node)
280341{
@@ -628,9 +689,9 @@ StageNode::WorldCallback()
628689 }
629690
630691 if (robotmodel->lasermodels .size () > 1 )
631- msg.header .frame_id = mapName (BASE_LASER_LINK, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
692+ msg.header .frame_id = mapTfName (BASE_LASER_LINK, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
632693 else
633- msg.header .frame_id = mapName (BASE_LASER_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
694+ msg.header .frame_id = mapTfName (BASE_LASER_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
634695
635696 msg.header .stamp = sim_time;
636697 robotmodel->laser_pubs [s].publish (msg);
@@ -645,12 +706,12 @@ StageNode::WorldCallback()
645706
646707 if (robotmodel->lasermodels .size () > 1 )
647708 tf.sendTransform (tf::StampedTransform (txLaser, sim_time,
648- mapName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
649- mapName (BASE_LASER_LINK, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
709+ mapTfName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
710+ mapTfName (BASE_LASER_LINK, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
650711 else
651712 tf.sendTransform (tf::StampedTransform (txLaser, sim_time,
652- mapName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
653- mapName (BASE_LASER_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
713+ mapTfName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
714+ mapTfName (BASE_LASER_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
654715 }
655716
656717 // loop on the fiducial detectors for the current robot
@@ -691,9 +752,9 @@ StageNode::WorldCallback()
691752 }
692753
693754 if (robotmodel->fiducialmodels .size () > 1 )
694- msg.header .frame_id = mapName (BASE_FIDUCIAL_LINK, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
755+ msg.header .frame_id = mapTfName (BASE_FIDUCIAL_LINK, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
695756 else
696- msg.header .frame_id = mapName (BASE_FIDUCIAL_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
757+ msg.header .frame_id = mapTfName (BASE_FIDUCIAL_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
697758
698759 msg.header .stamp = sim_time;
699760 robotmodel->fiducial_pubs [s].publish (msg);
@@ -707,19 +768,19 @@ StageNode::WorldCallback()
707768
708769 if (robotmodel->lasermodels .size () > 1 )
709770 tf.sendTransform (tf::StampedTransform (txFiducial, sim_time,
710- mapName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
711- mapName (BASE_FIDUCIAL_LINK, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
771+ mapTfName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
772+ mapTfName (BASE_FIDUCIAL_LINK, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
712773 else
713774 tf.sendTransform (tf::StampedTransform (txFiducial, sim_time,
714- mapName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
715- mapName (BASE_FIDUCIAL_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
775+ mapTfName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
776+ mapTfName (BASE_FIDUCIAL_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
716777 }
717778
718779 // the position of the robot
719780 tf.sendTransform (tf::StampedTransform (tf::Transform::getIdentity (),
720781 sim_time,
721- mapName (BASE_FOOTPRINT, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
722- mapName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
782+ mapTfName (BASE_FOOTPRINT, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
783+ mapTfName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
723784
724785 // Get latest odometry data
725786 // Translate into ROS message format and publish
@@ -735,7 +796,7 @@ StageNode::WorldCallback()
735796 // @todo Publish stall on a separate topic when one becomes available
736797 // this->odomMsgs[r].stall = this->positionmodels[r]->Stall();
737798 //
738- odom_msg.header .frame_id = mapName (ODOM, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
799+ odom_msg.header .frame_id = mapTfName (ODOM, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
739800 odom_msg.header .stamp = sim_time;
740801
741802 robotmodel->odom_pub .publish (odom_msg);
@@ -745,8 +806,8 @@ StageNode::WorldCallback()
745806 tf::quaternionMsgToTF (odom_msg.pose .pose .orientation , odomQ);
746807 tf::Transform txOdom (odomQ, tf::Point (odom_msg.pose .pose .position .x , odom_msg.pose .pose .position .y , 0.0 ));
747808 tf.sendTransform (tf::StampedTransform (txOdom, sim_time,
748- mapName (ODOM, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
749- mapName (BASE_FOOTPRINT, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
809+ mapTfName (ODOM, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
810+ mapTfName (BASE_FOOTPRINT, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
750811
751812 // Also publish the ground truth pose and velocity
752813 Stg::Pose gpose = robotmodel->positionmodel ->GetGlobalPose ();
@@ -782,7 +843,7 @@ StageNode::WorldCallback()
782843 ground_truth_msg.twist .twist .linear .z = gvel.z ;
783844 ground_truth_msg.twist .twist .angular .z = gvel.a ;
784845
785- ground_truth_msg.header .frame_id = mapName (BASE_POSE_GROUND_TRUTH, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
846+ ground_truth_msg.header .frame_id = mapTfName (BASE_POSE_GROUND_TRUTH, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
786847 ground_truth_msg.header .stamp = sim_time;
787848
788849 robotmodel->ground_truth_pub .publish (ground_truth_msg);
@@ -819,9 +880,9 @@ StageNode::WorldCallback()
819880 }
820881
821882 if (robotmodel->cameramodels .size () > 1 )
822- image_msg.header .frame_id = mapName (CAMERA, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
883+ image_msg.header .frame_id = mapTfName (CAMERA, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
823884 else
824- image_msg.header .frame_id = mapName (CAMERA, r,static_cast <Stg::Model*>(robotmodel->positionmodel ));
885+ image_msg.header .frame_id = mapTfName (CAMERA, r,static_cast <Stg::Model*>(robotmodel->positionmodel ));
825886 image_msg.header .stamp = sim_time;
826887
827888 robotmodel->image_pubs [s].publish (image_msg);
@@ -877,9 +938,9 @@ StageNode::WorldCallback()
877938 }
878939
879940 if (robotmodel->cameramodels .size () > 1 )
880- depth_msg.header .frame_id = mapName (CAMERA, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
941+ depth_msg.header .frame_id = mapTfName (CAMERA, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
881942 else
882- depth_msg.header .frame_id = mapName (CAMERA, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
943+ depth_msg.header .frame_id = mapTfName (CAMERA, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
883944 depth_msg.header .stamp = sim_time;
884945 robotmodel->depth_pubs [s].publish (depth_msg);
885946 }
@@ -900,18 +961,18 @@ StageNode::WorldCallback()
900961
901962 if (robotmodel->cameramodels .size () > 1 )
902963 tf.sendTransform (tf::StampedTransform (tr, sim_time,
903- mapName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
904- mapName (CAMERA, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
964+ mapTfName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
965+ mapTfName (CAMERA, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
905966 else
906967 tf.sendTransform (tf::StampedTransform (tr, sim_time,
907- mapName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
908- mapName (CAMERA, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
968+ mapTfName (BASE_LINK, r, static_cast <Stg::Model*>(robotmodel->positionmodel )),
969+ mapTfName (CAMERA, r, static_cast <Stg::Model*>(robotmodel->positionmodel ))));
909970
910971 sensor_msgs::CameraInfo camera_msg;
911972 if (robotmodel->cameramodels .size () > 1 )
912- camera_msg.header .frame_id = mapName (CAMERA, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
973+ camera_msg.header .frame_id = mapTfName (CAMERA, r, s, static_cast <Stg::Model*>(robotmodel->positionmodel ));
913974 else
914- camera_msg.header .frame_id = mapName (CAMERA, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
975+ camera_msg.header .frame_id = mapTfName (CAMERA, r, static_cast <Stg::Model*>(robotmodel->positionmodel ));
915976 camera_msg.header .stamp = sim_time;
916977 camera_msg.height = cameramodel->getHeight ();
917978 camera_msg.width = cameramodel->getWidth ();
0 commit comments