KrisLibrary  1.0.0
KinematicChain3D.h
1 #ifndef ROBOTICS_KINEMATIC_CHAIN3D_H
2 #define ROBOTICS_KINEMATIC_CHAIN3D_H
3 
4 #include <KrisLibrary/Logger.h>
5 #include "Frame.h"
6 #include "Rotation.h"
7 #include "Chain.h"
8 #include <string>
9 
11 {
12 public:
13  enum Type { Revolute, Prismatic, Spherical };
14 
15  void SetRotationJoint(const Vector3& w);
16  void SetTranslationJoint(const Vector3& v);
17 
18  //screw's transformation is a function of control qi
19  //say we're link i
20  //T(i->i)(qi) = R(w*qi)oT(v*qi) where R rotates the given angle, T translates
21  //T(i->pi)(qi) = T0(i->pi)*T(i->i)(qi)
22  void GetLocalTransform(Real qi,Frame3D& T) const;
23 
24  //velocity of a point (in frame 0) with respect to qi,dqi
25  void GetVelocity(Real qi,Real dqi,const Vector3& p,Vector3& vel) const;
26  void GetAngularVelocity(Real dqi,Vector3& omega) const;
27 
28  //Jacobian (orientation,position) of a point (in frame 0) with respect to qi
29  void GetJacobian(Real qi,const Vector3& p,Vector3& Jo,Vector3& Jp) const;
30  void GetOrientationJacobian(Vector3& Jo) const;
31  void GetPositionJacobian(Real qi,const Vector3& p,Vector3& Jp) const;
32 
33  //Position jacobian of points in frame 0 w.r.t. i
34  void GetJacobian(Real qi,Frame3D& J) const;
35  //Position jacobian of points in frame j w.r.t. i
36  void GetJacobian(Real qi,const Frame3D& Tj_World,Frame3D& J) const;
37 
38  Type type;
39  Vector3 w;
40  Frame3D T0_Parent;
41  Frame3D T_World;
42 };
43 
44 template <class Link>
46 {
47 public:
48  virtual ~KinematicChain3DTemplate() {}
49 
50  void Initialize(int numLinks)
51  {
52  links.resize(numLinks);
53  parents.resize(numLinks);
54  q.resize(numLinks,Zero);
55  qMin.resize(numLinks,-Inf);
56  qMax.resize(numLinks,Inf);
57  }
58 
59  virtual std::string LinkName(int i) const
60  {
61  char temp[20];
62  sprintf(temp,"Link[%d]",i);
63  return temp;
64  }
65 
66  inline bool InJointLimits(const Vector& q) const
67  {
68  assert(q.n == qMin.n);
69  for(int i=0;i<qMin.n;i++) {
70  if(qMin[i]>q[i] || q[i]>qMax[i]) {
71  return false;
72  }
73  }
74  return true;
75  }
76 
77  //based on the values in q, update the frames T
78  void UpdateFrames();
79 
80  //in the following, pi is a point in the local frame of body i
81 
82  //gets the world location of pi
83  void GetWorldPosition(const Vector3& pi, int i, Vector3& p) const;
84  //gets the world rotation of link i
85  const Matrix3& GetWorldRotation(int i) const;
86  void GetWorldRotation_Moment(int i, Vector3& m) const;
87 
88  //gets the world velocity/angular velocity of pi, given dq/dt
89  void GetWorldVelocity(const Vector3& pi, int i, const Vector& dq, Vector3& dp) const;
90  void GetWorldAngularVelocity(int i, const Vector& dq, Vector3& omega) const;
91  //derivative of Ri w.r.t. qj
92  bool GetWorldRotationDeriv(int i, int j, Matrix3& dR) const;
93  bool GetWorldRotationDeriv_Moment(int i, int j, Vector3& dm) const;
94  //same as above, but m s.t. Ri=e^[m] is specified
95  bool GetWorldRotationDeriv_Moment(int i, int j, const Vector3& m,Vector3& dm) const;
96 
97  //gets the jacobian of pi w.r.t qj
98  bool GetJacobian(const Vector3& pi, int i, int j, Vector3& dw, Vector3& dv) const;
99  bool GetOrientationJacobian(int i, int j, Vector3& dw) const;
100  bool GetPositionJacobian(const Vector3& pi, int i, int j, Vector3& dv) const;
101  //gets the jacobian of pi w.r.t q (row 0-2 is angular, 3-5 are translational)
102  void GetFullJacobian(const Vector3& pi, int i, Matrix& J) const;
103  //rows 3-5 of the above
104  void GetPositionJacobian(const Vector3& pi, int i, Matrix& J) const;
105 
106  std::vector<Link> links;
107  Vector q;
108  Vector qMin,qMax;
109 };
110 
112 
113 
114 template <class Link>
116 {
117  //based on the values in q, update the frames T
118  //assert(HasValidOrdering());
119  Frame3D Ti;
120  //get local transform T(i->i)(q)
121  //then do the parent transformations to get them to T(i->0)(q)
122  //since the chain is top down, we can loop straight through
123  //given parent j and T(j->0)(q), we have
124  //T(i->0)(q) = T(j->0)(q)*T0(i->j)*T(i->i)(q)
125  for(size_t i=0;i<links.size();i++) {
126  Link& li = links[i];
127  li.GetLocalTransform(q(i),Ti);
128  int pi=parents[i];
129  if(pi==-1)
130  li.T_World.mul(li.T0_Parent,Ti);
131  else {
132  li.T_World.mul(links[pi].T_World,li.T0_Parent);
133  li.T_World*=Ti;
134  }
135  }
136 }
137 
138 template <class Link>
140 {
141  links[i].T_World.mulPoint(pi,p);
142 }
143 
144 template <class Link>
146 {
147  return links[i].T_World.R;
148 }
149 
150 template <class Link>
152 {
153  MomentRotation rot;
154  rot.setMatrix(links[i].T_World.R);
155  theta=rot;
156 }
157 
158 template <class Link>
159 void KinematicChain3DTemplate<Link>::GetWorldVelocity(const Vector3& pi, int i, const Vector& dq, Vector3& dp) const
160 {
161  Vector3 tempp;
162  dp.setZero();
163  Vector3 p;
164  links[i].T_World.mulPoint(pi,p);
165  int j=i;
166  while(j!=-1) {
167  links[j].GetVelocity(q[j],dq[j],p,tempp);
168  dp+=tempp;
169  j=parents[j];
170  }
171 }
172 
173 template <class Link>
174 void KinematicChain3DTemplate<Link>::GetWorldAngularVelocity(int i, const Vector& dq, Vector3& omega) const
175 {
176  Vector3 tempw;
177  omega.setZero();
178  int j=i;
179  while(j!=-1) {
180  links[j].GetAngularVelocity(dq[j],tempw);
181  omega+=tempw;
182  j=parents[j];
183  }
184 }
185 
186 template <class Link>
188 {
189  if(IsAncestor(i,j)) {
190  Vector3 dw;
191  links[j].GetOrientationJacobian(dw);
192  MatrixDerivative(links[i].T_World.R,dw,dR);
193  return true;
194  }
195  dR.setZero();
196  return false;
197 }
198 
199 template <class Link>
201 {
202  if(IsAncestor(i,j)) {
203  Vector3 dw;
204  links[j].GetOrientationJacobian(dw);
205  MomentDerivative(links[i].T_World.R,dw,dm);
206  return true;
207  }
208  dm.setZero();
209  return false;
210 }
211 
212 template <class Link>
214 {
215  if(IsAncestor(i,j)) {
216  Vector3 dw;
217  links[j].GetOrientationJacobian(dw);
218  MomentDerivative(m,links[i].T_World.R,dw,dm);
219  return true;
220  }
221  dm.setZero();
222  return false;
223 }
224 
225 template <class Link>
226 bool KinematicChain3DTemplate<Link>::GetJacobian(const Vector3& pi, int i, int j, Vector3& dw, Vector3& dv) const
227 {
228  if(IsAncestor(i,j)) {
229  Vector3 p;
230  GetWorldPosition(pi,i,p);
231  links[j].GetJacobian(q[j],p,dw,dv);
232  return true;
233  }
234  dw.setZero();
235  dv.setZero();
236  return false;
237 }
238 
239 template <class Link>
241 {
242  if(IsAncestor(i,j)) {
243  links[j].GetOrientationJacobian(dw);
244  return true;
245  }
246  dw.setZero();
247  return false;
248 }
249 
250 template <class Link>
251 bool KinematicChain3DTemplate<Link>::GetPositionJacobian(const Vector3& pi, int i, int j, Vector3& dv) const
252 {
253  if(IsAncestor(i,j)) {
254  Vector3 p;
255  GetWorldPosition(pi,i,p);
256  links[j].GetPositionJacobian(q[j],p,dv);
257  return true;
258  }
259  dv.setZero();
260  return false;
261 }
262 
263 template <class Link>
264 void KinematicChain3DTemplate<Link>::GetFullJacobian(const Vector3& pi, int i, Matrix& J) const
265 {
266  J.resize(6,q.n,Zero);
267  Vector3 w; Vector3 v;
268  Vector3 p;
269  GetWorldPosition(pi,i,p);
270  int j=i;
271  while(j!=-1) {
272  links[j].GetJacobian(q[j],p,w,v);
273  J(0,j)=w.x; J(1,j)=w.y; J(2,j)=w.z;
274  J(3,j)=v.x; J(4,j)=v.y; J(5,j)=v.z;
275  j=parents[j];
276  }
277 }
278 
279 template <class Link>
280 void KinematicChain3DTemplate<Link>::GetPositionJacobian(const Vector3& pi, int i, Matrix& J) const
281 {
282  J.resize(3,q.n,Zero);
283  Vector3 v;
284  Vector3 p;
285  GetWorldPosition(pi,i,p);
286  int j=i;
287  while(j!=-1) {
288  links[j].GetPositionJacobian(q[j],p,v);
289  J(0,j)=v.x; J(1,j)=v.y; J(2,j)=v.z;
290  j=parents[j];
291  }
292 }
293 
294 
295 #endif
A 3D vector class.
Definition: math3d/primitives.h:136
void MomentDerivative(const MomentRotation &m, const Vector3 &z, Vector3 &dm)
Same as above, but specifies R with the moment m.
Definition: Rotation.cpp:277
"Moment", a.k.a. exponential map, 3D rotation parameterization
Definition: rotation.h:99
Definition: KinematicChain3D.h:10
Utility functions for converting between different rotation representations and computing derivatives...
A rigid-body transformation.
Definition: math3d/primitives.h:820
void mul(const RigidTransform &a, const RigidTransform &b)
mul = compose
Definition: math3d/primitives.h:2615
void MatrixDerivative(const Matrix3 &R, const Vector3 &z, Matrix3 &dR)
Derivative dR of the rotation matrix R of a frame as it rotates about the axis z. ...
Definition: Rotation.cpp:261
Definition: KinematicChain3D.h:45
A 3x3 matrix class.
Definition: math3d/primitives.h:469
The logging system used in KrisLibrary.
A tree-based chain structure.
Definition: Chain.h:16