Posted by
utrecht on
URL: http://official-rtab-map-forum.206.s1.nabble.com/Problem-fusing-LiDAR-and-depth-hector-slam-tp4115p4121.html
Hey Mathieu,
I've succeeded in integrating the LiDAR and IMU. Well, sort of... couple of questions:
1. When running without the IMU I'm running into a bit of trouble with saving the map. It keeps disappearing after losing odometry (the R200 really sucks sometimes...) as seen below:
Before:

After:

Is this normal? It's very annoying, and I just wanted to know if I am getting it right. Even if it's not possible to keep the combined clouds from the R200, is it possible to not erase the assembled clouds from the LiDAR? (note, I used the hector_laser_to_pointcloud for convenience, check it out if you have the time
https://github.com/team-vigir/vigir_lidar_proc/blob/master/vigir_laserscan_to_pointcloud/src/laserscan_to_pointcloud_node.cpp)
2. After combining with the LiDAR, I've come across a duplication problem once more, as seen below:

I've managed to correct it, thing is the pointcloud topic reverses in its yaw. If I remove it everything looks fine:

In the picture the pointcloud topic is the weird out of place one. If I uncheck the box in RVIZ everything looks ok.
Why do you think this is happening? Instead of using the robot_localization package I've decided to write my own node to publish the odometry information from the odom topic. It's unclean at the moment, but take a look:
#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <tf/transform_datatypes.h>
#include <sensor_msgs/Imu.h>
#include <geometry_msgs/PoseStamped.h>
#include <nav_msgs/Odometry.h>
class State {
private:
ros::NodeHandle nh_;
ros::Subscriber imu_sub_;
ros::Subscriber realsense_pose_sub_;
ros::Subscriber lidar_pose_sub_;
geometry_msgs::PoseStamped lidar_msg_;
nav_msgs::Odometry realsense_msg_;
tf::TransformBroadcaster br_;
tf::Transform transform_;
public:
State() {
imu_sub_ = nh_.subscribe("imu", 1, &State::imuCallback, this);
realsense_pose_sub_ = nh_.subscribe("rtabmap/odom", 1, &State::RealsenseCallback, this);
transform_.setOrigin(tf::Vector3(0.0, 0.0, 0.0));
transform_.setRotation(tf::Quaternion(0.0, 0.0, 0.0, 1.0));
}
void imuCallback(const sensor_msgs::Imu::ConstPtr &imu){
tf::Quaternion quat = tf::Quaternion(imu->orientation.x,
imu->orientation.y,
imu->orientation.z,
imu->orientation.w);
transform_.setRotation(quat);
br_.sendTransform(tf::StampedTransform(transform_, ros::Time::now(), "map", "base_footprint"));
}
void RealsenseCallback(const nav_msgs::Odometry::ConstPtr &msg){
transform_.setOrigin(tf::Vector3(msg->pose.pose.position.x, msg->pose.pose.position.y, msg->pose.pose.position.z));
br_.sendTransform(tf::StampedTransform(transform_, ros::Time::now(), "map", "base_footprint"));
}
};
int main(int argc, char** argv){
ros::init(argc, argv, "state_tf");
State s;
ros::spin();
return 0;
}
In addition, here is the TF tree and the launch file:

<?xml version="1.0"?>
<launch>
<arg name="rtabmapviz" default="false" />
<arg name="rviz" default="true" />
<arg name="localization" default="false"/>
<node pkg="maple" type="ScanToPointcloud2" name="ScanToPointcloud2" respawn="true">
<param name="min_range" value="0.25" />
<param name="use_high_fidelity_projection" value="true" />
<param name="target_frame" value="base_link" />
</node>
<node pkg="maple" type="IMUPositionEstimate" name="IMUPositionEstimate" />
<!-- sim time for convenience, if playing a rosbag -->
<arg name="use_sim_time" default="false"/>
<param if="$(arg use_sim_time)" name="use_sim_time" value="true"/>
<!-- Corresponding config files -->
<arg name="cfg" default="" /> <!-- To change RTAB-Map's parameters, set the path of config file (*.ini) generated by the standalone app -->
<arg name="gui_cfg" default="~/.ros/rtabmap_gui.ini" />
<arg name="rviz_cfg" default="$(find rtabmap_ros)/launch/config/rgbd.rviz" />
<arg name="frame_id" default="base_link"/> <!-- Fixed frame id, you may set "base_link" or "base_footprint" if they are published -->
<arg name="odom_frame_id" default=""/> <!-- If set, TF is used to get odometry instead of the topic -->
<arg name="map_frame_id" default="map"/>
<arg name="ground_truth_frame_id" default=""/> <!-- e.g., "world" -->
<arg name="ground_truth_base_frame_id" default=""/> <!-- e.g., "tracker", a fake frame matching the frame "frame_id" (but on different TF tree) -->
<arg name="namespace" default="rtabmap"/>
<arg name="database_path" default="~/.ros/rtabmap.db"/>
<arg name="queue_size" default="10"/>
<arg name="wait_for_transform" default="0.2"/>
<arg name="args" default=""/> <!-- delete_db_on_start, udebug -->
<arg name="rtabmap_args" default="--delete_db_on_start"/> <!-- deprecated, use "args" argument -->
<arg name="launch_prefix" default=""/> <!-- for debugging purpose, it fills launch-prefix tag of the nodes -->
<arg name="output" default="screen"/> <!--Control node output (screen or log)-->
<arg name="approx_sync" default="true"/>
<!-- RGB-D related topics -->
<arg name="rgb_topic" default="/camera/rgb/image_rect_color" />
<arg name="depth_topic" default="/camera/depth_registered/sw_registered/image_rect_raw" />
<arg name="camera_info_topic" default="/camera/rgb/camera_info" />
<arg name="image_raw_topic" default="/camera/depth/points/image_raw" />
<arg name="cloud_topic" default="/camera/depth/points" />
<arg name="image_topic" default="/camera/depth/image" />
<arg name="_approx" default="false" />
<arg name="_fill_holes_size" default="2" />
<!-- Already synchronized RGB-D related topic, with rtabmap_ros/rgbd_sync nodelet -->
<arg name="subscribe_rgbd" default="false"/>
<arg name="rgbd_topic" default="/camera/rgbd_image" />
<arg name="compressed" default="true"/> <!-- If you want to subscribe to compressed image topics -->
<arg name="rgb_image_transport" default="compressed"/> <!-- Common types: compressed, theora (see "rosrun image_transport list_transports") -->
<arg name="depth_image_transport" default="compressedDepth"/> <!-- Common types: compressed, theora (see "rosrun image_transport list_transports") -->
<arg name="subscribe_scan" default="false"/>
<arg name="scan_topic" default="/scan"/>
<arg name="subscribe_scan_cloud" default="true"/>
<arg name="scan_cloud_topic" default="/scan_cloud"/>
<arg name="scan_normal_k" default="0"/>
<arg name="visual_odometry" default="true"/> <!-- Launch rtabmap visual odometry node -->
<arg name="odom_topic" default="/odom"/> <!-- Odometry topic used if visual_odometry is false -->
<arg name="vo_frame_id" default="odom"/>
<arg name="odom_tf_angular_variance" default="1"/> <!-- If TF is used to get odometry, this is the default angular variance -->
<arg name="odom_tf_linear_variance" default="1"/> <!-- If TF is used to get odometry, this is the default linear variance -->
<arg name="odom_args" default="$(arg rtabmap_args)"/>
<arg name="odom_sensor_sync" default="false"/>
<arg name="subscribe_user_data" default="false"/> <!-- user data synchronized subscription -->
<arg name="user_data_topic" default="/user_data"/>
<arg name="user_data_async_topic" default="/user_data_async" /> <!-- user data async subscription (rate should be lower than map update rate) -->
<!-- These arguments should not be modified directly, see referred topics without "_relay" suffix above -->
<arg if="$(arg compressed)" name="rgb_topic_relay" default="$(arg rgb_topic)_relay"/>
<arg unless="$(arg compressed)" name="rgb_topic_relay" default="$(arg rgb_topic)"/>
<arg if="$(arg compressed)" name="depth_topic_relay" default="$(arg depth_topic)_relay"/>
<arg unless="$(arg compressed)" name="depth_topic_relay" default="$(arg depth_topic)"/>
<!-- Nodes -->
<group ns="$(arg namespace)">
<!-- RGB-D Odometry -->
<node if="$(arg compressed)" name="republish_rgb" type="republish" pkg="image_transport" args="$(arg rgb_image_transport) in:=$(arg rgb_topic) raw out:=$(arg rgb_topic_relay)" />
<node if="$(arg compressed)" name="republish_depth" type="republish" pkg="image_transport" args="$(arg depth_image_transport) in:=$(arg depth_topic) raw out:=$(arg depth_topic_relay)" />
<node if="$(arg visual_odometry)" pkg="rtabmap_ros" type="rgbd_odometry" name="rgbd_odometry" output="$(arg output)" args="$(arg odom_args)" launch-prefix="$(arg launch_prefix)">
<remap from="rgb/image" to="$(arg rgb_topic_relay)"/>
<remap from="depth/image" to="$(arg depth_topic_relay)"/>
<remap from="rgb/camera_info" to="$(arg camera_info_topic)"/>
<remap from="rgbd_image" to="$(arg rgbd_topic)"/>
<param name="publish_tf" type="bool" value="true"/>
<param name="guess_from_tf" type="bool" value="false"/>
<param name="guess_frame_id" type="string" value="base_footprint"/>
<param name="Odom/FillInfoData" type="string" value="true"/>
<param name="Vis/FeatureType" type="string" value="6"/>
<param name="OdomF2M/MaxSize" type="string" value="1000"/>
<param name="Vis/MinInliers" value="8"/>
<param name="Odom/ResetCountdown" value="1" />
<!-- 0: 3D - 3D, 1: 3D-2D -->
<param name="Odom/EstimationType" value="1"/>
<!-- Minimum Eucliedean distance in Mode 0 (3D-3D) -->
<param name="Odom/InlinerDistance" value="0.2" />
<!-- Reprojection error in Mode 1 (3D->2D) -->
<param name="Odom/PnPReprojError" value="5.0" />
<!-- Maximum depth -->
<param name="Odom/MaxDepth" value="10.0" />
<param name="GFFT/QualityLevel" value="0.001" />
<param name="GFFT/MinDistance" value="3" />
<param name="Kp/DetectorStrategy" value="6" />
<param name="frame_id" type="string" value="$(arg frame_id)"/>
<param name="odom_frame_id" type="string" value="$(arg vo_frame_id)"/>
<param name="ground_truth_frame_id" type="string" value="$(arg ground_truth_frame_id)"/>
<param name="ground_truth_base_frame_id" type="string" value="$(arg ground_truth_base_frame_id)"/>
<param name="wait_for_transform_duration" type="double" value="$(arg wait_for_transform)"/>
<param name="approx_sync" type="bool" value="$(arg approx_sync)"/>
<param name="config_path" type="string" value="$(arg cfg)"/>
<param name="queue_size" type="int" value="$(arg queue_size)"/>
<param name="subscribe_rgbd" type="bool" value="$(arg subscribe_rgbd)"/>
</node>
<!-- Visual SLAM (robot side) -->
<!-- args: "delete_db_on_start" and "udebug" -->
<node name="rtabmap" pkg="rtabmap_ros" type="rtabmap" output="$(arg output)" args="$(arg rtabmap_args)" launch-prefix="$(arg launch_prefix)">
<param name="subscribe_depth" type="bool" value="true"/>
<param name="subscribe_rgbd" type="bool" value="$(arg subscribe_rgbd)"/>
<param name="subscribe_scan" type="bool" value="$(arg subscribe_scan)"/>
<param name="subscribe_scan_cloud" type="bool" value="$(arg subscribe_scan_cloud)"/>
<param name="subscribe_user_data" type="bool" value="$(arg subscribe_user_data)"/>
<param name="frame_id" type="string" value="$(arg frame_id)"/>
<param name="map_frame_id" type="string" value="$(arg map_frame_id)"/>
<param name="odom_frame_id" type="string" value="$(arg odom_frame_id)"/>
<param name="ground_truth_frame_id" type="string" value="$(arg ground_truth_frame_id)"/>
<param name="ground_truth_base_frame_id" type="string" value="$(arg ground_truth_base_frame_id)"/>
<param name="odom_tf_angular_variance" type="double" value="$(arg odom_tf_angular_variance)"/>
<param name="odom_tf_linear_variance" type="double" value="$(arg odom_tf_linear_variance)"/>
<param name="odom_sensor_sync" type="bool" value="$(arg odom_sensor_sync)"/>
<param name="wait_for_transform_duration" type="double" value="$(arg wait_for_transform)"/>
<param name="database_path" type="string" value="$(arg database_path)"/>
<param name="approx_sync" type="bool" value="$(arg approx_sync)"/>
<param name="config_path" type="string" value="$(arg cfg)"/>
<param name="queue_size" type="int" value="$(arg queue_size)"/>
<param name="scan_normal_k" type="int" value="$(arg scan_normal_k)"/>
<param name="Rtabmap/DetectionRate" type="string" value="0"/>
<param name="RGBD/LinearUpdate" type="string" value="0"/>
<param name="RGBD/AngularUpdate" type="string" value="0"/>
<param name="RGBD/ProximityPathMaxNeighbors" type="string" value="0"/>
<param name="Grid/FromDepth" type="string" value="true"/>
<param name="RGBD/OptimizeMaxError" value="0.2" />
<remap from="rgb/image" to="$(arg rgb_topic_relay)"/>
<remap from="depth/image" to="$(arg depth_topic_relay)"/>
<remap from="rgb/camera_info" to="$(arg camera_info_topic)"/>
<remap from="rgbd_image" to="$(arg rgbd_topic)"/>
<remap from="scan" to="$(arg scan_topic)"/>
<remap from="scan_cloud" to="$(arg scan_cloud_topic)"/>
<remap from="user_data" to="$(arg user_data_topic)"/>
<remap from="user_data_async" to="$(arg user_data_async_topic)"/>
<remap unless="$(arg visual_odometry)" from="odom" to="$(arg odom_topic)"/>
<!-- localization mode -->
<param if="$(arg localization)" name="Mem/IncrementalMemory" type="string" value="false"/>
<param unless="$(arg localization)" name="Mem/IncrementalMemory" type="string" value="true"/>
<param name="Mem/InitWMWithAllNodes" type="string" value="$(arg localization)"/>
</node>
<!-- Visualisation RTAB-Map -->
<node if="$(arg rtabmapviz)" pkg="rtabmap_ros" type="rtabmapviz" name="rtabmapviz" args="-d $(arg gui_cfg)" output="$(arg output)" launch-prefix="$(arg launch_prefix)">
<param name="subscribe_depth" type="bool" value="true"/>
<param name="subscribe_rgbd" type="bool" value="$(arg subscribe_rgbd)"/>
<param name="subscribe_scan" type="bool" value="$(arg subscribe_scan)"/>
<param name="subscribe_scan_cloud" type="bool" value="$(arg subscribe_scan_cloud)"/>
<param name="subscribe_odom_info" type="bool" value="$(arg visual_odometry)"/>
<param name="frame_id" type="string" value="$(arg frame_id)"/>
<param name="odom_frame_id" type="string" value="$(arg odom_frame_id)"/>
<param name="wait_for_transform_duration" type="double" value="$(arg wait_for_transform)"/>
<param name="queue_size" type="int" value="$(arg queue_size)"/>
<param name="approx_sync" type="bool" value="$(arg approx_sync)"/>
<remap from="rgb/image" to="$(arg rgb_topic_relay)"/>
<remap from="depth/image" to="$(arg depth_topic_relay)"/>
<remap from="rgb/camera_info" to="$(arg camera_info_topic)"/>
<remap from="rgbd_image" to="$(arg rgbd_topic)"/>
<remap from="scan" to="$(arg scan_topic)"/>
<remap from="scan_cloud" to="$(arg scan_cloud_topic)"/>
<remap unless="$(arg visual_odometry)" from="odom" to="$(arg odom_topic)"/>
</node>
</group>
<!-- Visualization RVIZ -->
<node if="$(arg rviz)" pkg="rviz" type="rviz" name="rviz" args="-d $(arg rviz_cfg)"/>
<node if="$(arg rviz)" pkg="nodelet" type="nodelet" name="points_xyzrgb" args="standalone rtabmap_ros/point_cloud_xyzrgb">
<remap from="rgb/image" to="$(arg rgb_topic_relay)"/>
<remap from="depth/image" to="$(arg depth_topic_relay)"/>
<remap from="rgb/camera_info" to="$(arg camera_info_topic)"/>
<remap from="cloud" to="voxel_cloud" />
<param name="decimation" type="double" value="2"/>
<param name="voxel_size" type="double" value="0.05"/>
<param name="approx_sync" type="bool" value="$(arg approx_sync)"/>
</node>
<node pkg="tf" type="static_transform_publisher" name="base_footprint_to_base_link" args="0 0 0 0 0 0 base_footprint base_link 100"/>
<node pkg="tf" type="static_transform_publisher" name="base_link_to_camera" args="0 0 0 0 0 0 base_link camera_link 100"/>
</launch>BTW, maple is the name of my package. The nodes are pretty self-explanatory I assume. Does anything jump at you? Something obviously wrong?
Many gratitudes :)