microsoft / Azure_Kinect_ROS_Driver

A ROS sensor driver for the Azure Kinect Developer Kit.
MIT License
304 stars 226 forks source link

Synchronize kinects on different hosts #263

Open rouzinho opened 1 year ago

rouzinho commented 1 year ago

Hello,

I found many solution for synchronizing 2 kinects on the same computer and it was working well. Now, we want to dedicate one kinect per computer to increase the speed of our application. However, the kinects are not synchronized and the time stamp difference between the master node and the subordinate node is too large to receive them at the same time (through a message filter). I configured the master and slave kinects correctly and the ros master node is the master kinect. Here are the launch files for master and subordinate. master :

<launch>
  <arg name="tf_prefix"         default="" />                       <!-- Prefix added to tf frame IDs. It typically contains a trailing '_' unless empty. -->
  <arg name="master_tf_prefix"         default="master_" />
  <arg name="overwrite_robot_description" default="true" />         <!-- Flag to publish a standalone azure_description instead of the default robot_descrition parameter-->

  <group if="$(arg overwrite_robot_description)">
    <param name="robot_description"
      command="xacro $(find azure_kinect_ros_driver)/urdf/azure_kinect.urdf.xacro tf_prefix:=$(arg tf_prefix)" />
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
  </group>

  <group unless="$(arg overwrite_robot_description)">
    <param name="azure_description"
      command="xacro $(find azure_kinect_ros_driver)/urdf/azure_kinect.urdf.xacro tf_prefix:=$(arg tf_prefix)/" />
    <node name="joint_state_publisher_azure" pkg="joint_state_publisher" type="joint_state_publisher">
      <remap from="robot_description" to="azure_description" />
    </node>  
    <node name="robot_state_publisher_azure" pkg="robot_state_publisher" type="robot_state_publisher">
      <remap from="robot_description" to="azure_description" />
    </node>
  </group>

  <arg name="depth_enabled"           default="true" />           <!-- Enable or disable the depth camera -->
  <arg name="depth_mode"              default="WFOV_UNBINNED" />  <!-- Set the depth camera mode, which affects FOV, depth range, and camera resolution. See Azure Kinect documentation for full details. Valid options: NFOV_UNBINNED, NFOV_2X2BINNED, WFOV_UNBINNED, WFOV_2X2BINNED, and PASSIVE_IR -->
  <arg name="color_enabled"           default="true" />           <!-- Enable or disable the color camera -->
  <arg name="color_format"            default="bgra" />           <!-- The format of RGB camera. Valid options: bgra, jpeg -->
  <arg name="color_resolution"        default="720P" />          <!-- Resolution at which to run the color camera. Valid options: 720P, 1080P, 1440P, 1536P, 2160P, 3072P -->
  <arg name="fps"                     default="15" />              <!-- FPS to run both cameras at. Valid options are 5, 15, and 30 -->
  <arg name="point_cloud"             default="true" />           <!-- Generate a point cloud from depth data. Requires depth_enabled -->
  <arg name="rgb_point_cloud"         default="true" />           <!-- Colorize the point cloud using the RBG camera. Requires color_enabled and depth_enabled -->
  <arg name="point_cloud_in_depth_frame" default="false" />        <!-- Whether the RGB pointcloud is rendered in the depth frame (true) or RGB frame (false). Will either match the resolution of the depth camera (true) or the RGB camera (false). -->
  <arg name="required"                default="false" />          <!-- Argument which specified if the entire launch file should terminate if the node dies -->
  <arg name="sensor_sn"               default="" />               <!-- Sensor serial number. If none provided, the first sensor will be selected -->
  <arg name="master_sensor_sn"               default="000708621712" />               <!-- Sensor serial number of the master device. If none provided, the first sensor will be selected -->
  <arg name="recording_file"          default="" />               <!-- Absolute path to a mkv recording file which will be used with the playback api instead of opening a device -->
  <arg name="recording_loop_enabled"  default="false" />          <!-- If set to true the recording file will rewind the beginning once end of file is reached -->
  <arg name="body_tracking_enabled"           default="false" />  <!-- If set to true the joint positions will be published as marker arrays -->
  <arg name="body_tracking_smoothing_factor"  default="0.0" />    <!-- Set between 0 for no smoothing and 1 for full smoothing -->
  <arg name="rescale_ir_to_mono8"  default="false" />    <!-- Whether to rescale the IR image to an 8-bit monochrome image for visualization and further processing. A scaling factor (ir_mono8_scaling_factor) is applied. -->
  <arg name="ir_mono8_scaling_factor"  default="1.0" />    <!-- Scaling factor to apply when converting IR to mono8 (see rescale_ir_to_mono8). If using illumination, use the value 0.5-1. If using passive IR, use 10. -->
  <arg name="imu_rate_target" default="0"/>                       <!-- Desired output rate of IMU messages. Set to 0 (default) for full rate (1.6 kHz). --> 
  <arg name="wired_sync_mode" default="1"/>                       <!-- Wired sync mode. 0: OFF, 1: MASTER, 2: SUBORDINATE. --> 
  <arg name="master_wired_sync_mode" default="1"/>                       <!-- Wired sync mode. 0: OFF, 1: MASTER, 2: SUBORDINATE. --> 
  <arg name="subordinate_delay_off_master_usec" default="0"/>     <!-- Delay subordinate camera off master camera by specified amount in usec. --> 

  <node pkg="azure_kinect_ros_driver" type="node" name="azure_kinect_ros_driver_master" output="screen" required="$(arg required)" ns="master">
    <param name="depth_enabled"     type="bool"   value="$(arg depth_enabled)" />
    <param name="depth_mode"        type="string" value="$(arg depth_mode)" />
    <param name="color_enabled"     type="bool"   value="$(arg color_enabled)" />
    <param name="color_format"      type="string" value="$(arg color_format)" />
    <param name="color_resolution"  type="string" value="$(arg color_resolution)" />
    <param name="fps"               type="int"    value="$(arg fps)" />
    <param name="point_cloud"       type="bool"   value="$(arg point_cloud)" />
    <param name="rgb_point_cloud"   type="bool"   value="$(arg rgb_point_cloud)" />
    <param name="point_cloud_in_depth_frame"   type="bool"   value="$(arg point_cloud_in_depth_frame)" />
    <param name="sensor_sn"         type="string" value="$(arg master_sensor_sn)" />
    <param name="tf_prefix"         type="string" value="$(arg master_tf_prefix)" />
    <param name="recording_file"          type="string" value="$(arg recording_file)" />
    <param name="recording_loop_enabled"  type="bool"   value="$(arg recording_loop_enabled)" />
    <param name="body_tracking_enabled"           type="bool"   value="$(arg body_tracking_enabled)" />
    <param name="body_tracking_smoothing_factor"  type="double" value="$(arg body_tracking_smoothing_factor)" />
    <param name="rescale_ir_to_mono8" type="bool" value="$(arg rescale_ir_to_mono8)" />
    <param name="ir_mono8_scaling_factor" type="double" value="$(arg ir_mono8_scaling_factor)" />
    <param name="imu_rate_target" type="int" value="$(arg imu_rate_target)"/>
    <param name="wired_sync_mode" type="int" value="$(arg master_wired_sync_mode)"/>
    <param name="subordinate_delay_off_master_usec" type="int" value="0"/>
  </node>
