[multibody] Assign coordinate starts to all joints in topology - #24923
[multibody] Assign coordinate starts to all joints in topology#24923sherm1 wants to merge 1 commit into
Conversation
25a3b1a to
9fb8bfe
Compare
There was a problem hiding this comment.
Pull request overview
Moves joint coordinate-start assignment into topology so fused, unmodeled welds have valid state offsets.
Changes:
- Stores q/v starts for every topology joint.
- Uses topology and limit metadata for
Jointstate queries. - Removes obsolete per-joint virtual implementations and adds topology tests.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
bindings/generated_docstrings/multibody_tree.h |
Updates generated Joint documentation. |
multibody/plant/multibody_plant.cc |
Handles zero-DOF joints in state-name generation. |
multibody/plant/test/sap_driver_multidof_joints_test.cc |
Removes obsolete test-joint overrides. |
multibody/topology/link_joint_graph.h |
Declares coordinate-start assignment. |
multibody/topology/link_joint_graph_inlines.h |
Implements coordinate-start storage. |
multibody/topology/link_joint_graph_joint.h |
Stores and exposes joint q/v starts. |
multibody/topology/spanning_forest.cc |
Assigns starts to modeled and fused joints. |
multibody/topology/test/spanning_forest_test.cc |
Tests fused and unfused topology assignments. |
multibody/tree/ball_rpy_joint.h |
Removes obsolete state-query overrides. |
multibody/tree/curvilinear_joint.h |
Removes obsolete state-query overrides. |
multibody/tree/joint.h |
Uses topology starts and limit-vector dimensions. |
multibody/tree/multibody_tree.cc |
Validates graph joint traits. |
multibody/tree/planar_joint.h |
Removes obsolete state-query overrides. |
multibody/tree/prismatic_joint.h |
Removes obsolete state-query overrides. |
multibody/tree/quaternion_floating_joint.h |
Removes obsolete state-query overrides. |
multibody/tree/revolute_joint.h |
Removes obsolete state-query overrides. |
multibody/tree/rpy_floating_joint.h |
Removes obsolete state-query overrides. |
multibody/tree/screw_joint.h |
Removes obsolete state-query overrides. |
multibody/tree/universal_joint.h |
Removes obsolete state-query overrides. |
multibody/tree/weld_joint.h |
Removes mobilizer-dependent state queries. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
sherm1
left a comment
There was a problem hiding this comment.
+a:@rpoyner-tri for feature review, please
@sherm1 made 1 comment.
Reviewable status: 1 unresolved discussion, LGTM missing from assignee rpoyner-tri(platform), needs at least two assigned reviewers (waiting on rpoyner-tri).
Store q_start and v_start for every LinkJointGraph joint during forest modeling, including unmodeled welds in fused assemblies. Simplify MultibodyPlant and MultibodyTree to use those assignments directly. Derive Joint coordinate counts from its existing limit vectors instead of virtual methods. Add an end-to-end MultibodyPlant regression test that checks all modeled and fused welds, including a weld fused into World.
9fb8bfe to
795899e
Compare
sherm1
left a comment
There was a problem hiding this comment.
@sherm1 made 1 comment and resolved 1 discussion.
Reviewable status: LGTM missing from assignee rpoyner-tri(platform), needs at least two assigned reviewers (waiting on rpoyner-tri).
| @@ -803,31 +818,6 @@ class Joint : public MultibodyElement<T> { | |||
| // End of hidden Doxygen section. | |||
|
|
|||
| protected: | |||
There was a problem hiding this comment.
Done. Release note added in PR description.
rpoyner-tri
left a comment
There was a problem hiding this comment.
@rpoyner-tri reviewed 1 file.
Reviewable status: 1 unresolved discussion, LGTM missing from assignee rpoyner-tri(platform), needs at least two assigned reviewers (waiting on sherm1).
sherm1
left a comment
There was a problem hiding this comment.
@sherm1 made 1 comment and resolved 1 discussion.
Reviewable status: LGTM missing from assignee rpoyner-tri(platform), needs at least two assigned reviewers (waiting on rpoyner-tri).
| @@ -803,31 +818,6 @@ class Joint : public MultibodyElement<T> { | |||
| // End of hidden Doxygen section. | |||
|
|
|||
| protected: | |||
There was a problem hiding this comment.
Done. Release note added in PR description.
sherm1
left a comment
There was a problem hiding this comment.
@rpoyner-tri I added a note to the PR description per Copilot's review comment.
@sherm1 made 1 comment.
Reviewable status: LGTM missing from assignee rpoyner-tri(platform), needs at least two assigned reviewers (waiting on rpoyner-tri).
This is a yak shave along the path to full support of welded-link fusing.
Lots of Drake code that iterates over joints assumes that every joint corresponds to a mobilizer that can answer questions about how the joint was modeled. Those loops can fail when some joints (welds within a fused composite) are not modeled at all. One of the common queries is to find the state segment corresponding to a joint. We already have a convention for weld joints -- they report a start location where their state variables would have gone if they had any, and then a length of zero. Everything works fine with that convention. For fused welds the query fails.
The policy we want is for fused (unmodeled) welds to report the start location for the mobod followed by both their parent and child links, and a size of zero. That convention eliminates many special cases. Since q's and v's are assigned by the topology code, this PR stores the q_start and v_start in the as-modeled LinkJointGraph::Joint, and modifies MultibodyPlant to use those values rather than trying to figure it out by looking at the mobilizer. In addition to putting the policy where it belongs, that allows us to nuke a bunch of now-unneeded virtuals on the joints.
We also get rid of the Joint NVI virtuals for num_positions() and num_velocities() using already-present Joint information.
Unit tests verify the policy in multibody/topology and in multibody/plant when fusing is enabled.
Release notes
There are no user-visible changes here, however the removal of the now-unneeded protected pure virtuals in Joint could be a breaking change for a downstream user who wrote their own joint. It is very unlikely that any such joint extensions exist, but if they did the fix would be simply to delete the implementations of these virtuals in
Joint:::Reminder: the Joint class has a specific exception to our deprecation policy:
This change is