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.09k stars 2.25k forks source link

Drawing map from pbstream #1807

Open lelongg opened 3 years ago

lelongg commented 3 years ago

I need to draw a map from a pbstream produced by cartographer. I have the submaps pose from the trajectory field and the local_pose from the serialized Submap, however I can't make sense of any of these transformations but the submaps pose never match. I already tried a lot of combinations but the only source of information I found (https://github.com/cartographer-project/cartographer/issues/1507) is lacking.

The goal is to be able to display a pbstream in a third party tool, so using the available conversion nodes is not an option unfortunately.

In short: how am I supposed to combine data from a pbstream to produce a map ?

johuber commented 3 years ago

If you look at this that may help. Among some other things it creates a png image of the map from the pbstream.

I assume what you are trying to do is fairly similar and I hope this helps then.

lelongg commented 3 years ago

From what I understand, this process is used to aggregate, filter and output sensor data saved in a rosbag according to the localization data stored in a pbstream.

What I am trying to achieve is merging the probability grids already stored in the pbstream.

MichaelGrupp commented 3 years ago

I would recommend to take a look which API functions are used in here: https://github.com/cartographer-project/cartographer_ros/blob/master/cartographer_ros/cartographer_ros/pbstream_to_ros_map_main.cc

This tool reads a pbstream and creates an image from it. You can ignore the part where it writes the PGM and YAML files for ROS, but the creation of an cartographer::io::Image from the pbstream is only a few lines of code. You could base your code on this tool and use the image for your purposes with custom code.

lelongg commented 3 years ago

I didn't mention it but I'm writing the tool in rust and I would like to avoid binding. I skimmed through this code several times but a fresh look may have given me what I was missing.

const double max_x = limits().max().x() - resolution * offset.y();
const double max_y = limits().max().y() - resolution * offset.x();
*texture->mutable_slice_pose() = transform::ToProto(
    local_pose.inverse() *
    transform::Rigid3d::Translation(Eigen::Vector3d(max_x, max_y, 0.)));

This transformation between local_pose and slice_pose might be the piece I need.