versor  3.0
C++11 library for Geometric algebra
vsr_chain.h
1 /*
2  * Chain.h
3  * VERSOR
4  *
5  * Created by xpc on 9/29/10.
6  * Copyright 2010 wolftype. All rights reserved.
7  *
8 
9 3D KINEMATIC CHAIN can be closed or open (robot arm)
10 
11  > if one end is fixed, it is a MECHANISM
12 
13  > if a MECHANISM transmits power it is a MACHINE
14 
15 */
16 
17 #ifndef VSR_CHAIN_H_INCLUDED
18 #define VSR_CHAIN_H_INCLUDED
19 
20 #include "vsr_cga3D_frame.h"
21 #include "vsr_twist.h"
22 #include <map>
23 #include <string>
24 
25 namespace vsr{ namespace cga {
26 
27  using std::map;
28 
29 /* namespace Kinematic { */
30 /* enum Type{ */
31 /* REVOLUTE, PRISMATIC, CYLINDRICAL, HELICAL, PLANAR, SPHERICAL */
32 /* } */
33 /* } */
34 
35 struct Joint : public Frame {
36 
37  enum Type{
38  REVOLUTE, PRISMATIC, CYLINDRICAL, HELICAL, PLANAR, SPHERICAL
39  };
40 
41 // static map<string, Type> LowerPairMap;
42 
43 
44  Type type;
45 
46  Joint( Type t = Joint::SPHERICAL, const Frame& f = Frame() ) : Frame(f), type(t) {}
47 
48  virtual Frame operator()() const = 0;
49 
50 };
51 
52 /* map<string,Joint::Type> Joint::LowerPairMap = { */
53 /* make_pair("R",Joint::REVOLUTE), */
54 /* make_pair("P", Joint::PRISMATIC), */
55 /* make_pair("C", Joint::CYLINDRICAL), */
56 /* make_pair("H", Joint::HELICAL), */
57 /* make_pair("S", Joint::SPHERICAL) , */
58 /* make_pair("X", Joint::PLANAR) }; */
59 
60 
61 struct Prismatic {
62  Prismatic() : mFrame() {}
63  Frame operator() (VSR_PRECISION amt) { return mFrame.moveZ(amt); }//pos() = frame.pos().trs ( frame.z() * amt ) ; }
64  Frame mFrame;
65 };
66 
67 struct Revolute : public Joint {
68  Revolute( const Frame& f = Frame() ) : Joint ( Joint::REVOLUTE, f) {}
69  Frame operator() (VSR_PRECISION amt) { mAmt = amt; return rotXY( amt ); }
70  virtual Frame operator()() const { return rotXY( mAmt ); }
71  VSR_PRECISION mAmt;
72 };
73 
74 struct Cylindrical {
75  Cylindrical() : mFrame() {}
76  Frame operator() (VSR_PRECISION slide, VSR_PRECISION rotate) { return mFrame.moveZ(slide).rotXY( rotate ); }
77  Frame mFrame;
78 };
79 
80 struct Helical {
81  Helical( VSR_PRECISION period = PI, VSR_PRECISION pitch = 1.0 ) : mFrame(), mPeriod( period), mPitch(pitch) {}
82  Frame operator() (VSR_PRECISION amt) { return Frame( Gen::mot( Twist::Along( mFrame.dlz(), mPeriod, mPitch ) * amt ) * mFrame.mot() ); }
83  Frame mFrame;
84  VSR_PRECISION mPeriod, mPitch;
85 };
86 
87 struct Planar {
88  Planar() : mFrame() {}
89  Frame operator() (VSR_PRECISION dx, VSR_PRECISION dy, VSR_PRECISION rotate) { Frame f(mFrame); return f.move(dx,dy,0).rotXY( rotate ); }
90  Frame mFrame;
91 };
92 
93 struct Spherical : public Joint {
94  Spherical( const Frame& f = Frame() ) : Joint(Joint::SPHERICAL, f) {}
95  VSR_PRECISION theta, phi;
96  Frame operator() (VSR_PRECISION rx, VSR_PRECISION ry) { theta = rx; phi = ry; return Frame( pos(), Gen::rot(theta,phi) ); }
97  virtual Frame operator() () const { return Frame( pos(), Gen::rot(theta,phi) ); }
98 };
99 //spherical (sph coords)
100 //planar
101 
102 
107  class Chain : public Frame {
108 
109  protected:
110 
112 
113  vector<Frame> mJoint;
114  //
116  vector<Frame> mLink;
117 
118  vector<Frame> mFrame;
119 
120  int mNum;
121 
122  void _init(){
123  for (int i = 0; i < mNum; ++i){
124  Vec v(0,1.0,0);
125  mLink[i].pos() = Round:: null(v);
126  }
127  fk();
128  }
129 
130  public:
131 
132  Frame& baseFrame() { return mBaseFrame; }
133  Frame baseFrame() const { return mBaseFrame; }
134 
135  void resetJoints(){
136  for (auto& i : mJoint) i.reset();
137  }
138 
139  void reset(){
140  for (auto& i : mJoint) i.reset();
141  for (auto& i : mLink) i.reset();
142  mBaseFrame.reset();
143  _init();
144  }
145 
146  Chain(const string& s) {
147 
148  //mNum = s.length();
149  alloc(s);
150  _init();
151  }
152 
153  Chain(int n = 3) : mNum(n) {
154 
155  alloc(n);
156  _init();
157 
158  }
159 
160 
161  ~Chain(){
162  mFrame.clear();
163  mLink.clear();
164  mJoint.clear();
165  }
166 
167  void alloc(const string& s){
168  mNum = s.length();
169  if (mNum>0){
170 
171  mFrame.clear();
172  mLink.clear();
173  mJoint.clear();
174 
175  mJoint = vector<Frame>(mNum);
176  mLink = vector<Frame>(mNum);
177  mFrame = vector<Frame>(mNum);
178 
179 
180  for (int i = 0; i < mNum; ++i){
181 
182  if( strncmp( &s[i], "R", 1 ) == 0) mJoint.push_back( Revolute() );
183  else if (strncmp( &s[i], "S", 1 ) == 0 ) mJoint.push_back( Spherical() );
184 
185  /* case "R": mJoint.push_back( new Revolute() ); */
186  /* break; */
187  /* case "P": //mJoint.push_back( new Revolute() ); */
188  /* break; */
189  /* case "C": */
190  /* break; */
191  /* case "H": */
192  /* break; */
193  /* case "S": mJoint.push_back( new Spherical() ); */
194  /* break; */
195  /* case "X": */
196  /* break; */
197  /* } */
198 
199  // mJoint.push_back( Joint::LowerPairMap[ s[i] ]
200  }
201 
202  _init();
203  }
204 
205  }
206 
207  void alloc(int n){
208  mNum = n;
209  if (mNum>0){
210 
211  mFrame.clear();
212  mLink.clear();
213  mJoint.clear();
214 
215  mFrame = vector<Frame>(n);
216  mLink = vector<Frame>(n);
217  mJoint = vector<Frame>(n);
218 
219  /* for (int i = 0; i < mNum; ++i){ */
220  /* Spherical * s = new Spherical(); */
221  /* mJoint.push_back(s); */
222  /* } */
223  // mJoint = vector<Joint*>(n, new Spherical());///new Frame[n];
224  _init();
225  }
226  }
227 
228  //set first joint to this frame's position and rotation
229  void frameSet(){
230  mJoint[0].set( mPos, mRot ); fk();
231  }
232 
233  /* GETTERS AND SETTERS */
234  int num() const { return mNum; }
235  Frame& link(int k) { return mLink[k]; }
236  Frame& joint(int k) { return mJoint[k]; }
237  Frame& frame(int k) { return mFrame[k]; }
238 
239  Frame link(int k) const { return mLink[k]; }
240  Frame joint(int k) const { return mJoint[k]; }
241  Frame frame(int k) const { return mFrame[k]; }
242 
243  vector<Frame>& links() { return mLink; }
244  vector<Frame>& joints() { return mJoint; }
245 
246  Frame& operator [] (int k) { return mFrame[k]; }
247  Frame operator [] (int k) const { return mFrame[k]; }
248 
249  /* SURROUNDS */
250 
252  Dls nextSphere(int k) const{
253  return Round::dls(mFrame[k].pos(), mLink[k].vec().norm() );//mFrame[k+1].pos());
254  }
256  Dls prevSphere(int k) const{
257  return Round::dls(mFrame[k].pos(), mLink[k-1].vec().norm());//mFrame[k-1].pos());
258  }
259 
261  Dlp nextPlane(int k) const {
262  auto rj = Op::rj( link(k).vec(), Biv::xy );
263  return mFrame[k].dxy().translate(rj);
264  }
265 
267  Dlp prevPlane(int k) const {
268  auto rj = Op::rj( link(k-1).vec(), Biv::xy );
269  auto uxy = mFrame[k].dxy().spin( !link(k-1).rot() );//<-- "undo" orientation of current xy plane
270  return uxy.translate(-rj);
271  }
272 
274  Circle nextCircle(int k) const {
275  return (nextSphere(k) ^ nextPlane(k)).dual();
276  }
277 
279  Circle prevCircle(int k) const {
280  return (prevSphere(k) ^ prevPlane(k)).dual();
281  }
282 
283 
285  Dls goalSphere(const Pnt& p, int k){
286  return Round::dls(p, mLink[k].vec().norm());
287  }
289  Dls lastSphere(const Pnt& p){
290  return Round::dls(p,mLink[mNum-1].vec().norm());
291  }
292 
293  /* Possible Points */
294 
296  Pnt at(int idx, double t = 0.0){
297  return Round:: null( Interp::linear<Vec>( mFrame[idx].vec(), mFrame[idx+1].vec(), t) );
298  }
299 
300  Frame& base() { return mBaseFrame;} //mFrame[0]; }
301  Frame& first() { return mFrame[0]; }
302  Frame& last() { return mFrame[mNum -1]; }
303 
305  Dlp xy(const Pnt& p) {
306  return Op::dl(frame(0).pos()^Round:: null(0,1,0)^p^Inf(1)).unit();
307  }
309  Dlp xz(const Pnt& p) {
310  return Dlp(0,1,0,p[1]);
311  }
312 
314  Dll linkf(int k) { return Op::dl( mFrame[k].pos() ^ mFrame[k+1].pos() ^ Inf(1) ).runit() ; }
316  Dll linf(int k) { return Op::dl( mFrame[k].pos() ^ mFrame[k+1].pos() ^ Inf(1) ).runit() ; }
318  Dll linb(int k ) { return Op::dl( mFrame[k].pos() ^ mFrame[k-1].pos() ^ Inf(1) ).runit() ; }
320  Dll lin(const Pnt& p ) { return Op::dl( mFrame[mNum-1].pos() ^ p ^ Inf(1) ).runit() ; }
321 
323  Mot rel(int k){
324  if (k==0) return mJoint[0].mot();
325 
326  return mLink[k-1].mot() * mJoint[k].mot();
327  }
328 
329  void calcBase(){
330  Mot mot = mJoint[0].mot();
331  mFrame[0].mot( mBaseFrame.mot() * mot );
332  }
333 
335  void fk() {
336  Motor mot = mJoint[0].mot();
337  mFrame[0].mot( mBaseFrame.mot() * mot );
338  for (int i = 1; i < mNum; ++i){
339  Mot rel = mLink[i-1].mot() * mJoint[i].mot();//mLink[i-1].mot() * mJoint[i].mot();
340  mFrame[i].mot( mFrame[i-1].mot() * rel );// * mFrame[i-1].mot() );// mFrame[i-1].mot() * rel ) ;
341  }
342  }
343 
345  void fk(int end){
346 
347  Mot mot = mJoint[0].mot();
348  mFrame[0].mot( mBaseFrame.mot() * mot );
349 
350  for (int i = 1; i <= end; ++i){
351  Mot m = mFrame[i-1].mot() * mLink[i-1].mot() * mJoint[i].mot();
352  mFrame[i].mot( m );
353  }
354 
355  }
356 
358  void fk(int begin, int end){
359 
360  for (int i = begin; i < end; ++i){
361  Mot m = mFrame[i-1].mot() * mLink[i-1].mot() * mJoint[i].mot();
362  mFrame[i].mot( m );
363  }
364 
365  }
366 
367  // What is difference between ifabrik and fabrik?
368  void ik(int end, int begin){
369 
370  }
371 
372  // void ifabrik(const Pnt& p, int end, int begin, double err = .01){
373  // //squared distance between last frame and goal p
374  // Sca s = mFrame[end].pos() <= p * -2.0;
375  //
376  // //Temporary Goal
377  // Pnt goal = p;
378  // Pnt base = mFrame[begin].pos();
379  //
380  // int n = 0;
381  //
382  // //repeat until distance is decreased below threshold, or give up after 20 iterations
383  // while (s[0] > err){
384  //
385  // Pnt tmpGoal = goal;
386  // Pnt tmpBase = base;
387  //
388  // //some objects
389  // static Dls dls; //surround
390  // static Dll dll; //line
391  // static Par par; //intersection of line ^ surround
392  //
393  // //forward reaching
394  // for (int i = end; i < begin; ++i){
395  // mFrame[i].pos( tmpGoal ); //set position of ith frame
396  // dls = nextSphere(i); //set boundary sphere through i-1 th frame;
397  // dll = linf(i); //get line from tmp to i-1th frame
398  // par = (dll ^ dls).dual(); //get point pair intersection of line and boundary sphere
399  // tmpGoal = Round:: split(par,true); //extract point from point pair intersection
400  // }
401  //
402  // //backward correction
403  // for (int i = begin; i > end; --i){
404  // dls = prevSphere(i); //set boundary sphere through i+1 th frame
405  // dll = linb(i); //get line to i+1th frame;
406  // par = (dll ^ dls).dual(); //get point pair intersection of line and boundary sphere
407  // tmpBase = Round:: split(par,true);
408  // mFrame[i-1].pos(tmpBase); //set position of i+1th frame
409  // }
410  //
411  // //squared distance between end frame and goal p
412  // s = mFrame[ end ].pos() <= p * -2.0;
413  //
414  // n++; if (n > 20) { break; }
415  // }
416  //
417  // //calculate joint angles
418  // calcJoints();
419  // }
420 
423  void fabrik(const Pnt& p, int end, int begin, double err = .01){
424 
425  //squared distance between last frame and goal p
426  Sca s = mFrame[end].pos() <= p * -2.0;
427 
428  //Temporary Goal
429  Pnt goal = p;
430  //Base
431  Pnt base = mFrame[begin].pos();
432 
433  int n = 0;
434 
435  //repeat until distance is decreased to within error threshold, or give up after 20 iterations
436  while (s[0] > err){
437 
438  Pnt tmpGoal = goal;
439  Pnt tmpBase = base;
440 
441  static Dls dls; //surround
442  static Dll dll; //line
443  static Par par; //intersection of line ^ surround
444 
445  //backward reaching
446  for (int i = end; i > begin; --i){
447  mFrame[i].pos( tmpGoal ); //set position of ith frame
448  dls = prevSphere(i); //set boundary sphere through i-1 th frame;
449  dll = linb(i); //get line from ith to i-1th frame
450  par = (dll ^ dls).dual(); //get point pair intersection of line and boundary sphere
451  tmpGoal = Round:: split(par,true); //extract point from point pair intersection
452  }
453 
454  //forward correction
455  for (int i = begin; i < end; ++i){
456  dls = nextSphere(i); //set boundary sphere through i+1 th frame
457  dll = linf(i); //get line to i+1th frame;
458  par = (dll ^ dls).dual(); //get point pair intersection of line and boundary sphere
459  tmpBase = Round:: split(par,true);
460  mFrame[i+1].pos(tmpBase); //set position of i+1th frame
461  }
462 
463  s = mFrame[ end ].pos() <= p * -2.0;
464 
465  n++; if (n > 20) { break; }
466  }
467 
468  //calculate joint angles
469  calcJoints();
470 
471  }
472 
473 // /// Derive Joint Rotations from Current Positions
474 // void calcJoints(int start = 0, bool bLoop=false){
475 //
476 // Rot ry(1);// = mLink[start].rot();
477 //
478 // for (int i = start; i < mNum; ++i){
479 //
480 // int next = i < (mNum-1) ? i+1 : 0;
481 //
482 // auto target = (mFrame[next].vec() - mFrame[i].vec() ).unit(); //target direction
483 // auto linkRot = Gen::ratio(Vec::y, mLink[i].vec().unit() ); //what link position contributes...
484 // // target = target.spin( !linkRot );
485 // auto tmpRot = Gen::ratio( Vec::y, target ); //how to get there
486 //
487 //
488 // tmpRot = !linkRot * !ry * tmpRot;// * !linkRot; //...compensate for that and previous compound
489 //
490 // Vec correctedTarget = Vec(Op::project( Vec::y.spin( tmpRot ), Biv::xy)).unit(); //project onto xy axis of local link
491 //
492 // auto adjustedRot = Gen::ratio( Vec::y, correctedTarget );
493 // mJoint[i].rot() = adjustedRot;
494 //
495 // ry = ry * mJoint[i].rot() * mLink[i].rot(); //compound: last * current * next
496 // }
497 //
498 // }
499 //
500  // /// Derive Joint Rotations from Current Positions
501  // void calcJoints(int start = 0, bool bLoop=false){
502 
503  // Rot ry(1);// = mLink[start].rot();
504  //
505  // for (int i = start; i < (bLoop ? mNum : mNum-1); ++i){
506  //
507  // int next = i < (mNum-1) ? i+1 : 0;
508  //
509  // auto dir = Vec::y.spin( ry ); //current direction
510  //
511  // auto target = ( mFrame[next].vec() - mFrame[i].vec() ).unit(); //global target direction
512  // auto linkRot = Gen::ratio(Vec::y, mLink[i].vec().unit() ); //what link position contributes...
513  //
514  // //target in terms of origin
515  // target = target.spin( !linkRot * !mFrame[i].rot() );
516 
517  // //DrawAt( dir, mFrame[i].pos() + mFrame[i].y() );
518  // // DrawAt( target.spin( mFrame[i].rot() ) , mFrame[i].pos() + mFrame[i].y(),1,1,0);
519  //
520  // auto adjustedRot = Gen::ratio( dir.spin( !mFrame[i].rot() ), target );
521 
522  // mJoint[i].rot() = adjustedRot;// * !mFrame[i].rot();
523 
524  // // Mot tl = (start>0)? mLink[i-1].mot() : Mot(1);
525  // ry = ry * mJoint[i].rot() * mLink[i].rot(); //compound: last * current * next
526  // }
527  //
528  // }
529 
531  void calcJoints(int start = 0, bool bLoop=false){
532 
533  Rot ry(1);
534 
535  for (int i = start; i < (bLoop ? mNum : mNum-1); ++i){
536 
537  int next = i < (mNum-1) ? i+1 : 0;
538 
539  //auto dir = Vec::y.spin( ry ); //current direction
540 
541  auto target = ( mFrame[next].vec() - mFrame[i].vec() ).unit(); //global target direction
542  auto linkRot = Gen::ratio(Vec::y, mLink[i].vec().unit() ); //what link position contributes...
543 
544  //target in terms of origin
545  target = target.spin( !linkRot * !ry );
546 
547  auto adjustedRot = Gen::ratio( Vec::y, target );
548 
549  mJoint[i].rot() = adjustedRot;// * !mFrame[i].rot();
550 
551  ry = ry * mJoint[i].rot() * mLink[i].rot(); //compound: last * current * next
552  }
553 
554  }
555 
558  void calcLinks(bool bOrientation =false){
559 
560  if (!bOrientation){
561  for (int i = 0; i < mNum; ++i){
562  int next = (i<mNum-1)?i+1:0;
563  //mLink[i].rot() = Gen::ratio( mFrame[i].z(), mFrame[next].z() );
564  //auto ratio = mFrame[next].rot() / mFrame[i].rot(); //relative transform
565  auto yratio = Gen::ratio( mFrame[i].y(), mFrame[next].y() ); //relative rotational component
566 
567  //auto theta = Gen::iphi( Gen::ratio( mFrame[i].z(), mFrame[next].z() ) );//acos( (mFrame[i].z()<=mFrame[next].z())[0] );
568  mLink[i].rot() = !mFrame[i].rot() * !yratio * mFrame[next].rot(); //SEQUENCE MATTERS! first local rot, then undow local ys, then undo source
569 
570  auto dv = mFrame[next].vec() - mFrame[i].vec();
571  // Vec project = Op::project(dv, mFrame[i].xy());
572  // Vec reject = Op::reject(dv, mFrame[i].xy());
573  //under local transformation
574  mLink[i].pos() = dv.spin( !mFrame[i].rot() ).null();
576  }
577  } else{
578  for (int i = 0; i < mNum; ++i){
579  int next = (i<mNum-1)?i+1:0;
580  //mLink[i].rot() = Gen::ratio( mFrame[i].z(), mFrame[next].z() );
581  auto theta = acos( (mFrame[i].z()<=mFrame[next].z())[0] );
582  mLink[i].rot() = Gen::rotor( Biv::xz * theta * .5 );
583  auto vec = (mFrame[next].vec() - mFrame[i].vec()).spin( !mFrame[i].rot() );
584  mLink[i].pos() = vec.null();
585  }
586  }
587  }
588 
589 
591  void angle(int k, double theta){
592 
593  Rot R = mJoint[k].rot();
594 
595  Biv b = Biv( R ) * -1;
596  // * ( (t > 1) ? ); // note: check Op:lg and Gen::log_rot (maybe mult by -1 there as well)
597 
598  Rot nr = Gen::rot( b.unit() * theta );
599 
600  mJoint[k].rot( nr );
601 
602  //forward kinematics to k
603  fk(k, mNum);
604 
605  }
606 
607 
608  };
609 
610 } } //vsr::cga
611 
612 
613 
614 //OLD TMP
615 
616 // if (bLoop){
617 // Vec y = Vec::y.spin(ry);
618 // auto target = Vec(mFrame[0].pos()-mFrame[mNum-1].pos()).unit();
619 // auto linkRot = Gen::ratio( Vec::y, mLink[mNum-1].vec().unit() );
620 // auto dv = target.spin( !linkRot ); //current status
621 //
622 // mJoint[mNum-1].rot() = Gen::ratio( y, dv );//Gen::rot( Biv::xy * acos( ( dv <= y )[0] )/2.0 ); //set rotation
623 // }
624 //
625 // Vec t = mBaseFrame.y(); // Vec::y;
626 // Rot R = mBaseFrame.rot(); // (1,0,0,0);
627 
628 // //Where we are in current rotation scheme
629 // for (int i = 0; i < start; ++i){
630 // t = t.sp( mFrame[i].rot() );
631 // }
632 
633 // //From Here forward, what rotation we need to point where we want to go (note: assumes no offset!)
634 // for (int i=start;i<mNum-1;++i){
635 //
636 // Vec target = Vec(mFrame[i+1].pos() - mFrame[i].pos()).unit(); // Op::dle( Biv( linf(i) ) ); //0. Goal (Direction of Line to next joint)
637 // // if (i>0) t = t.sp( mLink[i-1].rot() ); //1. Consider Rotary Contribution of Previous Link
638 // Vec q = t.sp( Gen::ratio(Vec::y, mLink[i].vec().unit()) ); // And Translated Contribution of Current Link
639 // Rot nr = Gen::ratio( q, target ); //2. What additional work it takes to turn the current integration towards Goal
640 // //R = nr * R; //3. Compound into R
641 // // mFrame[i].rot( R ); //4. Apply Rotation to Frame temporarily
642 // mJoint[i].rot( nr ); //new
643 // t = t.sp( nr ); //5. Save new integrated angle
644 // }
645 //
646 // if (bLoop){
647 // Vec target = Vec(mFrame[0].pos()-mFrame[mNum-1].pos()).unit();
648 // Vec q = t.sp( Gen::ratio( Vec::y, mLink[mNum-1].vec().unit() ) );
649 // Rot nr = Gen::ratio( q, target );
650 // mJoint[mNum-1].rot(nr);
651 // }
652 
653 
654  //new version.
655  //Current rotation
656  // Vec t = mBaseFrame.y();
657  // Rot ry = mBaseFrame.rot();
658 
659  //Set Base Joint
660 // mJoint[0].rot( !mBaseFrame.rot() * mFrame[0].rot() );
661 //
662 // //Reverse engineer by getting relative transformations
663 // for (int i = 1; i < mNum; ++i){
664 // Rot Rt = (!mFrame[i-1].rot()) * mFrame[i].rot() ;
665 // mJoint[i].rot( Rt );
666 // }
667 
668  //Next apply fk() and see if it all worked !. . .
669 
670 
671 #endif
static std::vector< Point > split(const Pair &pp)
Split Points from Point Pair.
Dll linf(int k)
Dual Line Forward: Line from kth frame to kth+1 joint.
Definition: vsr_chain.h:316
Mot rel(int k)
relative transformation (lagrangian) at kth joint
Definition: vsr_chain.h:323
static DualSphere dls(VSR_PRECISION r, VSR_PRECISION x, VSR_PRECISION y, VSR_PRECISION z)
Dual Sphere from Coordinate Center (shorthand)
Definition: vsr_cga3D_round.h:79
Definition: vsr_chain.h:93
Dlp xz(const Pnt &p)
Horiz xz Plane Containing Target Point v.
Definition: vsr_chain.h:309
void fk(int begin, int end)
Forward Kinematics: calculate forward from "begin" to "end" joint.
Definition: vsr_chain.h:358
void calcJoints(int start=0, bool bLoop=false)
Derive Joint Rotations from Current Positions.
Definition: vsr_chain.h:531
Frame & link(int k)
set k's Link To Next Joint
Definition: vsr_chain.h:235
NDlp< 5 > Dlp
DualPlane
Definition: vsr_cga3D_types.h:81
void angle(int k, double theta)
Satisfy Specific Angle Constraint at frame k.
Definition: vsr_chain.h:591
Point pos() const
Get Position.
Definition: vsr_cga3D_frame.h:138
Mot mot() const
Get Absolute Motor Relative to Origin.
Vec y() const
Local y.
Circle nextCircle(int k) const
Dual Circle Centered at Joint K Going Through Joint K+1 (in plane of rotation)
Definition: vsr_chain.h:274
void fabrik(const Pnt &p, int end, int begin, double err=.01)
"FABRIK" Iterative Solver [see paper "Inverse Kinematic Solutions using Conformal Geometric Algebra"...
Definition: vsr_chain.h:423
Definition: vsr_chain.h:35
Generic Geometric Number Types (templated on an algebra and a basis )
Definition: vsr_algebra.h:69
Frame & spin()
Spin Step (Local Rotation) */.
Rotor mRot
Orientation.
Definition: vsr_cga3D_frame.h:53
static Rot rot(const Biv &b)
vsr::cga::Rotor from vsr::cga::Bivector
Multivector< algebra, typename algebra::vector_basis > null() const
Conformal Mapping \(\boldsymbol(x)\to n_o + \boldsymbol{x} + \boldsymbol{x}^2n_\infty \) ...
Definition: vsr_generic_op.h:1118
static Mot mot(const Dll &dll)
Generate a vsr::cga::Motor from a vsr::cga::DualLine Axis.
Circle prevCircle(int k) const
Dual Circle Centered at Joint K Going Through Joint K-1 (in plane of rotation)
Definition: vsr_chain.h:279
Definition: vsr_chain.h:87
Frame & reset()
Reset to Origin.
Definition: vsr_cga3D_frame.h:85
Dlp prevPlane(int k) const
Dual Plane of rotation of k-1th joint (translated by link rejection from yz)
Definition: vsr_chain.h:267
vector< Frame > mFrame
Absolute frames of Joints = prevFrame * prevLink * joint.
Definition: vsr_chain.h:118
Dls goalSphere(const Pnt &p, int k)
Sphere at Point p through Joint K.
Definition: vsr_chain.h:285
void calcLinks(bool bOrientation=false)
Derive New Relative Link Frames from current Positions @ param bOrientation: whether to consider curr...
Definition: vsr_chain.h:558
Dlp nextPlane(int k) const
Dual Plane of rotation of kth joint (translated by link rejection from yz)
Definition: vsr_chain.h:261
Vec vec() const
Get Euclidean Vector of position.
Definition: vsr_cga3D_frame.h:142
Dls nextSphere(int k) const
Sphere Centered at Joint K Going Through Joint K+1.
Definition: vsr_chain.h:252
void fk()
Forward Kinematics: Absolute Concatenations of previous frame, previous link, and current joint...
Definition: vsr_chain.h:335
Frame()
Default Constructor.
Frame & frame(int k)
set Absolute Displacement Motor
Definition: vsr_chain.h:237
void fk(int end)
Forward Kinematics: calculate forward to "end" joint.
Definition: vsr_chain.h:345
NInf< 5 > Inf
Infinity
Definition: vsr_cga3D_types.h:68
Definition: vsr_chain.h:80
Frame & mot(const Mot &m)
Set position and orientation by motor (absolute)
Dll dll() const
DualLine Representation of Pose.
Dlp xy(const Pnt &p)
Vert xy Plane Containing Root Target Point v ( NORMALIZED )
Definition: vsr_chain.h:305
Frame link(int k) const
Get k's Link To Next joint.
Definition: vsr_chain.h:239
A sequence of spatial Frames.
Definition: vsr_chain.h:107
vector< Frame > mLink
Relative Link to NEXT joint.
Definition: vsr_chain.h:116
Dls prevSphere(int k) const
Sphere Centered at Joint K Going Through Joint K-1.
Definition: vsr_chain.h:256
Frame joint(int k) const
Get kth Joint's In Socket Transformation.
Definition: vsr_chain.h:240
Dll lin(const Pnt &p)
Dual Line From Kth Joint to Input Target (Default is From Last joint)
Definition: vsr_chain.h:320
static Rot ratio(const Vec &v, const Vec &v2)
vsr::cga::Rotor that takes one vec to another
Definition: vsr_chain.h:67
Pnt at(int idx, double t=0.0)
Pnt at position t along Link idx.
Definition: vsr_chain.h:296
Frame & move()
Translation Step (translate by velocity vector)
the versor library namespace
Definition: vsr_algebra.h:29
Multivector rot(const MultivectorB< B > &b) const
Rotor rot() const
Get 4x4 Rotation Matrix.
Definition: vsr_cga3D_frame.h:97
Frame rotXY(VSR_PRECISION amt) const
Rotate around local xy and return a new frame.
Orthonormal Frame composed from a Position and Orientation.
Definition: vsr_cga3D_frame.h:47
NBiv< 5 > Biv
Bivector
Definition: vsr_cga3D_types.h:63
Point mPos
Position.
Definition: vsr_cga3D_frame.h:52
Frame & joint(int k)
set kth joint's In Socket Transformation
Definition: vsr_chain.h:236
Frame & operator[](int k)
Set kth Absolute Frame.
Definition: vsr_chain.h:246
Definition: vsr_chain.h:61
Frame mBaseFrame
default zero, to tie chains together, set this to another chain's frame.
Definition: vsr_chain.h:111
3D CGA Orthonormal Frame
static Rot rotor(const Biv &b)
vsr::cga::Rotor from vsr::cga::Bivector
Frame frame(int k) const
Get Absolute Displacement Motor.
Definition: vsr_chain.h:241
vector< Frame > mJoint
In Socket Transformation (RDHC, etc) SET THIS directly using joint(i) (all others follow after callin...
Definition: vsr_chain.h:113
Dll dlz() const
z direction dual line
Dll linb(int k)
Dual Line Backward: Line from kth frame to kth-1 joint.
Definition: vsr_chain.h:318
static Point null(const Vec &v)
Null Point from a vec.
Dls lastSphere(const Pnt &p)
Sphere at point p through last link (default, or set arbitary link)
Definition: vsr_chain.h:289
Vec z() const
Local z.
Definition: vsr_chain.h:74
Dll linkf(int k)
Dual Line Forward: Line from kth frame to kth Link.
Definition: vsr_chain.h:314