Loading...
Searching...
No Matches
Joint.h
Go to the documentation of this file.
1/*
2 * Copyright 2012-2019 CNRS-UM LIRMM, CNRS-AIST JRL
3 */
4
5#pragma once
6
7// includes
8// std
9#include <cmath>
10#include <sstream>
11#include <stdexcept>
12#include <string>
13#include <vector>
14
15// SpaceVecAlg
16#include <SpaceVecAlg/SpaceVecAlg>
17
18namespace rbd
19{
20
26template<typename T>
27Eigen::Matrix3<T> QuatToE(const std::vector<T> & q);
28
35class Joint
36{
37public:
49
60
61public:
62 Joint();
63
70 Joint(OldType type, bool forward, std::string name);
71
78 Joint(Type type, const Eigen::Vector3d & axis, bool forward, std::string name);
79
85 Joint(Type type, bool forward, std::string name);
86
91 Joint(std::string name);
92
102 void makeMimic(const std::string & name, double multiplier, double offset);
103
105 Type type() const
106 {
107 return type_;
108 }
109
111 double direction() const
112 {
113 return dir_;
114 }
115
117 bool forward() const
118 {
119 return dir_ == 1.;
120 }
121
123 void forward(bool forward)
124 {
125 if(forward != this->forward()) S_ *= -1;
126 dir_ = forward ? 1. : -1;
127 }
128
133 int params() const
134 {
135 return params_;
136 }
137
142 int dof() const
143 {
144 return dof_;
145 }
146
148 const std::string & name() const
149 {
150 return name_;
151 }
152
154 bool isMimic() const
155 {
156 return isMimic_;
157 }
158
160 const std::string & mimicName() const
161 {
162 return mimicName_;
163 }
164
166 double mimicMultiplier() const
167 {
168 return mimicMultiplier_;
169 }
170
172 double mimicOffset() const
173 {
174 return mimicOffset_;
175 }
176
182 void setRotorInertia(double Ir)
183 {
184 Ir_ = Ir;
185 }
186
188 double rotorInertia() const
189 {
190 return Ir_;
191 }
192
198 void setGearRatio(double gr)
199 {
200 gr_ = gr;
201 }
202
204 double gearRatio() const
205 {
206 return gr_;
207 }
208
210 const Eigen::Matrix<double, 6, Eigen::Dynamic> & motionSubspace() const
211 {
212 return S_;
213 }
214
220 template<typename T>
221 sva::PTransform<T> pose(const std::vector<T> & q) const;
222
228 sva::MotionVecd motion(const std::vector<double> & alpha) const;
229
235 sva::MotionVecd tanAccel(const std::vector<double> & alphaD) const;
236
240 std::vector<double> zeroParam() const;
241
245 std::vector<double> zeroDof() const;
246
253 sva::PTransformd sPose(const std::vector<double> & q) const;
254
261 sva::MotionVecd sMotion(const std::vector<double> & alpha) const;
262
269 sva::MotionVecd sTanAccel(const std::vector<double> & alphaD) const;
270
271 bool operator==(const Joint & b) const
272 {
273 return name_ == b.name_;
274 }
275
276 bool operator!=(const Joint & b) const
277 {
278 return name_ != b.name_;
279 }
280
281public:
285 static std::vector<double> ZeroParam(Type type);
286
290 static std::vector<double> ZeroDof(Type type);
291
292private:
293 void constructJoint(Type t, const Eigen::Vector3d & a);
294
295private:
296 Type type_;
297 Eigen::Matrix<double, 6, Eigen::Dynamic> S_;
298 double dir_;
299
300 int params_;
301 int dof_;
302
303 std::string name_;
304
305 bool isMimic_ = false;
306 std::string mimicName_ = "";
307 double mimicMultiplier_ = 1.0;
308 double mimicOffset_ = 0.0;
309
310 double Ir_ = 0.0;
311 double gr_ = 0.0;
312};
313
314inline std::ostream & operator<<(std::ostream & out, const Joint & b)
315{
316 out << "Joint: " << b.name();
317 return out;
318}
319
320inline Joint::Joint() : dir_(0.0), params_(0), dof_(0), name_("") {}
321
322inline Joint::Joint(OldType type, bool forward, std::string name)
323: dir_(forward ? 1. : -1), params_(0), dof_(0), name_(name)
324{
325 switch(type)
326 {
327 case RevX:
328 constructJoint(Rev, Eigen::Vector3d::UnitX());
329 break;
330 case RevY:
331 constructJoint(Rev, Eigen::Vector3d::UnitY());
332 break;
333 case RevZ:
334 constructJoint(Rev, Eigen::Vector3d::UnitZ());
335 break;
336 case PrismX:
337 constructJoint(Prism, Eigen::Vector3d::UnitX());
338 break;
339 case PrismY:
340 constructJoint(Prism, Eigen::Vector3d::UnitY());
341 break;
342 case PrismZ:
343 constructJoint(Prism, Eigen::Vector3d::UnitZ());
344 break;
345 default:
346 constructJoint(Fixed, Eigen::Vector3d::Zero());
347 break;
348 }
349}
350
351inline Joint::Joint(Type type, const Eigen::Vector3d & axis, bool forward, std::string name)
352: dir_(forward ? 1. : -1), params_(0), dof_(0), name_(name)
353{
354 constructJoint(type, axis);
355}
356
357inline Joint::Joint(Type type, bool forward, std::string name)
358: dir_(forward ? 1. : -1), params_(0), dof_(0), name_(name)
359{
360 constructJoint(type, Eigen::Vector3d::UnitZ());
361}
362
363inline Joint::Joint(std::string name) : dir_(1), params_(0), dof_(0), name_(name)
364{
365 constructJoint(Joint::Type::Fixed, Eigen::Vector3d::UnitZ());
366}
367
368inline void Joint::makeMimic(const std::string & name, double multiplier, double offset)
369{
370 isMimic_ = true;
371 mimicName_ = name;
372 mimicMultiplier_ = multiplier;
373 mimicOffset_ = offset;
374}
375
376template<typename T>
377inline sva::PTransform<T> Joint::pose(const std::vector<T> & q) const
378{
379 Eigen::Matrix3<T> rot;
380 switch(type_)
381 {
382 case Rev:
383 // minus S because rotation is anti trigonometric
384 return sva::PTransform<T>(Eigen::AngleAxis<T>(-q[0], S_.block<3, 1>(0, 0).cast<T>()).matrix());
385 case Prism:
386 return sva::PTransform<T>(Eigen::Vector3<T>(S_.block<3, 1>(3, 0).cast<T>() * q[0]));
387 case Spherical:
388 return sva::PTransform<T>(Eigen::Quaternion<T>(q[0], dir_ * q[1], dir_ * q[2], dir_ * q[3]).inverse());
389 case Planar:
390 rot = sva::RotZ(q[0]);
391 if(dir_ == 1.)
392 {
393 return sva::PTransform<T>(rot, rot.transpose() * Eigen::Vector3<T>(q[1], q[2], 0.));
394 }
395 else
396 {
397 return sva::PTransform<T>(rot, rot.transpose() * Eigen::Vector3<T>(q[1], q[2], 0.)).inv();
398 }
399 case Cylindrical:
400 return sva::PTransform<T>(Eigen::AngleAxis<T>(-q[0], S_.col(0).head<3>().cast<T>()).matrix(),
401 S_.col(1).tail<3>().cast<T>() * q[1]);
402 case Free:
403 rot = QuatToE(q);
404 if(dir_ == 1.)
405 {
406 return sva::PTransform<T>(rot, Eigen::Vector3<T>(q[4], q[5], q[6]));
407 }
408 else
409 {
410 return sva::PTransform<T>(rot, Eigen::Vector3<T>(q[4], q[5], q[6])).inv();
411 }
412 case Fixed:
413 default:
414 return sva::PTransform<T>::Identity();
415 }
416}
417
418inline sva::MotionVecd Joint::motion(const std::vector<double> & alpha) const
419{
420 switch(type_)
421 {
422 case Rev:
423 return sva::MotionVecd(
424 (Eigen::Vector6d() << S_.block<3, 1>(0, 0) * alpha[0], Eigen::Vector3d::Zero()).finished());
425 case Prism:
426 return sva::MotionVecd(
427 (Eigen::Vector6d() << Eigen::Vector3d::Zero(), S_.block<3, 1>(3, 0) * alpha[0]).finished());
428 case Spherical:
429 return sva::MotionVecd(S_ * Eigen::Vector3d(alpha[0], alpha[1], alpha[2]));
430 case Planar:
431 return sva::MotionVecd(S_ * Eigen::Vector3d(alpha[0], alpha[1], alpha[2]));
432 case Cylindrical:
433 return sva::MotionVecd(S_ * Eigen::Vector2d(alpha[0], alpha[1]));
434 case Free:
435 return sva::MotionVecd(
436 S_ * (Eigen::Vector6d() << alpha[0], alpha[1], alpha[2], alpha[3], alpha[4], alpha[5]).finished());
437 case Fixed:
438 default:
439 return sva::MotionVecd(Eigen::Vector6d::Zero());
440 }
441}
442
443inline sva::MotionVecd Joint::tanAccel(const std::vector<double> & alphaD) const
444{
445 switch(type_)
446 {
447 case Rev:
448 return sva::MotionVecd(
449 (Eigen::Vector6d() << S_.block<3, 1>(0, 0) * alphaD[0], Eigen::Vector3d::Zero()).finished());
450 case Prism:
451 return sva::MotionVecd(
452 (Eigen::Vector6d() << Eigen::Vector3d::Zero(), S_.block<3, 1>(3, 0) * alphaD[0]).finished());
453 case Spherical:
454 return sva::MotionVecd(S_ * Eigen::Vector3d(alphaD[0], alphaD[1], alphaD[2]));
455 case Planar:
456 return sva::MotionVecd(S_ * Eigen::Vector3d(alphaD[0], alphaD[1], alphaD[2]));
457 case Cylindrical:
458 return sva::MotionVecd(S_ * Eigen::Vector2d(alphaD[0], alphaD[1]));
459 case Free:
460 return sva::MotionVecd(
461 S_ * (Eigen::Vector6d() << alphaD[0], alphaD[1], alphaD[2], alphaD[3], alphaD[4], alphaD[5]).finished());
462 case Fixed:
463 default:
464 return sva::MotionVecd(Eigen::Vector6d::Zero());
465 }
466}
467
468inline std::vector<double> Joint::zeroParam() const
469{
470 auto q = ZeroParam(type_);
471 if(isMimic_)
472 {
473 for(auto & qi : q)
474 {
475 qi += mimicOffset_;
476 }
477 }
478 return q;
479}
480
481inline std::vector<double> Joint::zeroDof() const
482{
483 return ZeroDof(type_);
484}
485
486inline sva::PTransformd Joint::sPose(const std::vector<double> & q) const
487{
488 if(q.size() != static_cast<unsigned int>(params_))
489 {
490 std::ostringstream str;
491 str << "Wrong number of generalized position variable: expected " << params_ << " gived " << q.size();
492 throw std::domain_error(str.str());
493 }
494 return pose(q);
495}
496
497inline sva::MotionVecd Joint::sMotion(const std::vector<double> & alpha) const
498{
499 if(alpha.size() != static_cast<unsigned int>(dof_))
500 {
501 std::ostringstream str;
502 str << "Wrong number of generalized speed variable: expected " << params_ << " gived " << alpha.size();
503 throw std::domain_error(str.str());
504 }
505 return motion(alpha);
506}
507
508inline sva::MotionVecd Joint::sTanAccel(const std::vector<double> & alphaD) const
509{
510 if(alphaD.size() != static_cast<unsigned int>(dof_))
511 {
512 std::ostringstream str;
513 str << "Wrong number of generalized acceleration variable: expected " << params_ << " gived " << alphaD.size();
514 throw std::domain_error(str.str());
515 }
516 return tanAccel(alphaD);
517}
518
519inline std::vector<double> Joint::ZeroParam(Type type)
520{
521 switch(type)
522 {
523 case Rev:
524 case Prism:
525 return {0.};
526 case Spherical:
527 return {1., 0., 0., 0.};
528 case Planar:
529 return {0., 0., 0.};
530 case Cylindrical:
531 return {0., 0.};
532 case Free:
533 return {1., 0., 0., 0., 0., 0., 0.};
534 case Fixed:
535 default:
536 return {};
537 }
538}
539
540inline std::vector<double> Joint::ZeroDof(Type type)
541{
542 switch(type)
543 {
544 case Rev:
545 case Prism:
546 return {0.};
547 case Spherical:
548 return {0., 0., 0.};
549 case Planar:
550 return {0., 0., 0.};
551 case Cylindrical:
552 return {0., 0.};
553 case Free:
554 return {0., 0., 0., 0., 0., 0.};
555 case Fixed:
556 default:
557 return {};
558 }
559}
560
561inline void Joint::constructJoint(Type t, const Eigen::Vector3d & a)
562{
563 type_ = t;
564
565 switch(t)
566 {
567 case Rev:
568 S_ = dir_ * (Eigen::Vector6d() << a, Eigen::Vector3d::Zero()).finished();
569 params_ = 1;
570 dof_ = 1;
571 break;
572 case Prism:
573 S_ = dir_ * (Eigen::Vector6d() << Eigen::Vector3d::Zero(), a).finished();
574 params_ = 1;
575 dof_ = 1;
576 break;
577 case Spherical:
578 S_ = Eigen::Matrix<double, 6, 3>::Zero();
579 S_.block<3, 3>(0, 0).setIdentity();
580 S_ *= dir_;
581 params_ = 4;
582 dof_ = 3;
583 break;
584 case Planar:
585 S_ = Eigen::Matrix<double, 6, 3>::Zero();
586 S_.block<3, 3>(2, 0).setIdentity();
587 S_ *= dir_;
588 params_ = 3;
589 dof_ = 3;
590 break;
591 case Cylindrical:
592 S_ = Eigen::Matrix<double, 6, 2>::Zero();
593 S_.col(0).head<3>() = a;
594 S_.col(1).tail<3>() = a;
595 S_ *= dir_;
596 params_ = 2;
597 dof_ = 2;
598 break;
599 case Free:
600 S_ = dir_ * Eigen::Matrix6d::Identity();
601 params_ = 7;
602 dof_ = 6;
603 break;
604 case Fixed:
605 default:
606 S_ = Eigen::Matrix<double, 6, 0>::Zero();
607 params_ = 0;
608 dof_ = 0;
609 break;
610 }
611}
612
613template<typename T>
614inline Eigen::Matrix3<T> QuatToE(const std::vector<T> & q)
615{
616 T p0 = q[0];
617 T p1 = q[1];
618 T p2 = q[2];
619 T p3 = q[3];
620
621 T p0p1 = p0 * p1;
622 T p0p2 = p0 * p2;
623 T p0p3 = p0 * p3;
624
625 T p1p2 = p1 * p2;
626 T p1p3 = p1 * p3;
627
628 T p2p3 = p2 * p3;
629
630 T p0s = std::pow(p0, 2);
631 T p1s = std::pow(p1, 2);
632 T p2s = std::pow(p2, 2);
633 T p3s = std::pow(p3, 2);
634
635 return 2.
636 * (Eigen::Matrix3<T>() << p0s + p1s - 0.5, p1p2 + p0p3, p1p3 - p0p2, p1p2 - p0p3, p0s + p2s - 0.5, p2p3 + p0p1,
637 p1p3 + p0p2, p2p3 - p0p1, p0s + p3s - 0.5)
638 .finished();
639}
640
641} // namespace rbd
Definition Joint.h:36
double rotorInertia() const
Definition Joint.h:188
void makeMimic(const std::string &name, double multiplier, double offset)
Definition Joint.h:368
double mimicMultiplier() const
Definition Joint.h:166
bool operator==(const Joint &b) const
Definition Joint.h:271
const std::string & name() const
Definition Joint.h:148
double gearRatio() const
Definition Joint.h:204
int dof() const
Definition Joint.h:142
const Eigen::Matrix< double, 6, Eigen::Dynamic > & motionSubspace() const
Definition Joint.h:210
bool operator!=(const Joint &b) const
Definition Joint.h:276
double direction() const
Definition Joint.h:111
const std::string & mimicName() const
Definition Joint.h:160
static std::vector< double > ZeroParam(Type type)
Definition Joint.h:519
sva::MotionVecd tanAccel(const std::vector< double > &alphaD) const
Definition Joint.h:443
double mimicOffset() const
Definition Joint.h:172
static std::vector< double > ZeroDof(Type type)
Definition Joint.h:540
Joint()
Definition Joint.h:320
void setGearRatio(double gr)
Set Gear Ratio.
Definition Joint.h:198
sva::MotionVecd sMotion(const std::vector< double > &alpha) const
Definition Joint.h:497
sva::PTransform< T > pose(const std::vector< T > &q) const
Definition Joint.h:377
sva::MotionVecd motion(const std::vector< double > &alpha) const
Definition Joint.h:418
bool forward() const
Definition Joint.h:117
OldType
Old joint type for Api compatibility.
Definition Joint.h:52
@ PrismY
Prismatique joint about Y axis.
Definition Joint.h:57
@ RevX
Revolute joint about X axis.
Definition Joint.h:53
@ RevY
Revolute joint about Y axis.
Definition Joint.h:54
@ RevZ
Revolute joint about Z axis.
Definition Joint.h:55
@ PrismX
Prismatique joint about X axis.
Definition Joint.h:56
@ PrismZ
Prismatique joint about Z axis.
Definition Joint.h:58
bool isMimic() const
Definition Joint.h:154
std::vector< double > zeroDof() const
Definition Joint.h:481
sva::PTransformd sPose(const std::vector< double > &q) const
Definition Joint.h:486
std::vector< double > zeroParam() const
Definition Joint.h:468
void setRotorInertia(double Ir)
Set Rotor Inertia.
Definition Joint.h:182
sva::MotionVecd sTanAccel(const std::vector< double > &alphaD) const
Definition Joint.h:508
int params() const
Definition Joint.h:133
Type type() const
Definition Joint.h:105
void forward(bool forward)
Definition Joint.h:123
Type
Joint type.
Definition Joint.h:40
@ Cylindrical
Cylindrical joint (Z prismatic, Z revolute).
Definition Joint.h:45
@ Prism
Prismatic joint about an user specified axis.
Definition Joint.h:42
@ Fixed
Fixed joint.
Definition Joint.h:47
@ Spherical
Spherical joint, represented by a quaternion.
Definition Joint.h:43
@ Free
Free joint, represented by a quaternion.
Definition Joint.h:46
@ Planar
Planar joint (2 prismatic(X, Y) and 1 revolute(Z)).
Definition Joint.h:44
@ Rev
Revolute joint about an user specified axis.
Definition Joint.h:41
Definition common.h:21
Eigen::Matrix3< T > QuatToE(const std::vector< T > &q)
Definition Joint.h:614
std::ostream & operator<<(std::ostream &out, const Body &b)
Definition Body.h:69