AprilRobotics / apriltag_ros

A ROS wrapper of the AprilTag 3 visual fiducial detector
Other
362 stars 338 forks source link

Multiple Instances of apriltag_ros for Multiple Cameras #82

Closed shonigmann closed 3 years ago

shonigmann commented 3 years ago

Is running multiple instances of AprilTag_ROS under different namespaces possible?

I am working on a system with multiple cameras tracking the same set of tag bundles and would like to be able to start multiple instances of apriltag_ros in difference namespaces, to manage and fuse the tracking results independently.

I noticed that the node_namespace parameter in the .launch file is used as the apriltag_ros node "name" argument rather than as the namespace ("ns") argument. As a result, when I start multiple instances with different "node_namespace" values, they compete to publish to the same topic.

I tried adding a "ns" argument to the launch file, but this resulted in the loaded .yaml parameters being lost, returning the following warnings:

[ WARN] [1603304584.543327789]: No april tags specified
[ WARN] [1603304584.543889633]: No tag bundles specified

Worst case scenario, I could write a quick subscriber that sorts the published messages by "frame_id", which is unique between the different cameras... but I'm wondering if there is a cleaner route that I am missing.

Thanks in advance for any help! AprilTag is otherwise working great for me!

wxmerkt commented 3 years ago

Hi @shonigmann, This should be possible - the launch file is a bit confusing here:

  1. node_namespace is an argument to specify the name of the node, not the namespace.
  2. You can specify to load parameters within the <node> tag, and then also use the ns argument to specify a namespace.

E.g.:

<launch>
  <arg name="launch_prefix" default="" /> <!-- set to value="gdbserver localhost:10000" for remote debugging -->
  <arg name="camera_name" default="/cv_camera" />
  <arg name="camera_frame" default="camera" />
  <arg name="image_topic" default="image_rect_color" />

  <node pkg="apriltag_ros" type="apriltag_ros_continuous_node" name="apriltag_ros_continuous_node" clear_params="true" output="screen" launch-prefix="$(arg launch_prefix)" ns="my_apriltag_namespace">
    <!-- Remap topics from those used in code to those on the ROS network -->
    <remap from="image_rect" to="$(arg camera_name)/$(arg image_topic)" />
    <remap from="camera_info" to="$(arg camera_name)/camera_info" />

    <param name="camera_frame" type="str" value="$(arg camera_frame)" />
    <param name="publish_tag_detections_image" type="bool" value="true" />      <!-- default: false -->

    <!-- Set parameters -->
    <rosparam command="load" file="$(find apriltag_ros)/config/settings.yaml"/>
    <rosparam command="load" file="$(find apriltag_ros)/config/tags.yaml"/>
  </node>
</launch>

Note the namespace my_apriltag_namespace. The loaded rosparams are now:

/my_apriltag_namespace/apriltag_ros_continuous_node/camera_frame
/my_apriltag_namespace/apriltag_ros_continuous_node/publish_tag_detections_image
/my_apriltag_namespace/apriltag_ros_continuous_node/publish_tf
/my_apriltag_namespace/apriltag_ros_continuous_node/standalone_tags
/my_apriltag_namespace/apriltag_ros_continuous_node/tag_blur
/my_apriltag_namespace/apriltag_ros_continuous_node/tag_bundles
/my_apriltag_namespace/apriltag_ros_continuous_node/tag_debug
/my_apriltag_namespace/apriltag_ros_continuous_node/tag_decimate
/my_apriltag_namespace/apriltag_ros_continuous_node/tag_family
/my_apriltag_namespace/apriltag_ros_continuous_node/tag_refine_edges
/my_apriltag_namespace/apriltag_ros_continuous_node/tag_threads

And the rostopics:

/my_apriltag_namespace/tag_detections
/my_apriltag_namespace/tag_detections_image
/my_apriltag_namespace/tag_detections_image/compressed
/my_apriltag_namespace/tag_detections_image/compressed/parameter_descriptions
/my_apriltag_namespace/tag_detections_image/compressed/parameter_updates
/my_apriltag_namespace/tag_detections_image/compressedDepth
/my_apriltag_namespace/tag_detections_image/compressedDepth/parameter_descriptions
/my_apriltag_namespace/tag_detections_image/compressedDepth/parameter_updates
/my_apriltag_namespace/tag_detections_image/theora
/my_apriltag_namespace/tag_detections_image/theora/parameter_descriptions
/my_apriltag_namespace/tag_detections_image/theora/parameter_updates
/tf
shonigmann commented 3 years ago

Hi @wxmerkt ,

Thanks for the quick response! Your suggestion is just about perfect for me!

One more quick question for you - with the proposed change, the tag bundle TF estimates are still getting written to the same TF name (as defined by the bundle name in tags.yaml). I'm not terribly familiar with yaml, so I'm not sure if there is a good way to change this on the fly from within the launch file to so that the TF name matches the namespace, or if I would need to concatenate the namespace in the source code?

This isn't super important for my work - it would just make my RVIZ display a bit cleaner.

Thanks again!

wxmerkt commented 3 years ago

Hi @shonigmann, The tf currently do not consider the namespace. You'd either have to change it the name in the yaml or we'd have to add an option for a prefix.

shonigmann commented 3 years ago

Good to know!