@@ -228,6 +228,14 @@ enum class DiscreteContactApproximation {
228
228
kLagged ,
229
229
};
230
230
231
+ // / The kind of joint to be used to connect free bodies to world at Finalize().
232
+ // / @see SetBaseBodyJointType() for details.
233
+ enum class BaseBodyJointType {
234
+ kQuaternionFloatingJoint , // /< 6 dofs, unrestricted orientation.
235
+ kRpyFloatingJoint , // /< 6 dofs using 3 angles; has singularity.
236
+ kWeldJoint , // /< 0 dofs, fixed to World.
237
+ };
238
+
231
239
// / @cond
232
240
// Helper macro to throw an exception within methods that should not be called
233
241
// post-finalize.
@@ -1667,6 +1675,39 @@ class MultibodyPlant : public internal::MultibodyTreeSystem<T> {
1667
1675
void RenameModelInstance (ModelInstanceIndex model_instance,
1668
1676
const std::string& name);
1669
1677
1678
+ // / Sets the type of joint to be used by Finalize() to connect any otherwise
1679
+ // / unconnected bodies to World. Bodies connected by a joint to World are
1680
+ // / called _base bodies_ and are determined during Finalize() when we build
1681
+ // / a forest structure to model the multibody system for efficient
1682
+ // / computation.
1683
+ // /
1684
+ // / This can be set globally or for a particular model instance. Global
1685
+ // / options are used for any model elements that belong to model instances for
1686
+ // / which no options have been set explicitly. The default is to use a
1687
+ // / quaternion floating joint.
1688
+ // /
1689
+ // / | BaseBodyJointType:: | Notes |
1690
+ // / | ------------------------ | -------------------------------------- |
1691
+ // / | kQuaternionFloatingJoint | 6 dofs, unrestricted orientation |
1692
+ // / | kRpyFloatingJoint † | 6 dofs, uses 3 angles for orientation |
1693
+ // / | kWeldJoint | 0 dofs, welded to World ("anchored") |
1694
+ // /
1695
+ // / † The 3-angle orientation representation used by RpyFloatingJoint can be
1696
+ // / easier to work with than a quaternion (especially for optimization) but
1697
+ // / has a singular orientation which must be avoided (pitch angle near 90°).
1698
+ // /
1699
+ // / @note Reminder: if you aren't satisfied with the automatic choice of
1700
+ // / base body or the particular selection of joints here, you can always
1701
+ // / add an explicit joint to World with AddJoint().
1702
+ // /
1703
+ // / @param[in] joint_type The joint type to be used for base bodies.
1704
+ // / @param[in] model_instance (optional) the index of the model instance to
1705
+ // / which `joint_type` is to be applied.
1706
+ // / @throws std::exception if called after Finalize().
1707
+ void SetBaseBodyJointType (
1708
+ BaseBodyJointType joint_type,
1709
+ std::optional<ModelInstanceIndex> model_instance = {});
1710
+
1670
1711
// / This method must be called after all elements in the model (joints,
1671
1712
// / bodies, force elements, constraints, etc.) are added and before any
1672
1713
// / computations are performed.
@@ -3217,11 +3258,22 @@ class MultibodyPlant : public internal::MultibodyTreeSystem<T> {
3217
3258
}
3218
3259
3219
3260
// / Sets the distribution used by SetRandomState() to populate the free
3220
- // / body's `rotation` with respect to its parent frame.
3261
+ // / body's orientation with respect to its parent frame, expressed as a
3262
+ // / quaternion. Requires that the free body is modeled using a
3263
+ // / QuaternionFloatingJoint.
3221
3264
// / @note The parent frame is not necessarily the world frame. See
3222
- // / @ref mbp_working_with_free_bodies "above for details".
3265
+ // / @ref mbp_working_with_free_bodies "above for details".
3266
+ // / @note This distribution is not uniform over the sphere reachable by
3267
+ // / the quaternion. See SetFreeBodyRandomRotationDistributionToUniform()
3268
+ // / for a uniform alternative.
3223
3269
// / @throws std::exception if `body` is not a free body in the model.
3270
+ // / @throws std::exception if the free body is not modeled with a
3271
+ // / QuaternionFloatingJoint.
3224
3272
// / @throws std::exception if called pre-finalize.
3273
+ // / @see SetFreeBodyRandomAnglesDistribution() for a free body that is
3274
+ // / modeled using an RpyFloatingJoint.
3275
+ // / @see SetBaseBodyJointType() for control over the type of automatically-
3276
+ // / added joints.
3225
3277
void SetFreeBodyRandomRotationDistribution (
3226
3278
const RigidBody<T>& body,
3227
3279
const Eigen::Quaternion<symbolic::Expression>& rotation) {
@@ -3230,14 +3282,45 @@ class MultibodyPlant : public internal::MultibodyTreeSystem<T> {
3230
3282
}
3231
3283
3232
3284
// / Sets the distribution used by SetRandomState() to populate the free
3233
- // / body's rotation with respect to its parent frame using uniformly random
3234
- // / rotations.
3285
+ // / body's orientation with respect to its parent frame using uniformly random
3286
+ // / rotations (expressed as a quaternion). Requires that the free body is
3287
+ // / modeled using a QuaternionFloatingJoint.
3235
3288
// / @note The parent frame is not necessarily the world frame. See
3236
- // / @ref mbp_working_with_free_bodies "above for details".
3289
+ // / @ref mbp_working_with_free_bodies "above for details".
3237
3290
// / @throws std::exception if `body` is not a free body in the model.
3291
+ // / @throws std::exception if the free body is not modeled with a
3292
+ // / QuaternionFloatingJoint.
3238
3293
// / @throws std::exception if called pre-finalize.
3294
+ // / @see SetFreeBodyRandomAnglesDistribution() for a free body that is
3295
+ // / modeled using an RpyFloatingJoint.
3296
+ // / @see SetBaseBodyJointType() for control over the type of automatically-
3297
+ // / added joints.
3239
3298
void SetFreeBodyRandomRotationDistributionToUniform (const RigidBody<T>& body);
3240
3299
3300
+ // / Sets the distribution used by SetRandomState() to populate the free
3301
+ // / body's orientation with respect to its parent frame, expressed with
3302
+ // / roll-pitch-yaw angles. Requires that the free body is modeled using an
3303
+ // / RpyFloatingJoint.
3304
+ // / @note The parent frame is not necessarily the world frame. See
3305
+ // / @ref mbp_working_with_free_bodies "above for details".
3306
+ // / @note This distribution is not uniform over the sphere reachable by
3307
+ // / the three angles. See SetFreeBodyRandomRotationDistributionToUniform()
3308
+ // / for a uniform alternative.
3309
+ // / @throws std::exception if `body` is not a free body in the model.
3310
+ // / @throws std::exception if the free body is not modeled with an
3311
+ // / RpyFloatingJoint.
3312
+ // / @throws std::exception if called pre-finalize.
3313
+ // / @see SetFreeBodyRandomRotationDistribution() for a free body that is
3314
+ // / modeled using a QuaternionFloatingJoint.
3315
+ // / @see SetBaseBodyJointType() for control over the type of automatically-
3316
+ // / added joints.
3317
+ void SetFreeBodyRandomAnglesDistribution (
3318
+ const RigidBody<T>& body,
3319
+ const math::RollPitchYaw<symbolic::Expression>& angles) {
3320
+ this ->mutable_tree ().SetFreeBodyRandomAnglesDistributionOrThrow (body,
3321
+ angles);
3322
+ }
3323
+
3241
3324
// / Sets `context` to store the pose `X_WB` of a given _floating base_ `body`
3242
3325
// / B in the world frame W.
3243
3326
// / @param[in] context
0 commit comments