</launch>

and the subordinate node :

<launch>
  <arg name="tf_prefix"         default="" />                       <!-- Prefix added to tf frame IDs. It typically contains a trailing '_' unless empty. -->
  <arg name="sub_tf_prefix"         default="sub_" />
  <arg name="overwrite_robot_description" default="true" />         <!-- Flag to publish a standalone azure_description instead of the default robot_descrition parameter-->

  <group if="$(arg overwrite_robot_description)">
    <param name="robot_description"
      command="xacro $(find azure_kinect_ros_driver)/urdf/azure_kinect.urdf.xacro tf_prefix:=$(arg tf_prefix)" />
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
  </group>

  <group unless="$(arg overwrite_robot_description)">
    <param name="azure_description"
      command="xacro $(find azure_kinect_ros_driver)/urdf/azure_kinect.urdf.xacro tf_prefix:=$(arg tf_prefix)/" />
    <node name="joint_state_publisher_azure" pkg="joint_state_publisher" type="joint_state_publisher">
      <remap from="robot_description" to="azure_description" />
    </node>  
    <node name="robot_state_publisher_azure" pkg="robot_state_publisher" type="robot_state_publisher">
      <remap from="robot_description" to="azure_description" />
    </node>
  </group>

  <arg name="depth_enabled"           default="true" />           <!-- Enable or disable the depth camera -->
  <arg name="depth_mode"              default="WFOV_UNBINNED" />  <!-- Set the depth camera mode, which affects FOV, depth range, and camera resolution. See Azure Kinect documentation for full details. Valid options: NFOV_UNBINNED, NFOV_2X2BINNED, WFOV_UNBINNED, WFOV_2X2BINNED, and PASSIVE_IR -->
  <arg name="color_enabled"           default="true" />           <!-- Enable or disable the color camera -->
  <arg name="color_format"            default="bgra" />           <!-- The format of RGB camera. Valid options: bgra, jpeg -->
  <arg name="color_resolution"        default="720P" />          <!-- Resolution at which to run the color camera. Valid options: 720P, 1080P, 1440P, 1536P, 2160P, 3072P -->
  <arg name="fps"                     default="15" />              <!-- FPS to run both cameras at. Valid options are 5, 15, and 30 -->
  <arg name="point_cloud"             default="true" />           <!-- Generate a point cloud from depth data. Requires depth_enabled -->
  <arg name="rgb_point_cloud"         default="true" />           <!-- Colorize the point cloud using the RBG camera. Requires color_enabled and depth_enabled -->
  <arg name="point_cloud_in_depth_frame" default="false" />        <!-- Whether the RGB pointcloud is rendered in the depth frame (true) or RGB frame (false). Will either match the resolution of the depth camera (true) or the RGB camera (false). -->
  <arg name="required"                default="false" />          <!-- Argument which specified if the entire launch file should terminate if the node dies -->
  <arg name="sensor_sn"               default="" />               <!-- Sensor serial number. If none provided, the first sensor will be selected -->
  <arg name="sub_sensor_sn"               default="000768921812" />              <!-- Sensor serial number of the master device. If none provided, the first sensor will be selected -->
  <arg name="recording_file"          default="" />               <!-- Absolute path to a mkv recording file which will be used with the playback api instead of opening a device -->
  <arg name="recording_loop_enabled"  default="false" />          <!-- If set to true the recording file will rewind the beginning once end of file is reached -->
  <arg name="body_tracking_enabled"           default="false" />  <!-- If set to true the joint positions will be published as marker arrays -->
  <arg name="body_tracking_smoothing_factor"  default="0.0" />    <!-- Set between 0 for no smoothing and 1 for full smoothing -->
  <arg name="rescale_ir_to_mono8"  default="false" />    <!-- Whether to rescale the IR image to an 8-bit monochrome image for visualization and further processing. A scaling factor (ir_mono8_scaling_factor) is applied. -->
  <arg name="ir_mono8_scaling_factor"  default="1.0" />    <!-- Scaling factor to apply when converting IR to mono8 (see rescale_ir_to_mono8). If using illumination, use the value 0.5-1. If using passive IR, use 10. -->
  <arg name="imu_rate_target" default="0"/>                       <!-- Desired output rate of IMU messages. Set to 0 (default) for full rate (1.6 kHz). --> 
  <arg name="wired_sync_mode" default="2"/>                       <!-- Wired sync mode. 0: OFF, 1: MASTER, 2: SUBORDINATE. --> 
  <!--<arg name="master_wired_sync_mode" default="1"/>     -->                  <!-- Wired sync mode. 0: OFF, 1: MASTER, 2: SUBORDINATE. --> 
  <arg name="sub_wired_sync_mode" default="2"/>                       <!-- Wired sync mode. 0: OFF, 1: MASTER, 2: SUBORDINATE. --> 
  <arg name="subordinate_delay_off_master_usec" default="160"/>     <!-- Delay subordinate camera off master camera by specified amount in usec. --> 

  <node pkg="azure_kinect_ros_driver" type="node" name="azure_kinect_ros_driver_sub" output="screen" required="$(arg required)" ns="sub">
    <param name="depth_enabled"     type="bool"   value="$(arg depth_enabled)" />
    <param name="depth_mode"        type="string" value="$(arg depth_mode)" />
    <param name="color_enabled"     type="bool"   value="$(arg color_enabled)" />
    <param name="color_format"      type="string" value="$(arg color_format)" />
    <param name="color_resolution"  type="string" value="$(arg color_resolution)" />
    <param name="fps"               type="int"    value="$(arg fps)" />
    <param name="point_cloud"       type="bool"   value="$(arg point_cloud)" />
    <param name="rgb_point_cloud"   type="bool"   value="$(arg rgb_point_cloud)" />
    <param name="point_cloud_in_depth_frame"   type="bool"   value="$(arg point_cloud_in_depth_frame)" />
    <param name="sensor_sn"         type="string" value="$(arg sub_sensor_sn)" />
    <param name="tf_prefix"         type="string" value="$(arg sub_tf_prefix)" />
    <param name="recording_file"          type="string" value="$(arg recording_file)" />
    <param name="recording_loop_enabled"  type="bool"   value="$(arg recording_loop_enabled)" />
    <param name="body_tracking_enabled"           type="bool"   value="$(arg body_tracking_enabled)" />
    <param name="body_tracking_smoothing_factor"  type="double" value="$(arg body_tracking_smoothing_factor)" />
    <param name="rescale_ir_to_mono8" type="bool" value="$(arg rescale_ir_to_mono8)" />
    <param name="ir_mono8_scaling_factor" type="double" value="$(arg ir_mono8_scaling_factor)" />
    <param name="imu_rate_target" type="int" value="$(arg imu_rate_target)"/>
    <param name="wired_sync_mode" type="int" value="$(arg sub_wired_sync_mode)"/>
    <param name="subordinate_delay_off_master_usec" type="int" value="$(arg subordinate_delay_off_master_usec)"/>
  </node>
</launch>

I have some trouble with colliding robot_state_publisher and joint_state_publisher but I will see that later... I also noticed that the subordinate node is publishing more than the master node, I wonder if it's because the subordinate computer is more powerful than the other even though they have the same framerate...

Thanks a lot for all your help.

Quentin