Robotics StackExchange | Archived questions

Tuning Google Cartographer to work with a Velodyne HDL-32

The Problem (TL;DR)

I can get Google Cartographer to run in 2D mode, but not 3D. I want to write a .launch and .lua file that will get Cartographer (in 3D mode) to smoothly run over my bagfile.

The Problem (full explanation)

I've got a Velodyne HDL-32 mounted on a Clearpath Jackal UGV, and I'm trying to get Google Cartographer (in 3D mode) working with it. I've collected a short bagfile with all the necessary sensor and TF data, and I can get Cartographer working in 2D mode (see image below).

Completed map from Cartographer (2D): image description

But I can't for the life of me get it working in 3D, mostly because I don't really understand how to tune the myriad of settings Cartographer offers. Unfortunately I haven't found any demo files that use a similar setup (which I could therefore copy). The closest thing is the 3ddemopackpack.launch and backpack_3d.lua files. However, when I try a modified version of these files, this is what I get:

My best result from Cartographer (3D) image description

It looks like the raw data simply isn't being matched properly, and I suspect that fixing this may well be a case of tweaking the right parameters. However, none of the tinkering or tweaking I've done so far has produced anything better than what you see above. Everything under "options={}" in the .lua files is well documented here, and I think I've got those right, but the other parameters aren't documented at all and unfortunately I'm mostly guesstimating at what they do.

I'd like know how to write/configure a set of launch/lua files to get Cartographer working on my system. I suspect that my use case - one UGV and one 3D LiDAR - will be a relatively common as Cartographer grows in popularity. So hopefully any answers or advice here can help others with a similar setup. Thanks in advance for any help or advice anyone can provide. The details of my system are below.

System Information

Updates

Update 1

With some help from the developers, I've got a working configuration. The three key parameter changes for me were:

  1. TRAJECTORY_BUILDER_3D.scans_per_accumulation = 1 I don't really understand this parameter but it seems to be the number of scans (i.e. 360 degree rotation) per PointCloud2 message. Setting this to 1 made the difference between getting nothing and something.
  2. TRAJECTORY_BUILDER_3D.use_online_correlative_scan_matching = true As per the tuning guide, the correlative scan matcher matches each new scan to the existing submap. This defaults to off, but without it the map quickly becomes a black smudge.
  3. SPARSE_POSE_GRAPH.matcher_rotation_weight = 1.6e5 Every time a new submap is generated and matched to the previous one, this is the variable that determines the penalty for rotating the new submap. I.e. the higher it is, the less the new submap will be rotated to fit. Defaults to 1.6e3, I've had to set it higher (likely due to IMU problems that I'm currently experiencing) otherwise each new submap is added at a ridiculous angle.

I've updated the 3D .lua file with my most recent changes. This at least gives me a recognizable result:

image description

Although it's still far from perfect, and the global scan matcher needs a lot of tuning to correctly re-align the submaps.

Update 2

Long story short, Cartographer is VERY dependent on good IMU data, and my IMU yaw drifts far more than it should. I've implemented a zero velocity update to periodically de-bias the yaw angular velocity from the IMU and this has helped quite a lot.

Prior to semi-resolving my IMU issues I had to weight a lot of the rotation penalties quite highly, to prevent submaps from being mis-aligned at creation. Now, I have been able to reduce those weights which has somewhat improved the performance of later scan-matching.

I've also found that loop-closure is better and more reliable if I reverse the direction of travel and go down the long straight before taking the square-ish detours around the cubicles.

So now I get this:

image description

I've updated the 3D config file with the one I used to achieve the image above. I'll update the bagfile shortly. Obviously there is still room for improvement, and there are two issues in particular I want to focus on:

  1. The vertical drift (see below) image description
  2. The patchy occupancy map - free space is never marked solid white like it should be. The 2D version of my data and 3D backpack demo do this correctly, but my 3D data doesn't.

Asked by M@t on 2017-07-31 23:23:31 UTC

Comments

Hey, I am very interested in your integration of Cartographer with the LiDAR data since I am trying to achieve something very similar. Would it be okay if we talked directly on e-mail since I have quite a few questions?

Asked by i_robot_flight on 2017-10-30 16:17:55 UTC

@i_robot_flight: you should ask your questions here (as a question!) so that the entire community can benefit.

Asked by jayess on 2017-10-30 16:33:08 UTC

All right, thanks!

Asked by i_robot_flight on 2017-10-31 09:06:20 UTC

I've had MUCH better results with the latest release of Cartographer (dunno why). So I suggest you start with that and modify the 3D backpack demo files. I'm trying to update all this but CloudCompare has stopped working on my computer so I can't work with point clouds ATM.

Asked by M@t on 2017-10-31 17:42:33 UTC

Hi, Matt, How did you implement zero velocity update for imu. I am having a similar problem where my laser readings keep changing the position without moving lidar. Thus, this is giving me multiple submaps in different orientations of the same location.

Asked by RoboRos on 2018-04-29 15:32:24 UTC

I can give you the code I used to implement a zero velocity update, but if you're having other problems you're better to post it as its own question.

Asked by M@t on 2018-04-30 20:21:51 UTC

@mat that'd be great, if u can can share the code. Thanks.

Asked by RoboRos on 2018-05-01 03:17:13 UTC

@RoboRos here's a link: imu_processor. You'll need to install it in a catkin package, compile it and run it using rosrun <package_name> imu_processor.py Or just copy the code, it's not particularly well written but it works.

Asked by M@t on 2018-05-02 16:52:27 UTC

Note that I'm only using the ZUPT to calculate the angular velocity bias - in my use case that's the source of some of my problems but in your case you might also want to ZUPT the linear acceleration.

Asked by M@t on 2018-05-02 18:55:21 UTC

@M@t: I am new to ROS and this might be a very basic question. Based on the backpack_2d demo file isn't a remap required from "echos" to "scan" in your 2d launch file?

Asked by Atombomb on 2018-08-13 17:23:25 UTC

Hi @Atombomb, not in my case. According to this documentation echos and scans are two separate inputs, with two different data types. I'm not sure what the first is used for, but I receive a 2D...

Asked by M@t on 2018-08-16 22:48:13 UTC

... sensor_msgs/LaserScan and a 3D sensor_msgs/PointCloud2 from my LiDAR unit, so those are the only inputs I used in Cartographer. it is worth noting that I haven't used Cartographer for months now, and have moved on from it because it wasn't accurate enough for my application.

Asked by M@t on 2018-08-16 22:49:56 UTC

Oh, and "remapping" is not something you use to map one input to another - you just use it to change the name of the topic the data will be published on or subscribed to. E.g. remapping your IMU output from /imu/data to /imu1/data if you have multiple IMUs

Asked by M@t on 2018-08-16 23:22:37 UTC

Answers