-
Notifications
You must be signed in to change notification settings - Fork 148
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
Implement a technique to estimate scan_ts when packets are missing at beginning of a lidar scan #67
Implement a technique to estimate scan_ts when packets are missing at beginning of a lidar scan #67
Conversation
… the beginning of a frame
Tested with 2 Ouster OS0-64 (fw 2.4), on Jetson AGX Xavier with CISCO IE-3300 switch. Before this fix with high network load some point clouds from driver had invalid timestamps (2-3 secs into future), now this problem is fixed (tested for an hour). |
I think it would be quite easy to create an artificial dataset on which this function can be tested. I started creating it, but have no time the following few days to finish it. Basically, you just record the lidar packets into a bag file, figure out which packet represents start of a scan, and drop a few packets around that place. It would be quite interesting to know how does this behave if the first packet of the very first scan is missing. |
We can add tests that mimic the condition
Assuming the very fist frame had zero packets the imputation code will use the following values for last_scan: static int last_scan_last_nonzero_idx =
curr_scan_first_nonzero_idx - 1; // initialize to a known state (x0)
static uint64_t last_scan_last_nonzero_value =
curr_scan_first_nonzero_value; // impute with ts_v(idx) (y0) If you substitute these values into the linear interpolation equation |
Hmm, isn't this a reason to switch to the approach where you compute the timestamp from known sensor parameters? I.e. you know the rotation speed and index of the first packet in the scan, so it is possible to compute the timestamp with pretty simple math. Its precision only depends on the stability of rotation speed, but I always thought this isn't an issue with Ouster lidars. Or did your tests show otherwise? The benefit would be that the same code could also be used in case of timestamping with ROS time. And another benefit would be that it would work only on the current scan and would not depend on any preceding scan(s). |
I tried simple linear extrapolation |
Ok, if the tests show the imputation is more precise, then it is a good way to go. What about using the extrapolation for the first scan? |
The first packets of the very first scan are almost always missed (by a good margin), so it makes sense to handle this case with extrapolation. |
I pushed an update to extrapolate the timestamp of the very first frame. With regard to the |
I did push an update to the PR that addresses the |
imho, I would try to make the function for estimating the first column timestamp that operates on a single LidarScan as:
I've not tried it, but if it will work without losing precision it would be a single standalone function that will work for any LidarScan without keeping any other state around. |
if (predicate(*p)) return p - array.data(); | ||
} while (p-- != array.data()); | ||
return -1; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious would it possible to use a standard std::find_if
with Eigen reverse()
to get a reverse iterator? https://eigen.tuxfamily.org/dox/classEigen_1_1DenseBase.html#a38ea394036d8b096abf322469c80198f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially had it like this but found it that does not cross compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I thought you meant something else
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't want to create a reverse
of the array just so I could find the last element. while you could easily find the item by iterating the array backwards in-place..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally, I thought you were suggesting me to use std::reverse_iterator
, this would very appropriate and you can pass it to std::find_if
and it would traverse the array in-place backwards. The only issue it wouldn't cross-compile (failed on gcc-9).
The whole idea of my approach is to avoid having the estimated timestamp of the scan interleave with values from the previous scan. Imagine the case where you receive a frame with nonzero values only in the range of [1000, 1010]. So a very short range of valid value and you try to fit the line into it. It does not guarantee that the projected/estimated value of first timestamp can't go past previous frame. The approach used here does guarantee that you won't have values interfere/interleave between two different scans/frames. |
yeah, agree. I've tried some of these cases and they indeed can go past the previous frame, i've even played with least squares fit that uses not just 2 points, but all of those available and still in some LidarScans it may have error with ground truth's zero column timestamp to the extent of 150k - 250k nanosecs in some cases ... so probably we can't get rid of keeping the state of the previous frame and need to have this filter like approach. |
… beginning of a lidar scan (ouster-lidar#67) * Implement a technique to estimate scan_ts when packets are missing at the beginning of a frame * Be consistent with variable naming * Add an assert statement for find_if_reverse * Extrapolate the time for the first scan * Implement the extrapolation for TIME_FROM_ROS_TIME timestamp option * Address the issue with ulround function not working for integral types * Perform type conversion on the difference * Take always positive difference and compute sign * Use lround instead of invoking cast to integer/long * Update CHANGELOG
… beginning of a lidar scan (ouster-lidar#67) * Implement a technique to estimate scan_ts when packets are missing at the beginning of a frame * Be consistent with variable naming * Add an assert statement for find_if_reverse * Extrapolate the time for the first scan * Implement the extrapolation for TIME_FROM_ROS_TIME timestamp option * Address the issue with ulround function not working for integral types * Perform type conversion on the difference * Take always positive difference and compute sign * Use lround instead of invoking cast to integer/long * Update CHANGELOG
… beginning of a lidar scan (ouster-lidar#67) * Implement a technique to estimate scan_ts when packets are missing at the beginning of a frame * Be consistent with variable naming * Add an assert statement for find_if_reverse * Extrapolate the time for the first scan * Implement the extrapolation for TIME_FROM_ROS_TIME timestamp option * Address the issue with ulround function not working for integral types * Perform type conversion on the difference * Take always positive difference and compute sign * Use lround instead of invoking cast to integer/long * Update CHANGELOG
… beginning of a lidar scan (ouster-lidar#67) * Implement a technique to estimate scan_ts when packets are missing at the beginning of a frame * Be consistent with variable naming * Add an assert statement for find_if_reverse * Extrapolate the time for the first scan * Implement the extrapolation for TIME_FROM_ROS_TIME timestamp option * Address the issue with ulround function not working for integral types * Perform type conversion on the difference * Take always positive difference and compute sign * Use lround instead of invoking cast to integer/long * Update CHANGELOG
… missing at beginning of a lidar scan (ouster-lidar#67) * Implement a technique to estimate scan_ts when packets are missing at the beginning of a frame * Be consistent with variable naming * Add an assert statement for find_if_reverse * Extrapolate the time for the first scan * Implement the extrapolation for TIME_FROM_ROS_TIME timestamp option * Address the issue with ulround function not working for integral types * Perform type conversion on the difference * Take always positive difference and compute sign * Use lround instead of invoking cast to integer/long * Update CHANGELOG
Related Issues & PRs
Closes #47
Related #46
Summary of Changes
frame_ts
andscan_ts
when packets are missing at beginning of a LIDAR scanValidation