Skip to content

Understanding how to get the cartographer maps #1951

Open
@godbrigero

Description

@godbrigero

Hi!

Basically I have this port of cartographer and I would like to understand how to get the maps more efficiently and prep them for like pathfinding and other stuff. Right now all I am doing is getting all of the submaps and making one big map. I am assuming that that is VERY inefficient in the way that I am using it right now (requesting it every like 0.5 sec).

My code right now that I run to get the map:
`void CartoModule::paint_map(std::vector *output) {
if (isAdded) {
current_map->to_char_array(output);
return;
}

using io::PaintSubmapSlicesResult;
using io::SubmapSlice;
using mapping::SubmapId;

MapInfo info;
pthread_mutex_lock(&mutex);
double resolution = 0.05;

// 获取所有子图的位姿
std::map<SubmapId, SubmapSlice> submap_slices;
auto submap_poses = map_builder->pose_graph()->GetAllSubmapPoses();
for (const auto &submap_id_pose : submap_poses) {
    SubmapId submap_id = submap_id_pose.id;
    transform::Rigid3d pose = submap_id_pose.data.pose;
    int version = submap_id_pose.data.version;

    // 查询子图内容
    mapping::proto::SubmapQuery::Response response_proto;
    const std::string error = map_builder->SubmapToProto(submap_id, &response_proto);
    if (!error.empty()) {
        // LOG(ERROR) << error;
        pthread_mutex_unlock(&mutex);
        return;
    }
    int query_version = response_proto.submap_version();
    if (response_proto.textures_size() == 0) {
        // LOG(INFO) << "Responds of submap query is empty for submap '" << submap_id.submap_index << "'";
        continue;
    }
    // 提取第一个Texture
    auto first_texture = response_proto.textures().begin();
    std::string cells = first_texture->cells();
    int width = first_texture->width();
    int height = first_texture->height();
    resolution = first_texture->resolution();
    // LOG(INFO) << "############resolution=" << resolution<< "##############";
    transform::Rigid3d slice_pose = transform::ToRigid3(first_texture->slice_pose());
    auto pixels = io::UnpackTextureData(cells, width, height);

    // 填写SubmapSlice
    SubmapSlice &submap_slice = submap_slices[submap_id];
    submap_slice.pose = pose;
    submap_slice.metadata_version = version;
    submap_slice.version = query_version;
    submap_slice.width = width;
    submap_slice.height = height;
    submap_slice.slice_pose = slice_pose;
    submap_slice.resolution = resolution;
    submap_slice.cairo_data.clear();
    submap_slice.surface = ::io::DrawTexture(
        pixels.intensity, pixels.alpha, width, height,
        &submap_slice.cairo_data);
}  // for (const auto& submap_id_pose : submap_poses)

pthread_mutex_unlock(&mutex);
// LOG(INFO) << "Get and draw " << submap_slices.size() << " submaps";

// 使用Submap绘制地图
auto painted_slices = PaintSubmapSlices(submap_slices, resolution);
int width = cairo_image_surface_get_width(painted_slices.surface.get());
int height = cairo_image_surface_get_height(painted_slices.surface.get());

info.width = width;
info.height = height;
info.origen_x = -painted_slices.origin.x() * resolution;
info.origen_y = (-height + painted_slices.origin.y()) * resolution;
info.resolution = resolution;

current_map = std::make_unique<SimpleGridMap>(info);
uint32_t *pixel_data = reinterpret_cast<uint32_t *>(cairo_image_surface_get_data(painted_slices.surface.get()));
current_map->datas.reserve(width * height);
for (int y = height - 1; y >= 0; --y) {
    for (int x = 0; x < width; ++x) {
        const uint32_t packed = pixel_data[y * width + x];
        const unsigned char color = packed >> 16;
        const unsigned char observed = packed >> 8;
        const int value = observed == 0 ? -1 : common::RoundToInt((1. - color / 255.) * 100.);
        CHECK_LE(-1, value);
        CHECK_GE(100, value);
        current_map->datas.push_back((char)value);
    }
}

// LOG(INFO) << "Paint map with width " << width << ", height " << height << ", resolution " << resolution;
//  isAdded = true;

current_map->to_char_array(output);

};`

I noticed that the "LocalSlamResult" has this thing called "const std::unique_ptr insertion_result." I don't quite understand what that is but my hypothesis is that it is like the submap to which change was made. Am I correct? If so, how can I use it to not have to run the whole rendering of the map many times per second and only run it for a specific submap [that was changed].

My goal is to make a robot that auto-pathfinds around the room and stuff. Although I got the cartographer to work, the only way I can get the map is through that massive function that is (I am assuming) very slow and is not how you are supposed to do it. Is there a proper way to get the map in a 1D vector format with the ints (chars/bytes whatever) representing the color / obstructed not obstructed?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions