r1pro: Point-LIO odometry on the chassis Mid-360 - #4227
Draft
jeff-hykin wants to merge 8 commits into
Draft
jeff-hykin wants to merge 8 commits into
jeff-hykin wants to merge 8 commits into
Conversation
Point-LIO knows when its state is -- lidar_end_time, which the SDK writes into the odometry header -- and main.cpp overwrote it with system_clock::now(). While the estimator keeps up the two agree and nothing shows. When it falls behind, the queue inside Point-LIO grows and the pose being published is seconds old while the stamp still says now. On 20260916-085832-r1pro-kronknav that reached 22 s after the spin: every camera frame paired with tf at its own stamp was posed with where the robot had been 22 s earlier, and no lidar-side check could see it, because the cloud is deskewed into the same wrong estimate and the error cancels. Also refuse to publish a state twice -- re-sending one pose under a later stamp is the same lie -- and warn when the estimator trails the wall clock, which is the quantity that was invisible. (cherry picked from commit b2c139e618307b85413740eda03792568190111d)
The previous commit stamped with lidar_end_time directly, and that is the SENSOR time base: on this Mid-360 it reads 162,771 s, which is 45 hours of lidar uptime against a host at epoch. Publishing it raw is worse than the publish-time stamp it replaced, because nothing downstream resolves at all. Caught by the warning that commit added -- "pointlio is behind the world lag_s=1789421700" -- on the first live run, before any recording was taken. That is also WHY the original code reached for system_clock::now(): it was converting the sensor time base to epoch, and paid for it by describing the wrong moment whenever the estimator fell behind. Both are needed: the state time AND a way to express it on the host clock. HostClockOffset estimates that from packet arrivals, which is the only handle on it. host_arrival - device_stamp is the offset plus a delay that is always positive, so the minimum is the estimate, and it is observed on the SDK callback threads where arrival is honest -- anywhere further in and the estimator backlog folds into it. Two buckets rather than a running minimum, so it follows the clocks drifting apart instead of being captured by the luckiest packet ever seen. Four more tests, one per property, including the 45-hour number as measured. (cherry picked from commit eb00fdff39f171f24ef5759c8f4379ad72c72bc7)
A blueprint, r1pro-pointlio, that runs the existing C++ Point-LIO on the chassis Mid-360 and makes it the thing that places base_link. The wheel odometry the connection integrates from the commanded chassis speed is switched off, the lidar mount is republished inverted so base_link has one parent, and Point-LIO's pose reaches the planners under the name they already read (chassis_odom). On an R1 the lidar's address is already in the vendor's MID360_config.json, so R1ProPointLio reads it from there when nothing sets it, and refuses to start naming the file and the variables when that cannot answer either. A Livox streams to the host that last asked, so the vendor's livox_ros_driver2 goes quiet while this runs and does not recover on its own; the README says which vendor nodes keep running, and exactly how to give the sensor back.
Codecov Report❌ Patch coverage is
@@ Coverage Diff @@
## jeff/fix/livox_rust_reuse_addr #4227 +/- ##
==================================================================
+ Coverage 79.71% 79.73% +0.01%
==================================================================
Files 1508 1511 +3
Lines 142607 142713 +106
Branches 12209 12210 +1
==================================================================
+ Hits 113685 113791 +106
Misses 25483 25483
Partials 3439 3439
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
…into jeff/feat/r1_pointlio
The blueprint composes R1ProMid360 (dimos's driver, with the lidar's address read from the vendor's MID360_config.json when nothing sets it) into PointLioRust, in place of the C++ estimator that read the sensor itself. The driver's raw sweep is renamed to lidar_raw; the estimator's cloud stays on the lidar bus. The driver stamps with the Livox's own clock, which on a sensor with no time source is its uptime, so the Rust estimator now carries its odometry, tf and cloud onto the host's clock the way the C++ module does: the minimum of host-minus-device arrival over a 30 s window.
jeff-hykin
changed the base branch from
main
to
jeff/fix/livox_rust_reuse_addr
September 19, 2026 16:11
The vendor-file reader and the R1ProMid360 subclass go; the two addresses are constants in r1pro/config.py and the CLI overrides them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
r1pro-pointlio: the R1 placed by the Rust Point-LIO fed by dimos's own Mid-360 driver instead of wheel odometry, reading the lidar's address from the vendor's own config and carrying the estimator's stamps onto the host clock, with the README saying what it does to the vendor's lidar driver and how to undo it.