1 /*
2  * Copyright (c) 2011-2021, The DART development contributors
3  * All rights reserved.
4  *
5  * The list of contributors can be found at:
6  *   https://github.com/dartsim/dart/blob/master/LICENSE
7  *
8  * This file is provided under the following "BSD-style" License:
9  *   Redistribution and use in source and binary forms, with or
10  *   without modification, are permitted provided that the following
11  *   conditions are met:
12  *   * Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *   * Redistributions in binary form must reproduce the above
15  *     copyright notice, this list of conditions and the following
16  *     disclaimer in the documentation and/or other materials provided
17  *     with the distribution.
18  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  *   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  *   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26  *   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  *   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  *   POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef DART_DYNAMICS_SIMPLEFRAME_HPP_
34 #define DART_DYNAMICS_SIMPLEFRAME_HPP_
35 
36 #include "dart/dynamics/ShapeNode.hpp"
37 
38 namespace dart {
39 namespace dynamics {
40 
41 /// The SimpleFrame class offers a user-friendly way of creating arbitrary
42 /// Frames within the kinematic tree structure of DART. The user is free to
43 /// specify the relative transform, relative velocity, and relative acceleration
44 /// of this Frame.
45 ///
46 /// While many classes (such as BodyNode and EndEffector) inherit the Frame
47 /// class, they all have restrictions (constraints) on how their properties
48 /// (such as position, velocity, and acceleration) can be modified. Conversely,
49 /// the SimpleFrame class is nothing but a simple abstract Frame whose
50 /// properties can be arbitrarily set and modified by the user.
51 class SimpleFrame : public Detachable, public ShapeFrame
52 {
53 public:
54   DART_DEFINE_ALIGNED_SHARED_OBJECT_CREATOR(SimpleFrame)
55 
56   /// Constructor
57   explicit SimpleFrame(
58       Frame* _refFrame = Frame::World(),
59       const std::string& _name = "simple_frame",
60       const Eigen::Isometry3d& _relativeTransform
61       = Eigen::Isometry3d::Identity());
62 
63   /// Copy constructor. Note that the parent frame of _otherFrame will not be
64   /// copied as the reference frame for the newly created SimpleFrame.
65   SimpleFrame(
66       const SimpleFrame& _otherFrame, Frame* _refFrame = Frame::World());
67 
68   /// Destructor
69   ~SimpleFrame() override;
70 
71   // Documentation inherited
72   const std::string& setName(const std::string& _name) override;
73 
74   // Documentation inherited
75   const std::string& getName() const override;
76 
77   /// Create a new SimpleFrame with the same world transform, velocity, and
78   /// acceleration as this one. _refFrame will be used as the reference Frame
79   /// of the new SimpleFrame.
80   std::shared_ptr<SimpleFrame> clone(Frame* _refFrame = Frame::World()) const;
81 
82   /// Make the world transform, world velocity, and world acceleration of this
83   /// SimpleFrame match another Frame. The _refFrame argument will be the new
84   /// parent Frame of this SimpleFrame. Also copies the Entity Properties if
85   /// _copyProperties is left as true.
86   void copy(
87       const Frame& _otherFrame,
88       Frame* _refFrame = Frame::World(),
89       bool _copyProperties = true);
90 
91   /// Same as copy(const Frame&)
92   void copy(
93       const Frame* _otherFrame,
94       Frame* _refFrame = Frame::World(),
95       bool _copyProperties = true);
96 
97   /// Same as copy(const Frame&) except the parent frame of this SimpleFrame is
98   /// left the same, and _copyProperties is set to false.
99   SimpleFrame& operator=(const SimpleFrame& _otherFrame);
100 
101   /// Spawn a child SimpleFrame to this SimpleFrame. SimpleFrame doesn't have
102   /// the ownership of the created child SimpleFrame. This means that you are
103   /// responsible for holding onto the returned SimpleFrame. If you neglect to
104   /// store it, it will automatically be destroyed.
105   std::shared_ptr<SimpleFrame> spawnChildSimpleFrame(
106       const std::string& name = "SimpleFrame",
107       const Eigen::Isometry3d& relativeTransform
108       = Eigen::Isometry3d::Identity());
109 
110   //--------------------------------------------------------------------------
111   // Transform
112   //--------------------------------------------------------------------------
113 
114   /// Set the relative transform of this SimpleFrame
115   void setRelativeTransform(const Eigen::Isometry3d& _newRelTransform);
116 
117   /// Set the relative translation of this SimpleFrame
118   void setRelativeTranslation(const Eigen::Vector3d& _newTranslation);
119 
120   /// Set the relative rotation of this SimpleFrame
121   void setRelativeRotation(const Eigen::Matrix3d& _newRotation);
122 
123   /// Set the transform of this SimpleFrame so that its transform with respect
124   /// to Frame _withRespectTo is equal to _newTransform. Note that the parent
125   /// Frame of this SimpleFrame will not be changed.
126   void setTransform(
127       const Eigen::Isometry3d& _newTransform,
128       const Frame* _withRespectTo = Frame::World());
129 
130   /// Set the translation of this SimpleFrame so that its translation with
131   /// respect to Frame _withRespectTo is equal to _newTranslation. Note that the
132   /// parent Frame of this SimpleFrame will not be changed.
133   void setTranslation(
134       const Eigen::Vector3d& _newTranslation,
135       const Frame* _withRespectTo = Frame::World());
136 
137   /// Set the rotation of this SimpleFrame so that its rotation with respect
138   /// to Frame _withRespectTo is equal to _newRotation. Note that the parent
139   /// Frame of this SimpleFrame will not be changed.
140   void setRotation(
141       const Eigen::Matrix3d& _newRotation,
142       const Frame* _withRespectTo = Frame::World());
143 
144   // Documentation inherited
145   const Eigen::Isometry3d& getRelativeTransform() const override;
146 
147   //--------------------------------------------------------------------------
148   // Velocity
149   //--------------------------------------------------------------------------
150 
151   /// Set the spatial velocity of this SimpleFrame relative to its parent Frame.
152   /// Must be in the coordinates of THIS Frame.
153   ///
154   /// This is the most computationally efficient way of setting relative
155   /// velocity.
156   ///
157   /// Use setClassicDerivatives to set the velocity according to classic
158   /// relative linear and angular velocity values.
159   void setRelativeSpatialVelocity(const Eigen::Vector6d& _newSpatialVelocity);
160 
161   /// Set the spatial velocity of this SimpleFrame relative to its parent Frame.
162   /// Specify the coordinate Frame of _newSpatialVelocity.
163   ///
164   /// Use setClassicDerivatives to set the velocity according to classic
165   /// relative linear and angular velocity values.
166   void setRelativeSpatialVelocity(
167       const Eigen::Vector6d& _newSpatialVelocity,
168       const Frame* _inCoordinatesOf);
169 
170   // Documentation inherited
171   const Eigen::Vector6d& getRelativeSpatialVelocity() const override;
172 
173   //--------------------------------------------------------------------------
174   // Acceleration
175   //--------------------------------------------------------------------------
176 
177   /// Set the spatial acceleration of this SimpleFrame relative to its parent
178   /// Frame. Must be in the coordinates of THIS Frame.
179   ///
180   /// This is the most computationally efficient way of setting relative
181   /// acceleration.
182   void setRelativeSpatialAcceleration(
183       const Eigen::Vector6d& _newSpatialAcceleration);
184 
185   /// Set the spatial acceleration of this SimpleFrame relative to its parent
186   /// Frame. Specify the coordinate Frame of _newSpatialAcceleration.
187   void setRelativeSpatialAcceleration(
188       const Eigen::Vector6d& _newSpatialAcceleration,
189       const Frame* _inCoordinatesOf);
190 
191   // Documentation inherited
192   const Eigen::Vector6d& getRelativeSpatialAcceleration() const override;
193 
194   // Documentation inherited
195   const Eigen::Vector6d& getPrimaryRelativeAcceleration() const override;
196 
197   // Documentation inherited
198   const Eigen::Vector6d& getPartialAcceleration() const override;
199 
200   //--------------------------------------------------------------------------
201   // Classic Method
202   //--------------------------------------------------------------------------
203 
204   /// Set the relative velocity and acceleration of this Frame according to
205   /// classical (non-spatial) relative velocity and relative acceleration
206   /// vectors. These values must be given with respect to this Frame's parent
207   /// (note: this is unlike setRelativeSpatialVelocity and
208   /// setRelativeSpatialAcceleration which expect values in the Frame's own
209   /// coordinates).
210   ///
211   /// This method is slightly less computationally efficient than using
212   /// setRelativeSpatialVelocity and setRelativeSpatialAcceleration, but offers
213   /// the most intuitive way of setting relative velocities and relative
214   /// accelerations.
215   ///
216   /// These values are equivalent to the terms in the Newton-Euler
217   void setClassicDerivatives(
218       const Eigen::Vector3d& _linearVelocity = Eigen::Vector3d::Zero(),
219       const Eigen::Vector3d& _angularVelocity = Eigen::Vector3d::Zero(),
220       const Eigen::Vector3d& _linearAcceleration = Eigen::Vector3d::Zero(),
221       const Eigen::Vector3d& _angularAcceleration = Eigen::Vector3d::Zero());
222 
223 protected:
224   /// Name of this SimpleFrame
225   std::string mName;
226 
227   /// Relative transform of the SimpleFrame
228   Eigen::Isometry3d mRelativeTf;
229 
230   /// Relative spatial velocity of the SimpleFrame
231   Eigen::Vector6d mRelativeVelocity;
232 
233   /// Relative spatial acceleration of the SimpleFrame
234   Eigen::Vector6d mRelativeAcceleration;
235 
236   /// Partial Acceleration of this Frame
237   mutable Eigen::Vector6d mPartialAcceleration;
238 
239 public:
240   // To get byte-aligned Eigen vectors
241   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
242 };
243 
244 } // namespace dynamics
245 } // namespace dart
246 
247 #endif // DART_DYNAMICS_SIMPLEFRAME_HPP_
248