DART  6.10.1
TemplatedJacobianNode.hpp
Go to the documentation of this file.
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_DETAIL_TEMPLATEDJACOBIAN_HPP_
34 #define DART_DYNAMICS_DETAIL_TEMPLATEDJACOBIAN_HPP_
35 
37 
38 namespace dart {
39 namespace dynamics {
40 
41 //==============================================================================
42 template <class NodeType>
44  const Frame* _inCoordinatesOf) const
45 {
46  if (this == _inCoordinatesOf)
47  return static_cast<const NodeType*>(this)->getJacobian();
48  else if (_inCoordinatesOf->isWorld())
49  return static_cast<const NodeType*>(this)->getWorldJacobian();
50 
51  return math::AdRJac(
52  getTransform(_inCoordinatesOf),
53  static_cast<const NodeType*>(this)->getJacobian());
54 }
55 
56 //==============================================================================
57 template <class NodeType>
59  const Eigen::Vector3d& _offset) const
60 {
61  math::Jacobian J = static_cast<const NodeType*>(this)->getJacobian();
62  J.bottomRows<3>() += J.topRows<3>().colwise().cross(_offset);
63 
64  return J;
65 }
66 
67 //==============================================================================
68 template <class NodeType>
70  const Eigen::Vector3d& _offset, const Frame* _inCoordinatesOf) const
71 {
72  if (this == _inCoordinatesOf)
73  return getJacobian(_offset);
74  else if (_inCoordinatesOf->isWorld())
75  return getWorldJacobian(_offset);
76 
77  Eigen::Isometry3d T = getTransform(_inCoordinatesOf);
78  T.translation() = -T.linear() * _offset;
79 
80  return math::AdTJac(T, static_cast<const NodeType*>(this)->getJacobian());
81 }
82 
83 //==============================================================================
84 template <class NodeType>
86  const Eigen::Vector3d& _offset) const
87 {
88  math::Jacobian J = static_cast<const NodeType*>(this)->getWorldJacobian();
89  J.bottomRows<3>()
90  += J.topRows<3>().colwise().cross(getWorldTransform().linear() * _offset);
91 
92  return J;
93 }
94 
95 //==============================================================================
96 template <class NodeType>
98  const Frame* _inCoordinatesOf) const
99 {
100  if (this == _inCoordinatesOf)
101  {
102  const math::Jacobian& J = static_cast<const NodeType*>(this)->getJacobian();
103 
104  return J.bottomRows<3>();
105  }
106  else if (_inCoordinatesOf->isWorld())
107  {
108  const math::Jacobian& JWorld
109  = static_cast<const NodeType*>(this)->getWorldJacobian();
110 
111  return JWorld.bottomRows<3>();
112  }
113 
114  const math::Jacobian& J = static_cast<const NodeType*>(this)->getJacobian();
115 
116  return getTransform(_inCoordinatesOf).linear() * J.bottomRows<3>();
117 }
118 
119 //==============================================================================
120 template <class NodeType>
122  const Eigen::Vector3d& _offset, const Frame* _inCoordinatesOf) const
123 {
124  const math::Jacobian& J = static_cast<const NodeType*>(this)->getJacobian();
125 
126  math::LinearJacobian JLinear;
127  JLinear = J.bottomRows<3>() + J.topRows<3>().colwise().cross(_offset);
128 
129  if (this == _inCoordinatesOf)
130  return JLinear;
131 
132  return getTransform(_inCoordinatesOf).linear() * JLinear;
133 }
134 
135 //==============================================================================
136 template <class NodeType>
138  const Frame* _inCoordinatesOf) const
139 {
140  if (this == _inCoordinatesOf)
141  {
142  const math::Jacobian& J = static_cast<const NodeType*>(this)->getJacobian();
143  return J.topRows<3>();
144  }
145  else if (_inCoordinatesOf->isWorld())
146  {
147  const math::Jacobian& JWorld
148  = static_cast<const NodeType*>(this)->getWorldJacobian();
149  return JWorld.topRows<3>();
150  }
151 
152  const math::Jacobian& J = static_cast<const NodeType*>(this)->getJacobian();
153 
154  return getTransform(_inCoordinatesOf).linear() * J.topRows<3>();
155 }
156 
157 //==============================================================================
158 template <class NodeType>
160  const Frame* _inCoordinatesOf) const
161 {
162  if (this == _inCoordinatesOf)
163  return static_cast<const NodeType*>(this)->getJacobianSpatialDeriv();
164 
165  return math::AdRJac(
166  getTransform(_inCoordinatesOf),
167  static_cast<const NodeType*>(this)->getJacobianSpatialDeriv());
168 }
169 
170 //==============================================================================
171 template <class NodeType>
173  const Eigen::Vector3d& _offset) const
174 {
175  math::Jacobian J_d
176  = static_cast<const NodeType*>(this)->getJacobianSpatialDeriv();
177 
178  J_d.bottomRows<3>() += J_d.topRows<3>().colwise().cross(_offset);
179 
180  return J_d;
181 }
182 
183 //==============================================================================
184 template <class NodeType>
186  const Eigen::Vector3d& _offset, const Frame* _inCoordinatesOf) const
187 {
188  if (this == _inCoordinatesOf)
189  return getJacobianSpatialDeriv(_offset);
190 
191  Eigen::Isometry3d T = getTransform(_inCoordinatesOf);
192  T.translation() = T.linear() * -_offset;
193 
194  return math::AdTJac(
195  T, static_cast<const NodeType*>(this)->getJacobianSpatialDeriv());
196 }
197 
198 //==============================================================================
199 template <class NodeType>
201  const Frame* _inCoordinatesOf) const
202 {
203  if (_inCoordinatesOf->isWorld())
204  return static_cast<const NodeType*>(this)->getJacobianClassicDeriv();
205 
206  return math::AdRInvJac(
207  _inCoordinatesOf->getWorldTransform(),
208  static_cast<const NodeType*>(this)->getJacobianClassicDeriv());
209 }
210 
211 //==============================================================================
212 template <class NodeType>
214  const Eigen::Vector3d& _offset, const Frame* _inCoordinatesOf) const
215 {
216  math::Jacobian J_d
217  = static_cast<const NodeType*>(this)->getJacobianClassicDeriv();
218 
219  const math::Jacobian& J
220  = static_cast<const NodeType*>(this)->getWorldJacobian();
221 
222  const Eigen::Vector3d& w = getAngularVelocity();
223  const Eigen::Vector3d& p = (getWorldTransform().linear() * _offset).eval();
224 
225  J_d.bottomRows<3>() += J_d.topRows<3>().colwise().cross(p)
226  + J.topRows<3>().colwise().cross(w.cross(p));
227 
228  if (_inCoordinatesOf->isWorld())
229  return J_d;
230 
231  return math::AdRInvJac(_inCoordinatesOf->getWorldTransform(), J_d);
232 }
233 
234 //==============================================================================
235 template <class NodeType>
237  const Frame* _inCoordinatesOf) const
238 {
239  const math::Jacobian& J_d
240  = static_cast<const NodeType*>(this)->getJacobianClassicDeriv();
241 
242  if (_inCoordinatesOf->isWorld())
243  return J_d.bottomRows<3>();
244 
245  return _inCoordinatesOf->getWorldTransform().linear().transpose()
246  * J_d.bottomRows<3>();
247 }
248 
249 //==============================================================================
250 template <class NodeType>
252  const Eigen::Vector3d& _offset, const Frame* _inCoordinatesOf) const
253 {
254  const math::Jacobian& J_d
255  = static_cast<const NodeType*>(this)->getJacobianClassicDeriv();
256 
257  const math::Jacobian& J
258  = static_cast<const NodeType*>(this)->getWorldJacobian();
259 
260  const Eigen::Vector3d& w = getAngularVelocity();
261  const Eigen::Vector3d& p = (getWorldTransform().linear() * _offset).eval();
262 
263  if (_inCoordinatesOf->isWorld())
264  return J_d.bottomRows<3>() + J_d.topRows<3>().colwise().cross(p)
265  + J.topRows<3>().colwise().cross(w.cross(p));
266 
267  return _inCoordinatesOf->getWorldTransform().linear().transpose()
268  * (J_d.bottomRows<3>() + J_d.topRows<3>().colwise().cross(p)
269  + J.topRows<3>().colwise().cross(w.cross(p)));
270 }
271 
272 //==============================================================================
273 template <class NodeType>
275  const Frame* _inCoordinatesOf) const
276 {
277  const math::Jacobian& J_d
278  = static_cast<const NodeType*>(this)->getJacobianClassicDeriv();
279 
280  if (_inCoordinatesOf->isWorld())
281  return J_d.topRows<3>();
282 
283  return _inCoordinatesOf->getWorldTransform().linear().transpose()
284  * J_d.topRows<3>();
285 }
286 
287 //==============================================================================
288 template <class NodeType>
290  : Entity(Entity::ConstructAbstract),
291  Frame(Frame::ConstructAbstract),
292  JacobianNode(bn)
293 {
294  // Do nothing
295 }
296 
297 } // namespace dynamics
298 } // namespace dart
299 
300 #endif // DART_DYNAMICS_DETAIL_TEMPLATEDJACOBIAN_HPP_
BodyNode class represents a single node of the skeleton.
Definition: BodyNode.hpp:79
Entity class is a base class for any objects that exist in the kinematic tree structure of DART.
Definition: Entity.hpp:61
The Frame class serves as the backbone of DART's kinematic tree structure.
Definition: Frame.hpp:58
bool isWorld() const
Returns true if this Frame is the World Frame.
Definition: Frame.cpp:475
const Eigen::Isometry3d & getWorldTransform() const
Get the transform of this Frame with respect to the World Frame.
Definition: Frame.cpp:93
The JacobianNode class serves as a common interface for BodyNodes and EndEffectors to both be used as...
Definition: JacobianNode.hpp:55
virtual const math::Jacobian & getJacobian() const =0
Return the generalized Jacobian targeting the origin of this JacobianNode.
virtual const math::Jacobian & getJacobianClassicDeriv() const =0
Return the classical time derivative of the generalized Jacobian targeting the origin of this BodyNod...
virtual const math::Jacobian & getJacobianSpatialDeriv() const =0
Return the spatial time derivative of the generalized Jacobian targeting the origin of this BodyNode.
virtual const math::Jacobian & getWorldJacobian() const =0
Return the generalized Jacobian targeting the origin of this JacobianNode.
math::AngularJacobian getAngularJacobian(const Frame *_inCoordinatesOf=Frame::World()) const override final
Return the angular Jacobian targeting the origin of this BodyNode.
Definition: TemplatedJacobianNode.hpp:137
TemplatedJacobianNode(BodyNode *bn)
Constructor.
Definition: TemplatedJacobianNode.hpp:289
math::LinearJacobian getLinearJacobian(const Frame *_inCoordinatesOf=Frame::World()) const override final
Return the linear Jacobian targeting the origin of this BodyNode.
Definition: TemplatedJacobianNode.hpp:97
math::AngularJacobian getAngularJacobianDeriv(const Frame *_inCoordinatesOf=Frame::World()) const override final
Return the angular Jacobian time derivative, in terms of any coordinate Frame.
Definition: TemplatedJacobianNode.hpp:274
math::LinearJacobian getLinearJacobianDeriv(const Frame *_inCoordinatesOf=Frame::World()) const override final
Return the linear Jacobian (classical) time derivative, in terms of any coordinate Frame.
Definition: TemplatedJacobianNode.hpp:236
Derived::PlainObject AdRJac(const Eigen::Isometry3d &_T, const Eigen::MatrixBase< Derived > &_J)
Change coordinate Frame of a Jacobian.
Definition: Geometry.hpp:273
Eigen::Matrix< double, 6, Eigen::Dynamic > Jacobian
Definition: MathTypes.hpp:114
Eigen::Matrix< double, 3, Eigen::Dynamic > AngularJacobian
Definition: MathTypes.hpp:113
Derived::PlainObject AdRInvJac(const Eigen::Isometry3d &_T, const Eigen::MatrixBase< Derived > &_J)
Definition: Geometry.hpp:291
Eigen::Matrix< double, 3, Eigen::Dynamic > LinearJacobian
Definition: MathTypes.hpp:112
Derived::PlainObject AdTJac(const Eigen::Isometry3d &_T, const Eigen::MatrixBase< Derived > &_J)
Adjoint mapping for dynamic size Jacobian.
Definition: Geometry.hpp:216
Definition: BulletCollisionDetector.cpp:65