link.c
Go to the documentation of this file.
1 #include "link.h"
2 #include "polyhedron.h"
3 #include "varnames.h"
4 
5 #include <math.h>
6 #include <string.h>
7 
35 void CacheRotVars(unsigned int r,TCuikSystem *cs,Tlink *l);
36 
46 
56 
66 
67 /**********************************************************************/
68 
69 void InitLink(char *name,Tlink *l)
70 {
71  unsigned int namel,i;
72 
73  namel=strlen(name);
74  if (namel==0)
75  l->name=NULL;
76  else
77  {
78  NEW(l->name,namel+1,char);
79  strcpy(l->name,name);
80  }
81 
83 
84  l->s=1;
85  l->c=0;
86  HTransformIdentity(&(l->R));
87  HTransformIdentity(&(l->iR));
88 
89  l->allSpheres=TRUE;
90 
91  for(i=0;i<3;i++)
92  l->axisID[i]=NO_UINT;
93 
94  /*sum of the maximum coordinate value for all bodies in the link*/
95  l->maxCoord=0.0;
96 
97  l->csvID=NULL;
98  l->nvID=0;
99  l->vID=NULL;
100 }
101 
102 void CopyLink(Tlink *l_dst,Tlink *l_src)
103 {
104  unsigned int i,n;
105 
106  if (l_src==NULL)
107  l_dst->name=NULL;
108  else
109  {
110  NEW(l_dst->name,strlen(l_src->name)+1,char);
111  strcpy(l_dst->name,l_src->name);
112  }
113 
114  InitVector(sizeof(double *),CopyVoidPtr,DeleteVoidPtr,INIT_NUM_SHAPES,&(l_dst->bodies));
115 
116  l_dst->allSpheres=TRUE;
117 
118  n=LinkNBodies(l_src);
119  for(i=0;i<n;i++)
120  AddBody2Link(GetLinkBody(i,l_src),l_dst);
121 
122  l_dst->c=l_src->c;
123  l_dst->s=l_src->s;
124  HTransformCopy(&(l_dst->R),&(l_src->R));
125  HTransformCopy(&(l_dst->iR),&(l_src->iR));
126 
127  for(i=0;i<3;i++)
128  l_dst->axisID[i]=l_src->axisID[i];
129 
130  l_dst->maxCoord=l_src->maxCoord;
131 
132  if (l_src->csvID==NULL)
133  {
134  l_dst->csvID=NULL;
135  l_dst->nvID=0;
136  l_dst->vID=NULL;
137  }
138  else
139  {
140  l_dst->csvID=l_src->csvID;
141  l_dst->nvID=l_src->nvID;
142  NEW(l_dst->vID,l_dst->nvID,unsigned int);
143  memcpy(l_dst->vID,l_src->vID,l_dst->nvID*sizeof(unsigned int));
144  }
145 }
146 
148 {
149  Tpolyhedron *bint;
150 
151  NEW(bint,1,Tpolyhedron);
152  CopyPolyhedron(bint,b);
153 
154  NewVectorElement(&bint,&(l->bodies));
155 
156  l->allSpheres=((l->allSpheres)&&
157  ((GetPolyhedronType(bint)==SPHERE)||
158  (GetPolyhedronStatus(bint)==DECOR_SHAPE)));
159 
161 }
162 
163 void ChangeLinkReferenceFrame(unsigned int r,double **p1,double **p2,Tlink *l)
164 {
165  if ((r!=REP_QLINKS)&&(r!=REP_JOINTS))
166  {
167  /* This function has no effect when using quaternions. */
168  double v[3][3],n1,n2;
169  unsigned int i,j;
170  double s,c,d,ac;
171 
172  /* Define the vectors from the points */
173  n1=0;
174  n2=0;
175  for(i=0;i<3;i++)
176  {
177  v[0][i]=p1[1][i]-p1[0][i];
178  v[1][i]=p2[1][i]-p2[0][i];
179  n1+=v[0][i]*v[0][i];
180  n2+=v[1][i]*v[1][i];
181  }
182  /* Normalize the vectors */
183  n1=sqrt(n1);
184  n2=sqrt(n2);
185  for(i=0;i<3;i++)
186  {
187  v[0][i]/=n1;
188  v[1][i]/=n2;
189  }
190 
191  /*compute the cos/sin between the two vectors*/
192  /*The dot product of the two vectors is the cosinus
193  between the vectors*/
194  c=0;
195  for(i=0;i<3;i++)
196  c+=v[0][i]*v[1][i];
197  ac=fabs(c);
198  if (ac<0.9) /*Ensure the two vectors are (by far) not aligned*/
199  {
200  /*The cross product of the two vectors is a vector
201  orthogonal to the two vectors with norm the sinus
202  of the angle between the vectors*/
203  v[2][0]=v[0][1]*v[1][2]-v[0][2]*v[1][1];
204  v[2][1]=v[0][2]*v[1][0]-v[0][0]*v[1][2];
205  v[2][2]=v[0][0]*v[1][1]-v[0][1]*v[1][0];
206 
207  s=0;
208  for(i=0;i<3;i++)
209  s+=v[2][i]*v[2][i];
210  s=sqrt(s);
211  for(i=0;i<3;i++)
212  v[2][i]/=s;
213 
214  l->c=c;
215  l->s=s;
216 
217  /* Compute the inverse of the matrix with vector 'v' as colums
218  (i.e., the inverse of the basis change).
219  Rows of R are computed taking into account that
220  R * [v1 v2 v3] = Id
221  R=[w1;w2;w3]
222  From construction w3=v3
223  and w1=\alpha v1 + \beta v2
224  w2=\gamma v1 + \delta v2
225  where \alpa, \beta, \gamma, \delta are easy to find
226  taking into account that w1*v1\tr=1 w1*v2\tr=0,...
227  */
228  d=(1/(s*s));
229  for(j=0;j<3;j++)
230  HTransformSetElement(0,j,d*(v[0][j]-c*v[1][j]),&(l->R));
231  for(j=0;j<3;j++)
232  HTransformSetElement(1,j,d*(v[1][j]-c*v[0][j]),&(l->R));
233  for(j=0;j<3;j++)
234  HTransformSetElement(2,j,v[2][j],&(l->R));
235 
236  /* iR: The inverse of R: v1 v2 v3 in colums */
237  for(i=0;i<3;i++)
238  {
239  for(j=0;j<3;j++)
240  HTransformSetElement(j,i,v[i][j],&(l->iR));
241  }
242  }
243  }
244 }
245 
246 unsigned int LinkNBodies(Tlink *l)
247 {
248  return(VectorSize(&(l->bodies)));
249 }
250 
251 unsigned int LinkNAtoms(Tlink *l)
252 {
253  unsigned int i,m,n;
254  Tpolyhedron *bd;
255 
256  n=0;
257  m=LinkNBodies(l);
258 
259  if ((m>0)&&(VisibleLink(l)))
260  {
261  for(i=0;i<m;i++)
262  {
263  bd=GetLinkBody(i,l);
264  if (GetPolyhedronType(bd)==SPHERE)
265  n++;
266  }
267  }
268  return(n);
269 }
270 
271 Tpolyhedron *GetLinkBody(unsigned int i,Tlink *l)
272 {
273  Tpolyhedron **b;
274 
275  b=(Tpolyhedron **)GetVectorElement(i,&(l->bodies));
276  if (b==NULL)
277  return(NULL);
278  else
279  return(*b);
280 }
281 
282 unsigned int GetLinkBodyStatus(unsigned int i,Tlink *l)
283 {
284  Tpolyhedron **b;
285 
286  b=(Tpolyhedron **)GetVectorElement(i,&(l->bodies));
287  if (b==NULL)
288  return(NO_UINT);
289  else
290  return(GetPolyhedronStatus(*b));
291 }
292 
294 {
295  return(l->name);
296 }
297 
299 {
300  return(l->allSpheres);
301 }
302 
303 void SetPoseVars(Tparameters *p,boolean *vars,TCuikSystem *cs,Tlink *l)
304 {
305  SetTransVars(vars,cs,l);
306  SetRotVars(p,vars,cs,l);
307 }
308 
309 void SetTransVars(boolean *vars,TCuikSystem *cs,Tlink *l)
310 {
311  char *vname;
312  unsigned int k,id;
313 
314  NEW(vname,strlen(l->name)+100,char);
315  for(k=0;k<3;k++)
316  {
317  LINK_TRANS(vname,l->name,k);
318  id=GetCSVariableID(vname,cs);
319  if (id!=NO_UINT) /*Ground links has not variables*/
320  vars[id]=TRUE;
321  }
322  free(vname);
323 }
324 
325 
326 void CacheRotVars(unsigned int r,TCuikSystem *cs,Tlink *l)
327 {
328  switch(r)
329  {
330  case REP_LINKS:
331  CacheRotVarsLinks(cs,l);
332  break;
333  case REP_FLINKS:
334  CacheRotVarsFLinks(cs,l);
335  break;
336  case REP_QLINKS:
337  CacheRotVarsQLinks(cs,l);
338  break;
339  case REP_JOINTS:
340  break;
341  default:
342  Error("Undefined representation type in CacheRotVars");
343  }
344 }
345 
347 {
348  if (cs!=l->csvID)
349  {
350  char *vname;
351  unsigned int i,j,k;
352 
353  l->nvID=9;
354  if (l->csvID==NULL)
355  NEW(l->vID,l->nvID,unsigned int);
356 
357  NEW(vname,strlen(l->name)+100,char);
358  k=0;
359  for(i=0;i<3;i++) /*vector*/
360  {
361  for(j=0;j<3;j++) /*component*/
362  {
363  LINK_ROT(vname,l->name,i,j);
364  /* for the ground link all vID will be NO_UINT. Use at your own
365  risk. */
366  l->vID[k]=GetCSVariableID(vname,cs);
367  k++;
368  }
369  }
370  free(vname);
371 
372  l->csvID=cs;
373  }
374 }
375 
377 {
378  if (cs!=l->csvID)
379  {
380  char *vname;
381  unsigned int i,j,k;
382 
383  l->nvID=12;
384  if (l->csvID==NULL)
385  NEW(l->vID,l->nvID,unsigned int);
386 
387  NEW(vname,strlen(l->name)+100,char);
388  k=0;
389  for(i=0;i<4;i++) /*vector*/
390  {
391  for(j=0;j<3;j++) /*component*/
392  {
393  LINK_ROT2(vname,l->name,i,j);
394  /* for the ground link all vID will be NO_UINT. Use at your own*/
395  l->vID[k]=GetCSVariableID(vname,cs);
396  k++;
397  }
398  }
399  free(vname);
400 
401  l->csvID=cs;
402  }
403 }
404 
406 {
407  if (cs!=l->csvID)
408  {
409  char *vname;
410  unsigned int i,j,k;
411 
412  l->nvID=14;
413  if (l->csvID==NULL)
414  NEW(l->vID,l->nvID,unsigned int);
415 
416  NEW(vname,strlen(l->name)+100,char);
417  k=0;
418  for(j=0;j<4;j++)
419  {
420  LINK_ROT3_Q(vname,l->name,j);
421  l->vID[k]=GetCSVariableID(vname,cs);
422  k++;
423  }
424 
425  for(i=0;i<4;i++)
426  {
427  for(j=i;j<3;j++)
428  {
429  LINK_ROT3_E(vname,l->name,i,j);
430  /* for the ground link all vID will be NO_UINT. Use at your own */
431  l->vID[k]=GetCSVariableID(vname,cs);
432  k++;
433  }
434  }
435 
436  free(vname);
437 
438  l->csvID=cs;
439  }
440 }
441 
442 void SetRotVars(Tparameters *p,boolean *vars,TCuikSystem *cs,Tlink *l)
443 {
444  unsigned int r;
445 
446  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
447 
448  if (r!=REP_JOINTS)
449  {
450  unsigned int i,id,n=0;
451 
452  CacheRotVars(r,cs,l);
453 
454  switch(r)
455  {
456  case REP_LINKS:
457  n=6;
458  break;
459  case REP_FLINKS:
460  n=9;
461  break;
462  case REP_QLINKS:
463  n=4;
464  break;
465  default:
466  Error("Undefined representation type in SetRotVars");
467  }
468 
469  for(i=0;i<n;i++) /*system vars = 3 vectors*/
470  {
471  id=l->vID[i];
472  if (id!=NO_UINT) /*Ground links has not variables*/
473  vars[id]=TRUE;
474  }
475  }
476 }
477 
478 void GetLinkPoseSimpVars(Tparameters *p,boolean *sv,
479  TCuikSystem *cs,Tlink *l)
480 {
481  unsigned int r;
482 
483  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
484 
485  if (r!=REP_JOINTS)
486  {
487  unsigned int i,id,n=0;
488  char *v;
489 
490  CacheRotVars(r,cs,l);
491 
492  switch(r)
493  {
494  case REP_LINKS:
495  n=6;
496  break;
497  case REP_FLINKS:
498  n=9;
499  break;
500  case REP_QLINKS:
501  n=4;
502  break;
503  default:
504  Error("Undefined representation type in SetRotVars");
505  }
506 
507  for(i=0;i<n;i++) /*system vars = 3 vectors*/
508  {
509  id=l->vID[i];
510  if (id!=NO_UINT) /*Ground links has not variables*/
511  {
512  v=GetCSVariableName(id,cs);
513  if (IsSystemVarInSimpCS(p,v,cs))
514  sv[id]=TRUE;
515  }
516  }
517  }
518 }
519 
520 void GenerateLinkRot(Tparameters *p,unsigned int lID,TCuikSystem *cs,Tlink *l)
521 {
522  unsigned int r;
523 
524  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
525  switch(r)
526  {
527  case REP_LINKS:
528  GenerateLinkRotLinks(p,lID,cs,l);
529  break;
530  case REP_FLINKS:
531  GenerateLinkRotFLinks(p,lID,cs,l);
532  break;
533  case REP_QLINKS:
534  GenerateLinkRotQLinks(p,lID,cs,l);
535  break;
536  case REP_JOINTS:
537  break;
538  default:
539  Error("Undefined representation type in GenerateLinkRot");
540  }
541 }
542 
543 void GenerateLinkRotFLinks(Tparameters *p,unsigned int lID,TCuikSystem *cs,Tlink *l)
544 {
545  if (!IsGroundLink(lID))
546  {
547  char *vname;
548 
549  /*If the cuiksytem already has the link variables (and thus the corresponding equations)
550  there is nothing to be done. */
551 
552  NEW(vname,strlen(l->name)+100,char);
553 
554  LINK_ROT(vname,l->name,0,0);
555 
556  if (GetCSVariableID(vname,cs)==NO_UINT)
557  {
558  unsigned int i,j;
559  Tinterval range;
560  Tequation eqn;
561  Tequation eq[3];
562  unsigned int linkVars[9];
563  Tvariable var;
564 
565  NewInterval(-1.0,1.0,&range);
566  for(i=0;i<3;i++) /*vector*/
567  {
568  for(j=0;j<3;j++) /*component*/
569  {
570  LINK_ROT(vname,l->name,i,j);
571  NewVariable(SYSTEM_VAR,vname,&var);
572  SetVariableInterval(&range,&var);
573  linkVars[i*3+j]=AddVariable2CS(&var,cs);
574  DeleteVariable(&var);
575  }
576  }
577 
578  for(i=0;i<2+ROT_REDUNDANCY;i++)
579  {
580  GenerateNormEquation(linkVars[3*i+0],linkVars[3*i+1],linkVars[3*i+2],1.0,&eqn);
581  AddEquation2CS(p,&eqn,cs);
582  DeleteEquation(&eqn);
583  }
584 
585  /*ONLY ONE OF THE THREE FOLLOWING BLOCKS IS REQUIRED, THE OTHER TWO ARE REDUNDANT. */
586  #if (ROT_REDUNDANCY==1)
587  /*********************************************************************/
588 
589  GenerateDotProductEquation(linkVars[0],linkVars[1],linkVars[2], /* X */
590  linkVars[3],linkVars[4],linkVars[5], /* Y */
591  NO_UINT,l->c,&eqn);
592  AddEquation2CS(p,&eqn,cs);
593  DeleteEquation(&eqn);
594 
595 
596  GenerateCrossProductEquations(linkVars[0],linkVars[1],linkVars[2], /* X */
597  linkVars[3],linkVars[4],linkVars[5], /* Y */
598  linkVars[6],linkVars[7],linkVars[8], /* Z */
599  NO_UINT,l->s,eq);
600  for(i=0;i<3;i++)
601  {
602  AddEquation2CS(p,&(eq[i]),cs);
603  DeleteEquation(&(eq[i]));
604  }
605  /*********************************************************************/
606  #endif
607 
608  /*********************************************************************/
609 
610  GenerateDotProductEquation(linkVars[6],linkVars[7],linkVars[8], /* Z */
611  linkVars[0],linkVars[1],linkVars[2], /* X */
612  NO_UINT,0,&eqn);
613  AddEquation2CS(p,&eqn,cs);
614  DeleteEquation(&eqn);
615  if (l->s==1) /*This second redundant equation is only used for orthogonal X-Y vectors */
616  {
617  GenerateCrossProductEquations(linkVars[6],linkVars[7],linkVars[8], /* Z */
618  linkVars[0],linkVars[1],linkVars[2], /* X */
619  linkVars[3],linkVars[4],linkVars[5], /* Y */
620  NO_UINT,1.0,eq);
621  for(i=0;i<3;i++)
622  {
623  AddEquation2CS(p,&(eq[i]),cs);
624  DeleteEquation(&(eq[i]));
625  }
626  }
627  /*********************************************************************/
628 
629 
630  #if (ROT_REDUNDANCY==1) /*Redundancy is only used for orthogonal X-Y vectors */
631  /*********************************************************************/
632  GenerateDotProductEquation(linkVars[3],linkVars[4],linkVars[5], /* Y */
633  linkVars[6],linkVars[7],linkVars[8], /* Z */
634  NO_UINT,0,&eqn);
635  AddEquation2CS(p,&eqn,cs);
636  DeleteEquation(&eqn);
637 
638 
639  if (l->s==1) /*This second redundant equation is only used for orthogonal X-Y vectors */
640  {
641  GenerateCrossProductEquations(linkVars[3],linkVars[4],linkVars[5], /* Y */
642  linkVars[6],linkVars[7],linkVars[8], /* Z */
643  linkVars[0],linkVars[1],linkVars[2], /* X */
644  NO_UINT,1.0,eq);
645  for(i=0;i<3;i++)
646  {
647  AddEquation2CS(p,&(eq[i]),cs);
648  DeleteEquation(&(eq[i]));
649  }
650  }
651  /*********************************************************************/
652  #endif
653  }
654 
655  free(vname);
656  }
657 }
658 
659 void GenerateLinkRotLinks(Tparameters *p,unsigned int lID,TCuikSystem *cs,Tlink *l)
660 {
661  if (!IsGroundLink(lID))
662  {
663  char *vname;
664 
665  /*If the cuiksytem already has the link variables (and thus the corresponding equations)
666  there is nothing to be done. */
667 
668  NEW(vname,strlen(l->name)+100,char);
669 
670  LINK_ROT2(vname,l->name,0,0);
671 
672  if (GetCSVariableID(vname,cs)==NO_UINT)
673  {
674  unsigned int i,j;
675  Tinterval range;
676  Tequation eqn;
677  unsigned int linkVars[12];
678  Tvariable var;
679 
680  NewInterval(-1.0,1.0,&range);
681  /* vectors u,v,w,wp */
682  for(i=0;i<4;i++) /*vector*/
683  {
684  for(j=0;j<3;j++) /*component*/
685  {
686  LINK_ROT2(vname,l->name,i,j);
687  NewVariable((i<2?SYSTEM_VAR:DUMMY_VAR),vname,&var);
688  SetVariableInterval(&range,&var);
689  linkVars[i*3+j]=AddVariable2CS(&var,cs);
690  DeleteVariable(&var);
691  }
692  }
693 
694  GenerateScaledSaddleEquation(l->s,linkVars[1],linkVars[5],linkVars[6],&eqn);
695  AddEquation2CS(p,&eqn,cs);
696  DeleteEquation(&eqn);
697 
698  GenerateScaledSaddleEquation(l->s,linkVars[2],linkVars[3],linkVars[7],&eqn);
699  AddEquation2CS(p,&eqn,cs);
700  DeleteEquation(&eqn);
701 
702  GenerateScaledSaddleEquation(l->s,linkVars[0],linkVars[4],linkVars[8],&eqn);
703  AddEquation2CS(p,&eqn,cs);
704  DeleteEquation(&eqn);
705 
706  GenerateScaledSaddleEquation(l->s,linkVars[2],linkVars[4],linkVars[9],&eqn);
707  AddEquation2CS(p,&eqn,cs);
708  DeleteEquation(&eqn);
709 
710  GenerateScaledSaddleEquation(l->s,linkVars[0],linkVars[5],linkVars[10],&eqn);
711  AddEquation2CS(p,&eqn,cs);
712  DeleteEquation(&eqn);
713 
714  GenerateScaledSaddleEquation(l->s,linkVars[1],linkVars[3],linkVars[11],&eqn);
715  AddEquation2CS(p,&eqn,cs);
716  DeleteEquation(&eqn);
717 
718  for(i=0;i<2;i++)
719  {
720  GenerateNormEquation(linkVars[3*i+0],linkVars[3*i+1],linkVars[3*i+2],1.0,&eqn);
721  AddEquation2CS(p,&eqn,cs);
722  DeleteEquation(&eqn);
723  }
724 
725  GenerateDotProductEquation(linkVars[0],linkVars[1],linkVars[2], /* X */
726  linkVars[3],linkVars[4],linkVars[5], /* Y */
727  NO_UINT,l->c,&eqn);
728  AddEquation2CS(p,&eqn,cs);
729  DeleteEquation(&eqn);
730  }
731 
732  free(vname);
733  }
734 }
735 
736 void GenerateLinkRotQLinks(Tparameters *p,unsigned int lID,TCuikSystem *cs,Tlink *l)
737 {
738  if (!IsGroundLink(lID))
739  {
740  char *vname;
741 
742  /*If the cuiksytem already has the link variables (and thus the corresponding equations)
743  there is nothing to be done. */
744 
745  NEW(vname,strlen(l->name)+100,char);
746 
747  LINK_ROT3_E(vname,l->name,0,0);
748 
749  if (GetCSVariableID(vname,cs)==NO_UINT)
750  {
751  unsigned int i,j,n;
752  Tinterval range,range2;
753  Tequation eqn;
754  unsigned int linkVars[10];
755  unsigned int qVars[4];
756  Tvariable var;
757  Tmonomial f;
758 
759  NewInterval(-1.0,1.0,&range);
760  NewInterval(0.0,1.0,&range2);
761 
762  n=0;
763  for(i=0;i<4;i++)
764  {
765  for(j=i;j<4;j++)
766  {
767  LINK_ROT3_E(vname,l->name,i,j);
768  NewVariable(DUMMY_VAR,vname,&var);
769  if (i==j)
770  SetVariableInterval(&range2,&var);
771  else
772  SetVariableInterval(&range,&var);
773  linkVars[n]=AddVariable2CS(&var,cs);
774  n++;
775  DeleteVariable(&var);
776  }
777  }
778 
779  for(j=0;j<4;j++)
780  {
781  LINK_ROT3_Q(vname,l->name,j);
782  NewVariable(SYSTEM_VAR,vname,&var);
783  if (j==0)
784  SetVariableInterval(&range2,&var);
785  else
786  SetVariableInterval(&range,&var);
787  qVars[j]=AddVariable2CS(&var,cs);
788  DeleteVariable(&var);
789  }
790 
791  /* Add the relation between the E variables (dummies) and the
792  Q variables (system) */
793  n=0;
794  for(i=0;i<4;i++)
795  {
796  for(j=i;j<4;j++)
797  {
798  /* When i=j (-> qVars[i]==qVars[j]) a parabola equation is generated! */
799  GenerateSaddleEquation(qVars[i],qVars[j],linkVars[n],&eqn);
800  AddEquation2CS(p,&eqn,cs);
801  DeleteEquation(&eqn);
802  n++;
803  }
804  }
805 
806  /* norm of the Q (system) variables is 1 (we use the already introduced
807  dummy e_i variables) */
808  InitEquation(&eqn);
809  InitMonomial(&f);
810 
811  AddVariable2Monomial(NFUN,linkVars[0],1,&f);
812  AddMonomial(&f,&eqn);ResetMonomial(&f);
813  AddVariable2Monomial(NFUN,linkVars[4],1,&f);
814  AddMonomial(&f,&eqn);ResetMonomial(&f);
815  AddVariable2Monomial(NFUN,linkVars[7],1,&f);
816  AddMonomial(&f,&eqn);ResetMonomial(&f);
817  AddVariable2Monomial(NFUN,linkVars[9],1,&f);
818  AddMonomial(&f,&eqn);
819 
820  DeleteMonomial(&f);
821 
822  SetEquationCmp(EQU,&eqn);
823  SetEquationValue(1,&eqn);
825 
826  AddEquation2CS(p,&eqn,cs);
827  DeleteEquation(&eqn);
828 
829  }
830  free(vname);
831  }
832 }
833 
835  double sf,unsigned int sv,double *p,Tequation *eq,
836  TCuikSystem *cs,boolean groundLink,Tlink *l)
837 {
838  unsigned int r;
839 
840  r=(unsigned int)(GetParameter(CT_REPRESENTATION,pr));
841  switch(r)
842  {
843  case REP_LINKS:
844  ApplyLinkRotLinks(sf,sv,p,eq,cs,groundLink,l);
845  break;
846  case REP_FLINKS:
847  ApplyLinkRotFLinks(sf,sv,p,eq,cs,groundLink,l);
848  break;
849  case REP_QLINKS:
850  ApplyLinkRotQLinks(sf,sv,p,eq,cs,groundLink,l);
851  break;
852  case REP_JOINTS:
853  break;
854  default:
855  Error("Undefined representation type in ApplyLinkRot");
856  }
857 }
858 
859 void ApplyLinkRotFLinks(double sf,unsigned int sv,double *p,Tequation *eq,
860  TCuikSystem *cs,boolean groundLink,Tlink *l)
861 {
862  /*
863  sf*sv*R*T(px py px) where T is defined from the linkVars (check that hasVars==TRUE)
864  */
865 
866  Tmonomial f;
867  unsigned int i;
868 
869  InitMonomial(&f);
870  if (groundLink)
871  {
872  for(i=0;i<3;i++)
873  {
874  if (sv!=NO_UINT)
875  AddVariable2Monomial(NFUN,sv,1,&f);
876  AddCt2Monomial(sf*p[i],&f);
877 
878  AddMonomial(&f,&(eq[i]));
879  ResetMonomial(&f);
880  }
881  }
882  else
883  {
884  unsigned int j;
885  unsigned int linkVars[9];
886  char *vname;
887  double pInt[3];
888 
889  HTransformApply(p,pInt,&(l->R));
890 
891  NEW(vname,strlen(l->name)+100,char);
892 
893  for(i=0;i<3;i++)
894  {
895  for(j=0;j<3;j++)
896  {
897  LINK_ROT(vname,l->name,i,j);
898  linkVars[i*3+j]=GetCSVariableID(vname,cs);
899  if (linkVars[i*3+j]==NO_UINT)
900  Error("Undefined reference variable in ApplyLinkRotFM");
901  }
902  }
903 
904  for(i=0;i<3;i++)
905  {
906  for(j=0;j<3;j++)
907  {
908  if (fabs(pInt[j])>ZERO)
909  {
910  AddVariable2Monomial(NFUN,linkVars[j*3+i],1,&f);
911  if (sv!=NO_UINT)
912  AddVariable2Monomial(NFUN,sv,1,&f);
913  AddCt2Monomial(sf*pInt[j],&f);
914 
915  AddMonomial(&f,&(eq[i]));
916  ResetMonomial(&f);
917  }
918  }
919  }
920  free(vname);
921  }
922  DeleteMonomial(&f);
923 }
924 
925 void ApplyLinkRotLinks(double sf,unsigned int sv,double *p,Tequation *eq,
926  TCuikSystem *cs,boolean groundLink,Tlink *l)
927 {
928  /*
929  sf*sv*R*T(px py px) where T is defined from the linkVars (check that hasVars==TRUE)
930  */
931 
932  Tmonomial f;
933 
934  InitMonomial(&f);
935  if (groundLink)
936  {
937  unsigned int i;
938 
939  for(i=0;i<3;i++)
940  {
941  if (sv!=NO_UINT)
942  AddVariable2Monomial(NFUN,sv,1,&f);
943  AddCt2Monomial(sf*p[i],&f);
944 
945  AddMonomial(&f,&(eq[i]));
946  ResetMonomial(&f);
947  }
948  }
949  else
950  {
951  unsigned int i,j,n;
952  unsigned int linkVars[12];
953  char *vname;
954  double pInt[3];
955 
956  HTransformApply(p,pInt,&(l->R));
957 
958  NEW(vname,strlen(l->name)+100,char);
959 
960  for(i=0;i<4;i++) /*vector*/
961  {
962  for(j=0;j<3;j++) /*component*/
963  {
964  LINK_ROT2(vname,l->name,i,j);
965  n=i*3+j;
966  linkVars[n]=GetCSVariableID(vname,cs);
967  if (linkVars[n]==NO_UINT)
968  Error("Undefined reference variable in ApplyLinkRotPM");
969  }
970  }
971 
972  for(i=0;i<3;i++) /*row*/
973  {
974  for(j=0;j<4;j++) /*column*/
975  {
976  if (fabs(pInt[(j<2?j:2)])>ZERO)
977  {
978  AddVariable2Monomial(NFUN,linkVars[j*3+i],1,&f);
979  if (sv!=NO_UINT)
980  AddVariable2Monomial(NFUN,sv,1,&f);
981  AddCt2Monomial((j==3?-1:1)*sf*pInt[(j<2?j:2)],&f);
982 
983  AddMonomial(&f,&(eq[i]));
984  ResetMonomial(&f);
985  }
986  }
987  }
988 
989  free(vname);
990  }
991  DeleteMonomial(&f);
992 }
993 
994 void ApplyLinkRotQLinks(double sf,unsigned int sv,double *p,Tequation *eq,
995  TCuikSystem *cs,boolean groundLink,Tlink *l)
996 {
997  /*
998  sf*sv*R*T(px py px) where T is defined from the linkVars (check that hasVars==TRUE)
999  (R=Id for quaternions -> not used)
1000  */
1001 
1002  Tmonomial f;
1003  unsigned int i;
1004 
1005  /*Note that quaternions asume an orthonormal rotation matrix (i.e., we do not allow
1006  the change of the link reference)*/
1007 
1008  InitMonomial(&f);
1009  if (groundLink)
1010  {
1011  unsigned int j;
1012 
1013  double id[3][3]={{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}};
1014  /*
1015  double id[3][3]={{0.82559761618954,-0.52917109941051,-0.19587374426100},
1016  {0.20084362075732, 0.59999081140825,-0.77438547650815},
1017  {0.52730486072408, 0.59999081140825, 0.60163162324002}};
1018  */
1019  double ct;
1020 
1021  for(i=0;i<3;i++)
1022  {
1023  ct=0.0;
1024  for(j=0;j<3;j++)
1025  ct+=id[i][j]*p[j];
1026 
1027  if (sv!=NO_UINT)
1028  AddVariable2Monomial(NFUN,sv,1,&f);
1029  AddCt2Monomial(sf*ct,&f);
1030 
1031  AddMonomial(&f,&(eq[i]));
1032  ResetMonomial(&f);
1033  }
1034  }
1035  else
1036  {
1037  unsigned int i,j,n;
1038  unsigned int linkVars[10];
1039  char *vname;
1040  unsigned int map[2][3][3]={
1041  {{4,1,2},
1042  {1,0,5},
1043  {2,5,0}},
1044  {{7,8,6},
1045  {8,7,3},
1046  {6,3,4}}};
1047  double sg[2][3][3]={
1048  {{-1.0,+1.0,+1.0},
1049  {+1.0,-1.0,+1.0},
1050  {+1.0,+1.0,-1.0}},
1051  {{-1.0,-1.0,+1.0},
1052  {+1.0,-1.0,-1.0},
1053  {-1.0,+1.0,-1.0}}};
1054 
1055  NEW(vname,strlen(l->name)+100,char);
1056 
1057  n=0;
1058  for(i=0;i<4;i++)
1059  {
1060  for(j=i;j<4;j++)
1061  {
1062  LINK_ROT3_E(vname,l->name,i,j);
1063  linkVars[n]=GetCSVariableID(vname,cs);
1064  if (linkVars[n]==NO_UINT)
1065  Error("Undefined reference variable in ApplyLinkRot");
1066  n++;
1067  }
1068  }
1069 
1070  /* Diagonal elements */
1071  for(i=0;i<3;i++)
1072  {
1073  if (sv!=NO_UINT)
1074  AddVariable2Monomial(NFUN,sv,1,&f);
1075  AddCt2Monomial(sf*p[i],&f);
1076 
1077  AddMonomial(&f,&(eq[i]));
1078  ResetMonomial(&f);
1079  }
1080 
1081  for(n=0;n<2;n++)
1082  {
1083  for(i=0;i<3;i++) /*row*/
1084  {
1085  for(j=0;j<3;j++) /*column*/
1086  {
1087  if (fabs(p[j])>ZERO)
1088  {
1089  AddVariable2Monomial(NFUN,linkVars[map[n][i][j]],1,&f);
1090  if (sv!=NO_UINT)
1091  AddVariable2Monomial(NFUN,sv,1,&f);
1092  AddCt2Monomial(2.0*sg[n][i][j]*sf*p[j],&f);
1093 
1094  AddMonomial(&f,&(eq[i]));
1095  ResetMonomial(&f);
1096  }
1097  }
1098  }
1099  }
1100 
1101  free(vname);
1102  }
1103  DeleteMonomial(&f);
1104 }
1105 
1106 void ApplyLinkRotVar(Tparameters *pr,double sf,unsigned int *vID,Tequation *eq,
1107  TCuikSystem *cs,boolean groundLink,Tlink *l)
1108 {
1109  unsigned int r;
1110 
1111  r=(unsigned int)(GetParameter(CT_REPRESENTATION,pr));
1112  if (r!=REP_JOINTS)
1113  {
1114  Tequation u[3],v[3],w[3];
1115  unsigned int i,j;
1116  double ct[3];
1117 
1118  for(i=0;i<3;i++)
1119  {
1120  InitEquation(&(u[i]));
1121  InitEquation(&(v[i]));
1122  InitEquation(&(w[i]));
1123  }
1124  /* We have to compute M*R*[vID]
1125  M=matrix given by the link variables (=M*iR)
1126  R=Basis change
1127  vID=given variable vector
1128  This is computed as (M*R)*[vID]
1129  First [u v w]=M*R
1130  u=M*R_1 (first column or R)
1131  v=M*R_2 (second column or R)
1132  w=M*R_3 (third column or R)
1133  and then [u v w]*[vID] -> linear combination of u,v,w*/
1134  for(i=0;i<3;i++)
1135  {
1136  for(j=0;j<3;j++)
1137  ct[j]=l->R[j][i];
1138  ApplyLinkRot(pr,sf,NO_UINT,ct,(i==0?u:(i==1?v:w)),cs,groundLink,l);
1139  }
1140  for(i=0;i<3;i++)
1141  {
1142  VarAccumulateEquations(&(u[i]),vID[0],&(eq[i]));
1143  VarAccumulateEquations(&(v[i]),vID[1],&(eq[i]));
1144  VarAccumulateEquations(&(w[i]),vID[2],&(eq[i]));
1145  }
1146  for(i=0;i<3;i++)
1147  {
1148  DeleteEquation(&(u[i]));
1149  DeleteEquation(&(v[i]));
1150  DeleteEquation(&(w[i]));
1151  }
1152  }
1153 }
1154 
1156  boolean groundLink,Tlink *l)
1157 {
1158  unsigned int r;
1159 
1160  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1161  switch(r)
1162  {
1163  case REP_LINKS:
1164  RegenerateLinkSolutionLinks(cs,sol,groundLink,l);
1165  break;
1166  case REP_FLINKS:
1167  /* When using 9 variables all variables used to represent the
1168  rotation of the link are system variables and, thus, no
1169  dummy has to be computed.*/
1170  break;
1171  case REP_QLINKS:
1172  RegenerateLinkSolutionQLinks(cs,sol,groundLink,l);
1173  break;
1174  case REP_JOINTS:
1175  break;
1176  default:
1177  Error("Undefined representation type in RegenerateLinkSolution");
1178  }
1179 }
1180 
1181 void RegenerateLinkSolutionLinks(TCuikSystem *cs,double *sol,boolean groundLink,Tlink *l)
1182 {
1183  if (!groundLink)
1184  {
1185  CacheRotVarsLinks(cs,l);
1186 
1187  /* compute w and wp from u and v (recall that u X v = s*(w - wp) )*/
1188  sol[l->vID[6]]=sol[l->vID[1]]*sol[l->vID[5]]/l->s;
1189  sol[l->vID[7]]=sol[l->vID[2]]*sol[l->vID[3]]/l->s;
1190  sol[l->vID[8]]=sol[l->vID[0]]*sol[l->vID[4]]/l->s;
1191 
1192  sol[l->vID[9]] =sol[l->vID[2]]*sol[l->vID[4]]/l->s;
1193  sol[l->vID[10]]=sol[l->vID[0]]*sol[l->vID[5]]/l->s;
1194  sol[l->vID[11]]=sol[l->vID[1]]*sol[l->vID[3]]/l->s;
1195  }
1196 }
1197 
1198 void RegenerateLinkSolutionQLinks(TCuikSystem *cs,double *sol,boolean groundLink,Tlink *l)
1199 {
1200  if (!groundLink)
1201  {
1202  unsigned int i,j,n;
1203  double qVars[4];
1204 
1205  CacheRotVarsQLinks(cs,l);
1206 
1207  for(j=0;j<4;j++)
1208  qVars[j]=sol[l->vID[j]];
1209 
1210  n=4;
1211  for(i=0;i<4;i++)
1212  {
1213  for(j=i;j<4;j++)
1214  {
1215  sol[l->vID[n]]=qVars[i]*qVars[j];
1216  n++;
1217  }
1218  }
1219  }
1220 }
1221 
1223  boolean groundLink,Tlink *l)
1224 {
1225  unsigned int r;
1226 
1227  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1228  switch(r)
1229  {
1230  case REP_LINKS:
1231  RegenerateLinkBoxLinks(cs,b,groundLink,l);
1232  break;
1233  case REP_FLINKS:
1234  /* When using 9 variables all variables used to represent the
1235  rotation of the link are system variables and, thus, no
1236  dummy has to be computed.*/
1237  break;
1238  case REP_QLINKS:
1239  RegenerateLinkBoxQLinks(cs,b,groundLink,l);
1240  break;
1241  case REP_JOINTS:
1242  break;
1243  default:
1244  Error("Undefined representation type in RegenerateLinkBox");
1245  }
1246 }
1247 
1248 void RegenerateLinkBoxLinks(TCuikSystem *cs,Tbox *b,boolean groundLink,Tlink *l)
1249 {
1250  if (!groundLink)
1251  {
1252  Tinterval r,*is;
1253 
1254  CacheRotVarsLinks(cs,l);
1255 
1256  is=GetBoxIntervals(b);
1257 
1258  /* compute w and wp from u and v (recall that u X v = s*(w - wp)) */
1259  IntervalProduct(&(is[l->vID[1]]),&(is[l->vID[5]]),&r);
1260  IntervalScale(&r,1/l->s,&r);
1261  SetBoxInterval(l->vID[6],&r,b);
1262 
1263  IntervalProduct(&(is[l->vID[2]]),&(is[l->vID[3]]),&r);
1264  IntervalScale(&r,1/l->s,&r);
1265  SetBoxInterval(l->vID[7],&r,b);
1266 
1267  IntervalProduct(&(is[l->vID[0]]),&(is[l->vID[4]]),&r);
1268  IntervalScale(&r,1/l->s,&r);
1269  SetBoxInterval(l->vID[8],&r,b);
1270 
1271  IntervalProduct(&(is[l->vID[2]]),&(is[l->vID[4]]),&r);
1272  IntervalScale(&r,1/l->s,&r);
1273  SetBoxInterval(l->vID[9],&r,b);
1274 
1275  IntervalProduct(&(is[l->vID[0]]),&(is[l->vID[5]]),&r);
1276  IntervalScale(&r,1/l->s,&r);
1277  SetBoxInterval(l->vID[10],&r,b);
1278 
1279  IntervalProduct(&(is[l->vID[1]]),&(is[l->vID[3]]),&r);
1280  IntervalScale(&r,1/l->s,&r);
1281  SetBoxInterval(l->vID[11],&r,b);
1282  }
1283 }
1284 
1285 void RegenerateLinkBoxQLinks(TCuikSystem *cs,Tbox *b,boolean groundLink,Tlink *l)
1286 {
1287  if (!groundLink)
1288  {
1289  unsigned int i,j,n;
1290  Tinterval qVars[4];
1291  Tinterval r;
1292 
1293  CacheRotVarsQLinks(cs,l);
1294 
1295  for(j=0;j<4;j++)
1296  CopyInterval(&(qVars[j]),GetBoxInterval(l->vID[j],b));
1297 
1298  n=4;
1299  for(i=0;i<4;i++)
1300  {
1301  for(j=i;j<4;j++)
1302  {
1303  IntervalProduct(&(qVars[i]),&(qVars[j]),&r);
1304  SetBoxInterval(l->vID[n],&r,b);
1305  n++;
1306  }
1307  }
1308  }
1309 }
1310 
1312  boolean groundLink,double *trans,THTransform *t,Tlink *l)
1313 {
1314  unsigned int r;
1315 
1316  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1317  switch(r)
1318  {
1319  case REP_LINKS:
1320  GetTransform2LinkLinks(cs,sol,groundLink,trans,t,l);
1321  break;
1322  case REP_FLINKS:
1323  GetTransform2LinkFLinks(cs,sol,groundLink,trans,t,l);
1324  break;
1325  case REP_QLINKS:
1326  GetTransform2LinkQLinks(cs,sol,groundLink,trans,t,l);
1327  break;
1328  case REP_JOINTS:
1329  break;
1330  default:
1331  Error("Undefined representation type in GetTransform2Link");
1332  }
1333 }
1334 
1335 void GetTransform2LinkFLinks(TCuikSystem *cs,double *sol,boolean groundLink,
1336  double *r,THTransform *t,Tlink *l)
1337 {
1338  if (groundLink)
1339  HTransformIdentity(t);
1340  else
1341  {
1342  unsigned int i,j;
1343 
1344  CacheRotVarsFLinks(cs,l);
1345 
1346  /* Define the homogeneous transform using the rotation and the translation.*/
1347  HTransformIdentity(t);
1348  for(i=0;i<3;i++)
1349  {
1350  HTransformSetElement(i,AXIS_H,r[i],t);
1351  for(j=0;j<3;j++)
1352  HTransformSetElement(i,j,sol[l->vID[i+j*3]],t);
1353  }
1354 
1355  /* The link variables representing the link rotation encode
1356  M*iR
1357  M = orthonormal rotation matrix
1358  iR= basis change to obtain a more numerically safe basis
1359  The orthonormal matrix is obtained by multiplying
1360  (M*iR)*R
1361 
1362  See ChangeLinkReferenceFrame
1363  */
1364  HTransformProduct(t,&(l->R),t);
1365  /* This ensures that the transformation is actually rigid
1366  (fixes numerical errors and the error of taking the center
1367  of the solution box as a proper solution) */
1369  }
1370 }
1371 
1372 void GetTransform2LinkLinks(TCuikSystem *cs,double *sol,boolean groundLink,
1373  double *r,THTransform *t,Tlink *l)
1374 {
1375  if (groundLink)
1376  HTransformIdentity(t);
1377  else
1378  {
1379  unsigned int i,j;
1380 
1381  CacheRotVarsLinks(cs,l);
1382 
1383  /* Define the homogeneous transform using the rotation and the translation.*/
1384  HTransformIdentity(t);
1385  for(i=0;i<3;i++) /* component */
1386  {
1387  HTransformSetElement(i,AXIS_H,r[i],t);
1388  for(j=0;j<3;j++) /* vector */
1389  {
1390  if (j<2)
1391  HTransformSetElement(i,j,sol[l->vID[i+j*3]],t);
1392  else
1393  HTransformSetElement(i,j,(sol[l->vID[i+j*3]]-sol[l->vID[i+(j+1)*3]]),t);
1394  }
1395  }
1396 
1397  /* The link variables representing the link rotation encode
1398  M*iR
1399  M = orthonormal rotation matrix
1400  iR= basis change to obtain a more numerically safe basis
1401  The orthonormal matrix is obtained by multiplying
1402  (M*iR)*R
1403 
1404  See ChangeLinkReferenceFrame
1405  */
1406  HTransformProduct(t,&(l->R),t);
1407  /* This ensures that the transformation is actually rigid
1408  (fixes numerical errors and the error of taking the center
1409  of the solution box as a proper solution) */
1411  }
1412 }
1413 
1414 
1415 void GetTransform2LinkQLinks(TCuikSystem *cs,double *sol,boolean groundLink,
1416  double *r,THTransform *t,Tlink *l)
1417 {
1418  if (groundLink)
1419  HTransformIdentity(t);
1420  else
1421  {
1422  unsigned int i,j,n;
1423  double e[4][4]; /* only the upper half is used */
1424 
1425  n=4;
1426  for(i=0;i<4;i++)
1427  {
1428  for(j=i;j<4;j++)
1429  {
1430  e[i][j]=2*sol[l->vID[n]];
1431  n++;
1432  }
1433  }
1434 
1435  /* Define the homogeneous transform using the rotation and the translation.*/
1436  HTransformIdentity(t);
1437 
1438  HTransformSetElement(0,0,1-e[1][1]-e[2][2],t);
1439  HTransformSetElement(0,1, e[0][1]-e[2][3],t);
1440  HTransformSetElement(0,2, e[0][2]+e[1][3],t);
1441  HTransformSetElement(0,3,r[0],t);
1442 
1443  HTransformSetElement(1,0, e[0][1]+e[2][3],t);
1444  HTransformSetElement(1,1,1-e[0][0]-e[2][2],t);
1445  HTransformSetElement(1,2, e[1][2]-e[0][3],t);
1446  HTransformSetElement(1,3,r[1],t);
1447 
1448  HTransformSetElement(2,0, e[0][2]-e[1][3],t);
1449  HTransformSetElement(2,1, e[1][2]+e[0][3],t);
1450  HTransformSetElement(2,2,1-e[0][0]-e[1][1],t);
1451  HTransformSetElement(2,3,r[2],t);
1452 
1453  /* No basis change (R) is used in Quaternion representation */
1454 
1455  /* This ensures that the transformation is actually rigid */
1457  }
1458 }
1459 
1461  double *sol,boolean groundLink,Tlink *l)
1462 {
1463  unsigned int r;
1464 
1465  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1466  switch(r)
1467  {
1468  case REP_LINKS:
1469  GenerateLinkSolutionLinks(t,cs,sol,groundLink,l);
1470  break;
1471  case REP_FLINKS:
1472  GenerateLinkSolutionFLinks(t,cs,sol,groundLink,l);
1473  break;
1474  case REP_QLINKS:
1475  GenerateLinkSolutionQLinks(t,cs,sol,groundLink,l);
1476  break;
1477  case REP_JOINTS:
1478  break;
1479  default:
1480  Error("Undefined representation type in GenerateLinkSolution");
1481  }
1482 }
1483 
1485  double *sol,boolean groundLink,Tlink *l)
1486 {
1487  if (!groundLink)
1488  {
1489  unsigned int i,j,n;
1490  THTransform it;
1491 
1492  /* The link variables encode (M*iR) and the given 't' is only M */
1493  HTransformProduct(t,&(l->iR),&it);
1494 
1495  CacheRotVarsFLinks(cs,l);
1496 
1497  n=0;
1498  for(i=0;i<3;i++) /*vector*/
1499  {
1500  for(j=0;j<3;j++) /*component*/
1501  {
1502  sol[l->vID[n]]=HTransformGetElement(j,i,&it);
1503  n++;
1504  }
1505  }
1506  HTransformDelete(&it);
1507  }
1508 }
1509 
1511  double *sol,boolean groundLink,Tlink *l)
1512 {
1513  if (!groundLink)
1514  {
1515  unsigned int i,j,n;
1516  THTransform it;
1517 
1518  /* The link variables encode (M*iR) and the given 't' is only M */
1519  HTransformProduct(t,&(l->iR),&it);
1520 
1521  CacheRotVarsLinks(cs,l);
1522 
1523  n=0;
1524  for(i=0;i<2;i++) /*vector*/
1525  {
1526  for(j=0;j<3;j++) /*componet*/
1527  {
1528  sol[l->vID[n]]=HTransformGetElement(j,i,&it);
1529  n++;
1530  }
1531  }
1532  HTransformDelete(&it);
1533 
1534  RegenerateLinkSolutionLinks(cs,sol,groundLink,l);
1535  }
1536 }
1537 
1539  double *sol,boolean groundLink,Tlink *l)
1540 {
1541  if (!groundLink)
1542  {
1543  double r,s,q;
1544 
1545  CacheRotVarsQLinks(cs,l);
1546 
1547  /* Recover the 4 quaternion elements from the transformation
1548  matrix*/
1549  q=HTransformGetElement(0,0,t)+
1550  HTransformGetElement(1,1,t)+
1551  HTransformGetElement(2,2,t);
1552  r=sqrt(1+q);
1553  s=0.5/r;
1554 
1555  sol[l->vID[0]]=0.5*r;
1556  sol[l->vID[1]]=(HTransformGetElement(2,1,t)-HTransformGetElement(1,2,t))*s;
1557  sol[l->vID[2]]=(HTransformGetElement(0,2,t)-HTransformGetElement(2,0,t))*s;
1558  sol[l->vID[3]]=(HTransformGetElement(1,0,t)-HTransformGetElement(0,1,t))*s;
1559 
1560  RegenerateLinkSolutionQLinks(cs,sol,groundLink,l);
1561  }
1562 }
1563 
1564 boolean VisibleLink(Tlink *l)
1565 {
1566  /* A visible link is a link with at least one visible body */
1567  unsigned int i,n;
1568  boolean found;
1569 
1570  found=FALSE;
1571 
1572  n=LinkNBodies(l);
1573 
1574  for(i=0;((i<n)&&(!found));i++)
1576 
1577  return(found);
1578 }
1579 
1581 {
1582  return(l->maxCoord);
1583 }
1584 
1585 void PlotLink(Tplot3d *pt,double axesLength,Tlink *l)
1586 {
1587  unsigned int n;
1588 
1589  n=LinkNBodies(l);
1590 
1591  if ((n>0)&&(VisibleLink(l)))
1592  {
1593  unsigned int i;
1594 
1595  for(i=0;i<n;i++)
1596  PlotPolyhedron(pt,GetLinkBody(i,l));
1597 
1598  if (axesLength>0)
1599  {
1600  double points[3][2]={{0,0},{0,0},{0,0}};
1601  Tcolor axesColor;
1602 
1603  for(i=0;i<3;i++)
1604  {
1605  NewColor((i==0?1:0),(i==1?1:0),(i==2?1:0),&axesColor);
1606  l->axisID[i]=StartNew3dObject(&axesColor,pt);
1607  DeleteColor(&axesColor);
1608 
1609  points[i][1]=axesLength;
1610  PlotVect3d(2,points[0],points[1],points[2],pt);
1611  points[i][1]=0;
1612 
1613  Close3dObject(pt);
1614  }
1615  }
1616  else
1617  {
1618  for(i=0;i<3;i++)
1619  l->axisID[i]=NO_UINT;
1620  }
1621  }
1622 }
1623 
1624 void LinkPrintAtoms(FILE *f,THTransform *tl,Tlink *l)
1625 {
1626  unsigned int i,m;
1627  Tpolyhedron *bd;
1628 
1629  m=LinkNBodies(l);
1630 
1631  if ((m>0)&&(VisibleLink(l)))
1632  {
1633  for(i=0;i<m;i++)
1634  {
1635  bd=GetLinkBody(i,l);
1636  PolyhedronPrintCenter(f,tl,bd);
1637  }
1638  }
1639 }
1640 
1641 void LinkStoreAtoms(FILE *f,THTransform *tl,Tlink *l)
1642 {
1643  unsigned int i,m;
1644  Tpolyhedron *bd;
1645 
1646  m=LinkNBodies(l);
1647 
1648  if ((m>0)&&(VisibleLink(l)))
1649  {
1650  for(i=0;i<m;i++)
1651  {
1652  bd=GetLinkBody(i,l);
1654  }
1655  }
1656 }
1657 
1659 {
1660  unsigned int m;
1661 
1662  m=LinkNBodies(l);
1663 
1664  if ((m>0)&&(VisibleLink(l)))
1665  {
1666  /* Systems not included in any loop are not in the system -> can
1667  not be moved (can move freely)*/
1668 
1669  unsigned int i;
1670  Tpolyhedron *bd;
1671 
1672  for(i=0;i<3;i++)
1673  {
1674  if (l->axisID[i]!=NO_UINT)
1675  Move3dObject(l->axisID[i],t,pt);
1676  }
1677 
1678  /*Apply the same transform to all the bodies in the link*/
1679  for(i=0;i<m;i++)
1680  {
1681  bd=GetLinkBody(i,l);
1682  MovePolyhedron(pt,t,bd);
1683  }
1684  }
1685 }
1686 
1687 void PrintLink(FILE *f,char *path,char *prefix,Tlink *l)
1688 {
1689  unsigned int i;
1690  unsigned int n;
1691  Tpolyhedron *b;
1692  char *label;
1693 
1694  if (prefix==NULL)
1695  label=l->name;
1696  else
1697  {
1698  unsigned int ln,lp;
1699 
1700  ln=strlen(l->name);
1701  lp=strlen(prefix);
1702  NEW(label,ln+2+lp,char);
1703  sprintf(label,"%s_%s",prefix,l->name);
1704  label[lp+ln+1]=0;
1705  }
1706 
1707  fprintf(f," %s ",l->name);
1708  n=LinkNBodies(l);
1709  if (n>0)
1710  fprintf(f,": ");
1711  for(i=0;i<n;i++)
1712  {
1713  b=GetLinkBody(i,l);
1714  PrintPolyhedron(f,path,label,i,b);
1715  }
1716  fprintf(f,"\n");
1717 
1718  if (prefix!=NULL)
1719  free(label);
1720 }
1721 
1723 {
1724  unsigned int i,n;
1725  Tpolyhedron *b;
1726 
1727  if (l->name!=NULL)
1728  free(l->name);
1729 
1730  /*Bodies are not deleted since mechanisms take care of them
1731  (here we only have IDs of the bodies)*/
1732 
1733  n=LinkNBodies(l);
1734  for(i=0;i<n;i++)
1735  {
1736  b=GetLinkBody(i,l);
1737  DeletePolyhedron(b);
1738  free(b);
1739  }
1740  DeleteVector(&(l->bodies));
1741 
1742  HTransformDelete(&(l->R));
1743  HTransformDelete(&(l->iR));
1744 
1745  if (l->csvID!=NULL)
1746  {
1747  free(l->vID);
1748  l->vID=NULL;
1749  l->csvID=NULL;
1750  l->nvID=0;
1751  }
1752 }
void PlotVect3d(unsigned int n, double *x, double *y, double *z, Tplot3d *p)
Adds a polyline to the current object.
Definition: plot3d.c:447
void DeleteVector(void *vector)
Destructor.
Definition: vector.c:388
Tinterval * GetBoxInterval(unsigned int n, Tbox *b)
Returns a pointer to one of the intervals defining the box.
Definition: box.c:270
#define SYSTEM_EQ
One of the possible type of equations.
Definition: equation.h:146
#define REP_JOINTS
One of the possible values of the REPRESENTATION parameter.
Definition: parameters.h:60
unsigned int VectorSize(Tvector *vector)
Gets the number of elements in a vector.
Definition: vector.c:169
#define FALSE
FALSE.
Definition: boolean.h:30
void HTransformApply(double *p_in, double *p_out, THTransform *t)
Multiply a homogeneous transform and a vector.
Definition: htransform.c:728
void GenerateSaddleEquation(unsigned int vx, unsigned int vy, unsigned int vz, Tequation *eq)
Construtor. Generates a saddle equation.
Definition: equation.c:1392
#define REP_FLINKS
One of the possible values of the REPRESENTATION parameter.
Definition: parameters.h:37
#define REP_LINKS
One of the possible values of the REPRESENTATION parameter.
Definition: parameters.h:27
void SetEquationType(unsigned int type, Tequation *eq)
Changes the type of the equation (SYSTEM_EQ, CARTESIAN_EQ, DUMMY_EQ, DERIVED_EQ). ...
Definition: equation.c:1013
void GenerateCrossProductEquations(unsigned int v1x, unsigned int v1y, unsigned int v1z, unsigned int v2x, unsigned int v2y, unsigned int v2z, unsigned int v3x, unsigned int v3y, unsigned int v3z, unsigned int vs, double s, Tequation *eq)
Construtor. Generates the three equations of the cross product of two unitary vectors.
Definition: equation.c:1464
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
#define LINK_ROT3_Q(vname, linkName, j)
System variables for a rotation matrix using quaternions.
Definition: varnames.h:121
void GenerateNormEquation(unsigned int vx, unsigned int vy, unsigned int vz, double n, Tequation *eq)
Construtor. Generates an equation that is the norm of a 3d vector.
Definition: equation.c:1431
void DeleteEquation(Tequation *eq)
Destructor.
Definition: equation.c:1748
void * GetVectorElement(unsigned int i, Tvector *vector)
Returns a pointer to a vector element.
Definition: vector.c:269
A homgeneous transform in R^3.
void SetBoxInterval(unsigned int n, Tinterval *is, Tbox *b)
Replaces a particular interval in a box.
Definition: box.c:259
#define SYSTEM_VAR
One of the possible type of variables.
Definition: variable.h:24
unsigned int AddVariable2CS(Tvariable *v, TCuikSystem *cs)
Adds a variable to the system.
Definition: cuiksystem.c:2511
void PlotPolyhedron(Tplot3d *pt, Tpolyhedron *p)
Adds the polyhedron to a 3D geometry.
Definition: polyhedron.c:1255
Definition of variable names.
#define EQU
In a Tequation, the equation relational operator is equal.
Definition: equation.h:201
#define LINK_ROT(vname, linkName, vn, cn)
Frame of reference for a link.
Definition: varnames.h:68
char * GetCSVariableName(unsigned int id, TCuikSystem *cs)
Gets a variable name.
Definition: cuiksystem.c:2591
void SetVariableInterval(Tinterval *i, Tvariable *v)
Sets the new range for the variable.
Definition: variable.c:70
#define TRUE
TRUE.
Definition: boolean.h:21
void InitEquation(Tequation *eq)
Constructor.
Definition: equation.c:86
void PrintPolyhedron(FILE *f, char *path, char *label, unsigned int n, Tpolyhedron *p)
Stores the polyhedron information into a file.
Definition: polyhedron.c:1366
void Error(const char *s)
General error function.
Definition: error.c:80
#define NFUN
No trigonometric function for the variable.
Definition: variable_set.h:36
A color.
Definition: color.h:23
#define LINK_ROT3_E(vname, linkName, rn, cn)
Frame of reference for a link using quaternions.
Definition: varnames.h:106
#define AXIS_H
The homogeneous dimension in R^3.
Definition: htransform.h:108
CBLAS_INLINE void HTransformProduct(THTransform *t1, THTransform *t2, THTransform *t3)
Product of two homogeneous transforms.
Definition: htransform.c:404
#define ZERO
Floating point operations giving a value below this constant (in absolute value) are considered 0...
Definition: defines.h:37
void CopyInterval(Tinterval *i_dst, Tinterval *i_org)
Copy constructor.
Definition: interval.c:59
void SetEquationValue(double v, Tequation *eq)
Changes the right-hand value of the equation.
Definition: equation.c:1026
void CopyVoidPtr(void *a, void *b)
Copy constructor for void pointers.
Definition: vector.c:87
void Move3dObject(unsigned int nobj, THTransform *t, Tplot3d *p)
Moves a 3d object.
Definition: plot3d.c:217
void AddMonomial(Tmonomial *f, Tequation *eq)
Adds a new monomial to the equation.
Definition: equation.c:1356
A polyhedron.
Definition: polyhedron.h:124
A 3D plot.
Definition: plot3d.h:54
double HTransformGetElement(unsigned int i, unsigned int j, THTransform *t)
Gets an element in a homogeneous transform.
Definition: htransform.c:323
void SetEquationCmp(unsigned int cmp, Tequation *eq)
Changes the relational operator (LEQ, GEQ, EQU) of the equation.
Definition: equation.c:1018
void ResetMonomial(Tmonomial *f)
Reset the monomial information.
Definition: monomial.c:24
An equation.
Definition: equation.h:236
void DeleteVariable(Tvariable *v)
Destructor.
Definition: variable.c:95
void InitVector(unsigned int ele_size, void(*Copy)(void *, void *), void(*Delete)(void *), unsigned int max_ele, Tvector *vector)
Constructor.
Definition: vector.c:100
void NewVariable(unsigned int type, char *name, Tvariable *v)
Constructor.
Definition: variable.c:21
void AddEquation2CS(Tparameters *p, Tequation *eq, TCuikSystem *cs)
Adds an equation to the system.
Definition: cuiksystem.c:2481
A scaled product of powers of variables.
Definition: monomial.h:32
A table of parameters.
double GetPolyhedronMaxCoordinate(Tpolyhedron *p)
Returns the maximum coordinate value used in a polyhedron.
Definition: polyhedron.c:1250
void PolyhedronPrintCenterAndCenter(FILE *f, THTransform *t, Tpolyhedron *p)
Prints the center and the radius of a sphere to a file.
Definition: polyhedron.c:1297
#define CT_REPRESENTATION
Representation.
Definition: parameters.h:215
void GenerateScaledSaddleEquation(double s, unsigned int vx, unsigned int vy, unsigned int vz, Tequation *eq)
Construtor. Generates a scaled saddle equation.
Definition: equation.c:1398
A box.
Definition: box.h:83
#define SPHERE
One of the possible type of polyhedrons.
Definition: polyhedron.h:70
Data associated with each variable in the problem.
Definition: variable.h:84
unsigned int GetPolyhedronStatus(Tpolyhedron *p)
Gets the status of a polyhedron (NORMAL, HIDDEN, DECOR).
Definition: polyhedron.c:1170
Definition of the Tpolyhedron type and the associated functions.
void VarAccumulateEquations(Tequation *eqn, unsigned int v, Tequation *eq)
Adds an equation scaled with a variable to another equation.
Definition: equation.c:377
A cuiksystem, i.e., a set of variables and equations defining a position analysis problem...
Definition: cuiksystem.h:181
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
void MovePolyhedron(Tplot3d *pt, THTransform *t, Tpolyhedron *p)
Moves an object previously added to a 3D scene.
Definition: polyhedron.c:1309
void IntervalScale(Tinterval *i1, double e, Tinterval *i_out)
Scales an interval.
Definition: interval.c:355
void AddVariable2Monomial(unsigned int fn, unsigned int varid, unsigned int p, Tmonomial *f)
Adds a power variable to the monomial.
Definition: monomial.c:171
boolean IsSystemVarInSimpCS(Tparameters *p, char *v, TCuikSystem *cs)
Identifies system variables that survive in the simplified system.
Definition: cuiksystem.c:2596
void DeleteVoidPtr(void *a)
Destructor for void pointers.
Definition: vector.c:92
Tinterval * GetBoxIntervals(Tbox *b)
Returns a pointer to the array of intervals defining the box.
Definition: box.c:284
void HTransformDelete(THTransform *t)
Destructor.
Definition: htransform.c:833
double GetParameter(unsigned int n, Tparameters *p)
Gets the value for a particular parameter.
Definition: parameters.c:93
void DeletePolyhedron(Tpolyhedron *p)
Destructor.
Definition: polyhedron.c:1484
void IntervalProduct(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Product of two intervals.
Definition: interval.c:384
void DeleteColor(Tcolor *c)
Destructor.
Definition: color.c:93
void NewInterval(double lower, double upper, Tinterval *i)
Constructor.
Definition: interval.c:47
void HTransformSetElement(unsigned int i, unsigned int j, double v, THTransform *t)
Sets an element in a homogeneous transform.
Definition: htransform.c:306
void AddCt2Monomial(double k, Tmonomial *f)
Scales a monomial.
Definition: monomial.c:158
void HTransformCopy(THTransform *t_dst, THTransform *t_src)
Copy constructor.
Definition: htransform.c:83
unsigned int GetCSVariableID(char *name, TCuikSystem *cs)
Gets the numerical identifier of a variable given its name.
Definition: cuiksystem.c:2586
void NewColor(double r, double g, double b, Tcolor *c)
Constructor.
Definition: color.c:14
Defines a interval.
Definition: interval.h:33
void CopyPolyhedron(Tpolyhedron *p_dst, Tpolyhedron *p_src)
Copy constructor.
Definition: polyhedron.c:1051
void HTransformIdentity(THTransform *t)
Constructor.
Definition: htransform.c:69
void InitMonomial(Tmonomial *f)
Constructor.
Definition: monomial.c:17
void PolyhedronPrintCenter(FILE *f, THTransform *t, Tpolyhedron *p)
Prints the center of a sphere to a file.
Definition: polyhedron.c:1285
unsigned int StartNew3dObject(Tcolor *c, Tplot3d *p)
Start a composed object.
Definition: plot3d.c:157
void HTransformOrthonormalize(THTransform *t, THTransform *ta)
Orthonormalizes the rotation part of a homogenouos transform.
Definition: htransform.c:494
#define DUMMY_VAR
One of the possible type of variables.
Definition: variable.h:53
#define LINK_TRANS(vname, linkName, cn)
Translation part of the homogeneous transform defining the position of a link in global coordinates...
Definition: varnames.h:136
#define LINK_ROT2(vname, linkName, vn, cn)
Frame of reference for a link.
Definition: varnames.h:86
void Close3dObject(Tplot3d *p)
Closes a composed object.
Definition: plot3d.c:171
void DeleteMonomial(Tmonomial *f)
Destructor.
Definition: monomial.c:289
unsigned int GetPolyhedronType(Tpolyhedron *p)
Retrives the type of a polyhedron.
Definition: polyhedron.c:1155
void GenerateDotProductEquation(unsigned int v1x, unsigned int v1y, unsigned int v1z, unsigned int v2x, unsigned int v2y, unsigned int v2z, unsigned int vc, double c, Tequation *eq)
Construtor. Generates the equation of the dot product of two unitary vectors.
Definition: equation.c:1526
unsigned int NewVectorElement(void *e, Tvector *vector)
Adds an element to the vector.
Definition: vector.c:212
#define DECOR_SHAPE
One of the possible type of shapes.
Definition: polyhedron.h:46
#define HIDDEN_SHAPE
One of the possible type of shapes.
Definition: polyhedron.h:37
#define REP_QLINKS
One of the possible values of the REPRESENTATION parameter.
Definition: parameters.h:48