Below is my EKF configuration file. Is this accurate? When using pure visual odometry, there won't be any ghosting, but when there is no texture, it will be lost. After the loss, the mapping process will be interrupted. I don't want this to happen, so I want to fuse the odometry information as an auxiliary. However, after the fusion, there is ghosting and the same object appears multiple times. Why is that? Is it because the timestamps of the odometry and the image are not the same? I measured it and the time difference between them is over 100 ms. Could it be because of this?
ekf_filter_node:
ros__parameters:
frequency: 30.0
sensor_timeout: 0.1
two_d_mode: true
publish_tf: true
map_frame: map
odom_frame: odom
base_link_frame: base_footprint
world_frame: odom
odom0: /odom
odom0_config: [false, false, false,
false, false, false,
true, true, false,
false, false, true,
false, false, false]
odom0_differential: false
odom0_relative: false
odom0_queue_size: 10
odom1: /vo
odom1_config: [true, true, false,
false, false, true,
false, false, false,
false, false, false,
false, false, false]
odom1_differential: false
odom1_relative: false
odom1_queue_size: 10
print_diagnostics: true
debug: false
process_noise_covariance: [0.05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.06, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.03, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.03, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.06, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.025, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.025, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.04, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.02, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.015]
initial_estimate_covariance: [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9]
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
def generate_launch_description():
base_frame = LaunchConfiguration('base_frame')
use_viz = LaunchConfiguration('use_viz')
ekf_config_file = LaunchConfiguration('ekf_config')
rtabmap_odom_params = {
'frame_id': base_frame,
'subscribe_rgbd': False,
'subscribe_stereo': True,
'subscribe_odom_info': True,
'use_sim_time': True,
'approx_sync': True,
'approx_sync_max_interval': 0.1,
'sync_queue_size': 30,
'topic_queue_size': 30,
'wait_for_transform': 0.5,
'Rtabmap/ImagesAlreadyRectified': 'true',
'publish_tf': False,
'Vis/FeatureType': '8',
'Vis/EstimationType': '1',
'Vis/MinInliers': '20',
'Vis/MaxFeatures': '1500',
'Vis/CorType': '0',
'Odom/ResetCountdown': '1',
'Odom/Strategy': '0',
'OdomF2M/MaxSize': '1000',
'GFTT/MinDistance': '5',
'GFTT/QualityLevel': '0.00001',
'Stereo/MaxDisparity': '128',
}
rtabmap_slam_params = {
'frame_id': base_frame,
'subscribe_rgbd': False,
'subscribe_stereo': True,
'subscribe_odom_info': False,
'subscribe_odom': False,
'odom_frame_id':'odom',
'use_sim_time': True,
'approx_sync': True,
'approx_sync_max_interval': 0.1,
'sync_queue_size': 30,
'topic_queue_size': 30,
'wait_for_transform': 0.5,
'tf_delay': 0.05,
'Rtabmap/ImagesAlreadyRectified': 'true',
'Rtabmap/DetectionRate': '3',
'Reg/Force3DoF': 'true',
'Kp/MaxFeatures': '1000',
'GFTT/MinDistance': '5',
'GFTT/QualityLevel': '0.00001',
'Stereo/MaxDisparity': '128',
'Grid/RayTracing': 'true',
'Grid/RangeMax': '3',
'odom_sensor_sync': True,
}
odom_remaps = [
('left/image_rect', '/stereo/left/camera/image_rect'),
('right/image_rect', '/stereo/right/camera/image_rect'),
('left/camera_info', '/stereo/left/camera/camera_info'),
('right/camera_info', '/stereo/right/camera/camera_info'),
('odom', '/vo'),
]
slam_remaps = [
('left/image_rect', '/stereo/left/camera/image_rect'),
('right/image_rect', '/stereo/right/camera/image_rect'),
('left/camera_info', '/stereo/left/camera/camera_info'),
('right/camera_info', '/stereo/right/camera/camera_info'),
('odom', '/odometry/filtered'),
]
return LaunchDescription([
DeclareLaunchArgument('base_frame', default_value='base_footprint'),
DeclareLaunchArgument('use_viz', default_value='true'),
DeclareLaunchArgument(
'ekf_config',
default_value='/home/yahboom/camera_ws/src/stereo_camera_pkg/config/ekf_wheel_imu_vo.yaml'
),
Node(
package='image_proc',
executable='rectify_node',
name='rectify_left',
namespace='/stereo/left/camera',
parameters=[{'use_sim_time': True}],
remappings=[
('image', '/stereo/left/camera/image_mono'),
('camera_info', '/stereo/left/camera/camera_info'),
('image_rect', '/stereo/left/camera/image_rect')
]
),
Node(
package='image_proc',
executable='rectify_node',
name='rectify_right',
namespace='/stereo/right/camera',
parameters=[{'use_sim_time': True}],
remappings=[
('image', '/stereo/right/camera/image_mono'),
('camera_info', '/stereo/right/camera/camera_info'),
('image_rect', '/stereo/right/camera/image_rect')
]
),
Node(
package='robot_localization',
executable='ekf_node',
name='ekf_filter_node',
output='screen',
parameters=[ekf_config_file, {'use_sim_time': True}],
),
Node(
package='rtabmap_odom',
executable='stereo_odometry',
name='stereo_odometry',
output='screen',
parameters=[rtabmap_odom_params],
remappings=odom_remaps
),
Node(
package='rtabmap_slam',
executable='rtabmap',
name='rtabmap',
output='screen',
parameters=[rtabmap_slam_params],
remappings=slam_remaps,
arguments=['-d']
),
Node(
package='rtabmap_viz',
executable='rtabmap_viz',
name='rtabmap_viz',
output='screen',
condition=IfCondition(use_viz),
parameters=[rtabmap_slam_params],
remappings=slam_remaps
),
])
And I noticed that if "subscribe_odom=true" is set and the "odom_frame_id" is deleted, the loop closure will not be triggered. Why is that?
Hope to receive your reply. Thank you.
Below is my EKF configuration file. Is this accurate? When using pure visual odometry, there won't be any ghosting, but when there is no texture, it will be lost. After the loss, the mapping process will be interrupted. I don't want this to happen, so I want to fuse the odometry information as an auxiliary. However, after the fusion, there is ghosting and the same object appears multiple times. Why is that? Is it because the timestamps of the odometry and the image are not the same? I measured it and the time difference between them is over 100 ms. Could it be because of this?
Below is my rtabmap startup file
And I noticed that if "subscribe_odom=true" is set and the "odom_frame_id" is deleted, the loop closure will not be triggered. Why is that?
Hope to receive your reply. Thank you.