feat(g1-groot): navigation on the real G1 (Point-LIO + raytracing costmap)#2861
feat(g1-groot): navigation on the real G1 (Point-LIO + raytracing costmap)#2861Nabla7 wants to merge 6 commits into
Conversation
❌ 1 Tests Failed:
View the full list of 1 ❄️ flaky test(s)
To view more test analytics, go to the Test Analytics Dashboard |
355667d to
a57aad4
Compare
Greptile SummaryThis PR adds real-hardware G1 navigation through the existing WBC coordinator. The main changes are:
Confidence Score: 4/5This is close, but the command mode handling should be fixed before merging.
dimos/robot/unitree/g1/wholebody_connection.py Important Files Changed
Reviews (3): Last reviewed commit: "Merge branch 'main' into pim/feat/g1-rea..." | Re-trigger Greptile |
| self._mode_machine = actual | ||
| if self._low_cmd is not None: | ||
| self._low_cmd.mode_machine = actual |
There was a problem hiding this comment.
First LowState Becomes Permanent
If the first LowState after startup reports a transient or not-yet-set mode_machine, this one-shot path stores that value and never checks later samples. Subsequent commands are stamped with the stale value and can be silently rejected for the rest of the run, leaving the robot unresponsive until restart.
The unitree-g1-nav-simple middle (raytracing voxel map -> height costmap -> replanning A*) fed by the MID-360 through Point-LIO, executed through the coordinator's twist_command by the WBC policy instead of sport mode. Rerun roots the mesh on the LIO odometry via the URDF pelvis->mid360 transform and draws costmaps on the boot frame's true ground plane. Voxel size matches go2 nav_3d: at 0.05 the raytracer saturated the Orin and registered scans against stale poses (the map rotated with the robot).
The reported value varies per boot on some G1 units and a mismatch makes the firmware silently reject every motor command, so the configured value is only a default until the first LowState.
100 Hz tick / decimation 2 (a 500 Hz Python tick collapses to ~90 Hz on the Orin and starves the 50 Hz policy), n_workers=10, and 10 Hz Rerun caps on the ~440 Hz raw state streams.
a57aad4 to
75bed8a
Compare
| from dimos.msgs.geometry_msgs.Quaternion import Quaternion | ||
|
|
||
| t_world_mid360 = np.eye(4) | ||
| # The MID-360 is mounted upside down (the URDF doesn't carry the flip): |
There was a problem hiding this comment.
The URDF should contain the flip, but also the flip shouldn't matter cause we gravity align by default.
If its tested and working though I think ignore this comment by me
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
jeff-hykin
left a comment
There was a problem hiding this comment.
LGTM so long as its working on hardware.
| """ | ||
| if self._mode_machine_verified: | ||
| return | ||
| self._mode_machine_verified = True |
There was a problem hiding this comment.
_mode_machine_verified is set on the first LowState before the reported value is known to be stable. If the first frame carries a transient/default value, or briefly matches the configured default before firmware reports the real boot-specific value, every later LowState returns early and commands keep using the stale mode. The robot can still receive commands stamped with a mode the firmware silently rejects.
Nav for the real G1 in the groot WBC blueprint: MID-360 -> Point-LIO → raytracing voxel map -> height costmap -> replanning A*, driven through the coordinator's
twist_command(no sport mode). Same front-end and mapper as go2 nav_3d.Split out of #2477 so it can land on its own; that branch rebases after.
Two small fixes are included because nav is unusable on the robot without them:
Voxel size is 0.08 to match go2 — at 0.05 the raytracer pegged the Orin and fell ~60 s behind its inputs, registering scans against stale odometry (the "map rotates with the robot" issue). Verified on the robot: map stays correct over long runs, goal nav works. Sim path untouched.
Point-LIO IPs default to the G1's onboard NIC; override with
LIDAR_HOST_IP/LIDAR_IP.