iCub-main
Loading...
Searching...
No Matches
iKinFwd.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006-2018 Istituto Italiano di Tecnologia (IIT)
3 * Copyright (C) 2006-2010 RobotCub Consortium
4 * All rights reserved.
5 *
6 * This software may be modified and distributed under the terms
7 * of the BSD-3-Clause license. See the accompanying LICENSE file for
8 * details.
9*/
10
11#include <cstdlib>
12#include <cstdio>
13#include <sstream>
14#include <cmath>
15#include <algorithm>
16
17#include <yarp/os/Log.h>
18
19#include <iCub/iKin/iKinFwd.h>
20
21using namespace std;
22using namespace yarp::os;
23using namespace yarp::dev;
24using namespace yarp::sig;
25using namespace yarp::math;
26using namespace iCub::ctrl;
27using namespace iCub::iKin;
28
29
30/************************************************************************/
31void iCub::iKin::notImplemented(const unsigned int verbose)
32{
33 if (verbose)
34 yError("iKin: not implemented");
35}
36
37
38/************************************************************************/
39iKinLink::iKinLink(double _A, double _D, double _Alpha, double _Offset,
40 double _Min, double _Max): zeros1x1(zeros(1,1)), zeros1(zeros(1))
41{
42 A =_A;
43 D =_D;
44 Alpha =_Alpha;
45 Offset=_Offset;
46
47 Min=_Min;
48 Max=_Max;
49 Ang=Min;
50
51 c_alpha=cos(Alpha);
52 s_alpha=sin(Alpha);
53
54 blocked =false;
55 cumulative =false;
56 constrained=true;
57 verbose =0;
58
59 H.resize(4,4);
60 H.zero();
61 DnH =H;
62 cumH=H;
63 cumH.eye();
64
65 H(2,1)=s_alpha;
66 H(2,2)=c_alpha;
67 H(2,3)=D;
68 H(3,3)=1.0;
69}
70
71
72/************************************************************************/
74{
75 A =l.A;
76 D =l.D;
77 Alpha =l.Alpha;
78 Offset=l.Offset;
79
82
83 Ang=l.Ang;
84 Min=l.Min;
85 Max=l.Max;
86
91
92 H =l.H;
93 cumH=l.cumH;
94 DnH =l.DnH;
95}
96
97
98/************************************************************************/
100{
101 clone(l);
102}
103
104
105/************************************************************************/
107{
108 clone(l);
109
110 return *this;
111}
112
113
114/************************************************************************/
115void iKinLink::setMin(const double _Min)
116{
117 Min=_Min;
118
119 if (Ang<Min)
120 Ang=Min;
121}
122
123
124/************************************************************************/
125void iKinLink::setMax(const double _Max)
126{
127 Max=_Max;
128
129 if (Ang>Max)
130 Ang=Max;
131}
132
133
134/************************************************************************/
135void iKinLink::setD(const double _D)
136{
137 H(2,3)=D=_D;
138}
139
140
141/************************************************************************/
142void iKinLink::setAlpha(const double _Alpha)
143{
144 Alpha=_Alpha;
145
146 H(2,2)=c_alpha=cos(Alpha);
147 H(2,1)=s_alpha=sin(Alpha);
148}
149
150
151/************************************************************************/
152double iKinLink::setAng(double _Ang)
153{
154 if (!blocked)
155 {
156 if (constrained)
157 Ang=(_Ang<Min) ? Min : ((_Ang>Max) ? Max : _Ang);
158 else
159 Ang=_Ang;
160 }
161 else if (verbose)
162 yWarning("Attempt to set joint angle to %g while blocked",_Ang);
163
164 return Ang;
165}
166
167
168/************************************************************************/
169Matrix iKinLink::getH(bool c_override)
170{
171 double theta=Ang+Offset;
172 double c_theta=cos(theta);
173 double s_theta=sin(theta);
174
175 H(0,0)=c_theta;
176 H(0,1)=-s_theta*c_alpha;
177 H(0,2)=s_theta*s_alpha;
178 H(0,3)=c_theta*A;
179
180 H(1,0)=s_theta;
181 H(1,1)=c_theta*c_alpha;
182 H(1,2)=-c_theta*s_alpha;
183 H(1,3)=s_theta*A;
184
185 if (cumulative && !c_override)
186 return cumH*H;
187 else
188 return H;
189}
190
191
192/************************************************************************/
193Matrix iKinLink::getH(double _Ang, bool c_override)
194{
195 setAng(_Ang);
196
197 return getH(c_override);
198}
199
200
201/************************************************************************/
202Matrix iKinLink::getDnH(unsigned int n, bool c_override)
203{
204 if (n==0)
205 return getH(c_override);
206 else
207 {
208 double theta=Ang+Offset;
209 double c_theta=cos(theta);
210 double s_theta=sin(theta);
211
212 int C=(n>>1)&1 ? -1 : 1;
213
214 if (n&1)
215 {
216 DnH(0,0)=-C*s_theta;
217 DnH(0,1)=-C*c_theta*c_alpha;
218 DnH(0,2)=C*c_theta*s_alpha;
219 DnH(0,3)=-C*s_theta*A;
220
221 DnH(1,0)=C*c_theta;
222 DnH(1,1)=-C*s_theta*c_alpha;
223 DnH(1,2)=C*s_theta*s_alpha;
224 DnH(1,3)=C*c_theta*A;
225 }
226 else
227 {
228 DnH(0,0)=C*c_theta;
229 DnH(0,1)=-C*s_theta*c_alpha;
230 DnH(0,2)=C*s_theta*s_alpha;
231 DnH(0,3)=C*c_theta*A;
232
233 DnH(1,0)=C*s_theta;
234 DnH(1,1)=C*c_theta*c_alpha;
235 DnH(1,2)=-C*c_theta*s_alpha;
236 DnH(1,3)=C*s_theta*A;
237 }
238
239 if (cumulative && !c_override)
240 return cumH*DnH;
241 else
242 return DnH;
243 }
244}
245
246
247/************************************************************************/
248void iKinLink::addCumH(const Matrix &_cumH)
249{
250 cumulative=true;
251 cumH=_cumH;
252}
253
254
255/************************************************************************/
257{
258 N=DOF=verbose=0;
259 H0=HN=eye(4,4);
260}
261
262
263/************************************************************************/
265{
266 N =c.N;
267 DOF =c.DOF;
268 H0 =c.H0;
269 HN =c.HN;
270 curr_q =c.curr_q;
271 verbose =c.verbose;
272 hess_J =c.hess_J;
274
275 allList.assign(c.allList.begin(),c.allList.end());
276 quickList.assign(c.quickList.begin(),c.quickList.end());
277 hash.assign(c.hash.begin(),c.hash.end());
278 hash_dof.assign(c.hash_dof.begin(),c.hash_dof.end());
279}
280
281
282/************************************************************************/
284{
285 clone(c);
286}
287
288
289/************************************************************************/
291{
292 clone(c);
293
294 return *this;
295}
296
297
298/************************************************************************/
299bool iKinChain::addLink(const unsigned int i, iKinLink &l)
300{
301 if (i<=N)
302 {
303 allList.insert(allList.begin()+i,&l);
304 N=(unsigned int)allList.size();
305
306 build();
307
308 return true;
309 }
310 else
311 {
312 if (verbose)
313 yError("addLink() failed due to out of range index: %d>%d",i,N);
314
315 return false;
316 }
317}
318
319
320/************************************************************************/
321bool iKinChain::rmLink(const unsigned int i)
322{
323 if (i<N)
324 {
325 allList.erase(allList.begin()+i);
326 N=(unsigned int)allList.size();
327
328 build();
329
330 return true;
331 }
332 else
333 {
334 if (verbose)
335 yError("rmLink() failed due to out of range index: %d>=%d",i,N);
336
337 return false;
338 }
339}
340
341
342/************************************************************************/
344{
345 allList.push_back(&l);
346 N=(unsigned int)allList.size();
347
348 build();
349}
350
351
352/************************************************************************/
354{
355 allList.clear();
356 quickList.clear();
357 hash.clear();
358 hash_dof.clear();
359
360 N=DOF=0;
361 H0=HN=eye(4,4);
362}
363
364
365/************************************************************************/
367{
368 pushLink(l);
369
370 return *this;
371}
372
373
374/************************************************************************/
376{
377 allList.pop_back();
378 N=(unsigned int)allList.size();
379
380 build();
381}
382
383
384/************************************************************************/
386{
387 popLink();
388
389 return *this;
390}
391
392
393/************************************************************************/
394bool iKinChain::blockLink(const unsigned int i, double Ang)
395{
396 if (i<N)
397 {
398 allList[i]->block(Ang);
399 build();
400
401 return true;
402 }
403 else
404 {
405 if (verbose)
406 yError("blockLink() failed due to out of range index: %d>=%d",i,N);
407
408 return false;
409 }
410}
411
412
413/************************************************************************/
414bool iKinChain::setBlockingValue(const unsigned int i, double Ang)
415{
416 if (i<N)
417 {
418 if (allList[i]->isBlocked() && (Ang!=allList[i]->getAng()))
419 {
420 allList[i]->blocked=false; // remove the block temporarly
421 allList[i]->block(Ang); // update the blocked link
422
423 // update the cumulative link which follows in the chain
424 if (i<N-1)
425 {
426 Matrix H=eye(4,4);
427 int j;
428
429 for (j=i-1; j>=0; j--)
430 if (!allList[j]->isBlocked())
431 break;
432
433 for (++j; j<=(int)i; j++)
434 H*=allList[j]->getH(true);
435
436 for (; j<(int)N && !allList[j]->isCumulative(); j++)
437 H*=allList[j]->getH(true);
438
439 allList[j]->addCumH(H);
440 }
441
442 return true;
443 }
444 else
445 {
446 if (verbose)
447 yError("setBlockingValue() failed since the %dth link was not already blocked",i);
448
449 return false;
450 }
451 }
452 else
453 {
454 if (verbose)
455 yError("setBlockingValue() failed due to out of range index: %d>=%d",i,N);
456
457 return false;
458 }
459}
460
461
462/************************************************************************/
463bool iKinChain::releaseLink(const unsigned int i)
464{
465 if (i<N)
466 {
467 allList[i]->release();
468 build();
469
470 return true;
471 }
472 else
473 {
474 if (verbose)
475 yError("releaseLink() failed due to out of range index: %d>=%d",i,N);
476
477 return false;
478 }
479}
480
481
482/************************************************************************/
483bool iKinChain::isLinkBlocked(const unsigned int i)
484{
485 if (i<N)
486 return allList[i]->isBlocked();
487 else
488 {
489 if (verbose)
490 yError("isLinkBlocked() failed due to out of range index: %d>=%d",i,N);
491
492 return false;
493 }
494}
495
496
497/************************************************************************/
498void iKinChain::setAllConstraints(bool _constrained)
499{
500 for (unsigned int i=0; i<N; i++)
501 allList[i]->setConstraint(_constrained);
502}
503
504
505/************************************************************************/
506void iKinChain::setAllLinkVerbosity(unsigned int _verbose)
507{
508 for (unsigned int i=0; i<N; i++)
509 allList[i]->setVerbosity(_verbose);
510}
511
512
513/************************************************************************/
515{
516 quickList.clear();
517 hash.clear();
518 hash_dof.clear();
519 DOF=0;
520
521 Matrix H=eye(4,4);
522 bool cumulOn=false;
523
524 for (unsigned int i=0; i<N; i++)
525 {
526 allList[i]->rmCumH();
527
528 if (allList[i]->isBlocked())
529 {
530 if (i==N-1)
531 {
532 allList[i]->addCumH(H);
533 quickList.push_back(allList[i]);
534 }
535 else
536 {
537 H*=allList[i]->getH();
538 cumulOn=true;
539 }
540 }
541 else
542 {
543 if (cumulOn)
544 allList[i]->addCumH(H);
545
546 DOF++;
547 quickList.push_back(allList[i]);
548 hash_dof.push_back((unsigned int)quickList.size()-1);
549 hash.push_back(i);
550
551 H.eye();
552 cumulOn=false;
553 }
554 }
555
556 if (DOF>0)
557 curr_q.resize(DOF,0);
558}
559
560
561/************************************************************************/
562bool iKinChain::setH0(const Matrix &_H0)
563{
564 if ((_H0.rows()==4) && (_H0.cols()==4))
565 {
566 H0=_H0;
567 return true;
568 }
569 else
570 {
571 if (verbose)
572 yError("Attempt to reference a wrong matrix H0 (not 4x4)");
573
574 return false;
575 }
576}
577
578
579/************************************************************************/
580bool iKinChain::setHN(const Matrix &_HN)
581{
582 if ((_HN.rows()==4) && (_HN.cols()==4))
583 {
584 HN=_HN;
585 return true;
586 }
587 else
588 {
589 if (verbose)
590 yError("Attempt to reference a wrong matrix HN (not 4x4)");
591
592 return false;
593 }
594}
595
596
597/************************************************************************/
598Vector iKinChain::setAng(const Vector &q)
599{
600 yAssert(DOF>0);
601
602 size_t sz=std::min(q.length(),(size_t)DOF);
603 for (size_t i=0; i<sz; i++)
604 curr_q[i]=quickList[hash_dof[i]]->setAng(q[i]);
605
606 return curr_q;
607}
608
609
610/************************************************************************/
612{
613 yAssert(DOF>0);
614
615 for (unsigned int i=0; i<DOF; i++)
617
618 return curr_q;
619}
620
621
622/************************************************************************/
623double iKinChain::setAng(const unsigned int i, double _Ang)
624{
625 double res=0.0;
626
627 if (i<N)
628 {
629 if (allList[i]->isBlocked())
630 {
631 setBlockingValue(i,_Ang);
632 res=allList[i]->getAng();
633 }
634 else
635 res=allList[i]->setAng(_Ang);
636 }
637 else if (verbose)
638 yError("setAng() failed due to out of range index: %d>=%d",i,N);
639
640 return res;
641}
642
643
644/************************************************************************/
645double iKinChain::getAng(const unsigned int i)
646{
647 double res=0.0;
648
649 if (i<N)
650 res=allList[i]->getAng();
651 else if (verbose)
652 yError("getAng() failed due to out of range index: %d>=%d",i,N);
653
654 return res;
655}
656
657
658/************************************************************************/
659Vector iKinChain::RotAng(const Matrix &R)
660{
661 Vector r(3);
662
663 // Euler Angles as XYZ (see dcm2angle.m)
664 r[0]=atan2(-R(2,1),R(2,2));
665 r[1]=asin(R(2,0));
666 r[2]=atan2(-R(1,0),R(0,0));
667
668 return r;
669}
670
671
672/************************************************************************/
673Vector iKinChain::dRotAng(const Matrix &R, const Matrix &dR)
674{
675 Vector dr(3);
676
677 dr[0]=(R(2,1)*dR(2,2) - R(2,2)*dR(2,1)) / (R(2,1)*R(2,1) + R(2,2)*R(2,2));
678 dr[1]=dR(2,0)/sqrt(fabs(1-R(2,0)*R(2,0)));
679 dr[2]=(R(1,0)*dR(0,0) - R(0,0)*dR(1,0)) / (R(1,0)*R(1,0) + R(0,0)*R(0,0));
680
681 return dr;
682}
683
684
685/************************************************************************/
686Vector iKinChain::d2RotAng(const Matrix &R, const Matrix &dRi,
687 const Matrix &dRj, const Matrix &d2R)
688{
689 Vector d2r(3);
690
691 double y,yi,yj,yij,x,xi,xj,xij;
692 double tmp1,tmp2;
693
694 y =-R(2,1);
695 yi =-dRi(2,1);
696 yj =-dRj(2,1);
697 yij=-d2R(2,1);
698 x = R(2,2);
699 xi = dRi(2,2);
700 xj = dRj(2,2);
701 xij= d2R(2,2);
702
703 tmp1 =x*x+y*y;
704 d2r[0]=((xj*yi+x*yij-xij*y-xi*yj)*tmp1 - 2.0*(x*yi-xi*y)*(x*xj+y*yj)) / (tmp1*tmp1);
705
706 x =R(2,0);
707 xi =dRi(2,0);
708 xj =dRj(2,0);
709 xij=d2R(2,0);
710
711 tmp1 =1-x*x;
712 tmp2 =sqrt(fabs(tmp1));
713 d2r[1]=(xij-(x*xi*xj)/tmp1) / (tmp1*tmp2);
714
715 y =-R(1,0);
716 yi =-dRi(1,0);
717 yj =-dRj(1,0);
718 yij=-d2R(1,0);
719 x = R(0,0);
720 xi = dRi(0,0);
721 xj = dRj(0,0);
722 xij= d2R(0,0);
723
724 tmp1 =x*x+y*y;
725 d2r[2]=((xj*yi+x*yij-xij*y-xi*yj)*tmp1 - 2.0*(x*yi-xi*y)*(x*xj+y*yj)) / (tmp1*tmp1);
726
727 return d2r;
728}
729
730
731/************************************************************************/
732Matrix iKinChain::getH(const unsigned int i, const bool allLink)
733{
734 Matrix H=H0;
735 unsigned int _i,n;
736 deque<iKinLink*> *l;
737 bool cumulHN=false;
738 bool c_override;
739
740 if (allLink)
741 {
742 n=N;
743 l=&allList;
744 c_override=true;
745
746 _i=i;
747 if (_i>=N-1)
748 cumulHN=true;
749 }
750 else
751 {
752 n=DOF;
753 l=&quickList;
754 c_override=false;
755
756 if (i==DOF)
757 _i=(unsigned int)quickList.size();
758 else
759 _i=i;
760
761 if (hash[_i]>=N-1)
762 cumulHN=true;
763 }
764
765 yAssert(i<n);
766
767 for (unsigned int j=0; j<=_i; j++)
768 H*=((*l)[j]->getH(c_override));
769
770 if (cumulHN)
771 H*=HN;
772
773 return H;
774}
775
776
777/************************************************************************/
779{
780 // may be different from DOF since one blocked link may lie
781 // at the end of the chain.
782 unsigned int n=(unsigned int)quickList.size();
783 Matrix H=H0;
784
785 for (unsigned int i=0; i<n; i++)
786 H*=quickList[i]->getH();
787
788 return H*HN;
789}
790
791
792/************************************************************************/
793Matrix iKinChain::getH(const Vector &q)
794{
795 yAssert(DOF>0);
796
797 setAng(q);
798 return getH();
799}
800
801
802/************************************************************************/
803Vector iKinChain::Pose(const unsigned int i, const bool axisRep)
804{
805 Matrix H=getH(i,true);
806 Vector v;
807
808 if (i<N)
809 {
810 if (axisRep)
811 {
812 v.resize(7);
813 Vector r=dcm2axis(H);
814 v[0]=H(0,3);
815 v[1]=H(1,3);
816 v[2]=H(2,3);
817 v[3]=r[0];
818 v[4]=r[1];
819 v[5]=r[2];
820 v[6]=r[3];
821 }
822 else
823 {
824 v.resize(6);
825 Vector r=RotAng(H);
826 v[0]=H(0,3);
827 v[1]=H(1,3);
828 v[2]=H(2,3);
829 v[3]=r[0];
830 v[4]=r[1];
831 v[5]=r[2];
832 }
833 }
834 else if (verbose)
835 yError("Pose() failed due to out of range index: %d>=%d",i,N);
836
837 return v;
838}
839
840
841/************************************************************************/
842Vector iKinChain::Position(const unsigned int i)
843{
844 yAssert(i<N);
845 return getH(i,true).subcol(0,3,3);
846}
847
848
849/************************************************************************/
850Vector iKinChain::EndEffPose(const bool axisRep)
851{
852 Matrix H=getH();
853 Vector v;
854
855 if (axisRep)
856 {
857 v.resize(7);
858 Vector r=dcm2axis(H);
859 v[0]=H(0,3);
860 v[1]=H(1,3);
861 v[2]=H(2,3);
862 v[3]=r[0];
863 v[4]=r[1];
864 v[5]=r[2];
865 v[6]=r[3];
866 }
867 else
868 {
869 v.resize(6);
870 Vector r=RotAng(H);
871 v[0]=H(0,3);
872 v[1]=H(1,3);
873 v[2]=H(2,3);
874 v[3]=r[0];
875 v[4]=r[1];
876 v[5]=r[2];
877 }
878
879 return v;
880}
881
882
883/************************************************************************/
884Vector iKinChain::EndEffPose(const Vector &q, const bool axisRep)
885{
886 yAssert(DOF>0);
887
888 setAng(q);
889 return EndEffPose(axisRep);
890}
891
892
893/************************************************************************/
895{
896 return getH().subcol(0,3,3);
897}
898
899
900/************************************************************************/
901Vector iKinChain::EndEffPosition(const Vector &q)
902{
903 yAssert(DOF>0);
904
905 setAng(q);
906 return EndEffPosition();
907}
908
909
910/************************************************************************/
911Matrix iKinChain::AnaJacobian(const unsigned int i, unsigned int col)
912{
913 yAssert(i<N);
914
915 col=col>3 ? 3 : col;
916
917 Matrix J(6,i+1);
918 Matrix H,dH,_H;
919 Vector dr;
920
921 for (unsigned int j=0; j<=i; j++)
922 {
923 H=dH=H0;
924
925 for (unsigned int k=0; k<=i; k++)
926 {
927 _H=allList[k]->getH(true);
928 H*=_H;
929
930 if (j==k)
931 dH*=allList[k]->getDnH(1,true);
932 else
933 dH*=_H;
934 }
935
936 if (i>=N-1)
937 {
938 H*=HN;
939 dH*=HN;
940 }
941
942 dr=dRotAng(H,dH);
943
944 J(0,j)=dH(0,col);
945 J(1,j)=dH(1,col);
946 J(2,j)=dH(2,col);
947 J(3,j)=dr[0];
948 J(4,j)=dr[1];
949 J(5,j)=dr[2];
950 }
951
952 return J;
953}
954
955
956/************************************************************************/
957Matrix iKinChain::AnaJacobian(unsigned int col)
958{
959 yAssert(DOF>0);
960
961 col=col>3 ? 3 : col;
962
963 // may be different from DOF since one blocked link may lie
964 // at the end of the chain.
965 unsigned int n=(unsigned int)quickList.size();
966 Matrix J(6,DOF);
967 Matrix H,dH,_H;
968 Vector dr;
969
970 for (unsigned int i=0; i<DOF; i++)
971 {
972 H=dH=H0;
973
974 for (unsigned int j=0; j<n; j++)
975 {
976 _H=quickList[j]->getH();
977 H*=_H;
978
979 if (hash_dof[i]==j)
980 dH*=quickList[j]->getDnH();
981 else
982 dH*=_H;
983 }
984
985 H*=HN;
986 dH*=HN;
987 dr=dRotAng(H,dH);
988
989 J(0,i)=dH(0,col);
990 J(1,i)=dH(1,col);
991 J(2,i)=dH(2,col);
992 J(3,i)=dr[0];
993 J(4,i)=dr[1];
994 J(5,i)=dr[2];
995 }
996
997 return J;
998}
999
1000
1001/************************************************************************/
1002Matrix iKinChain::AnaJacobian(const Vector &q, unsigned int col)
1003{
1004 yAssert(DOF>0);
1005
1006 setAng(q);
1007 return AnaJacobian(col);
1008}
1009
1010
1011/************************************************************************/
1012Matrix iKinChain::GeoJacobian(const unsigned int i)
1013{
1014 yAssert(i<N);
1015
1016 Matrix J(6,i+1);
1017 Matrix PN,Z;
1018 Vector w;
1019
1020 deque<Matrix> intH;
1021 intH.push_back(H0);
1022
1023 for (unsigned int j=0; j<=i; j++)
1024 intH.push_back(intH[j]*allList[j]->getH(true));
1025
1026 PN=intH[i+1];
1027 if (i>=N-1)
1028 PN=PN*HN;
1029
1030 for (unsigned int j=0; j<=i; j++)
1031 {
1032 Z=intH[j];
1033 w=cross(Z,2,PN-Z,3);
1034
1035 J(0,j)=w[0];
1036 J(1,j)=w[1];
1037 J(2,j)=w[2];
1038 J(3,j)=Z(0,2);
1039 J(4,j)=Z(1,2);
1040 J(5,j)=Z(2,2);
1041 }
1042
1043 return J;
1044}
1045
1046
1047/************************************************************************/
1049{
1050 yAssert(DOF>0);
1051
1052 Matrix J(6,DOF);
1053 Matrix PN,Z;
1054 Vector w;
1055
1056 deque<Matrix> intH;
1057 intH.push_back(H0);
1058
1059 for (unsigned int i=0; i<N; i++)
1060 intH.push_back(intH[i]*allList[i]->getH(true));
1061
1062 PN=intH[N]*HN;
1063
1064 for (unsigned int i=0; i<DOF; i++)
1065 {
1066 unsigned int j=hash[i];
1067
1068 Z=intH[j];
1069 w=cross(Z,2,PN-Z,3);
1070
1071 J(0,i)=w[0];
1072 J(1,i)=w[1];
1073 J(2,i)=w[2];
1074 J(3,i)=Z(0,2);
1075 J(4,i)=Z(1,2);
1076 J(5,i)=Z(2,2);
1077 }
1078
1079 return J;
1080}
1081
1082
1083/************************************************************************/
1084Matrix iKinChain::GeoJacobian(const Vector &q)
1085{
1086 yAssert(DOF>0);
1087
1088 setAng(q);
1089 return GeoJacobian();
1090}
1091
1092
1093/************************************************************************/
1094Vector iKinChain::Hessian_ij(const unsigned int i, const unsigned int j)
1095{
1097 return fastHessian_ij(i,j);
1098}
1099
1100
1101/************************************************************************/
1103{
1104 if (DOF==0)
1105 {
1106 if (verbose)
1107 yError("prepareForHessian() failed since DOF==0");
1108
1109 return;
1110 }
1111
1113}
1114
1115
1116/************************************************************************/
1117Vector iKinChain::fastHessian_ij(const unsigned int i, const unsigned int j)
1118{
1119 yAssert((i<DOF) && (j<DOF));
1120
1121 // ref. E.D. Pohl, H. Lipkin, "A New Method of Robotic Motion Control Near Singularities",
1122 // Advanced Robotics, 1991
1123 Vector h(6,0.0);
1124 if(i<j)
1125 {
1126 //h.setSubvector(0,cross(hess_Jo,i,hess_Jl,j));
1127 h[0] = hess_J(4,i)*hess_J(2,j) - hess_J(5,i)*hess_J(1,j);
1128 h[1] = hess_J(5,i)*hess_J(0,j) - hess_J(3,i)*hess_J(2,j);
1129 h[2] = hess_J(3,i)*hess_J(1,j) - hess_J(4,i)*hess_J(0,j);
1130 //h.setSubvector(3,cross(hess_Jo,i,hess_Jo,j));
1131 h(3) = hess_J(4,i)*hess_J(5,j)-hess_J(5,i)*hess_J(4,j);
1132 h(4) = hess_J(5,i)*hess_J(3,j)-hess_J(3,i)*hess_J(5,j);
1133 h(5) = hess_J(3,i)*hess_J(4,j)-hess_J(4,i)*hess_J(3,j);
1134 }
1135 else
1136 {
1137 //h.setSubvector(0, cross(Jo,j,Jl,i));
1138 h[0] = hess_J(4,j)*hess_J(2,i) - hess_J(5,j)*hess_J(1,i);
1139 h[1] = hess_J(5,j)*hess_J(0,i) - hess_J(3,j)*hess_J(2,i);
1140 h[2] = hess_J(3,j)*hess_J(1,i) - hess_J(4,j)*hess_J(0,i);
1141 h[3]=h[4]=h[5]=0.0;
1142 }
1143
1144 return h;
1145}
1146
1147
1148/************************************************************************/
1149Vector iKinChain::Hessian_ij(const unsigned int lnk, const unsigned int i,
1150 const unsigned int j)
1151{
1152 prepareForHessian(lnk);
1153 return fastHessian_ij(lnk,i,j);
1154}
1155
1156
1157/************************************************************************/
1158void iKinChain::prepareForHessian(const unsigned int lnk)
1159{
1160 if (lnk>=N)
1161 {
1162 if (verbose)
1163 yError("prepareForHessian() failed due to out of range index: %d>=%d",lnk,N);
1164
1165 return;
1166 }
1167
1169}
1170
1171
1172/************************************************************************/
1173Vector iKinChain::fastHessian_ij(const unsigned int lnk, const unsigned int i,
1174 const unsigned int j)
1175{
1176 yAssert((i<lnk) && (j<lnk));
1177
1178 Vector h(6,0.0);
1179 if (i<j)
1180 {
1181 //h.setSubvector(0,cross(hess_Jlnko,i,hess_Jlnkl,j));
1182 h[0] = hess_Jlnk(4,i)*hess_Jlnk(2,j) - hess_Jlnk(5,i)*hess_Jlnk(1,j);
1183 h[1] = hess_Jlnk(5,i)*hess_Jlnk(0,j) - hess_Jlnk(3,i)*hess_Jlnk(2,j);
1184 h[2] = hess_Jlnk(3,i)*hess_Jlnk(1,j) - hess_Jlnk(4,i)*hess_Jlnk(0,j);
1185 //h.setSubvector(3,cross(hess_Jlnko,i,hess_Jlnko,j));
1186 h[3] = hess_Jlnk(4,i)*hess_Jlnk(5,j) - hess_Jlnk(5,i)*hess_Jlnk(4,j);
1187 h[4] = hess_Jlnk(5,i)*hess_Jlnk(3,j) - hess_Jlnk(3,i)*hess_Jlnk(5,j);
1188 h[5] = hess_Jlnk(3,i)*hess_Jlnk(4,j) - hess_Jlnk(4,i)*hess_Jlnk(3,j);
1189 }
1190 else
1191 {
1192 //h.setSubvector(0,cross(hess_Jlnko,j,hess_Jlnkl,i));
1193 h[0] = hess_Jlnk(4,j)*hess_Jlnk(2,i) - hess_Jlnk(5,j)*hess_Jlnk(1,i);
1194 h[1] = hess_Jlnk(5,j)*hess_Jlnk(0,i) - hess_Jlnk(3,j)*hess_Jlnk(2,i);
1195 h[2] = hess_Jlnk(3,j)*hess_Jlnk(1,i) - hess_Jlnk(4,j)*hess_Jlnk(0,i);
1196 h[3]=h[4]=h[5]=0.0;
1197 }
1198
1199 return h;
1200}
1201
1202
1203/************************************************************************/
1204Matrix iKinChain::DJacobian(const Vector &dq)
1205{
1206 Matrix J=GeoJacobian();
1207 Matrix dJ(6,DOF); dJ.zero();
1208 double dqj,dqi,a,b,c;
1209 for (unsigned int i=0; i<DOF; i++) // i: col
1210 {
1211 for (unsigned int j=0; j<=i; j++) // j: row
1212 {
1213 dqj=dq[j];
1214
1215 a=J(4,j)*J(2,i)-J(5,j)*J(1,i);
1216 b=J(5,j)*J(0,i)-J(3,j)*J(2,i);
1217 c=J(3,j)*J(1,i)-J(4,j)*J(0,i);
1218 dJ(0,i)+=dqj*a;
1219 dJ(1,i)+=dqj*b;
1220 dJ(2,i)+=dqj*c;
1221 dJ(3,i)+=dqj*(J(4,j)*J(5,i)-J(5,j)*J(4,i));
1222 dJ(4,i)+=dqj*(J(5,j)*J(3,i)-J(3,j)*J(5,i));
1223 dJ(5,i)+=dqj*(J(3,j)*J(4,i)-J(4,j)*J(3,i));
1224
1225 if (i!=j)
1226 {
1227 dqi =dq[i];
1228 dJ(0,j)+=dqi*a;
1229 dJ(1,j)+=dqi*b;
1230 dJ(2,j)+=dqi*c;
1231 }
1232 }
1233 }
1234
1235 return dJ;
1236
1237 /* OLD IMPLEMENTATION (SLOWER, BUT CLEARER)
1238 prepareForHessian();
1239 Vector tmp(6,0.0);
1240 for (unsigned int i=0; i<DOF; i++)
1241 {
1242 for (unsigned int j=0; j<DOF; j++)
1243 tmp+=fastHessian_ij(j,i)*dq(j);
1244
1245 dJ.setCol(i,tmp);
1246 tmp.zero();
1247 }*/
1248}
1249
1250
1251/************************************************************************/
1252Matrix iKinChain::DJacobian(const unsigned int lnk, const Vector &dq)
1253{
1254 Matrix J=GeoJacobian(lnk);
1255 Matrix dJ(6,lnk-1); dJ.zero();
1256 double dqj,dqi,a,b,c;
1257 for (unsigned int i=0; i<lnk; i++) // i: col
1258 {
1259 for (unsigned int j=0; j<=i; j++) // j: row
1260 {
1261 dqj=dq[j];
1262
1263 a=J(4,j)*J(2,i)-J(5,j)*J(1,i);
1264 b=J(5,j)*J(0,i)-J(3,j)*J(2,i);
1265 c=J(3,j)*J(1,i)-J(4,j)*J(0,i);
1266 dJ(0,i)+=dqj*a;
1267 dJ(1,i)+=dqj*b;
1268 dJ(2,i)+=dqj*c;
1269 dJ(3,i)+=dqj*(J(4,j)*J(5,i)-J(5,j)*J(4,i));
1270 dJ(4,i)+=dqj*(J(5,j)*J(3,i)-J(3,j)*J(5,i));
1271 dJ(5,i)+=dqj*(J(3,j)*J(4,i)-J(4,j)*J(3,i));
1272
1273 if (i!=j)
1274 {
1275 dqi =dq[i];
1276 dJ(0,j)+=dqi*a;
1277 dJ(1,j)+=dqi*b;
1278 dJ(2,j)+=dqi*c;
1279 }
1280 }
1281 }
1282
1283 return dJ;
1284
1285 // OLD IMPLEMENTATION (SLOWER, BUT CLEARER)
1286 /*prepareForHessian(lnk);
1287 Vector tmp(6,0.0);
1288 for (unsigned int i=0; i<lnk; i++)
1289 {
1290 for (unsigned int j=0; j<lnk; j++)
1291 tmp+=fastHessian_ij(lnk,j,i)*dq(j);
1292
1293 dJ.setCol(i,tmp);
1294 tmp.zero();
1295 }*/
1296}
1297
1298
1299/************************************************************************/
1301{
1302 dispose();
1303}
1304
1305
1306/************************************************************************/
1308{
1309 allList.clear();
1310 quickList.clear();
1311}
1312
1313
1314/************************************************************************/
1316{
1317 allocate("right");
1318}
1319
1320
1321/************************************************************************/
1322iKinLimb::iKinLimb(const string &_type)
1323{
1324 allocate(_type);
1325}
1326
1327
1328/************************************************************************/
1330{
1331 clone(limb);
1332}
1333
1334
1335/************************************************************************/
1336iKinLimb::iKinLimb(const Property &options)
1337{
1338 fromLinksProperties(options);
1339}
1340
1341
1342/************************************************************************/
1344{
1345 linkList.push_back(pl);
1346 pushLink(*pl);
1347}
1348
1349
1350/************************************************************************/
1351void iKinLimb::getMatrixFromProperties(const Property &options, const string &tag,
1352 Matrix &H)
1353{
1354 if (Bottle *bH=options.find(tag).asList())
1355 {
1356 int i=0;
1357 int j=0;
1358
1359 H.zero();
1360 for (int cnt=0; (cnt<bH->size()) && (cnt<H.rows()*H.cols()); cnt++)
1361 {
1362 H(i,j)=bH->get(cnt).asFloat64();
1363 if (++j>=H.cols())
1364 {
1365 i++;
1366 j=0;
1367 }
1368 }
1369 }
1370}
1371
1372
1373/************************************************************************/
1374void iKinLimb::setMatrixToProperties(Property &options, const string &tag,
1375 Matrix &H)
1376{
1377 Bottle b; Bottle &l=b.addList();
1378 for (int r=0; r<H.rows(); r++)
1379 for (int c=0; c<H.cols(); c++)
1380 l.addFloat64(H(r,c));
1381
1382 options.put(tag,b.get(0));
1383}
1384
1385
1386/************************************************************************/
1387bool iKinLimb::fromLinksProperties(const Property &options)
1388{
1389 dispose();
1390
1391 type=options.check("type",Value("right")).asString();
1392
1393 getMatrixFromProperties(options,"H0",H0);
1394 getMatrixFromProperties(options,"HN",HN);
1395
1396 int numLinks=options.check("numLinks",Value(0)).asInt32();
1397 if (numLinks==0)
1398 {
1399 yError("invalid number of links specified!");
1400
1401 type="right";
1402 H0.eye();
1403 HN.eye();
1404
1405 return false;
1406 }
1407
1408 for (int i=0; i<numLinks; i++)
1409 {
1410 ostringstream link;
1411 link<<"link_"<<i;
1412
1413 Bottle &bLink=options.findGroup(link.str());
1414 if (bLink.isNull())
1415 {
1416 yError("%s is missing!",link.str().c_str());
1417
1418 type="right";
1419 H0.eye();
1420 dispose();
1421
1422 return false;
1423 }
1424
1425 double A=bLink.check("A",Value(0.0)).asFloat64();
1426 double D=bLink.check("D",Value(0.0)).asFloat64();
1427 double alpha=CTRL_DEG2RAD*bLink.check("alpha",Value(0.0)).asFloat64();
1428 double offset=CTRL_DEG2RAD*bLink.check("offset",Value(0.0)).asFloat64();
1429 double min=CTRL_DEG2RAD*bLink.check("min",Value(-180.0)).asFloat64();
1430 double max=CTRL_DEG2RAD*bLink.check("max",Value(180.0)).asFloat64();
1431
1432 pushLink(new iKinLink(A,D,alpha,offset,min,max));
1433
1434 if (bLink.check("blocked"))
1435 blockLink(i,CTRL_DEG2RAD*bLink.find("blocked").asFloat64());
1436 }
1437
1438 return true;
1439}
1440
1441
1442/************************************************************************/
1443bool iKinLimb::toLinksProperties(Property &options)
1444{
1445 Bottle links;
1446 for (unsigned int i=0; i<N; i++)
1447 {
1448 Bottle &link=links.addList();
1449 ostringstream tag;
1450 tag<<"link_"<<i;
1451 link.addString(tag.str());
1452
1453 Bottle &A=link.addList();
1454 A.addString("A");
1455 A.addFloat64((*this)[i].getA());
1456
1457 Bottle &D=link.addList();
1458 D.addString("D");
1459 D.addFloat64((*this)[i].getD());
1460
1461 Bottle &alpha=link.addList();
1462 alpha.addString("alpha");
1463 alpha.addFloat64(CTRL_RAD2DEG*(*this)[i].getAlpha());
1464
1465 Bottle &offset=link.addList();
1466 offset.addString("offset");
1467 offset.addFloat64(CTRL_RAD2DEG*(*this)[i].getOffset());
1468
1469 Bottle &min=link.addList();
1470 min.addString("min");
1471 min.addFloat64(CTRL_RAD2DEG*(*this)[i].getMin());
1472
1473 Bottle &max=link.addList();
1474 max.addString("max");
1475 max.addFloat64(CTRL_RAD2DEG*(*this)[i].getMax());
1476
1477 if ((*this)[i].isBlocked())
1478 {
1479 Bottle &blocked=link.addList();
1480 blocked.addString("blocked");
1481 blocked.addFloat64(CTRL_RAD2DEG*(*this)[i].getAng());
1482 }
1483 }
1484
1485 // merge the link groups into options without clearing what is already there
1486 options.fromString(links.toString(),false);
1487
1488 options.put("type",getType());
1489 options.put("numLinks",(int)N);
1490
1491 setMatrixToProperties(options,"H0",H0);
1492 setMatrixToProperties(options,"HN",HN);
1493
1494 return true;
1495}
1496
1497
1498/************************************************************************/
1500{
1501 dispose();
1502 clone(limb);
1503
1504 return *this;
1505}
1506
1507
1508/************************************************************************/
1510{
1511 dispose();
1512}
1513
1514
1515/************************************************************************/
1516void iKinLimb::allocate(const string &_type)
1517{
1518 type=_type;
1519}
1520
1521
1522/************************************************************************/
1523void iKinLimb::clone(const iKinLimb &limb)
1524{
1525 type=limb.type;
1526 H0=limb.H0;
1527 HN=limb.HN;
1528
1529 for (unsigned int i=0; i<limb.getN(); i++)
1530 pushLink(new iKinLink(*(limb.linkList[i])));
1531}
1532
1533
1534/************************************************************************/
1536{
1537 for (unsigned int i=0; i<linkList.size(); i++)
1538 if (linkList[i]!=NULL)
1539 delete linkList[i];
1540
1541 linkList.clear();
1543}
1544
1545
1546/************************************************************************/
1550
1551
1552/************************************************************************/
1554{
1555 size_t point=version.find('.');
1556 if ((point!=string::npos) && (point!=version.length()-1))
1557 {
1558 v_major=strtoul(version.substr(0,point).c_str(),NULL,0);
1559 v_minor=strtoul(version.substr(point+1).c_str(),NULL,0);
1560 }
1561 else
1562 {
1563 v_major=strtoul(version.c_str(),NULL,0);
1564 v_minor=0U;
1565 }
1566}
1567
1568
1569/************************************************************************/
1571 const unsigned long int v_minor)
1572{
1573 this->v_major=v_major;
1574 this->v_minor=v_minor;
1575}
1576
1577
1578/************************************************************************/
1584
1585
1586/************************************************************************/
1587unsigned long int iKinLimbVersion::get_major() const
1588{
1589 return v_major;
1590}
1591
1592
1593/************************************************************************/
1594unsigned long int iKinLimbVersion::get_minor() const
1595{
1596 return v_minor;
1597}
1598
1599
1600/************************************************************************/
1602{
1603 ostringstream version;
1604 version<<v_major<<"."<<v_minor;
1605 return version.str();
1606}
1607
1608
1609/************************************************************************/
1611{
1612 v_major=v.v_major;
1613 v_minor=v.v_minor;
1614 return *this;
1615}
1616
1617
1618/************************************************************************/
1620{
1621 if (v_major<v.v_major)
1622 return true;
1623 else if (v_major==v.v_major)
1624 return v_minor<v.v_minor;
1625 else
1626 return false;
1627}
1628
1629
1630/************************************************************************/
1632{
1633 return !(*this<v);
1634}
1635
1636
1637/************************************************************************/
1639{
1640 return (v_major==v.v_major) && (v_minor==v.v_minor);
1641}
1642
1643
1644/************************************************************************/
1646{
1647 return !(*this==v);
1648}
1649
1650
1651/************************************************************************/
1653{
1654 return (*this<v) || (*this==v);
1655}
1656
1657
1658/************************************************************************/
1660{
1661 return (*this>v) || (*this==v);
1662}
1663
1664
1665/************************************************************************/
1667{
1668 unsigned long int m1=(v_major>v.v_major)?v_major-v.v_major:v.v_major-v_major;
1669 unsigned long int m2=0L;
1670 if (m1==0L)
1672 return iKinLimbVersion(m1, m2);
1673}
1674
1675
1676/************************************************************************/
1678{
1679 allocate(getType());
1680}
1681
1682
1683/************************************************************************/
1684iCubTorso::iCubTorso(const string &_type) : iKinLimb(_type)
1685{
1686 allocate(_type);
1687}
1688
1689
1690/************************************************************************/
1691void iCubTorso::allocate(const string &_type)
1692{
1693 if (getType().size()>1)
1694 version=iKinLimbVersion(getType().substr(1));
1695 else
1696 version=iKinLimbVersion("1.0");
1697
1698 Matrix H0(4,4);
1699 H0.zero();
1700 H0(3,3)=1.0;
1701
1702 if (version<iKinLimbVersion("3.0"))
1703 {
1704 H0(0,1)=-1.0;
1705 H0(1,2)=-1.0;
1706 H0(2,0)=1.0;
1707 setH0(H0);
1708
1709 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
1710 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
1711 pushLink(new iKinLink(0.00231, -0.1933, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
1712 }
1713 else
1714 {
1715 H0(0,2)=1.0;
1716 H0(1,1)=-1.0;
1717 H0(2,0)=1.0;
1718 setH0(H0);
1719
1720 pushLink(new iKinLink( 0.0725, 0.0, -M_PI/2.0, 0.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
1721 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -15.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
1722 pushLink(new iKinLink(-0.00486151, -0.26377, -M_PI/2.0, M_PI, -40.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
1723 }
1724}
1725
1726
1727/************************************************************************/
1728bool iCubTorso::alignJointsBounds(const deque<IControlLimits*> &lim)
1729{
1730 if (lim.size()==0)
1731 return false;
1732
1733 IControlLimits &limTorso=*lim[0];
1734
1735 unsigned int iTorso;
1736 double min, max;
1737
1738 for (iTorso=0; iTorso<3; iTorso++)
1739 {
1740 if (!limTorso.getLimits(iTorso,&min,&max))
1741 return false;
1742
1743 if (version<iKinLimbVersion("3.0"))
1744 {
1745 (*this)[2-iTorso].setMin(CTRL_DEG2RAD*min);
1746 (*this)[2-iTorso].setMax(CTRL_DEG2RAD*max);
1747 }
1748 else
1749 {
1750 (*this)[iTorso].setMin(CTRL_DEG2RAD*min);
1751 (*this)[iTorso].setMax(CTRL_DEG2RAD*max);
1752 }
1753 }
1754
1755 return true;
1756}
1757
1758
1759/************************************************************************/
1760iCubArm::iCubArm() : iKinLimb(string("right"))
1761{
1762 allocate(getType());
1763}
1764
1765
1766/************************************************************************/
1767iCubArm::iCubArm(const string &_type) : iKinLimb(_type)
1768{
1769 allocate(_type);
1770}
1771
1772
1773/************************************************************************/
1774void iCubArm::allocate(const string &_type)
1775{
1776 string arm;
1777 size_t underscore=getType().find('_');
1778 if (underscore!=string::npos)
1779 {
1780 arm=getType().substr(0,underscore);
1781 version=iKinLimbVersion(getType().substr(underscore+2));
1782 }
1783 else
1784 {
1785 arm=getType();
1786 version=iKinLimbVersion("1.0");
1787 }
1788
1789 Matrix H0(4,4);
1790 H0.zero();
1791
1792 if (version<iKinLimbVersion("3.0"))
1793 {
1794 H0(0,1)=-1.0;
1795 H0(1,2)=-1.0;
1796 H0(2,0)=1.0;
1797 }
1798 else
1799 {
1800 H0(0,2)=1.0;
1801 H0(1,1)=-1.0;
1802 H0(2,0)=1.0;
1803 }
1804
1805 H0(3,3)=1.0;
1806 setH0(H0);
1807
1808 if (arm=="right")
1809 {
1810 if (version<iKinLimbVersion("3.0"))
1811 {
1812 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
1813 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
1814 pushLink(new iKinLink(-0.0233647, -0.1433, M_PI/2.0, -105.0*CTRL_DEG2RAD, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
1815 pushLink(new iKinLink( 0.0, -0.10774, M_PI/2.0, -M_PI/2.0, -95.5*CTRL_DEG2RAD, 5.0*CTRL_DEG2RAD));
1816 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, 0.0*CTRL_DEG2RAD, 160.8*CTRL_DEG2RAD));
1817 pushLink(new iKinLink( -0.015, -0.15228, -M_PI/2.0, -105.0*CTRL_DEG2RAD, -37.0*CTRL_DEG2RAD, 100.0*CTRL_DEG2RAD));
1818 pushLink(new iKinLink( 0.015, 0.0, M_PI/2.0, 0.0, 5.5*CTRL_DEG2RAD, 106.0*CTRL_DEG2RAD));
1819 if (version<iKinLimbVersion("1.7"))
1820 pushLink(new iKinLink( 0.0, -0.1373, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
1821 else
1822 pushLink(new iKinLink( 0.0, -0.1413, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
1823 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, M_PI/2.0, -65.0*CTRL_DEG2RAD, 10.0*CTRL_DEG2RAD));
1824 if (version<iKinLimbVersion("2.0"))
1825 pushLink(new iKinLink( 0.0625, 0.016, 0.0, M_PI, -25.0*CTRL_DEG2RAD, 25.0*CTRL_DEG2RAD));
1826 else
1827 pushLink(new iKinLink( 0.0625, 0.02598, 0.0, M_PI, -25.0*CTRL_DEG2RAD, 25.0*CTRL_DEG2RAD));
1828 }
1829 else
1830 {
1831 pushLink(new iKinLink( 0.0725, 0.0, -M_PI/2.0, 0.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
1832 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -15.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
1833 pushLink(new iKinLink(-0.0304112, -0.161133, 75.489181*CTRL_DEG2RAD, 165.0*CTRL_DEG2RAD, -40.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
1834 pushLink(new iKinLink( 0.0, -0.163978, M_PI/2.0, -M_PI/2.0, -90.0*CTRL_DEG2RAD, 2.0*CTRL_DEG2RAD));
1835 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -104.5*CTRL_DEG2RAD, -5.0*CTRL_DEG2RAD, 140.0*CTRL_DEG2RAD));
1836 pushLink(new iKinLink( -0.01065, -0.2005, -M_PI/2.0, -105*CTRL_DEG2RAD, -45.0*CTRL_DEG2RAD, 80.0*CTRL_DEG2RAD));
1837 pushLink(new iKinLink( 0.0146593, 0.00308819, M_PI/2.0, 0.0, -5.0*CTRL_DEG2RAD, 110.0*CTRL_DEG2RAD));
1838 pushLink(new iKinLink(-0.0020075, -0.1628, M_PI/2.0, -M_PI/2.0, -60.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
1839 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, M_PI/2.0, -70.0*CTRL_DEG2RAD, 25.0*CTRL_DEG2RAD));
1840 pushLink(new iKinLink( 0.0625, 0.016, 0.0, M_PI, -15.0*CTRL_DEG2RAD, 35.0*CTRL_DEG2RAD));
1841 }
1842 }
1843 else
1844 {
1845 if (arm!="left")
1846 type.replace(0,underscore,"left");
1847
1848 if (version<iKinLimbVersion("3.0"))
1849 {
1850 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
1851 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
1852 pushLink(new iKinLink( 0.0233647, -0.1433, -M_PI/2.0, 105.0*CTRL_DEG2RAD, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
1853 pushLink(new iKinLink( 0.0, 0.10774, -M_PI/2.0, M_PI/2.0, -95.5*CTRL_DEG2RAD, 5.0*CTRL_DEG2RAD));
1854 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, 0.0*CTRL_DEG2RAD, 160.8*CTRL_DEG2RAD));
1855 pushLink(new iKinLink( 0.015, 0.15228, -M_PI/2.0, 75.0*CTRL_DEG2RAD, -37.0*CTRL_DEG2RAD, 100.0*CTRL_DEG2RAD));
1856 pushLink(new iKinLink( -0.015, 0.0, M_PI/2.0, 0.0, 5.5*CTRL_DEG2RAD, 106.0*CTRL_DEG2RAD));
1857 if (version<iKinLimbVersion("1.7"))
1858 pushLink(new iKinLink( 0.0, 0.1373, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
1859 else
1860 pushLink(new iKinLink( 0.0, 0.1413, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
1861 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, M_PI/2.0, -65.0*CTRL_DEG2RAD, 10.0*CTRL_DEG2RAD));
1862 if (version<iKinLimbVersion("2.0"))
1863 pushLink(new iKinLink( 0.0625, -0.016, 0.0, 0.0, -25.0*CTRL_DEG2RAD, 25.0*CTRL_DEG2RAD));
1864 else
1865 pushLink(new iKinLink( 0.0625, -0.02598, 0.0, 0.0, -25.0*CTRL_DEG2RAD, 25.0*CTRL_DEG2RAD));
1866 }
1867 else
1868 {
1869 pushLink(new iKinLink( 0.0725, 0.0, -M_PI/2.0, 0.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
1870 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -15.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
1871 pushLink(new iKinLink( 0.0304112, -0.161133, -104.510819*CTRL_DEG2RAD, 15.0*CTRL_DEG2RAD, -40.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
1872 pushLink(new iKinLink( 0.0, 0.163978, M_PI/2.0, -M_PI/2.0, -90.0*CTRL_DEG2RAD, 2.0*CTRL_DEG2RAD));
1873 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, 75.5*CTRL_DEG2RAD, -5.0*CTRL_DEG2RAD, 140.0*CTRL_DEG2RAD));
1874 pushLink(new iKinLink( 0.01065, 0.2005, -M_PI/2.0, 75.0*CTRL_DEG2RAD, -45.0*CTRL_DEG2RAD, 80.0*CTRL_DEG2RAD));
1875 pushLink(new iKinLink(-0.0146593, -0.00308819, M_PI/2.0, 0.0, -5.0*CTRL_DEG2RAD, 110.0*CTRL_DEG2RAD));
1876 pushLink(new iKinLink( 0.0020075, 0.1628, M_PI/2.0, -M_PI/2.0, -60.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
1877 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, M_PI/2.0, -70.0*CTRL_DEG2RAD, 25.0*CTRL_DEG2RAD));
1878 pushLink(new iKinLink( 0.0625, -0.016, 0.0, 0.0, -15.0*CTRL_DEG2RAD, 35.0*CTRL_DEG2RAD));
1879 }
1880 }
1881
1882 blockLink(0,0.0);
1883 blockLink(1,0.0);
1884 blockLink(2,0.0);
1885}
1886
1887
1888/************************************************************************/
1889bool iCubArm::alignJointsBounds(const deque<IControlLimits*> &lim)
1890{
1891 if (lim.size()<2)
1892 return false;
1893
1894 IControlLimits &limTorso=*lim[0];
1895 IControlLimits &limArm =*lim[1];
1896
1897 unsigned int iTorso;
1898 unsigned int iArm;
1899 double min, max;
1900
1901 for (iTorso=0; iTorso<3; iTorso++)
1902 {
1903 if (!limTorso.getLimits(iTorso,&min,&max))
1904 return false;
1905
1906 if (version<iKinLimbVersion("3.0"))
1907 {
1908 (*this)[2-iTorso].setMin(CTRL_DEG2RAD*min);
1909 (*this)[2-iTorso].setMax(CTRL_DEG2RAD*max);
1910 }
1911 else
1912 {
1913 (*this)[iTorso].setMin(CTRL_DEG2RAD*min);
1914 (*this)[iTorso].setMax(CTRL_DEG2RAD*max);
1915 }
1916 }
1917
1918 for (iArm=0; iArm<getN()-iTorso; iArm++)
1919 {
1920 if (!limArm.getLimits(iArm,&min,&max))
1921 return false;
1922
1923 (*this)[iTorso+iArm].setMin(CTRL_DEG2RAD*min);
1924 (*this)[iTorso+iArm].setMax(CTRL_DEG2RAD*max);
1925 }
1926
1927 return true;
1928}
1929
1930
1931/************************************************************************/
1932iCubFinger::iCubFinger() : iKinLimb(string("right_index"))
1933{
1934 allocate(getType());
1935}
1936
1937
1938/************************************************************************/
1939iCubFinger::iCubFinger(const string &_type) : iKinLimb(_type)
1940{
1941 allocate(_type);
1942}
1943
1944
1945/************************************************************************/
1950
1951
1952/************************************************************************/
1954{
1955 this->hand=finger.hand;
1956 this->finger=finger.finger;
1957 this->version=finger.version;
1958}
1959
1960
1961/************************************************************************/
1963{
1964 dispose();
1966 clone(finger);
1967
1968 return *this;
1969}
1970
1971
1972/************************************************************************/
1973void iCubFinger::allocate(const string &_type)
1974{
1975 size_t underscore=getType().find('_');
1976 if (underscore!=string::npos)
1977 {
1978 hand=getType().substr(0,underscore);
1979 finger=getType().substr(underscore+1,getType().length()-underscore-1);
1980
1981 underscore=finger.find('_');
1982 if (underscore!=string::npos)
1983 {
1984 version=finger.substr(underscore+1,finger.length()-underscore-1);
1985 finger=finger.substr(0,underscore);
1986 }
1987 else
1988 version="na";
1989 }
1990 else
1991 {
1992 hand="right";
1993 finger="index";
1994 version="na";
1995 }
1996
1997 type=hand+"_"+finger+"_"+version;
1998
1999 // reinforce hand info
2000 if (hand!="left")
2001 hand="right";
2002
2003 Matrix H0(4,4);
2004 if (finger=="thumb")
2005 {
2006 if (version=="a")
2007 {
2008 H0(0,0)=0.121132; H0(0,1)=0.043736; H0(0,2)=-0.991672; H0(0,3)=-0.025391770;
2009 H0(1,0)=-0.958978; H0(1,1)=0.263104; H0(1,2)=-0.105535; H0(1,3)=-0.011783901;
2010 H0(2,0)=0.256297; H0(2,1)=0.963776; H0(2,2)=0.073812; H0(2,3)=-0.0017018;
2011 H0(3,0)=0.0; H0(3,1)=0.0; H0(3,2)=0.0; H0(3,3)=1.0;
2012 }
2013 else
2014 {
2015 version="b";
2016 H0(0,0)=0.478469; H0(0,1)=0.063689; H0(0,2)=-0.875792; H0(0,3)=-0.024029759;
2017 H0(1,0)=-0.878095; H0(1,1)=0.039246; H0(1,2)=-0.476873; H0(1,3)=-0.01193433;
2018 H0(2,0)=0.004; H0(2,1)=0.997198; H0(2,2)=0.074703; H0(2,3)=-0.00168926;
2019 H0(3,0)=0.0; H0(3,1)=0.0; H0(3,2)=0.0; H0(3,3)=1.0;
2020 }
2021
2022 if (hand=="left")
2023 {
2024 H0(2,1)=-H0(2,1);
2025 H0(0,2)=-H0(0,2);
2026 H0(1,2)=-H0(1,2);
2027 H0(2,3)=-H0(2,3);
2028
2029 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, 0.0, 10.0*CTRL_DEG2RAD, 90.0*CTRL_DEG2RAD));
2030 pushLink(new iKinLink(0.0210, -0.0056, 0.0, 0.0, 0.0*CTRL_DEG2RAD, 0.0*CTRL_DEG2RAD));
2031 }
2032 else
2033 {
2034 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, 0.0, 10.0*CTRL_DEG2RAD, 90.0*CTRL_DEG2RAD));
2035 pushLink(new iKinLink(0.0210, 0.0056, 0.0, 0.0, 0.0*CTRL_DEG2RAD, 0.0*CTRL_DEG2RAD));
2036 }
2037
2038 pushLink(new iKinLink(0.0260, 0.0, 0.0, 0.0, 0.0*CTRL_DEG2RAD, 90.0*CTRL_DEG2RAD));
2039 pushLink(new iKinLink(0.0220, 0.0, 0.0, 0.0, 0.0*CTRL_DEG2RAD, 90.0*CTRL_DEG2RAD));
2040 pushLink(new iKinLink(0.0168, 0.0, -M_PI/2.0, 0.0, 0.0*CTRL_DEG2RAD, 90.0*CTRL_DEG2RAD));
2041
2042 // this is a dummy link
2043 blockLink(1,0.0);
2044 }
2045 else if (finger=="index")
2046 {
2047 H0(0,0)=0.898138; H0(0,1)=0.439714; H0(0,2)=0.0; H0(0,3)=0.00245549;
2048 H0(1,0)=-0.43804; H0(1,1)=0.89472; H0(1,2)=0.087156; H0(1,3)=-0.025320433;
2049 H0(2,0)=0.038324; H0(2,1)=-0.078278; H0(2,2)=0.996195; H0(2,3)=-0.010973325;
2050 H0(3,0)=0.0; H0(3,1)=0.0; H0(3,2)=0.0; H0(3,3)=1.0;
2051
2052 if (hand=="left")
2053 {
2054 H0(2,0)=-H0(2,0);
2055 H0(2,1)=-H0(2,1);
2056 H0(1,2)=-H0(1,2);
2057 H0(2,3)=-H0(2,3);
2058
2059 pushLink(new iKinLink(0.0148, 0.0, -M_PI/2.0, 0.0, 0.0, 20.0*CTRL_DEG2RAD));
2060 }
2061 else
2062 pushLink(new iKinLink(0.0148, 0.0, M_PI/2.0, 0.0, 0.0, 20.0*CTRL_DEG2RAD));
2063
2064 pushLink(new iKinLink(0.0259, 0.0, 0.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2065 pushLink(new iKinLink(0.0220, 0.0, 0.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2066 pushLink(new iKinLink(0.0168, 0.0, -M_PI/2.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2067 }
2068 else if (finger=="middle")
2069 {
2070 H0(0,0)=1.0; H0(0,1)=0.0; H0(0,2)=0.0; H0(0,3)=0.0178;
2071 H0(1,0)=0.0; H0(1,1)=0.0; H0(1,2)=-1.0; H0(1,3)=-0.00830233;
2072 H0(2,0)=0.0; H0(2,1)=1.0; H0(2,2)=0.0; H0(2,3)=-0.0118;
2073 H0(3,0)=0.0; H0(3,1)=0.0; H0(3,2)=0.0; H0(3,3)=1.0;
2074
2075 if (hand=="left")
2076 {
2077 H0(2,1)=-H0(2,1);
2078 H0(1,2)=-H0(1,2);
2079 H0(2,3)=-H0(2,3);
2080 }
2081
2082 pushLink(new iKinLink(0.0285, 0.0, 0.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2083 pushLink(new iKinLink(0.0240, 0.0, 0.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2084 pushLink(new iKinLink(0.0168, 0.0, -M_PI/2.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2085 }
2086 else if (finger=="ring")
2087 {
2088 H0(0,0)=0.9998; H0(0,1)=0.0192; H0(0,2)=0.0; H0(0,3)=0.001569230;
2089 H0(1,0)=0.0191; H0(1,1)=-0.9960; H0(1,2)=0.0872; H0(1,3)=0.007158757;
2090 H0(2,0)=0.0017; H0(2,1)=-0.0871; H0(2,2)=-0.9962; H0(2,3)=-0.011458935;
2091 H0(3,0)=0.0; H0(3,1)=0.0; H0(3,2)=0.0; H0(3,3)=1.0;
2092
2093 if (hand=="left")
2094 {
2095 H0(2,0)=-H0(2,0);
2096 H0(2,1)=-H0(2,1);
2097 H0(1,2)=-H0(1,2);
2098 H0(2,3)=-H0(2,3);
2099
2100 pushLink(new iKinLink(0.0148, 0.0, M_PI/2.0, -20.0*CTRL_DEG2RAD, 0.0, 20.0*CTRL_DEG2RAD));
2101 }
2102 else
2103 pushLink(new iKinLink(0.0148, 0.0, -M_PI/2.0, -20.0*CTRL_DEG2RAD, 0.0, 20.0*CTRL_DEG2RAD));
2104
2105 pushLink(new iKinLink(0.0259, 0.0, 0.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2106 pushLink(new iKinLink(0.0220, 0.0, 0.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2107 pushLink(new iKinLink(0.0168, 0.0, -M_PI/2.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2108 }
2109 else if (finger=="little")
2110 {
2111 H0(0,0)=0.9998; H0(0,1)=0.0192; H0(0,2)=0.0; H0(0,3)=-0.00042147;
2112 H0(1,0)=0.0191; H0(1,1)=-0.9960; H0(1,2)=0.0872; H0(1,3)=0.0232755;
2113 H0(2,0)=0.0017; H0(2,1)=-0.0871; H0(2,2)=-0.9962; H0(2,3)=-0.00956329;
2114 H0(3,0)=0.0; H0(3,1)=0.0; H0(3,2)=0.0; H0(3,3)=1.0;
2115
2116 if (hand=="left")
2117 {
2118 H0(2,0)=-H0(2,0);
2119 H0(2,1)=-H0(2,1);
2120 H0(1,2)=-H0(1,2);
2121 H0(2,3)=-H0(2,3);
2122
2123 pushLink(new iKinLink(0.0148, 0.0, M_PI/2.0, -20.0*CTRL_DEG2RAD, 0.0, 20.0*CTRL_DEG2RAD));
2124 }
2125 else
2126 pushLink(new iKinLink(0.0148, 0.0, -M_PI/2.0, -20.0*CTRL_DEG2RAD, 0.0, 20.0*CTRL_DEG2RAD));
2127
2128 pushLink(new iKinLink(0.0219, 0.0, 0.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2129 pushLink(new iKinLink(0.0190, 0.0, 0.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2130 pushLink(new iKinLink(0.0168, 0.0, -M_PI/2.0, 0.0, 0.0, 90.0*CTRL_DEG2RAD));
2131 }
2132
2133 if ((finger=="index") || (finger=="ring") || (finger=="little"))
2134 {
2135 // evaluate maximum fingers abduction using the default limits
2136 fingers_abduction_max = (*this)[0].getMax()*3.0*CTRL_RAD2DEG;
2137 }
2138
2139 setH0(H0);
2140}
2141
2142
2143/************************************************************************/
2144bool iCubFinger::alignJointsBounds(const deque<IControlLimits*> &lim)
2145{
2146 if (lim.size()<1)
2147 return false;
2148
2149 IControlLimits &limFinger=*lim[0];
2150 double min, max;
2151
2152 if (finger=="thumb")
2153 {
2154 if (!limFinger.getLimits(8,&min,&max))
2155 return false;
2156
2157 (*this)[0].setMin(CTRL_DEG2RAD*min);
2158 (*this)[0].setMax(CTRL_DEG2RAD*max);
2159
2160 if (!limFinger.getLimits(9,&min,&max))
2161 return false;
2162
2163 (*this)[2].setMin(CTRL_DEG2RAD*min);
2164 (*this)[2].setMax(CTRL_DEG2RAD*max);
2165
2166 if (!limFinger.getLimits(10,&min,&max))
2167 return false;
2168
2169 (*this)[3].setMin(CTRL_DEG2RAD*min);
2170 (*this)[3].setMax(CTRL_DEG2RAD*max/2.0);
2171 (*this)[4].setMin(CTRL_DEG2RAD*min);
2172 (*this)[4].setMax(CTRL_DEG2RAD*max/2.0);
2173 }
2174 else if (finger=="index")
2175 {
2176 if (!limFinger.getLimits(7,&min,&max))
2177 return false;
2178
2180
2181 (*this)[0].setMin(0.0);
2182 (*this)[0].setMax(CTRL_DEG2RAD*(max-min)/3.0);
2183
2184 if (!limFinger.getLimits(11,&min,&max))
2185 return false;
2186
2187 (*this)[1].setMin(CTRL_DEG2RAD*min);
2188 (*this)[1].setMax(CTRL_DEG2RAD*max);
2189
2190 if (!limFinger.getLimits(12,&min,&max))
2191 return false;
2192
2193 (*this)[2].setMin(CTRL_DEG2RAD*min);
2194 (*this)[2].setMax(CTRL_DEG2RAD*max/2.0);
2195 (*this)[3].setMin(CTRL_DEG2RAD*min);
2196 (*this)[3].setMax(CTRL_DEG2RAD*max/2.0);
2197 }
2198 else if (finger=="middle")
2199 {
2200 if (!limFinger.getLimits(13,&min,&max))
2201 return false;
2202
2203 (*this)[0].setMin(CTRL_DEG2RAD*min);
2204 (*this)[0].setMax(CTRL_DEG2RAD*max);
2205
2206 if (!limFinger.getLimits(14,&min,&max))
2207 return false;
2208
2209 (*this)[1].setMin(CTRL_DEG2RAD*min);
2210 (*this)[1].setMax(CTRL_DEG2RAD*max/2.0);
2211 (*this)[2].setMin(CTRL_DEG2RAD*min);
2212 (*this)[2].setMax(CTRL_DEG2RAD*max/2.0);
2213 }
2214 else if ((finger=="ring") || (finger=="little"))
2215 {
2216 if (!limFinger.getLimits(7,&min,&max))
2217 return false;
2218
2220
2221 (*this)[0].setMin(0.0);
2222 (*this)[0].setMax(CTRL_DEG2RAD*(max-min)/3.0);
2223
2224 if (!limFinger.getLimits(15,&min,&max))
2225 return false;
2226
2227 (*this)[1].setMin(CTRL_DEG2RAD*min);
2228 (*this)[1].setMax(CTRL_DEG2RAD*max/3.0);
2229 (*this)[2].setMin(CTRL_DEG2RAD*min);
2230 (*this)[2].setMax(CTRL_DEG2RAD*max/3.0);
2231 (*this)[3].setMin(CTRL_DEG2RAD*min);
2232 (*this)[3].setMax(CTRL_DEG2RAD*max/3.0);
2233 }
2234
2235 return true;
2236}
2237
2238
2239/************************************************************************/
2240bool iCubFinger::getChainJoints(const Vector &motorEncoders,
2241 Vector &chainJoints)
2242{
2243 if ((motorEncoders.length()!=9) && (motorEncoders.length()!=16))
2244 return false;
2245
2246 int offs=(motorEncoders.length()==16?7:0);
2247
2248 if (finger=="thumb")
2249 {
2250 chainJoints.resize(4);
2251 chainJoints[0]=motorEncoders[offs+1];
2252 chainJoints[1]=motorEncoders[offs+2];
2253 chainJoints[2]=motorEncoders[offs+3]/2.0;
2254 chainJoints[3]=chainJoints[2];
2255 }
2256 else if (finger=="index")
2257 {
2258 chainJoints.resize(4);
2259 chainJoints[0]=(fingers_abduction_max-motorEncoders[offs+0])/3.0;
2260 chainJoints[1]=motorEncoders[offs+4];
2261 chainJoints[2]=motorEncoders[offs+5]/2.0;
2262 chainJoints[3]=chainJoints[2];
2263 }
2264 else if (finger=="middle")
2265 {
2266 chainJoints.resize(3);
2267 chainJoints[0]=motorEncoders[offs+6];
2268 chainJoints[1]=motorEncoders[offs+7]/2.0;
2269 chainJoints[2]=chainJoints[1];
2270 }
2271 else if ((finger=="ring") || (finger=="little"))
2272 {
2273 chainJoints.resize(4);
2274 chainJoints[0]=(fingers_abduction_max-motorEncoders[offs+0])/3.0;
2275 chainJoints[1]=motorEncoders[offs+8]/3.0;
2276 chainJoints[3]=chainJoints[2]=chainJoints[1];
2277 }
2278 else
2279 return false;
2280
2281 return true;
2282}
2283
2284
2285/************************************************************************/
2286bool iCubFinger::getChainJoints(const Vector &motorEncoders,
2287 const Vector &jointEncoders,
2288 Vector &chainJoints,
2289 const Matrix &jointEncodersBounds)
2290{
2291 if (((motorEncoders.length()!=9) && (motorEncoders.length()!=16)) ||
2292 (jointEncoders.length()<15) || (jointEncodersBounds.cols()<2))
2293 return false;
2294
2295 int offs=(motorEncoders.length()==16?7:0);
2296
2297 Matrix bounds=jointEncodersBounds;
2298 if (bounds.rows()!=jointEncoders.length())
2299 {
2300 bounds=zeros((unsigned int)jointEncoders.length(),2);
2301 for (size_t r=0; r<jointEncoders.length(); r++)
2302 bounds(r,0)=255.0;
2303 }
2304
2305 if (finger=="thumb")
2306 {
2307 chainJoints.resize(4);
2308 chainJoints[0]=motorEncoders[offs+1];
2309 for (unsigned int i=1; i<chainJoints.length(); i++)
2310 {
2311 double c=0.0;
2312 double span=bounds(i-1,1)-bounds(i-1,0);
2313 if (span>0.0)
2314 c=std::min(1.0,std::max(0.0,(jointEncoders[i-1]-bounds(i-1,0))/span));
2315 else if (span<0.0)
2316 c=1.0-std::min(1.0,std::max(0.0,(bounds(i-1,1)-jointEncoders[i-1])/span));
2317 chainJoints[i]=CTRL_RAD2DEG*(c*((*this)(i).getMax()-(*this)(i).getMin())+(*this)(i).getMin());
2318 }
2319 }
2320 else if (finger=="index")
2321 {
2322 chainJoints.resize(4);
2323 chainJoints[0]=(fingers_abduction_max-motorEncoders[offs+0])/3.0;
2324 for (unsigned int i=1; i<chainJoints.length(); i++)
2325 {
2326 double c=0.0;
2327 double span=bounds(i+2,1)-bounds(i+2,0);
2328 if (span>0.0)
2329 c=std::min(1.0,std::max(0.0,(jointEncoders[i+2]-bounds(i+2,0))/span));
2330 else if (span<0.0)
2331 c=1.0-std::min(1.0,std::max(0.0,(bounds(i+2,1)-jointEncoders[i+2])/span));
2332 chainJoints[i]=CTRL_RAD2DEG*(c*((*this)(i).getMax()-(*this)(i).getMin())+(*this)(i).getMin());
2333 }
2334 }
2335 else if (finger=="middle")
2336 {
2337 chainJoints.resize(3);
2338 for (unsigned int i=0; i<chainJoints.length(); i++)
2339 {
2340 double c=0.0;
2341 double span=bounds(i+6,1)-bounds(i+6,0);
2342 if (span>0.0)
2343 c=std::min(1.0,std::max(0.0,(jointEncoders[i+6]-bounds(i+6,0))/span));
2344 else if (span<0.0)
2345 c=1.0-std::min(1.0,std::max(0.0,(bounds(i+6,1)-jointEncoders[i+6])/span));
2346 chainJoints[i]=CTRL_RAD2DEG*(c*((*this)(i).getMax()-(*this)(i).getMin())+(*this)(i).getMin());
2347 }
2348 }
2349 else if (finger=="ring")
2350 {
2351 chainJoints.resize(4);
2352 chainJoints[0]=(fingers_abduction_max-motorEncoders[offs+0])/3.0;
2353 for (unsigned int i=1; i<chainJoints.length(); i++)
2354 {
2355 double c=0.0;
2356 double span=bounds(i+8,1)-bounds(i+8,0);
2357 if (span>0.0)
2358 c=std::min(1.0,std::max(0.0,(jointEncoders[i+8]-bounds(i+8,0))/span));
2359 else if (span<0.0)
2360 c=1.0-std::min(1.0,std::max(0.0,(bounds(i+8,1)-jointEncoders[i+8])/span));
2361 chainJoints[i]=CTRL_RAD2DEG*(c*((*this)(i).getMax()-(*this)(i).getMin())+(*this)(i).getMin());
2362 }
2363 }
2364 else if (finger=="little")
2365 {
2366 chainJoints.resize(4);
2367 chainJoints[0]=(fingers_abduction_max-motorEncoders[offs+0])/3.0;
2368 for (unsigned int i=1; i<chainJoints.length(); i++)
2369 {
2370 double c=0.0;
2371 double span=bounds(i+11,1)-bounds(i+11,0);
2372 if (span>0.0)
2373 c=std::min(1.0,std::max(0.0,(jointEncoders[i+11]-bounds(i+11,0))/span));
2374 else if (span<0.0)
2375 c=1.0-std::min(1.0,std::max(0.0,(bounds(i+11,1)-jointEncoders[i+11])/span));
2376 chainJoints[i]=CTRL_RAD2DEG*(c*((*this)(i).getMax()-(*this)(i).getMin())+(*this)(i).getMin());
2377 }
2378 }
2379 else
2380 return false;
2381
2382 return true;
2383}
2384
2385
2386/************************************************************************/
2387iCubLeg::iCubLeg() : iKinLimb(string("right"))
2388{
2389 allocate(getType());
2390}
2391
2392
2393/************************************************************************/
2394iCubLeg::iCubLeg(const string &_type) : iKinLimb(_type)
2395{
2396 allocate(_type);
2397}
2398
2399
2400/************************************************************************/
2401void iCubLeg::allocate(const string &_type)
2402{
2403 string leg;
2404 size_t underscore=getType().find('_');
2405 if (underscore!=string::npos)
2406 {
2407 leg=getType().substr(0,underscore);
2408 version=iKinLimbVersion(getType().substr(underscore+2));
2409 }
2410 else
2411 {
2412 leg=getType();
2413 version=iKinLimbVersion("1.0");
2414 }
2415
2416 Matrix H0(4,4);
2417 H0.zero();
2418 H0(0,0)=1.0;
2419 H0(1,2)=1.0;
2420 H0(2,1)=-1.0;
2421 H0(2,3)=-0.1199;
2422 H0(3,3)=1.0;
2423
2424 if (leg=="right")
2425 {
2426 if (version<iKinLimbVersion("2.0"))
2427 {
2428 H0(1,3)=0.0681;
2429
2430 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, M_PI/2.0, -44.0*CTRL_DEG2RAD, 132.0*CTRL_DEG2RAD));
2431 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, M_PI/2.0, -119.0*CTRL_DEG2RAD, 17.0*CTRL_DEG2RAD));
2432 pushLink(new iKinLink( 0.0, 0.2236, -M_PI/2.0, -M_PI/2.0, -79.0*CTRL_DEG2RAD, 79.0*CTRL_DEG2RAD));
2433 pushLink(new iKinLink(-0.213, 0.0, M_PI, M_PI/2.0, -125.0*CTRL_DEG2RAD, 0.0*CTRL_DEG2RAD));
2434 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, 0.0, -42.0*CTRL_DEG2RAD, 21.0*CTRL_DEG2RAD));
2435 pushLink(new iKinLink(-0.041, 0.0, M_PI, 0.0, -24.0*CTRL_DEG2RAD, 24.0*CTRL_DEG2RAD));
2436 }
2437 else if (version<iKinLimbVersion("3.0"))
2438 {
2439 H0(1,3)=0.0681;
2440
2441 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, M_PI/2.0, -44.0*CTRL_DEG2RAD, 132.0*CTRL_DEG2RAD));
2442 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, M_PI/2.0, -119.0*CTRL_DEG2RAD, 17.0*CTRL_DEG2RAD));
2443 pushLink(new iKinLink(-0.0009175, 0.234545, -M_PI/2.0, -M_PI/2.0, -79.0*CTRL_DEG2RAD, 79.0*CTRL_DEG2RAD));
2444 pushLink(new iKinLink( -0.2005, 0.0, M_PI, M_PI/2.0, -125.0*CTRL_DEG2RAD, 0.0*CTRL_DEG2RAD));
2445 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, 0.0, -42.0*CTRL_DEG2RAD, 21.0*CTRL_DEG2RAD));
2446 pushLink(new iKinLink( -0.06805, 0.0035, M_PI, 0.0, -24.0*CTRL_DEG2RAD, 24.0*CTRL_DEG2RAD));
2447 }
2448 else // version>=3.0
2449 {
2450 H0.zero();
2451 H0(0,0)=1.0;
2452 H0(1,2)=1.0;
2453 H0(2,1)=-1.0;
2454 H0(0,3)=-0.0216;
2455 H0(1,3)=0.07365;
2456 H0(2,3)=-0.0605;
2457 H0(3,3)=1.0;
2458
2459 pushLink(new iKinLink( 0.009, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 125.0*CTRL_DEG2RAD));
2460 pushLink(new iKinLink( -0.015, 0.0106, M_PI/2.0, M_PI/2.0, 5.0*CTRL_DEG2RAD, 111.0*CTRL_DEG2RAD));
2461 pushLink(new iKinLink( 0.015, 0.2668, -M_PI/2.0, -M_PI/2.0, -62.5*CTRL_DEG2RAD, 62.5*CTRL_DEG2RAD));
2462 pushLink(new iKinLink(-0.255988, 0.0062, M_PI, M_PI/2.0, -100.0*CTRL_DEG2RAD, 0.0*CTRL_DEG2RAD));
2463 pushLink(new iKinLink( -0.035, 0.0, M_PI/2.0, 0.0, -40.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
2464 pushLink(new iKinLink( -0.0532, 0.0, M_PI, 0.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
2465 }
2466 }
2467 else // left
2468 {
2469 if (version<iKinLimbVersion("2.0"))
2470 {
2471 H0(1,3)=-0.0681;
2472
2473 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, M_PI/2.0, -44.0*CTRL_DEG2RAD, 132.0*CTRL_DEG2RAD));
2474 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, M_PI/2.0, -119.0*CTRL_DEG2RAD, 17.0*CTRL_DEG2RAD));
2475 pushLink(new iKinLink( 0.0, -0.2236, M_PI/2.0, -M_PI/2.0, -79.0*CTRL_DEG2RAD, 79.0*CTRL_DEG2RAD));
2476 pushLink(new iKinLink(-0.213, 0.0, M_PI, M_PI/2.0, -125.0*CTRL_DEG2RAD, 0.0*CTRL_DEG2RAD));
2477 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, 0.0, -42.0*CTRL_DEG2RAD, 21.0*CTRL_DEG2RAD));
2478 pushLink(new iKinLink(-0.041, 0.0, 0.0, 0.0, -24.0*CTRL_DEG2RAD, 24.0*CTRL_DEG2RAD));
2479 }
2480 else if (version<iKinLimbVersion("3.0"))
2481 {
2482 H0(1,3)=-0.0681;
2483
2484 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, M_PI/2.0, -44.0*CTRL_DEG2RAD, 132.0*CTRL_DEG2RAD));
2485 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, M_PI/2.0, -119.0*CTRL_DEG2RAD, 17.0*CTRL_DEG2RAD));
2486 pushLink(new iKinLink(-0.0009175, -0.234545, M_PI/2.0, -M_PI/2.0, -79.0*CTRL_DEG2RAD, 79.0*CTRL_DEG2RAD));
2487 pushLink(new iKinLink( -0.2005, 0.0, M_PI, M_PI/2.0, -125.0*CTRL_DEG2RAD, 0.0*CTRL_DEG2RAD));
2488 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, 0.0, -42.0*CTRL_DEG2RAD, 21.0*CTRL_DEG2RAD));
2489 pushLink(new iKinLink( -0.06805, -0.0035, 0.0, 0.0, -24.0*CTRL_DEG2RAD, 24.0*CTRL_DEG2RAD));
2490 }
2491 else // version>=3.0
2492 {
2493 H0.zero();
2494 H0(0,0)=1.0;
2495 H0(1,2)=1.0;
2496 H0(2,1)=-1.0;
2497 H0(0,3)=-0.0216;
2498 H0(1,3)=-0.07365;
2499 H0(2,3)=-0.0605;
2500 H0(3,3)=1.0;
2501
2502 pushLink(new iKinLink( 0.009, 0.0, -M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 125.0*CTRL_DEG2RAD));
2503 pushLink(new iKinLink( -0.015, -0.0106, -M_PI/2.0, M_PI/2.0, 5.0*CTRL_DEG2RAD, 111.0*CTRL_DEG2RAD));
2504 pushLink(new iKinLink( 0.015, -0.2668, M_PI/2.0, -M_PI/2.0, -62.5*CTRL_DEG2RAD, 62.5*CTRL_DEG2RAD));
2505 pushLink(new iKinLink(-0.255988, 0.0062, M_PI, M_PI/2.0, -100.0*CTRL_DEG2RAD, 0.0*CTRL_DEG2RAD));
2506 pushLink(new iKinLink( -0.035, 0.0, -M_PI/2.0, 0.0, -40.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
2507 pushLink(new iKinLink( -0.0532, 0.0, 0.0, 0.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
2508 }
2509 }
2510
2511 setH0(H0);
2512}
2513
2514
2515/************************************************************************/
2516bool iCubLeg::alignJointsBounds(const deque<IControlLimits*> &lim)
2517{
2518 if (lim.size()<1)
2519 return false;
2520
2521 IControlLimits &limLeg=*lim[0];
2522
2523 unsigned int iLeg;
2524 double min, max;
2525
2526 for (iLeg=0; iLeg<getN(); iLeg++)
2527 {
2528 if (!limLeg.getLimits(iLeg,&min,&max))
2529 return false;
2530
2531 (*this)[iLeg].setMin(CTRL_DEG2RAD*min);
2532 (*this)[iLeg].setMax(CTRL_DEG2RAD*max);
2533 }
2534
2535 return true;
2536}
2537
2538
2539/************************************************************************/
2540iCubEye::iCubEye() : iKinLimb(string("right"))
2541{
2542 allocate(getType());
2543}
2544
2545
2546/************************************************************************/
2547iCubEye::iCubEye(const string &_type) : iKinLimb(_type)
2548{
2549 allocate(_type);
2550}
2551
2552
2553/************************************************************************/
2554void iCubEye::allocate(const string &_type)
2555{
2556 string eye;
2557 size_t underscore=getType().find('_');
2558 if (underscore!=string::npos)
2559 {
2560 eye=getType().substr(0,underscore);
2561 version=iKinLimbVersion(getType().substr(underscore+2));
2562 }
2563 else
2564 {
2565 eye=getType();
2566 version=iKinLimbVersion("1.0");
2567 }
2568
2569 Matrix H0(4,4);
2570 H0.zero();
2571 H0(0,1)=-1.0;
2572 H0(1,2)=-1.0;
2573 H0(2,0)=1.0;
2574 H0(3,3)=1.0;
2575 setH0(H0);
2576
2577 if (eye=="right")
2578 {
2579 if (version<iKinLimbVersion("2.0"))
2580 {
2581 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
2582 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
2583 pushLink(new iKinLink(0.00231, -0.1933, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
2584 pushLink(new iKinLink( 0.033, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 30.0*CTRL_DEG2RAD));
2585 pushLink(new iKinLink( 0.0, 0.001, -M_PI/2.0, -M_PI/2.0, -70.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
2586 pushLink(new iKinLink( -0.054, 0.0825, -M_PI/2.0, M_PI/2.0, -55.0*CTRL_DEG2RAD, 55.0*CTRL_DEG2RAD));
2587 pushLink(new iKinLink( 0.0, 0.034, -M_PI/2.0, 0.0, -35.0*CTRL_DEG2RAD, 15.0*CTRL_DEG2RAD));
2588 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
2589 }
2590 else if (version==iKinLimbVersion("2.10"))
2591 {
2592 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
2593 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
2594 pushLink(new iKinLink( 0.0053, -0.2233, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
2595 pushLink(new iKinLink( 0.0110, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 30.0*CTRL_DEG2RAD));
2596 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, -70.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
2597 pushLink(new iKinLink(-0.0510, 0.08052, -M_PI/2.0, M_PI/2.0, -55.0*CTRL_DEG2RAD, 55.0*CTRL_DEG2RAD));
2598 pushLink(new iKinLink( 0.0, 0.034, -M_PI/2.0, 0.0, -35.0*CTRL_DEG2RAD, 15.0*CTRL_DEG2RAD));
2599 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
2600 }
2601 else if (version<iKinLimbVersion("3.0"))
2602 {
2603 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
2604 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
2605 pushLink(new iKinLink( 0.0, -0.2233, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
2606 pushLink(new iKinLink( 0.0095, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 30.0*CTRL_DEG2RAD));
2607 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, -70.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
2608 pushLink(new iKinLink(-0.0509, 0.08205, -M_PI/2.0, M_PI/2.0, -55.0*CTRL_DEG2RAD, 55.0*CTRL_DEG2RAD));
2609 pushLink(new iKinLink( 0.0, 0.034, -M_PI/2.0, 0.0, -35.0*CTRL_DEG2RAD, 15.0*CTRL_DEG2RAD));
2610 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
2611 }
2612 else // version=3.0
2613 {
2614 H0.zero();
2615 H0(0,2)=1.0;
2616 H0(1,1)=-1.0;
2617 H0(2,0)=1.0;
2618 H0(3,3)=1.0;
2619 setH0(H0);
2620
2621 pushLink(new iKinLink( 0.0725, 0.0, -M_PI/2.0, 0.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
2622 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -15.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
2623 pushLink(new iKinLink(-0.00486151, -0.26377, -M_PI/2.0, M_PI, -40.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
2624 pushLink(new iKinLink( 0.0095, 0.0, M_PI/2.0, M_PI/2.0, -30.0*CTRL_DEG2RAD, 22.0*CTRL_DEG2RAD));
2625 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
2626 pushLink(new iKinLink( -0.0509, 0.08205, -M_PI/2.0, M_PI/2.0, -45.0*CTRL_DEG2RAD, 45.0*CTRL_DEG2RAD));
2627 pushLink(new iKinLink( 0.0, 0.034, -M_PI/2.0, 0.0, -35.0*CTRL_DEG2RAD, 15.0*CTRL_DEG2RAD));
2628 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
2629 }
2630 }
2631 else // left
2632 {
2633 if (version<iKinLimbVersion("2.0"))
2634 {
2635 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
2636 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
2637 pushLink(new iKinLink(0.00231, -0.1933, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
2638 pushLink(new iKinLink( 0.033, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 30.0*CTRL_DEG2RAD));
2639 pushLink(new iKinLink( 0.0, 0.001, -M_PI/2.0, -M_PI/2.0, -70.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
2640 pushLink(new iKinLink( -0.054, 0.0825, -M_PI/2.0, M_PI/2.0, -55.0*CTRL_DEG2RAD, 55.0*CTRL_DEG2RAD));
2641 pushLink(new iKinLink( 0.0, -0.034, -M_PI/2.0, 0.0, -35.0*CTRL_DEG2RAD, 15.0*CTRL_DEG2RAD));
2642 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
2643 }
2644 else if (version==iKinLimbVersion("2.10"))
2645 {
2646 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
2647 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
2648 pushLink(new iKinLink( 0.0053, -0.2233, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
2649 pushLink(new iKinLink( 0.0110, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 30.0*CTRL_DEG2RAD));
2650 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, -70.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
2651 pushLink(new iKinLink(-0.0510, 0.08052, -M_PI/2.0, M_PI/2.0, -55.0*CTRL_DEG2RAD, 55.0*CTRL_DEG2RAD));
2652 pushLink(new iKinLink( 0.0, -0.034, -M_PI/2.0, 0.0, -35.0*CTRL_DEG2RAD, 15.0*CTRL_DEG2RAD));
2653 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
2654 }
2655 else if (version<iKinLimbVersion("3.0"))
2656 {
2657 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
2658 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
2659 pushLink(new iKinLink( 0.0, -0.2233, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
2660 pushLink(new iKinLink( 0.0095, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 30.0*CTRL_DEG2RAD));
2661 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, -70.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
2662 pushLink(new iKinLink(-0.0509, 0.08205, -M_PI/2.0, M_PI/2.0, -55.0*CTRL_DEG2RAD, 55.0*CTRL_DEG2RAD));
2663 pushLink(new iKinLink( 0.0, -0.034, -M_PI/2.0, 0.0, -35.0*CTRL_DEG2RAD, 15.0*CTRL_DEG2RAD));
2664 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
2665 }
2666 else // version=3.0
2667 {
2668 H0.zero();
2669 H0(0,2)=1.0;
2670 H0(1,1)=-1.0;
2671 H0(2,0)=1.0;
2672 H0(3,3)=1.0;
2673 setH0(H0);
2674
2675 pushLink(new iKinLink( 0.0725, 0.0, -M_PI/2.0, 0.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
2676 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -15.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
2677 pushLink(new iKinLink(-0.00486151, -0.26377, -M_PI/2.0, M_PI, -40.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
2678 pushLink(new iKinLink( 0.0095, 0.0, M_PI/2.0, M_PI/2.0, -30.0*CTRL_DEG2RAD, 22.0*CTRL_DEG2RAD));
2679 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
2680 pushLink(new iKinLink( -0.0509, 0.08205, -M_PI/2.0, M_PI/2.0, -45.0*CTRL_DEG2RAD, 45.0*CTRL_DEG2RAD));
2681 pushLink(new iKinLink( 0.0, -0.034, -M_PI/2.0, 0.0, -35.0*CTRL_DEG2RAD, 15.0*CTRL_DEG2RAD));
2682 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -50.0*CTRL_DEG2RAD, 50.0*CTRL_DEG2RAD));
2683 }
2684 }
2685
2686 // event driven cameras virtual image plane
2687 if (version==iKinLimbVersion("2.8"))
2688 {
2689 Matrix HN=yarp::math::eye(4, 4);
2690 HN(2, 3)=-0.01;
2691 setHN(HN);
2692 }
2693 // 4k cameras image plane
2694 else if (version==iKinLimbVersion("2.10"))
2695 {
2696 Matrix HN=yarp::math::eye(4, 4);
2697 HN(2, 3)=-9.83e-3;
2698 setHN(HN);
2699 }
2700
2701 blockLink(0,0.0);
2702 blockLink(1,0.0);
2703 blockLink(2,0.0);
2704}
2705
2706
2707/************************************************************************/
2708bool iCubEye::alignJointsBounds(const deque<IControlLimits*> &lim)
2709{
2710 if (lim.size()<2)
2711 return false;
2712
2713 IControlLimits &limTorso=*lim[0];
2714 IControlLimits &limHead =*lim[1];
2715
2716 unsigned int iTorso;
2717 unsigned int iHead;
2718 double min, max;
2719
2720 for (iTorso=0; iTorso<3; iTorso++)
2721 {
2722 if (!limTorso.getLimits(iTorso,&min,&max))
2723 return false;
2724
2725 if (version<iKinLimbVersion("3.0"))
2726 {
2727 (*this)[2-iTorso].setMin(CTRL_DEG2RAD*min);
2728 (*this)[2-iTorso].setMax(CTRL_DEG2RAD*max);
2729 }
2730 else
2731 {
2732 (*this)[iTorso].setMin(CTRL_DEG2RAD*min);
2733 (*this)[iTorso].setMax(CTRL_DEG2RAD*max);
2734 }
2735 }
2736
2737 for (iHead=0; iHead<getN()-iTorso; iHead++)
2738 {
2739 if (!limHead.getLimits(iHead,&min,&max))
2740 return false;
2741
2742 (*this)[iTorso+iHead].setMin(CTRL_DEG2RAD*min);
2743 (*this)[iTorso+iHead].setMax(CTRL_DEG2RAD*max);
2744 }
2745
2746 return true;
2747}
2748
2749
2750/************************************************************************/
2752{
2753 allocate(getType());
2754}
2755
2756
2757/************************************************************************/
2758iCubEyeNeckRef::iCubEyeNeckRef(const string &_type) : iCubEye(_type)
2759{
2760 allocate(_type);
2761}
2762
2763
2764/************************************************************************/
2765void iCubEyeNeckRef::allocate(const string &_type)
2766{
2767 rmLink(0);
2768 rmLink(0);
2769 rmLink(0);
2770
2771 delete linkList[0];
2772 delete linkList[1];
2773 delete linkList[2];
2774
2775 linkList.erase(linkList.begin(),linkList.begin()+2);
2776}
2777
2778
2779/************************************************************************/
2781{
2782 allocate(getType());
2783}
2784
2785
2786/************************************************************************/
2787iCubHeadCenter::iCubHeadCenter(const string &_type) : iCubEye(_type)
2788{
2789 allocate(_type);
2790}
2791
2792
2793/************************************************************************/
2794void iCubHeadCenter::allocate(const string &_type)
2795{
2796 // change DH parameters
2797 (*this)[getN()-2].setD(0.0);
2798
2799 // block last two links
2800 blockLink(getN()-2,0.0);
2801 blockLink(getN()-1,0.0);
2802}
2803
2804
2805/************************************************************************/
2810
2811
2812/************************************************************************/
2814{
2815 allocate(_type);
2816}
2817
2818
2819/************************************************************************/
2820void iCubInertialSensor::allocate(const string &_type)
2821{
2822 if (getType().size()>1)
2823 version=iKinLimbVersion(getType().substr(1));
2824 else
2825 version=iKinLimbVersion("1.0");
2826
2827 Matrix H0(4,4);
2828 H0.zero();
2829 H0(3,3)=1.0;
2830
2831 if (version<iKinLimbVersion("2.0"))
2832 {
2833 H0(0,1)=-1.0;
2834 H0(1,2)=-1.0;
2835 H0(2,0)=1.0;
2836
2837 type="v1";
2838 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
2839 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
2840 pushLink(new iKinLink(0.00231, -0.1933, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
2841 pushLink(new iKinLink( 0.033, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 30.0*CTRL_DEG2RAD));
2842 pushLink(new iKinLink( 0.0, 0.001, -M_PI/2.0, -M_PI/2.0, -70.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
2843 pushLink(new iKinLink( 0.0225, 0.1005, -M_PI/2.0, M_PI/2.0, -55.0*CTRL_DEG2RAD, 55.0*CTRL_DEG2RAD));
2844 }
2845 else if (version==iKinLimbVersion("2.10"))
2846 {
2847 H0(0,1)=-1.0;
2848 H0(1,2)=-1.0;
2849 H0(2,0)=1.0;
2850
2851 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
2852 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
2853 pushLink(new iKinLink( 0.0, -0.2233, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
2854 pushLink(new iKinLink( 0.0110, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 30.0*CTRL_DEG2RAD));
2855 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, -70.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
2856 pushLink(new iKinLink( 0.0055, 0.1690, M_PI/2.0, 0.0, -55.0*CTRL_DEG2RAD, 55.0*CTRL_DEG2RAD));
2857 }
2858 else if (version<iKinLimbVersion("3.0"))
2859 {
2860 H0(0,1)=-1.0;
2861 H0(1,2)=-1.0;
2862 H0(2,0)=1.0;
2863
2864 pushLink(new iKinLink( 0.032, 0.0, M_PI/2.0, 0.0, -22.0*CTRL_DEG2RAD, 84.0*CTRL_DEG2RAD));
2865 pushLink(new iKinLink( 0.0, -0.0055, M_PI/2.0, -M_PI/2.0, -39.0*CTRL_DEG2RAD, 39.0*CTRL_DEG2RAD));
2866 pushLink(new iKinLink( 0.0, -0.2233, -M_PI/2.0, -M_PI/2.0, -59.0*CTRL_DEG2RAD, 59.0*CTRL_DEG2RAD));
2867 pushLink(new iKinLink( 0.0095, 0.0, M_PI/2.0, M_PI/2.0, -40.0*CTRL_DEG2RAD, 30.0*CTRL_DEG2RAD));
2868 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, -70.0*CTRL_DEG2RAD, 60.0*CTRL_DEG2RAD));
2869 pushLink(new iKinLink( 0.0185, 0.1108, -M_PI/2.0, M_PI/2.0, -55.0*CTRL_DEG2RAD, 55.0*CTRL_DEG2RAD));
2870 }
2871 else // version=3.0
2872 {
2873 H0(0,2)=1.0;
2874 H0(1,1)=-1.0;
2875 H0(2,0)=1.0;
2876
2877 pushLink(new iKinLink( 0.0725, 0.0, -M_PI/2.0, 0.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
2878 pushLink(new iKinLink( 0.0, 0.0, M_PI/2.0, -M_PI/2.0, -15.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
2879 pushLink(new iKinLink(-0.00486151, -0.26377, -M_PI/2.0, M_PI, -40.0*CTRL_DEG2RAD, 40.0*CTRL_DEG2RAD));
2880 pushLink(new iKinLink( 0.0095, 0.0, M_PI/2.0, M_PI/2.0, -30.0*CTRL_DEG2RAD, 22.0*CTRL_DEG2RAD));
2881 pushLink(new iKinLink( 0.0, 0.0, -M_PI/2.0, -M_PI/2.0, -20.0*CTRL_DEG2RAD, 20.0*CTRL_DEG2RAD));
2882 pushLink(new iKinLink( 0.0185, 0.1108, -M_PI/2.0, M_PI/2.0, -45.0*CTRL_DEG2RAD, 45.0*CTRL_DEG2RAD));
2883 }
2884
2885 setH0(H0);
2886
2887 // T_nls: see https://icub-tech-iit.github.io/documentation/icub_kinematics/icub-forward-kinematics/icub-forward-kinematics-imu/
2888 Matrix HN(4,4);
2889 HN.zero();
2890 HN(0,0)=1.0;
2891 HN(2,1)=1.0;
2892 HN(1,2)=-1.0;
2893 HN(2,3)=0.0066;
2894 HN(3,3)=1.0;
2895 setHN(HN);
2896
2897 if (version>iKinLimbVersion("2.0"))
2898 {
2899 Matrix HN=eye(4,4);
2900 HN(0,3)=0.0087;
2901 HN(1,3)=0.01795;
2902 HN(2,3)=-0.0105;
2903 setHN(getHN()*HN);
2904 }
2905
2906 // further displacement for >= 2.6
2907 if (version>=iKinLimbVersion("2.6") && version!=iKinLimbVersion("2.10"))
2908 {
2909 Matrix HN=zeros(4,4);
2910 HN(0,3)=0.0323779;
2911 HN(1,3)=-0.0139537;
2912 HN(2,3)=0.072;
2913 HN(1,0)=1.0;
2914 HN(0,1)=1.0;
2915 HN(2,2)=-1.0;
2916 HN(3,3)=1.0;
2917 setHN(getHN()*HN);
2918 }
2919
2920 // new HN for version 2.10 (see https://github.com/icub-tech-iit/study-icub-headedge/issues/230#issuecomment-3279162879)
2921 else if (version==iKinLimbVersion("2.10"))
2922 {
2923 Matrix HN=zeros(4,4);
2924 HN(0,0)=-1.0;
2925 HN(1,2)=-1.0;
2926 HN(2,1)=-1.0;
2927 HN(2,3)=0.00345;
2928 HN(3,3)=1.0;
2929 setHN(HN);
2930 }
2931}
2932
2933
2934/************************************************************************/
2935bool iCubInertialSensor::alignJointsBounds(const deque<IControlLimits*> &lim)
2936{
2937 if (lim.size()<2)
2938 return false;
2939
2940 IControlLimits &limTorso=*lim[0];
2941 IControlLimits &limHead =*lim[1];
2942
2943 unsigned int iTorso;
2944 unsigned int iHead;
2945 double min, max;
2946
2947 for (iTorso=0; iTorso<3; iTorso++)
2948 {
2949 if (!limTorso.getLimits(iTorso,&min,&max))
2950 return false;
2951
2952 if (version<iKinLimbVersion("3.0"))
2953 {
2954 (*this)[2-iTorso].setMin(CTRL_DEG2RAD*min);
2955 (*this)[2-iTorso].setMax(CTRL_DEG2RAD*max);
2956 }
2957 else
2958 {
2959 (*this)[iTorso].setMin(CTRL_DEG2RAD*min);
2960 (*this)[iTorso].setMax(CTRL_DEG2RAD*max);
2961 }
2962 }
2963
2964 // only the neck
2965 for (iHead=0; iHead<3; iHead++)
2966 {
2967 if (!limHead.getLimits(iHead,&min,&max))
2968 return false;
2969
2970 (*this)[iTorso+iHead].setMin(CTRL_DEG2RAD*min);
2971 (*this)[iTorso+iHead].setMax(CTRL_DEG2RAD*max);
2972 }
2973
2974 return true;
2975}
2976
2977
2978/************************************************************************/
2983
2984
2985/************************************************************************/
2987{
2988 allocate(_type);
2989}
2990
2991
2992/************************************************************************/
2993void iCubInertialSensorWaist::allocate(const string &_type)
2994{
2995 if (getType().size()>1)
2996 version=iKinLimbVersion(getType().substr(1));
2997 else
2998 version=iKinLimbVersion("2.7");
2999
3000 Matrix H0(4,4);
3001 H0.zero();
3002
3003 H0(0,1)=-0.5;
3004 H0(0,2)=0.866025;
3005 H0(0,3)=0.0906529;
3006
3007 H0(1,0)=-1.0;
3008 H0(1,3)=-0.011;
3009
3010 H0(2,1)=-0.866025;
3011 H0(2,2)=-0.5;
3012 H0(2,3)=-0.112309;
3013
3014 H0(3,3)=1.0;
3015 setH0(H0);
3016}
#define CTRL_RAD2DEG
Definition XSensMTx.cpp:25
#define CTRL_DEG2RAD
Definition XSensMTx.cpp:26
#define M_PI
Definition XSensMTx.cpp:24
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:1774
iCubArm()
Default constructor.
Definition iKinFwd.cpp:1760
iKinLimbVersion version
Definition iKinFwd.h:1195
virtual bool alignJointsBounds(const std::deque< yarp::dev::IControlLimits * > &lim)
Alignes the Arm joints bounds with current values set aboard the iCub.
Definition iKinFwd.cpp:1889
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:2765
iCubEyeNeckRef()
Default constructor.
Definition iKinFwd.cpp:2751
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:2554
iKinLimbVersion version
Definition iKinFwd.h:1387
virtual bool alignJointsBounds(const std::deque< yarp::dev::IControlLimits * > &lim)
Alignes the Eye joints bounds with current values set aboard the iCub.
Definition iKinFwd.cpp:2708
iCubEye()
Default constructor.
Definition iKinFwd.cpp:2540
virtual bool alignJointsBounds(const std::deque< yarp::dev::IControlLimits * > &lim)
Alignes the finger joints bounds with current values set aboard the iCub.
Definition iKinFwd.cpp:2144
virtual void clone(const iCubFinger &finger)
Definition iKinFwd.cpp:1953
iCubFinger()
Default constructor.
Definition iKinFwd.cpp:1932
virtual bool getChainJoints(const yarp::sig::Vector &motorEncoders, yarp::sig::Vector &chainJoints)
Retrieves the vector of actual finger's joint values (to be used in conjuction with the iKinLimb meth...
iCubFinger & operator=(const iCubFinger &finger)
Copies a Finger object into the current one.
Definition iKinFwd.cpp:1962
std::string version
Definition iKinFwd.h:1237
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:1973
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:2794
iCubHeadCenter()
Default constructor.
Definition iKinFwd.cpp:2780
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:2993
iCubInertialSensorWaist()
Default constructor.
Definition iKinFwd.cpp:2979
iCubInertialSensor()
Default constructor.
Definition iKinFwd.cpp:2806
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:2820
virtual bool alignJointsBounds(const std::deque< yarp::dev::IControlLimits * > &lim)
Alignes the Inertial Sensor joints bounds with current values set aboard the iCub.
Definition iKinFwd.cpp:2935
iCubLeg()
Default constructor.
Definition iKinFwd.cpp:2387
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:2401
iKinLimbVersion version
Definition iKinFwd.h:1350
virtual bool alignJointsBounds(const std::deque< yarp::dev::IControlLimits * > &lim)
Alignes the Leg joints bounds with current values set aboard the iCub.
Definition iKinFwd.cpp:2516
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:1691
iCubTorso()
Default constructor.
Definition iKinFwd.cpp:1677
virtual bool alignJointsBounds(const std::deque< yarp::dev::IControlLimits * > &lim)
Alignes the Torso joints bounds with current values set aboard the iCub.
Definition iKinFwd.cpp:1728
iKinLimbVersion version
Definition iKinFwd.h:1159
yarp::sig::Vector curr_q
Definition iKinFwd.h:361
void popLink()
Removes a Link from the bottom of the Chain.
Definition iKinFwd.cpp:375
yarp::sig::Matrix getHN() const
Returns HN, the rigid roto-translation matrix from the Nth frame to the end-effector.
Definition iKinFwd.h:578
yarp::sig::Vector Position(const unsigned int i)
Returns the 3D position coordinates of ith Link.
Definition iKinFwd.cpp:842
bool setHN(const yarp::sig::Matrix &_HN)
Sets HN, the rigid roto-translation matrix from the Nth frame to the end-effector.
Definition iKinFwd.cpp:580
void prepareForHessian()
Prepares computation for a successive call to fastHessian_ij().
Definition iKinFwd.cpp:1102
yarp::sig::Matrix GeoJacobian()
Returns the geometric Jacobian of the end-effector.
Definition iKinFwd.cpp:1048
yarp::sig::Vector EndEffPosition()
Returns the 3D coordinates of end-effector position.
Definition iKinFwd.cpp:894
yarp::sig::Matrix hess_J
Definition iKinFwd.h:369
yarp::sig::Vector d2RotAng(const yarp::sig::Matrix &R, const yarp::sig::Matrix &dRi, const yarp::sig::Matrix &dRj, const yarp::sig::Matrix &d2R)
Definition iKinFwd.cpp:686
yarp::sig::Vector Hessian_ij(const unsigned int i, const unsigned int j)
Returns the 6x1 vector where is the forward kinematic function and is the DOF couple.
Definition iKinFwd.cpp:1094
yarp::sig::Matrix H0
Definition iKinFwd.h:359
void pushLink(iKinLink &l)
Adds a Link at the bottom of the Chain.
Definition iKinFwd.cpp:343
bool isLinkBlocked(const unsigned int i)
Queries whether the ith Link is blocked.
Definition iKinFwd.cpp:483
iKinChain & operator--(int)
Removes a Link from the bottom of the Chain.
Definition iKinFwd.cpp:385
yarp::sig::Matrix AnaJacobian(const unsigned int i, unsigned int col)
Returns the analitical Jacobian of the ith link.
Definition iKinFwd.cpp:911
bool releaseLink(const unsigned int i)
Releases the ith Link.
Definition iKinFwd.cpp:463
virtual void clone(const iKinChain &c)
Definition iKinFwd.cpp:264
void clear()
Removes all Links.
Definition iKinFwd.cpp:353
void setAllLinkVerbosity(unsigned int _verbose)
Sets the verbosity level of all Links belonging to the Chain.
Definition iKinFwd.cpp:506
virtual void build()
Definition iKinFwd.cpp:514
unsigned int verbose
Definition iKinFwd.h:358
yarp::sig::Vector fastHessian_ij(const unsigned int i, const unsigned int j)
Returns the 6x1 vector where is the forward kinematic function and is the DOF couple.
Definition iKinFwd.cpp:1117
bool setBlockingValue(const unsigned int i, double Ang)
Changes the value of the ith blocked Link.
Definition iKinFwd.cpp:414
void setVerbosity(unsigned int _verbose)
Sets the verbosity level of the Chain.
Definition iKinFwd.h:537
void setConstraint(unsigned int i, bool _constrained)
Sets the constraint status of ith link.
Definition iKinFwd.h:516
iKinChain & operator=(const iKinChain &c)
Copies a Chain object into the current one.
Definition iKinFwd.cpp:290
bool rmLink(const unsigned int i)
Removes the ith Link from the Chain.
Definition iKinFwd.cpp:321
std::deque< unsigned int > hash_dof
Definition iKinFwd.h:367
iKinChain()
Default constructor.
Definition iKinFwd.cpp:256
yarp::sig::Vector EndEffPose(const bool axisRep=true)
Returns the coordinates of end-effector.
Definition iKinFwd.cpp:850
yarp::sig::Vector Pose(const unsigned int i, const bool axisRep=true)
Returns the coordinates of ith Link.
Definition iKinFwd.cpp:803
bool addLink(const unsigned int i, iKinLink &l)
Adds a Link at the position ith within the Chain.
Definition iKinFwd.cpp:299
yarp::sig::Vector getAng()
Returns the current free joint angles values.
Definition iKinFwd.cpp:611
yarp::sig::Vector setAng(const yarp::sig::Vector &q)
Sets the free joint angles to values of q[i].
std::deque< unsigned int > hash
Definition iKinFwd.h:366
yarp::sig::Matrix getH()
Returns the rigid roto-translation matrix from the root reference frame to the end-effector frame in ...
Definition iKinFwd.cpp:778
yarp::sig::Vector dRotAng(const yarp::sig::Matrix &R, const yarp::sig::Matrix &dR)
Definition iKinFwd.cpp:673
virtual ~iKinChain()
Destructor.
Definition iKinFwd.cpp:1300
std::deque< iKinLink * > quickList
Definition iKinFwd.h:364
yarp::sig::Matrix DJacobian(const yarp::sig::Vector &dq)
Compute the time derivative of the geometric Jacobian.
unsigned int N
Definition iKinFwd.h:356
yarp::sig::Vector RotAng(const yarp::sig::Matrix &R)
Definition iKinFwd.cpp:659
unsigned int getN() const
Returns the number of Links belonging to the Chain.
Definition iKinFwd.h:549
yarp::sig::Matrix hess_Jlnk
Definition iKinFwd.h:370
bool blockLink(const unsigned int i, double Ang)
Blocks the ith Link at the a certain value of its joint angle.
Definition iKinFwd.cpp:394
bool setH0(const yarp::sig::Matrix &_H0)
Sets H0, the rigid roto-translation matrix from the root reference frame to the 0th frame.
Definition iKinFwd.cpp:562
virtual void dispose()
Definition iKinFwd.cpp:1307
unsigned int DOF
Definition iKinFwd.h:357
void setAllConstraints(bool _constrained)
Sets the constraint status of all chain links.
Definition iKinFwd.cpp:498
yarp::sig::Matrix HN
Definition iKinFwd.h:360
iKinChain & operator<<(iKinLink &l)
Adds a Link at the bottom of the Chain.
Definition iKinFwd.cpp:366
std::deque< iKinLink * > allList
Definition iKinFwd.h:363
A class for defining the versions of the iCub limbs.
Definition iKinFwd.h:1045
iKinLimbVersion operator-(const iKinLimbVersion &v) const
Overloaded - operator.
Definition iKinFwd.cpp:1666
iKinLimbVersion & operator=(const iKinLimbVersion &v)
Overloaded assignment operator.
Definition iKinFwd.cpp:1610
unsigned long int v_minor
Definition iKinFwd.h:1048
bool operator==(const iKinLimbVersion &v) const
Overloaded == operator.
Definition iKinFwd.cpp:1638
bool operator<=(const iKinLimbVersion &v) const
Overloaded <= operator.
Definition iKinFwd.cpp:1652
bool operator>=(const iKinLimbVersion &v) const
Overloaded >=</=> operator.
Definition iKinFwd.cpp:1659
bool operator!=(const iKinLimbVersion &v) const
Overloaded != operator.
Definition iKinFwd.cpp:1645
unsigned long int get_minor() const
Return the minor version.
Definition iKinFwd.cpp:1594
unsigned long int get_major() const
Return the major version.
Definition iKinFwd.cpp:1587
bool operator>(const iKinLimbVersion &v) const
Overloaded > operator.
Definition iKinFwd.cpp:1631
bool operator<(const iKinLimbVersion &v) const
Overloaded < operator.
Definition iKinFwd.cpp:1619
unsigned long int v_major
Definition iKinFwd.h:1047
iKinLimbVersion()
Default Constructor.
Definition iKinFwd.cpp:1547
std::string get_version() const
Return the version string.
Definition iKinFwd.cpp:1601
std::deque< iKinLink * > linkList
Definition iKinFwd.h:875
virtual void getMatrixFromProperties(const yarp::os::Property &options, const std::string &tag, yarp::sig::Matrix &H)
Definition iKinFwd.cpp:1351
virtual void dispose()
Definition iKinFwd.cpp:1535
virtual ~iKinLimb()
Destructor.
Definition iKinFwd.cpp:1509
bool rmLink(const unsigned int i)
Definition iKinFwd.h:895
bool fromLinksProperties(const yarp::os::Property &options)
Initializes the Limb from a list of properties wherein links parameters are specified.
Definition iKinFwd.cpp:1387
std::string getType() const
Returns the Limb type as a string.
Definition iKinFwd.h:1018
iKinChain & operator=(const iKinChain &c)
Definition iKinFwd.h:889
virtual void allocate(const std::string &_type)
Definition iKinFwd.cpp:1516
bool toLinksProperties(yarp::os::Property &options)
Provides the links attributes listed in a property object.
Definition iKinFwd.cpp:1443
void pushLink(iKinLink &l)
Definition iKinFwd.h:896
virtual void setMatrixToProperties(yarp::os::Property &options, const std::string &tag, yarp::sig::Matrix &H)
Definition iKinFwd.cpp:1374
std::string type
Definition iKinFwd.h:876
iKinLimb()
Default constructor.
Definition iKinFwd.cpp:1315
virtual void clone(const iKinLimb &limb)
Definition iKinFwd.cpp:1523
zeros(2, 2) eye(2
int n
yarp::sig::Vector cross(const yarp::sig::Matrix &A, int colA, const yarp::sig::Matrix &B, int colB)
Returns the cross product between two vectors given in the form: matrix(:,col).
void notImplemented(const unsigned int verbose)
Definition iKinFwd.cpp:31
A
Definition sine.m:16
degrees offset
Definition sine.m:4