Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map rotating with lidar. #1943

Open
lolhol opened this issue Jan 3, 2024 · 5 comments
Open

Map rotating with lidar. #1943

lolhol opened this issue Jan 3, 2024 · 5 comments

Comments

@lolhol
Copy link

lolhol commented Jan 3, 2024

Hello, I have just recently started working with the cartographer and, since then, have gotten it to make at least some sort of a map. I am using just a lidar (10hz RPLidar S1M1) and no other sensors (imu, odometry etc.). Unfortunately though, whenever I turn a lot or try to make a map while moving (with turning), the output is completely broken.

CartoBagOut1

Furthermore, (I have created a bag file with the exact same data I was feeding originally) anything I do in the "trajectory_builder_2d" (in ceres_scan_matcher) relating to the rotation_weight (I tried setting it to 4e3) seems to do nothing and the end map just looks the same.

What seems to do the trick (kind of) is replaying the bag file at very high speeds instead of sleeping the ~ amount of time between lidar scans (100ms in my case). The lower the sleep time the better the map quality but the less information there is on it. (in this example I have 0 sleep time).

CartoBagOut

As can be seen, the map is much cleaner, but some of the information is just not there (there is supposed to be another whole room on the top right which I went into multiple times)

My configuration files can be found here - https://drive.google.com/drive/folders/1gWdDzMxo_ecXL6LcsQY0rLTHE8rXgypw?usp=sharing

@lolhol
Copy link
Author

lolhol commented Jan 4, 2024

It seems like the map is not rotating, rather the cartographer is not detecting change in position (possibly). The way I was able to "fix" it is by making a fake time measurement:

Int c = 1000;

// update LiDAR data with c as time

c += 100;

Currently I am trying to figure out how I can give carto real time measurement, but all my attempts have failed. I tried giving carto both Ms, nano, and micro seconds but nothing works. I suspect that the function that I use to convert this time into carto time (FromUniversal) takes in something different and not nano/milli.

(By that I mean I was feeding the carto System.currentTimeMs()) (I have converted some key functions to Java because my main program is in it)

So, can anyone please give me possibly some sample code on when you convert your LiDAR data (Cartesian data, intensity, timestamp) into the TimedPointCloud (not sure what the name is but the function which you call to update LiDAR data takes that in). Also, my LiDAR doesn't naturally give me time measurements, but I still want to fake them. Is there a way I can do that?

@lolhol
Copy link
Author

lolhol commented Jan 5, 2024

update: it seems like the cartographer just does not see the movement of the lidar (I am not using any other method of detecting movement). It just returns 0.0000 when I try to get the position (occasionally 0.0003). I think something may be wrong with the conversion of my raw lidar data to carto data ->

`cartographer::sensor::TimedPointCloudData to_carto_point_cloud(PointCloudData& data, double time_offset, int64_t startTime) {
double timeSec = (data.timestamp - startTime) / 1000.;
cartographer::common::Time time = cartographer::common::FromUniversal(123) + cartographer::common::FromSeconds(timeSec);
std::cout << "Time Sec: " << timeSec << std::endl;

cartographer::sensor::TimedPointCloud carto_data;
int size = data.points.size();
carto_data.reserve(size);
double timestep = time_offset / size;
double minus_time = -time_offset;
for (int i = 0; i < size; i++) {
    if (i == size - 1) {
        minus_time = 0.;
    }
    cartographer::sensor::TimedRangefinderPoint tmp_point{
        Eigen::Vector3f(data.points.at(i)(0), data.points.at(i)(1), 0.), minus_time};

    carto_data.push_back(tmp_point);
    minus_time += timestep;
}

return cartographer::sensor::TimedPointCloudData{time, Eigen::Vector3f(0, 0, 0), carto_data};

}`

any help?

@adiego73
Copy link

adiego73 commented Jan 5, 2024

Hi! It's been some time since the last time I did something with cartogpraher. If you are not using any other sensor but a LIDAR, you should enable the real time correlative scan matcher: TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true;

In fact, the doc says:

The RealTimeCorrelativeScanMatcher can be enabled if you do not have other sensors or you do not trust them. It uses an approach similar to how scans are matched against submaps in loop closure (described later), but instead it matches against the current submap. The best match is then used as prior for the CeresScanMatcher. This scan matcher is very expensive and will essentially override any signal from other sensors but the range finder, but it is robust in feature rich environments.

Hope it helps!

@lolhol
Copy link
Author

lolhol commented Jan 5, 2024

Hi!

I just figured this out last night so you are a little bit late. It is ok though.

I guess the question now is what I am doing wrong because I followed the guide (just put the config in thats it) based on this video and my map looks much much worse. I suspect that it is due to cartographer accepting new data too fast (starting to think of new points as hard truth walls). But I don't know how to fix this. Additionally, contrary to the video clip, the walls sometimes move with me (like the cartographer marks the spots where there were no walls before as walls).

(Ps: in case you did not understand because I suck as explaining, cartographer just maps new walls instead of seeing that position changed.)

trim.DD495F99-E2B6-4AC3-A6BA-F7A6DF33FEBE.MOV

(During this video I moved a total of 3 times, each a step long -> ~1m, towards the long wall on the right. Than I rotated 90 deg to the left (up))

Also, is there a way I can get the local slam map? Because what I have right now is
'map_builder->pose_graph()->GetAllSubmapPoses();'

It is pretty slow and, in ros rviz, it seems like the map is being updated much much faster.

Any help?

(edit: it seems like cartographer returns wrong position as well since the position that it returns in the callback is completely wrong)

(edit2: I don't know if it is significant but I just though it is good to mention that my lidar scans can skip some degrees. EX: 215: 5m, 216: 6m, 218: 3m)

@lolhol
Copy link
Author

lolhol commented Jan 7, 2024

Ok, so the reason my map was breaking is because I did not understand what "num_accumulated_range_data" meant. I had it set to 10 when I only inputted one source of scans. When I changed it to one (I have a single lidar) everything started working.

Although so, I still don't know if it is possible to get the local slam map.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants