Drake
body.h
Go to the documentation of this file.
1 #pragma once
2
3 #include <memory>
4 #include <string>
5 #include <vector>
6
7 #include "drake/common/autodiff.h"
8 #include "drake/common/drake_copyable.h"
9 #include "drake/common/unused.h"
10 #include "drake/multibody/multibody_tree/frame.h"
11 #include "drake/multibody/multibody_tree/multibody_tree_element.h"
12 #include "drake/multibody/multibody_tree/multibody_tree_indexes.h"
13 #include "drake/multibody/multibody_tree/multibody_tree_topology.h"
14 #include "drake/multibody/multibody_tree/spatial_inertia.h"
15
16 namespace drake {
17 namespace multibody {
18
19 // Forward declaration for BodyFrame<T>.
20 template<typename T> class Body;
21
22 /// A %BodyFrame is a material Frame that serves as the unique reference frame
23 /// for a Body.
24 ///
25 /// Each Body B, regardless of whether it represents a rigid body or a
26 /// flexible body, has a unique body frame for which we use the same symbol B
27 /// (with meaning clear from context). The body frame is also referred to as
28 /// a _reference frame_ in the literature for flexible body mechanics modeling
29 /// using the Finite Element Method. All properties of a body are defined with
30 /// respect to its body frame, including its mass properties and attachment
31 /// locations for joints, constraints, actuators, geometry and so on. Run time
32 /// motion of the body is defined with respect to the motion of its body frame.
33 /// We represent a body frame by a %BodyFrame object that is created whenever a
34 /// Body is constructed and is owned by the Body.
35 ///
36 /// Note that the %BodyFrame associated with
37 /// a body does not necessarily need to be located at its center of mass nor
38 /// does it need to be aligned with the body's principal axes, although, in
39 /// practice, it frequently is.
40 /// For flexible bodies, %BodyFrame provides a representation for the body's
41 /// reference frame. The flexible degrees of freedom associated with a flexible
42 /// body describe the body's deformation in this frame. Therefore, the motion of
43 /// a flexible body is defined by the motion of its %BodyFrame, or reference
44 /// frame, plus the motion of the material points on the body with respect to
45 /// its %BodyFrame.
46 ///
47 /// A %BodyFrame and Body are tightly coupled concepts; neither makes sense
48 /// without the other. Therefore, a %BodyFrame instance is constructed in
49 /// conjunction with its Body and cannot be
50 /// constructed anywhere else. However, you can still access the frame
51 /// associated with a body, see Body::body_frame().
52 /// This access is more than a convenience; you can use the %BodyFrame to
53 /// define other frames on the body and to attach other multibody elements
54 /// to it.
55 ///
56 /// @tparam T The scalar type. Must be a valid Eigen scalar.
57 template <typename T>
58 class BodyFrame final : public Frame<T> {
59  public:
61
63  const systems::Context<T>&) const override {
64  return Isometry3<T>::Identity();
65  }
66
68  const systems::Context<T>&,
69  const Isometry3<T>& X_FQ) const override {
70  return X_FQ;
71  }
72
73  protected:
74  // Frame<T>::DoCloneToScalar() overrides.
75  std::unique_ptr<Frame<double>> DoCloneToScalar(
76  const MultibodyTree<double>& tree_clone) const override;
77
78  std::unique_ptr<Frame<AutoDiffXd>> DoCloneToScalar(
79  const MultibodyTree<AutoDiffXd>& tree_clone) const override;
80
81  private:
82  // Body<T> and BodyFrame<T> are natural allies. A BodyFrame object is created
83  // every time a Body object is created and they are associated with each
84  // other.
85  friend class Body<T>;
86
87  // Make BodyFrame templated on any other scalar type a friend of
88  // BodyFrame<T> so that CloneToScalar<ToAnyOtherScalar>() can access
89  // private methods from BodyFrame<T>.
90  template <typename> friend class BodyFrame;
91
92  // Only Body objects can create BodyFrame objects since Body is a friend of
93  // BodyFrame.
94  explicit BodyFrame(const Body<T>& body) : Frame<T>(body) {}
95
96  // Helper method to make a clone templated on any other scalar type.
97  // This method holds the common implementation for the different overrides to
98  // DoCloneToScalar().
99  template <typename ToScalar>
100  std::unique_ptr<Frame<ToScalar>> TemplatedDoCloneToScalar(
101  const MultibodyTree<ToScalar>& tree_clone) const;
102 };
103
104 // Forward declarations for Body<T>.
105 template<typename T> class MultibodyTree;
106
107 /// @cond
108 // Internal implementation details. Users should not access implementations
109 // in this namespace.
110 namespace internal {
111 template <typename T>
112 // Attorney-Client idiom to grant MultibodyTree access to a selected set of
113 // private methods in Body.
114 // BodyAttorney serves as a "proxy" to the Body class but only providing an
115 // interface to a selected subset of methods that should be accessible to
116 // MultibodyTree. These methods are related to the construction and finalize
117 // stage of the multibody system.
118 class BodyAttorney {
119  private:
120  // MultibodyTree keeps a list of mutable pointers to each of the body frames
121  // in the system and therefore it needs mutable access.
122  // Notice this method is private and therefore users do not have access to it
123  // even in the rare event they'd attempt to peek into the "internal::"
124  // namespace.
125  static BodyFrame<T>& get_mutable_body_frame(Body<T>* body) {
126  return body->get_mutable_body_frame();
127  }
128  friend class MultibodyTree<T>;
129 };
130 } // namespace internal
131 /// @endcond
132
133 /// %Body provides the general abstraction of a body with an API that
134 /// makes no assumption about whether a body is rigid or deformable and neither
135 /// does it make any assumptions about the underlying physical model or
136 /// approximation.
137 /// As an element or component of a MultibodyTree, a body is a
138 /// MultibodyTreeElement, and therefore it has a unique index of type BodyIndex
139 /// within the multibody tree it belongs to.
140 ///
141 /// A %Body contains a unique BodyFrame; see BodyFrame class documentation for
143 ///
144 /// @tparam T The scalar type. Must be a valid Eigen scalar.
145 template <typename T>
146 class Body : public MultibodyTreeElement<Body<T>, BodyIndex> {
147  public:
149
150  /// Creates a %Body with a BodyFrame associated with it.
151  Body() : body_frame_(*this) {}
152
153  /// Creates a %Body named name with a given default_mass and a BodyFrame
154  /// associated with it.
155  explicit Body(const std::string& name, double default_mass) :
156  name_(name), body_frame_(*this), default_mass_(default_mass) {}
157
158  /// Gets the name associated with this body.
159  const std::string& name() const { return name_; }
160
161  /// Returns the number of generalized positions q describing flexible
162  /// deformations for this body. A rigid body will therefore return zero.
163  virtual int get_num_flexible_positions() const = 0;
164
165  /// Returns the number of generalized velocities v describing flexible
166  /// deformations for this body. A rigid body will therefore return zero.
167  virtual int get_num_flexible_velocities() const = 0;
168
169  /// Returns a const reference to the associated BodyFrame.
170  const BodyFrame<T>& body_frame() const {
171  return body_frame_;
172  }
173
174  /// Returns the index of the node in the underlying tree structure of
175  /// the parent MultibodyTree to which this body belongs.
178  }
179
180  /// Returns the default mass (not Context dependent) for this body.
181  /// In general, the mass for a body can be a parameter of the model that can
182  /// be retrieved with the method get_mass(). When the mass of a body is a
183  /// parameter, the value returned by get_default_mass() is used to initialize
184  /// the mass parameter in the context.
185  double get_default_mass() const { return default_mass_; }
186
187  /// Returns the mass of this body stored in context.
188  virtual T get_mass(const MultibodyTreeContext<T> &context) const = 0;
189
190  /// Computes the center of mass p_BoBcm_B (or p_Bcm for short) of this
191  /// body measured from this body's frame origin Bo and expressed in the body
192  /// frame B.
193  virtual const Vector3<T> CalcCenterOfMassInBodyFrame(
194  const MultibodyTreeContext<T>& context) const = 0;
195
196  /// Computes the SpatialInertia I_BBo_B of this body about its frame
197  /// origin Bo (not necessarily its center of mass) and expressed in its body
198  /// frame B.
199  /// In general, the spatial inertia of a body is a function of state.
200  /// Consider for instance the case of a flexible body for which its spatial
201  /// inertia in the body frame depends on the generalized coordinates
202  /// describing its state of deformation. As a particular case, the spatial
203  /// inertia of a RigidBody in its body frame is constant.
204  virtual SpatialInertia<T> CalcSpatialInertiaInBodyFrame(
205  const MultibodyTreeContext<T>& context) const = 0;
206
207  /// NVI (Non-Virtual Interface) to DoCloneToScalar() templated on the scalar
208  /// type of the new clone to be created. This method is mostly intended to be
209  /// called by MultibodyTree::CloneToScalar(). Most users should not call this
210  /// clone method directly but rather clone the entire parent MultibodyTree if
211  /// needed.
212  /// @sa MultibodyTree::CloneToScalar()
213  template <typename ToScalar>
214  std::unique_ptr<Body<ToScalar>> CloneToScalar(
215  const MultibodyTree<ToScalar>& tree_clone) const {
216  return DoCloneToScalar(tree_clone);
217  }
218
219  protected:
220  /// @name Methods to make a clone templated on different scalar types.
221  ///
222  /// These methods are meant to be called by MultibodyTree::CloneToScalar()
223  /// when making a clone of the entire tree or a new instance templated on a
224  /// different scalar type. The only const argument to these methods is the
225  /// new MultibodyTree clone under construction. Specific %Body subclasses
226  /// might specify a number of prerequisites on the cloned tree and therefore
227  /// require it to be at a given state of cloning (for instance requiring that
228  /// the cloned tree already contains all the frames in the world as in the
229  /// original tree.) See MultibodyTree::CloneToScalar() for a list of
230  /// prerequisites that are guaranteed to be satisfied during the cloning
231  /// process.
232  ///
233  /// @{
234
235  /// Clones this %Body (templated on T) to a body templated on double.
236  virtual std::unique_ptr<Body<double>> DoCloneToScalar(
237  const MultibodyTree<double>& tree_clone) const = 0;
238
239  /// Clones this %Body (templated on T) to a body templated on AutoDiffXd.
240  virtual std::unique_ptr<Body<AutoDiffXd>> DoCloneToScalar(
241  const MultibodyTree<AutoDiffXd>& tree_clone) const = 0;
242
243  /// @}
244
245  private:
246  // Only friends of BodyAttorney (i.e. MultibodyTree) have access to a selected
247  // set of private Body methods.
248  friend class internal::BodyAttorney<T>;
249
250  // Implementation for MultibodyTreeElement::DoSetTopology().
251  // At MultibodyTree::Finalize() time, each body retrieves its topology
252  // from the parent MultibodyTree.
253  void DoSetTopology(const MultibodyTreeTopology& tree_topology) final {
254  topology_ = tree_topology.get_body(this->index());
255  body_frame_.SetTopology(tree_topology);
256  }
257
259  BodyFrame<T>& get_mutable_body_frame() {
260  return body_frame_;
261  }
262
263  // A string identifying the body in its model.
264  // Within a MultibodyPlant model this string is guaranteed to be unique by
265  // MultibodyPlant's API.
266  std::string name_;
267
268  // Body frame associated with this body.
269  BodyFrame<T> body_frame_;
270
271  // In general, the mass of a body can be a constant property of the body or a
272  // Parameter of the model. The default mass value is directly reported by
273  // get_default_mass() in the former case and used to initialize the mass
274  // Parameter in the Context in the latter case.
275  double default_mass_{0.0};
276
277  // The internal bookkeeping topology struct used by MultibodyTree.
278  BodyTopology topology_;
279 };
280
281 } // namespace multibody
282 } // namespace drake
Eigen::Transform< Scalar, 3, Eigen::Isometry > Isometry3
An Isometry templated on scalar type.
Definition: eigen_types.h:127
const BodyFrame< T > & body_frame() const
Returns a const reference to the associated BodyFrame.
Definition: body.h:170
MultibodyTreeContext is an object that contains all the information needed to uniquely determine the ...
Definition: multibody_tree_context.h:40
Definition: automotive_demo.cc:90
Data structure to store the topological information associated with a Body.
Definition: multibody_tree_topology.h:38
const std::string & name() const
Gets the name associated with this body.
Definition: body.h:159
std::unique_ptr< Frame< double > > DoCloneToScalar(const MultibodyTree< double > &tree_clone) const override
Clones this Frame (templated on T) to a frame templated on double.
Definition: body.cc:24
Context is an abstract class template that represents all the typed values that are used in a System&#39;...
Definition: context.h:40
Body provides the general abstraction of a body with an API that makes no assumption about whether a ...
Definition: body.h:20
MultibodyTree provides a representation for a physical system consisting of a collection of interconn...
Definition: body.h:105
Body(const std::string &name, double default_mass)
Creates a Body named name with a given default_mass and a BodyFrame associated with it...
Definition: body.h:155
A BodyFrame is a material Frame that serves as the unique reference frame for a Body.
Definition: body.h:58
Frame is an abstract class representing a material frame (also called a physical frame), meaning that it is associated with a material point of a Body.
Definition: frame.h:41
Eigen::Matrix< Scalar, 3, 1 > Vector3
A column vector of size 3, templated on scalar type.
Definition: eigen_types.h:34
Data structure to store the topological information associated with an entire MultibodyTree.
Definition: multibody_tree_topology.h:408
double get_default_mass() const
Returns the default mass (not Context dependent) for this body.
Definition: body.h:185
friend class BodyFrame
Definition: body.h:90
Isometry3< T > CalcOffsetPoseInBody(const systems::Context< T > &, const Isometry3< T > &X_FQ) const override
Given the offset pose X_FQ of a frame Q in this frame F, this method computes the pose X_BQ of frame ...
Definition: body.h:67
std::unique_ptr< Body< ToScalar > > CloneToScalar(const MultibodyTree< ToScalar > &tree_clone) const
NVI (Non-Virtual Interface) to DoCloneToScalar() templated on the scalar type of the new clone to be ...
Definition: body.h:214
This class represents the physical concept of a Spatial Inertia.
Definition: spatial_inertia.h:96
#define DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(Classname)
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN deletes the special member functions for copy-construction, copy-assignment, move-construction, and move-assignment.
Definition: drake_copyable.h:33
BodyNodeIndex node_index() const
Returns the index of the node in the underlying tree structure of the parent MultibodyTree to which t...
Definition: body.h:176
Isometry3< T > CalcPoseInBodyFrame(const systems::Context< T > &) const override
Returns the pose X_BF of this frame F in the body frame B associated with this frame.
Definition: body.h:62
const Body< T > & body() const
Returns a const reference to the body associated to this Frame.
Definition: frame.h:46