cartographer-project / cartographer

Cartographer is a system that provides real-time simultaneous localization and mapping (SLAM) in 2D and 3D across multiple platforms and sensor configurations.
Apache License 2.0
7.03k stars 2.24k forks source link

Localization not working #1948

Closed j1and1 closed 4 months ago

j1and1 commented 5 months ago

I have created a 2D map with rosbags and ros2/cartographer_ros and saved the map as *.pbstream.

I am now trying to test the localization part of the cartographer by offsetting the playback start of the bag playback. I have modified config according to backpack_2d_localization.lua sample provided in the ros2 cartographer repo. However, it still is updating the map and not trying to localize to the correct spot in the map.

The questions that rose in my mind are:

I run the cartographer node with following args:

cartographer = Node(
        package='cartographer_ros',
        executable='cartographer_node',
        name='cartographer_node',
        output='screen',
        parameters=[{'use_sim_time': True}],
        arguments=['-configuration_directory', configs_dir,
                    '-configuration_basename', 'localization.lua',
                    '-load_state_filename', map_path,
                    '-load_frozen_state true',
                    ],
        remappings=[
            ('/points2', RAW_POINT_CLOUD_TOPIC),
            ('/odom', ODOM_DATA_TOPIC),
            ('/imu', IMU_DATA_TOPIC)
        ])

The config I have currently looks like so:

include "map_builder.lua"
include "trajectory_builder.lua"

options = {
  map_builder = MAP_BUILDER,
  trajectory_builder = TRAJECTORY_BUILDER,
  map_frame = "map",
  tracking_frame = "base_link",
  published_frame = "base_link",
  odom_frame = "odom",
  provide_odom_frame = false,
  publish_frame_projected_to_2d = false,
  use_pose_extrapolator = true,
  use_odometry = true,
  use_nav_sat = false,
  use_landmarks = false,
  num_laser_scans = 0,
  num_multi_echo_laser_scans = 0,
  num_subdivisions_per_laser_scan = 10,
  num_point_clouds = 1,
  lookup_transform_timeout_sec = 0.2,
  submap_publish_period_sec = 0.3,
  pose_publish_period_sec = 5e-3,
  trajectory_publish_period_sec = 30e-3,
  rangefinder_sampling_ratio = 1.,
  odometry_sampling_ratio = 1.,
  fixed_frame_pose_sampling_ratio = 1.,
  imu_sampling_ratio = 1.,
  landmarks_sampling_ratio = 1.,
}

MAP_BUILDER.use_trajectory_builder_2d = true
TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 10

TRAJECTORY_BUILDER.pure_localization_trimmer = {
  max_submaps_to_keep = 3,
}
POSE_GRAPH.optimize_every_n_nodes = 20

return options

The issue looks like this: Map is broken

j1and1 commented 5 months ago

I see that those are sub-maps that are shown in the screenshot, but it still doesn't localize to the correct point. If I give it a start position then it can compensate for the small amount of rotation difference between the actual position and the hint.

So my problem is that it needs a hint with somewhat precise rotation... I would like to avoid passing precise rotation when I'm running in localization mode

j953302 commented 4 months ago

Hello @j1and1 , I'm not sure my solution whether is the best method. But I could use the old map and do re-localization. I will not use pure_localization_trimmer this parameter. Below is lua about parameters of pure localization:

TRAJECTORY_BUILDER.pure_localization = true
--TRAJECTORY_BUILDER.pure_localization_trimmer = {max_submaps_to_keep = 3,}
--  TEST 
TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 1 
--TRAJECTORY_BUILDER_2D.voxel_filter_size = 0.05
--TRAJECTORY_BUILDER_2D.submaps.num_range_data = 45
MAP_BUILDER.num_background_threads = 4

--  TEST
POSE_GRAPH.constraint_builder.min_score = 0.65
POSE_GRAPH.constraint_builder.global_localization_min_score = 0.6
POSE_GRAPH.global_sampling_ratio = 0.9
POSE_GRAPH.constraint_builder.sampling_ratio = 0.5
POSE_GRAPH.optimize_every_n_nodes = 5

Be free to discuss.

j1and1 commented 4 months ago

I forgot that I opened this issue. I resolved the issue by setting the POSE_GRAPH.constraint_builder.fast_correlative_scan_matcher.angular_search_window to math.rad(180.) since we didn't pass the angle with the initial position from UI and this worked. The cartographer could compensate rotation based on the map that was created before.