Skip to content

Fix/ivan/motion stability - #3731

Open
leshy wants to merge 130 commits into
mainfrom
fix/ivan/motion_stability
Open

Fix/ivan/motion stability#3731
leshy wants to merge 130 commits into
mainfrom
fix/ivan/motion_stability

Conversation

@leshy

@leshy leshy commented Aug 27, 2026

Copy link
Copy Markdown
Member

Contribution path

  • Small, safe change that does not need a tracking issue
  • Linked issue or discussion: DIM-XXX / #XXX / URL

Problem

Solution

How to Test

AI assistance

Checklist

  • I have read and approved the CLA.

aclauer and others added 30 commits August 4, 2026 17:07
…hub.com:dimensionalOS/dimos into andrew/feat/ray-tracer-performance-improvements
leshy and others added 24 commits August 26, 2026 18:35
md-babel-py run README.md regenerates it from the modules' In/Out hints.
MotionPlanner and TrajectoryFollower, python and rust, no longer subscribe
odometry. Each tick looks the body up on tf -- the planner
`world_frame -> base_frame`, the follower `path.frame_id -> base_frame`, so
it controls in the frame the plan is expressed in -- and go2_tf's odometry
edge plus the mount tree is what it finds there.

The deadman rides the edge's stamp on our own clock: an edge whose stamp has
not advanced for the module's age limit (max_map_age_s, max_path_age_s) is a
missing pose -- the planner plans nothing, the follower zeroes the twist and
names `pose`. Stamp-keyed rather than stamp-compared, because the stamp is
the robot's clock and ours need not agree with it.

OdomBasePose stays for goal_relay and basic_path_follower; TfPose sits
beside it. The rust tf_pose.rs is now PoseWatch, the same watch.
…dy off path

plan_body was the path message again, republished at viz_publish_hz so the
bridge had a topic to hang the body boxes on. The bridge can return more than
one entity per topic, so the boxes now draw on world/path/body from the one
path the planner already publishes -- the port, the rate cap, the config knob
and the motion_viz_hz blueprint dial go, in python and rust alike.
The follower had two tracks named the wrong way round: `blind` decoded the
room the planner encoded in the path timestamps, `hinted` measured it again
off `local_map`. From the follower's side the hints ARE in the path, so the
stamp-reading law is now `hinted` and the only law besides the `seed`
baseline. The map-reading law, its pyo3 class, its parity sequence and the
no-map fallback (ceilings bent back into clearance) are deleted, and with
them everything the follower only needed to see the map: the `local_map`
port, `clearance_for`, the obstacle model, `body_dilate_m`, the track
machinery and the `-blind` blueprint. `controller="module:factory"` stays
as the override. Tuning fields only that law read leave `ControllerConfig`
and the rust `Tuning`; `gait_band`/`command_slew` stay on the body.

Parity is unchanged: the renamed law is bit for bit the one that ran.
# Conflicts:
#	docs/platforms/quadruped/go2/index.md
#	docs/usage/modules.md
…sforms' into ivan/feat/motion

# Conflicts:
#	dimos/navigation/test_tf_pose.py
#	dimos/navigation/tf_pose.py
#	dimos/robot/unitree/go2/constants.py
#	dimos/robot/unitree/go2/zenoh/zenohconnection.py
The bake/scp/systemctl recipe was four commands in a doc and a service file
parked in misc/. Now it is dimos/navigation/motion/deploy/deploy.sh <host>,
with the unit file beside it.

It checks the robot over ssh BEFORE baking, so a robot that is off costs
seconds instead of a build. It stops the unit before scp because Linux will
not overwrite a running executable. It verifies four `config loaded` lines
scoped to the invocation it just started, not a time window that would count
the previous restart too.

The bake is unconditional: cargo already does the incremental staleness check
and the config is re-emitted every run, so an mtime heuristic here would be a
worse copy of that, and would go stale the first time someone added an import
it did not know about.

Also drops two stale claims from the doc: the installed unit feeds no stdin,
and the journal says `config loaded`, not `module started`.
motion.md and motion-deployment.md go back in when the deployment story is
settled. The four things that pointed at them now point at the script and the
module docs instead, so nothing dangles in the meantime.
start_relay.py came in with the navigation-with-transforms merge and then got
unstaged again -- the resolution swept `git restore --staged` across every added
path to drop untracked scratch, and took a real file with it. Its test was
tracked, so CI ran a test importing a module that was not in the tree. That is
the lint/md-babel/self-hosted failure, not three separate ones.

The rust failure is the merge commit, not the branch: #3699 added a dep to
dimos-module and relocked the five workspaces that exist on main. The motion
crates only exist here, so their locks went stale the moment CI merged main in,
and --locked refused them. Relocked adapter, movement_manager and go2/tf; the
other two were already current.
self-hosted-large-tests collects every test module but only the pyo3 job runs
maturin, so a module-level load_extension() raised through collection and took
the whole run down -- 5093 deselected tests never got to run because of one
module the job was not going to execute anyway.

test_voxel_map, test_mls_planner and both test_transformers already guard with
pytest.importorskip. This one now does the same, so it skips there and still
runs everywhere the crate is built.
@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review (140 files, 100 file limit).

Bypass the limit by tagging @greptile-apps to review.

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

Successfully merging this pull request may close these issues.

2 participants