Skip to content

Commit e4892d5

Browse files
committed
Velocity kinematics for composites working; needs tests.
1 parent 83cead6 commit e4892d5

19 files changed

Lines changed: 296 additions & 178 deletions

bindings/generated_docstrings/multibody_plant.h

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -186,32 +186,6 @@ This method must be called pre-Finalize.
186186
Raises:
187187
RuntimeError if ``plant`` is finalized or if time_step is changed.)""";
188188
} ApplyMultibodyPlantConfig;
189-
// Symbol: drake::multibody::BaseBodyJointType
190-
struct /* BaseBodyJointType */ {
191-
// Source: drake/multibody/plant/multibody_plant.h
192-
const char* doc =
193-
R"""(The kind of joint to be used to connect base bodies to world at
194-
Finalize(). See mbp_working_with_free_bodies "Working with free
195-
bodies" for definitions and discussion.
196-
197-
See also:
198-
SetBaseBodyJointType() for details.)""";
199-
// Symbol: drake::multibody::BaseBodyJointType::kQuaternionFloatingJoint
200-
struct /* kQuaternionFloatingJoint */ {
201-
// Source: drake/multibody/plant/multibody_plant.h
202-
const char* doc = R"""(6 dofs, unrestricted orientation.)""";
203-
} kQuaternionFloatingJoint;
204-
// Symbol: drake::multibody::BaseBodyJointType::kRpyFloatingJoint
205-
struct /* kRpyFloatingJoint */ {
206-
// Source: drake/multibody/plant/multibody_plant.h
207-
const char* doc = R"""(6 dofs using 3 angles; has singularity.)""";
208-
} kRpyFloatingJoint;
209-
// Symbol: drake::multibody::BaseBodyJointType::kWeldJoint
210-
struct /* kWeldJoint */ {
211-
// Source: drake/multibody/plant/multibody_plant.h
212-
const char* doc = R"""(0 dofs, fixed to World.)""";
213-
} kWeldJoint;
214-
} BaseBodyJointType;
215189
// Symbol: drake::multibody::CalcContactFrictionFromSurfaceProperties
216190
struct /* CalcContactFrictionFromSurfaceProperties */ {
217191
// Source: drake/multibody/plant/coulomb_friction.h
@@ -4968,7 +4942,7 @@ be used by Finalize(); post-finalize it returns the joint type that
49684942
*was* used if there were any base bodies in need of a joint.
49694943
49704944
See also:
4971-
SetBaseBodyJointType())""";
4945+
SetBaseBodyJointType(), GetCombineWeldedBodies(), Finalize())""";
49724946
} GetBaseBodyJointType;
49734947
// Symbol: drake::multibody::MultibodyPlant::GetBodiesKinematicallyAffectedBy
49744948
struct /* GetBodiesKinematicallyAffectedBy */ {
@@ -5125,6 +5099,23 @@ geometries for ``body`` previously registered with a SceneGraph.
51255099
See also:
51265100
RegisterCollisionGeometry(), Finalize())""";
51275101
} GetCollisionGeometriesForBody;
5102+
// Symbol: drake::multibody::MultibodyPlant::GetCombineWeldedBodies
5103+
struct /* GetCombineWeldedBodies */ {
5104+
// Source: drake/multibody/plant/multibody_plant.h
5105+
const char* doc =
5106+
R"""(Returns the currently-set choice for whether welded-together bodies
5107+
should be combined or modeled separately, either for the global
5108+
setting or for a specific model instance. If a model instance is
5109+
provided for which no explicit choice was made, the global setting is
5110+
returned. Any model instance index is acceptable here; if not
5111+
recognized then the global setting is returned. This can be called any
5112+
time -- pre-finalize it returns the setting that will be used by
5113+
Finalize(); post-finalize it returns the setting that *was* used if
5114+
there were any welded-together bodies.
5115+
5116+
See also:
5117+
SetCombineWeldedBodies(), GetBaseBodyJointType(), Finalize())""";
5118+
} GetCombineWeldedBodies;
51285119
// Symbol: drake::multibody::MultibodyPlant::GetConstraintActiveStatus
51295120
struct /* GetConstraintActiveStatus */ {
51305121
// Source: drake/multibody/plant/multibody_plant.h
@@ -6625,8 +6616,33 @@ Parameter ``model_instance``:
66256616
is to be applied.
66266617
66276618
Raises:
6628-
RuntimeError if called after Finalize().)""";
6619+
RuntimeError if called after Finalize().
6620+
6621+
See also:
6622+
GetBaseBodyJointType(), SetCombineWeldedBodies(), Finalize())""";
66296623
} SetBaseBodyJointType;
6624+
// Symbol: drake::multibody::MultibodyPlant::SetCombineWeldedBodies
6625+
struct /* SetCombineWeldedBodies */ {
6626+
// Source: drake/multibody/plant/multibody_plant.h
6627+
const char* doc =
6628+
R"""(Controls whether welded-together RigidBody elements are to be combined
6629+
into a single composite mobilized body in the generated model. If so,
6630+
the Weld joints will not appear in the post-Finalize() model and there
6631+
will be fewer bodies and joints in the generated model than in the
6632+
user's specification. Results for the original RigidBody elements can
6633+
still be obtained by name or BodyIndex, but no results (in particular,
6634+
no reaction forces) are available for the unmodeled Weld joints.
6635+
6636+
You can set this globally or on a per-model instance basis.
6637+
6638+
The default for Drake is *not* to combine welded RigidBody elements.
6639+
6640+
Raises:
6641+
RuntimeError if called after Finalize().
6642+
6643+
See also:
6644+
GetCombineWeldedBodies(), SetBaseBodyJointType(), Finalize())""";
6645+
} SetCombineWeldedBodies;
66306646
// Symbol: drake::multibody::MultibodyPlant::SetConstraintActiveStatus
66316647
struct /* SetConstraintActiveStatus */ {
66326648
// Source: drake/multibody/plant/multibody_plant.h

bindings/generated_docstrings/multibody_tree.h

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,32 @@ representation.)""";
589589
const char* doc = R"""()""";
590590
} type_name;
591591
} BallRpyJoint;
592+
// Symbol: drake::multibody::BaseBodyJointType
593+
struct /* BaseBodyJointType */ {
594+
// Source: drake/multibody/tree/multibody_tree.h
595+
const char* doc =
596+
R"""(The kind of joint to be used to connect base bodies to world at
597+
Finalize(). See mbp_working_with_free_bodies "Working with free
598+
bodies" for definitions and discussion.
599+
600+
See also:
601+
SetBaseBodyJointType() for details.)""";
602+
// Symbol: drake::multibody::BaseBodyJointType::kQuaternionFloatingJoint
603+
struct /* kQuaternionFloatingJoint */ {
604+
// Source: drake/multibody/tree/multibody_tree.h
605+
const char* doc = R"""(6 dofs, unrestricted orientation.)""";
606+
} kQuaternionFloatingJoint;
607+
// Symbol: drake::multibody::BaseBodyJointType::kRpyFloatingJoint
608+
struct /* kRpyFloatingJoint */ {
609+
// Source: drake/multibody/tree/multibody_tree.h
610+
const char* doc = R"""(6 dofs using 3 angles; has singularity.)""";
611+
} kRpyFloatingJoint;
612+
// Symbol: drake::multibody::BaseBodyJointType::kWeldJoint
613+
struct /* kWeldJoint */ {
614+
// Source: drake/multibody/tree/multibody_tree.h
615+
const char* doc = R"""(0 dofs, fixed to World.)""";
616+
} kWeldJoint;
617+
} BaseBodyJointType;
592618
// Symbol: drake::multibody::BodyIndex
593619
struct /* BodyIndex */ {
594620
// Source: drake/multibody/tree/multibody_tree_indexes.h
@@ -2778,7 +2804,7 @@ extract X_BF for this Frame from it.
27782804
since the last parameter change; we can't check here.
27792805
27802806
Returns ``X_BF``:
2781-
pose of this frame in its body's frame)""";
2807+
pose of this frame in its Mobod's frame)""";
27822808
} get_X_BF;
27832809
// Symbol: drake::multibody::Frame::get_X_FB
27842810
struct /* get_X_FB */ {
@@ -2792,15 +2818,22 @@ extract X_FB (=X_BF⁻¹) for this Frame from it.
27922818
since the last parameter change; we can't check here.
27932819
27942820
Returns ``X_FB``:
2795-
inverse of this frame's pose in its body's frame)""";
2821+
inverse of this frame's pose in its Mobod's frame)""";
27962822
} get_X_FB;
2797-
// Symbol: drake::multibody::Frame::get_body_pose_index_in_cache
2798-
struct /* get_body_pose_index_in_cache */ {
2823+
// Symbol: drake::multibody::Frame::get_X_LF
2824+
struct /* get_X_LF */ {
27992825
// Source: drake/multibody/tree/frame.h
28002826
const char* doc =
2801-
R"""((Internal use only) Retrieve this Frame's body pose index in the
2802-
cache.)""";
2803-
} get_body_pose_index_in_cache;
2827+
R"""((Internal use only) Given an already up-to-date frame body pose cache,
2828+
extract X_LF for this Frame from it.
2829+
2830+
Note:
2831+
Be sure you have called MultibodyTreeSystem∷EvalFrameBodyPoses()
2832+
since the last parameter change; we can't check here.
2833+
2834+
Returns ``X_LF``:
2835+
pose of this frame in its Link's frame)""";
2836+
} get_X_LF;
28042837
// Symbol: drake::multibody::Frame::index
28052838
struct /* index */ {
28062839
// Source: drake/multibody/tree/frame.h
@@ -2850,26 +2883,6 @@ name will be empty (the scope name and the element name).
28502883
RuntimeError if this element is not associated with a
28512884
MultibodyPlant.)""";
28522885
} scoped_name;
2853-
// Symbol: drake::multibody::Frame::set_body_pose_index_in_cache
2854-
struct /* set_body_pose_index_in_cache */ {
2855-
// Source: drake/multibody/tree/frame.h
2856-
const char* doc =
2857-
R"""((Internal use only) A Frame's pose-in-parent X_PF can be
2858-
parameterized, the parent's pose may also be parameterized, and so on.
2859-
Thus the calculation of this frame's pose in its body (X_BF) can be
2860-
expensive. There is a cache entry that holds the calculated X_BF,
2861-
evaluated whenever parameters change. This allows us to grab X_BF as a
2862-
const reference rather than having to extract and reformat parameters,
2863-
and compose with parent and ancestor poses at runtime.
2864-
2865-
At the time parameters are allocated we assign a slot in the body pose
2866-
cache entry to each Frame and record its index using this function.
2867-
(The index for a RigidBodyFrame will refer to an identity transform.)
2868-
Note that the body pose index is not necessarily the same as the Frame
2869-
index because all RigidBodyFrames can share an entry. (Of course if
2870-
you know you are working with a RigidBodyFrame you don't need to ask
2871-
about its body pose!))""";
2872-
} set_body_pose_index_in_cache;
28732886
} Frame;
28742887
// Symbol: drake::multibody::FrameIndex
28752888
struct /* FrameIndex */ {
@@ -5115,6 +5128,17 @@ body frame B.)""";
51155128
const char* doc = R"""()""";
51165129
} stiffness;
51175130
} LinearSpringDamper;
5131+
// Symbol: drake::multibody::LinkIndex
5132+
struct /* LinkIndex */ {
5133+
// Source: drake/multibody/tree/multibody_tree_indexes.h
5134+
const char* doc = R"""(This is a synonym for BodyIndex.)""";
5135+
} LinkIndex;
5136+
// Symbol: drake::multibody::LinkOrdinal
5137+
struct /* LinkOrdinal */ {
5138+
// Source: drake/multibody/tree/multibody_tree_indexes.h
5139+
const char* doc =
5140+
R"""(Type used to identify links by ordinal within a multibody plant.)""";
5141+
} LinkOrdinal;
51185142
// Symbol: drake::multibody::ModelInstanceIndex
51195143
struct /* ModelInstanceIndex */ {
51205144
// Source: drake/multibody/tree/multibody_tree_indexes.h
@@ -7676,6 +7700,14 @@ the index into all associated quantities.)""";
76767700
R"""(Gets the ``name`` associated with this rigid body. The name will never
76777701
be empty.)""";
76787702
} name;
7703+
// Symbol: drake::multibody::RigidBody::ordinal
7704+
struct /* ordinal */ {
7705+
// Source: drake/multibody/tree/rigid_body.h
7706+
const char* doc =
7707+
R"""((Internal use only) Returns this Link's (RigidBody's) unique ordinal.
7708+
Currently identical to the index but will differ when we permit
7709+
removal of Links as we do for Joints.)""";
7710+
} ordinal;
76797711
// Symbol: drake::multibody::RigidBody::scoped_name
76807712
struct /* scoped_name */ {
76817713
// Source: drake/multibody/tree/rigid_body.h

bindings/pydrake/multibody/plant_py.cc

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,17 +1775,6 @@ PYBIND11_MODULE(plant, m) {
17751775
.value("kLagged", Class::kLagged, cls_doc.kLagged.doc);
17761776
}
17771777

1778-
{
1779-
using Class = BaseBodyJointType;
1780-
constexpr auto& cls_doc = doc.BaseBodyJointType;
1781-
py::enum_<Class> cls(m, "BaseBodyJointType", cls_doc.doc);
1782-
cls.value("kQuaternionFloatingJoint", Class::kQuaternionFloatingJoint,
1783-
cls_doc.kQuaternionFloatingJoint.doc)
1784-
.value("kRpyFloatingJoint", Class::kRpyFloatingJoint,
1785-
cls_doc.kRpyFloatingJoint.doc)
1786-
.value("kWeldJoint", Class::kWeldJoint, cls_doc.kWeldJoint.doc);
1787-
}
1788-
17891778
{
17901779
using Class = MultibodyPlantConfig;
17911780
constexpr auto& cls_doc = doc.MultibodyPlantConfig;

bindings/pydrake/multibody/test/plant_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
AddMultibodyPlant,
6060
AddMultibodyPlantSceneGraph,
6161
ApplyMultibodyPlantConfig,
62-
BaseBodyJointType,
6362
CalcContactFrictionFromSurfaceProperties,
6463
ConnectContactResultsToDrakeVisualizer,
6564
ContactModel,
@@ -81,6 +80,7 @@
8180
)
8281
from pydrake.multibody.tree import (
8382
BallRpyJoint_,
83+
BaseBodyJointType,
8484
Body_, # dispreferred alias for RigidBody_
8585
BodyIndex,
8686
CalcSpatialInertia,

bindings/pydrake/multibody/tree_py.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,17 @@ void DoScalarIndependentDefinitions(py::module m) {
148148
.value("kV", Enum::kV, enum_doc.kV.doc);
149149
}
150150

151+
{
152+
using Enum = BaseBodyJointType;
153+
constexpr auto& cls_doc = doc.BaseBodyJointType;
154+
py::enum_<Enum> cls(m, "BaseBodyJointType", cls_doc.doc);
155+
cls.value("kQuaternionFloatingJoint", Enum::kQuaternionFloatingJoint,
156+
cls_doc.kQuaternionFloatingJoint.doc)
157+
.value("kRpyFloatingJoint", Enum::kRpyFloatingJoint,
158+
cls_doc.kRpyFloatingJoint.doc)
159+
.value("kWeldJoint", Enum::kWeldJoint, cls_doc.kWeldJoint.doc);
160+
}
161+
151162
{
152163
using Class = ScopedName;
153164
constexpr auto& cls_doc = doc.ScopedName;

multibody/optimization/test/toppra_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ TEST_F(IiwaToppraTest, JointTorqueLimit) {
210210
auto s_path = result.value();
211211

212212
// This tolerance was tuned to work with the given gridpoints.
213-
const double tol = 1e-14;
213+
const double tol = 1e-13;
214214
Eigen::MatrixXd M(7, 7);
215215
Eigen::VectorXd Cv(7);
216216
Eigen::VectorXd G(7);

multibody/plant/multibody_plant.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,7 @@ class MultibodyPlant final : public internal::MultibodyTreeSystem<T> {
12571257
const systems::OutputPort<T>& get_generalized_contact_forces_output_port(
12581258
ModelInstanceIndex model_instance) const;
12591259

1260-
// BLAH(sherm1) Modify the next comment to explain that unmodeled joints will
1260+
// TODO(sherm1) Modify the next comment to explain that unmodeled joints will
12611261
// have NaN reaction force entries here. (Joints can be unmodeled because
12621262
// they were removed or because they are internal to a composite body.)
12631263

multibody/plant/test/multibody_plant_forward_dynamics_test.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ class KukaIiwaModelForwardDynamicsTests : public test::KukaIiwaModelTests {
113113
// matrix.
114114
const int nv = plant_->num_velocities();
115115
MatrixX<double> M(nv, nv);
116-
plant_->CalcMassMatrixViaInverseDynamics(*context_, &M);
116+
plant_->CalcMassMatrix(*context_, &M);
117117
const double kappa = 1.0 / M.llt().rcond();
118118

119-
// Compare expected results against actual vdot.
120-
const double kRelativeTolerance = kappa * kEpsilon;
119+
// Compare expected results against actual vdot (add a little slop).
120+
const double kRelativeTolerance = 2 * kappa * kEpsilon;
121121
EXPECT_TRUE(CompareMatrices(vdot, vdot_expected, kRelativeTolerance,
122122
MatrixCompareType::relative));
123123
}
@@ -189,6 +189,14 @@ GTEST_TEST(MultibodyPlantForwardDynamics, AtlasRobot) {
189189
.FixValue(context.get(), VectorX<double>::Zero(num_actuators));
190190
auto derivatives = plant.AllocateTimeDerivatives();
191191
{
192+
// Make sure to get global and parameter-change heap allocations done
193+
// before we check CalcTimeDerivatives() heap use.
194+
195+
// Initialization of Highway may use heap on the first call.
196+
const math::RotationMatrix<double> R_AB, R_BC; // Both identity.
197+
EXPECT_TRUE((R_AB * R_BC).IsExactlyIdentity());
198+
plant.EvalFrameBodyPoses(*context); // Updated when parameters change.
199+
192200
// CalcTimeDerivatives should not be allocating, but for now we have a few
193201
// remaining fixes before it's down to zero:
194202
// 2 temps in MbTS::CalcArticulatedBodyForceCache (F_B_W_, tau_).

multibody/rational/rational_forward_kinematics.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,12 @@ RationalForwardKinematics::CalcChildBodyPoseAsMultilinearPolynomial(
245245

246246
internal::MobodIndex mobilizer_index;
247247
bool is_order_reversed{};
248-
if (parent_mobod.inboard().is_valid() &&
249-
parent_mobod.inboard() == child_mobod_index) {
248+
if (parent_mobod.inboard_mobod().is_valid() &&
249+
parent_mobod.inboard_mobod() == child_mobod_index) {
250250
is_order_reversed = true;
251251
mobilizer_index = parent_mobod_index;
252-
} else if (child_mobod.inboard().is_valid() &&
253-
child_mobod.inboard() == parent_mobod_index) {
252+
} else if (child_mobod.inboard_mobod().is_valid() &&
253+
child_mobod.inboard_mobod() == parent_mobod_index) {
254254
is_order_reversed = false;
255255
mobilizer_index = child_mobod_index;
256256
} else {

multibody/rational/rational_forward_kinematics_internal.cc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,17 @@ std::vector<BodyIndex> FindPath(const MultibodyPlant<double>& plant,
4646
forest.mobods(current_link.mobod_index());
4747
if (current != world_index()) {
4848
const SpanningForest::Mobod& parent_mobod =
49-
forest.mobods(current_mobod.inboard());
49+
forest.mobods(current_mobod.inboard_mobod());
5050
const BodyIndex parent =
51-
tree.forest().links(parent_mobod.link_ordinal()).index();
51+
tree.forest().links(parent_mobod.active_link_ordinal()).index();
5252
visit_edge(current, parent);
5353
}
54-
for (const MobodIndex& child_mobod_index : current_mobod.outboards()) {
54+
for (const MobodIndex& child_mobod_index :
55+
current_mobod.outboard_mobods()) {
5556
const SpanningForest::Mobod& child_mobod =
5657
forest.mobods(child_mobod_index);
5758
const BodyIndex child =
58-
tree.forest().links(child_mobod.link_ordinal()).index();
59+
tree.forest().links(child_mobod.active_link_ordinal()).index();
5960
visit_edge(current, child);
6061
}
6162
}
@@ -86,7 +87,8 @@ std::vector<MobodIndex> FindMobilizersOnPath(
8687
const LinkJointGraph::Link& link_i = forest.link_by_index(path[i]);
8788
const LinkJointGraph::Link& link_ip1 = forest.link_by_index(path[i + 1]);
8889
const SpanningForest::Mobod& mobod_i = forest.mobods(link_i.mobod_index());
89-
if (!mobod_i.is_world() && mobod_i.inboard() == link_ip1.mobod_index()) {
90+
if (!mobod_i.is_world() &&
91+
mobod_i.inboard_mobod() == link_ip1.mobod_index()) {
9092
// path[i] is the child of path[i+1] in MultibodyTreeTopology, they are
9193
// connected by path[i]'s inboard mobilizer.
9294
mobilizers_on_path.push_back(link_i.mobod_index());

0 commit comments

Comments
 (0)