joint.c
Go to the documentation of this file.
1 #include "joint.h"
2 
3 #include "error.h"
4 #include "defines.h"
5 #include "algebra.h"
6 #include "varnames.h"
7 
8 #include <math.h>
9 #include <string.h>
10 
37 void InitJoint(unsigned int t,unsigned int id,
38  unsigned int linkID1,Tlink *link1,
39  unsigned int linkID2,Tlink *link2,
40  Tjoint *j);
41 
42 void InitJoint(unsigned int t,unsigned int id,
43  unsigned int linkID1,Tlink *link1,
44  unsigned int linkID2,Tlink *link2,
45  Tjoint *j)
46 {
47  unsigned int i,k;
48 
49  j->t=t;
50  j->id=id;
51 
52  if ((linkID1==linkID2)||(link1==link2))
53  Error("Setting up a joint on a single link");
54 
55  j->linkID[0]=linkID1;
56  j->linkID[1]=linkID2;
57  j->link[0]=link1;
58  j->link[1]=link2;
59 
60  for(i=0;i<6;i++)
61  {
62  for(k=0;k<3;k++)
63  j->points[i][k]=0.0;
64  }
65 
66  for(i=0;i<3;i++)
67  {
68  for(k=0;k<3;k++)
69  j->normals[i][k]=0.0;
70  }
71 
72  NewInterval(-INF,INF,&(j->normRange));
73 
74  j->hasLimits=FALSE;
75 
76  j->coupled=NULL;
77 
78  j->avoidLimits=FALSE;
79  j->avoidLimitsWeight=0.0;
80 
81  NewInterval(-INF,INF,&(j->range));
82  NewInterval(-INF,INF,&(j->range2));
83 
84  j->offset=0;
85  j->offset2=0;
86 
87  HTransformIdentity(&(j->preT));
89 
90  j->maxCoord=0.0;
91 }
92 
93 void NewFreeJoint(unsigned int id,
94  unsigned int linkID1,Tlink *link1,
95  unsigned int linkID2,Tlink *link2,
96  Tjoint *j)
97 {
98  InitJoint(FREE_JOINT,id,linkID1,link1,linkID2,link2,j);
99  j->maxCoord=INF;
100 }
101 
102 void NewFixJoint(unsigned int id,
103  unsigned int linkID1,Tlink *link1,
104  unsigned int linkID2,Tlink *link2,
105  THTransform *t,
106  Tjoint *j)
107 {
108  InitJoint(FIX_JOINT,id,linkID1,link1,linkID2,link2,j);
109 
110  HTransformCopy(&(j->preT),t);
111 
112  /*
113  The translation form link1 to link2 is used in loops.
114  We store it in points[0] to speed up the access
115  (see GenerateJointEquationsInBranch)
116  */
117  j->points[0][0]=HTransformGetElement(0,3,t);
118  j->points[0][1]=HTransformGetElement(1,3,t);
119  j->points[0][2]=HTransformGetElement(2,3,t);
120 
121  j->maxCoord=Norm(3,j->points[0]);
122 }
123 
124 void NewRevoluteJoint(unsigned int id,unsigned int r,
125  unsigned int linkID1,Tlink *link1,
126  unsigned int linkID2,Tlink *link2,
127  double **points,
128  boolean hasLimits,Tinterval *range,double **rPoints,
129  boolean avoidLimits,double avoidLimitsWeight,Tjoint *coupled,
130  Tjoint *j)
131 {
132  unsigned int i,k;
133  double nr;
134  double *x,*y,z[3],v[3],c;
135 
136  InitJoint(REV_JOINT,id,linkID1,link1,linkID2,link2,j);
137 
138  j->maxCoord=0;
139  for(i=0;i<4;i++)
140  {
141  for(k=0;k<3;k++)
142  j->points[i][k]=ADJUST_REAL(points[i][k]);
143  c=Norm(3,j->points[i]);
144  if (c>j->maxCoord) j->maxCoord=c;
145  }
146 
147  /* compute the normalized vectors along the rotation axis */
148  for(i=0;i<2;i++)
149  {
150  nr=0.0;
151  for(k=0;k<3;k++)
152  {
153  j->normals[i][k]=j->points[2*i+1][k]-j->points[2*i][k];
154  nr+=(j->normals[i][k]*j->normals[i][k]);
155  }
156  nr=sqrt(nr);
157  if (nr<ZERO)
158  Error("Null rotation axis in NewRevoluteJoint");
159  for(k=0;k<3;k++)
160  j->normals[i][k]/=nr;
161  }
162 
163  j->hasLimits=hasLimits;
164 
165  if (j->hasLimits)
166  {
167  double c;
168 
169  for(i=0;i<2;i++)
170  {
171  /*normalize the reference vectors*/
172  nr=0.0;
173  for(k=0;k<3;k++)
174  {
175  j->vrange[i][k]=ADJUST_REAL(rPoints[i][k])-j->points[2*i][k];
176  nr+=(j->vrange[i][k]*j->vrange[i][k]);
177  }
178  nr=sqrt(nr);
179  if (nr<ZERO)
180  Error("Null reference vector in NewRevoluteJoint");
181  for(k=0;k<3;k++)
182  j->vrange[i][k]/=nr;
183 
184  /*Test that the rotation vectors are orthogonal to the rotation axes*/
185  c=0; /*cosinus between the two vectors*/
186  for(k=0;k<3;k++)
187  c+=(j->vrange[i][k]*j->normals[i][k]);
188 
189  if (fabs(c)>ZERO)
190  Error("Rotation axes and rotation reference vectors are not orthonormal (Revolute Joint)");
191  }
192 
193  /*Copy of the range for the rotation angle*/
194  CopyInterval(&(j->range),range);
195  }
196 
197  /* The pre-post transform matrices are computed before applying any offset to the
198  reference axis, if any. */
199  x=j->normals[0];
200  if (j->hasLimits)
201  y=j->vrange[0];
202  else
203  {
204  DefineNormalVector(v,x);
205  y=v;
206  }
207  CrossProduct(x,y,z);
208  HTransformFromVectors(x,y,z,j->points[0],&(j->preT));
209 
210  x=j->normals[1];
211  if (j->hasLimits)
212  y=j->vrange[1];
213  else
214  {
215  DefineNormalVector(v,x);
216  y=v;
217  }
218  CrossProduct(x,y,z);
219  HTransformFromVectors(x,y,z,j->points[2],&(j->postT));
220  HTransformInverse(&(j->postT),&(j->postT));
221 
222  /* Now offset the references for those representation that need it */
223  if ((j->hasLimits)&&(r!=REP_JOINTS))
224  {
225  THTransform t,rx,a;
226  double zero[3]={0,0,0};
227 
228  /*We offset the range so that it is zero-centered*/
229  j->offset=IntervalCenter(&(j->range));
230  IntervalOffset(&(j->range),-j->offset,&(j->range));
231 
232  /* Since we moved the rotation range to make it zero-centered, we
233  have to rotate the reference vectors accordingly.
234  In this way, the angle between the reference vectors is changed in
235  the same way as the offset applied to the range interval. */
236  /* The rotation is around the vector defining the revolute joint for
237  the current link. This rotation is defined by rotating the axis
238  vector to the X axis, rotating around X and then rotating the
239  vector back to the its original position.*/
240 
241  HTransformX2Vect(1,1,zero,j->normals[0],&t); /* this rotates X to the
242  revolute axis vector*/
243  HTransformRx(j->offset,&rx); /*rotation around X*/
244 
245  HTransformInverse(&t,&a); /*this rotates the axis vector to X*/
246  HTransformProduct(&rx,&a,&a);
247  HTransformProduct(&t,&a,&a);
248 
249  HTransformApply(j->vrange[0],j->vrange[0],&a);
250 
251  HTransformDelete(&a);
252  HTransformDelete(&rx);
253  HTransformDelete(&t);
254  }
255 
256  if (IntervalSize(&(j->range))>0)
257  {
258  j->avoidLimits=avoidLimits;
259  j->avoidLimitsWeight=avoidLimitsWeight;
260  }
261  else
262  {
263  j->avoidLimits=FALSE;
264  j->avoidLimitsWeight=0;
265  }
266 
267  if (coupled!=NULL)
268  {
269  if (coupled->t!=REV_JOINT)
270  Error("Revolute joints can only be coupled with other revolute joints");
271 
272  if (!coupled->hasLimits)
273  Error("Revolute joints can not be coupled to an unbounded revolute joint");
274 
275  j->coupled=(void *)coupled;
276  }
277 }
278 
279 
280 void NewUniversalJoint(unsigned int id,unsigned int r,
281  unsigned int linkID1,Tlink *link1,
282  unsigned int linkID2,Tlink *link2,
283  double **points,
284  boolean hasLimits,
285  Tinterval*range1,Tinterval *range2,double **rPoints,
286  boolean avoidLimits,double avoidLimitsWeight,
287  Tjoint *j)
288 {
289  unsigned int i,k;
290  double nr;
291  double *x,*y,z[3],v[3],c;
292 
293  InitJoint(UNV_JOINT,id,linkID1,link1,linkID2,link2,j);
294 
295  j->maxCoord=0;
296  for(i=0;i<4;i++)
297  {
298  for(k=0;k<3;k++)
299  j->points[i][k]=ADJUST_REAL(points[i][k]);
300  c=Norm(3,j->points[i]);
301  if (c>j->maxCoord) j->maxCoord=c;
302  }
303 
304  /* compute the normalized vectors along the rotation axis */
305  for(i=0;i<2;i++)
306  {
307  nr=0.0;
308  for(k=0;k<3;k++)
309  {
310  j->normals[i][k]=j->points[2*i+1][k]-j->points[2*i][k];
311  nr+=(j->normals[i][k]*j->normals[i][k]);
312  }
313  if (nr<ZERO)
314  Error("Null rotation axis in NewUniversalJoint");
315  nr=sqrt(nr);
316  for(k=0;k<3;k++)
317  j->normals[i][k]/=nr;
318  }
319 
320  j->hasLimits=hasLimits;
321 
322  if (j->hasLimits)
323  {
324  double c;
325 
326  for(i=0;i<2;i++)
327  {
328  /*normalize the reference vectors*/
329  nr=0.0;
330  for(k=0;k<3;k++)
331  {
332  j->vrange[i][k]=ADJUST_REAL(rPoints[i][k])-j->points[2*i][k];
333  nr+=(j->vrange[i][k]*j->vrange[i][k]);
334  }
335  nr=sqrt(nr);
336  if (nr<ZERO)
337  Error("Null reference vector in NewUniversalJoint");
338  for(k=0;k<3;k++)
339  j->vrange[i][k]/=nr;
340 
341  /*Test that the rotation vectors are orthogonal to the rotation axes*/
342  c=0; /*cosinus between the two vectors*/
343  for(k=0;k<3;k++)
344  c+=(j->vrange[i][k]*j->normals[i][k]);
345 
346  if (fabs(c)>ZERO)
347  Error("Rotation axes and rotation reference vectors are not orthonormal (Universal Joint)");
348  }
349 
350  /*Copy of the ranges for the 2 rotation angles*/
351  /*and we offset them so that they are zero-centered*/
352 
353  CopyInterval(&(j->range),range1);
354  CopyInterval(&(j->range2),range2);
355  }
356 
357  /* The pre-post transform matrices are computed before applying any offset to the
358  reference axis, if any. */
359  x=j->normals[0];
360  if (j->hasLimits)
361  y=j->vrange[0];
362  else
363  {
364  DefineNormalVector(v,x);
365  y=v;
366  }
367  CrossProduct(x,y,z);
368  HTransformFromVectors(x,y,z,j->points[0],&(j->preT));
369 
370  x=j->normals[1];
371  if (j->hasLimits)
372  y=j->vrange[1];
373  else
374  {
375  DefineNormalVector(v,x);
376  y=v;
377  }
378  CrossProduct(x,y,z);
379  HTransformFromVectors(x,y,z,j->points[2],&(j->postT));
380  HTransformInverse(&(j->postT),&(j->postT));
381 
382  /* Now offset the references for those representation that need it */
383  if ((j->hasLimits)&&(r!=REP_JOINTS))
384  {
385  THTransform t,rx,a;
386  double zero[3]={0,0,0};
387  Tinterval *rd;
388  double *center;
389 
390  for(k=0;k<2;k++)
391  {
392  if (k==0)
393  {
394  rd=&(j->range);
395  center=&(j->offset);
396  }
397  else
398  {
399  rd=&(j->range2);
400  center=&(j->offset2);
401  }
402 
403  /*We offset the ranges so that they are zero-centered*/
404  *center=IntervalCenter(rd);
405  IntervalOffset(rd,-(*center),rd);
406 
407  /* Since we moved the rotation range to make it zero-centered, we
408  have to rotate ONE of the the reference vectors accordingly.
409  In this way, the angle between the reference vectors is changed
410  in the same way as the offset applied to the range interval. */
411  /* The rotation is around the vector defining the revolute joint
412  for the current link. This rotation is defined by rotating the
413  axis vector to the X axis, rotating around X and then rotating
414  the vector back to the its original position.*/
415  HTransformX2Vect(1,1,zero,j->normals[k],&t); /* this rotates X to
416  to the revolute
417  axis vector*/
418  HTransformRx((k==0?1:-1)*(*center),&rx); /* rotation around X */
419 
420  HTransformInverse(&t,&a); /* this rotates the axis vector to X */
421  HTransformProduct(&rx,&a,&a);
422  HTransformProduct(&t,&a,&a);
423 
424  HTransformApply(j->vrange[k],j->vrange[k],&a);
425 
426  HTransformDelete(&a);
427  HTransformDelete(&rx);
428  HTransformDelete(&t);
429  }
430  }
431  if ((IntervalSize(&(j->range))>0)&&
432  (IntervalSize(&(j->range2))>0))
433  {
434  j->avoidLimits=avoidLimits;
435  j->avoidLimitsWeight=avoidLimitsWeight;
436  }
437  else
438  {
439  j->avoidLimits=FALSE;
440  j->avoidLimitsWeight=0;
441  }
442 }
443 
444 void NewSphericalJoint(unsigned int id,
445  unsigned int linkID1,Tlink *link1,
446  unsigned int linkID2,Tlink *link2,
447  double **points,
448  boolean hasLimits,double range,double **rPoints,
449  boolean avoidLimits,double avoidLimitsWeight,
450  Tjoint *j)
451 {
452  unsigned int i,k;
453  double nr,c;
454  double zero[3]={0.0,0.0,0.0};
455 
456  InitJoint(SPH_JOINT,id,linkID1,link1,linkID2,link2,j);
457 
458  /*for spherical joints only one point in each link is given, we replicate
459  if as if we are given two points. */
460  for(k=0;k<3;k++)
461  {
462  j->points[0][k]=ADJUST_REAL(points[0][k]);
463  j->points[1][k]=ADJUST_REAL(points[0][k]);
464  }
465  for(k=0;k<3;k++)
466  {
467  j->points[2][k]=ADJUST_REAL(points[1][k]);
468  j->points[3][k]=ADJUST_REAL(points[1][k]);
469  }
470  j->maxCoord=0;
471  for(k=0;k<4;k++)
472  {
473  c=Norm(3,j->points[k]);
474  if (c>j->maxCoord) j->maxCoord=c;
475  }
476 
477  j->hasLimits=hasLimits;
478 
479  if (j->hasLimits)
480  {
481  NewInterval(-range,range,&(j->range));
482  j->offset=0;
483  /*normalize the reference vectors*/
484  for(i=0;i<2;i++)
485  {
486  nr=0.0;
487  for(k=0;k<3;k++)
488  {
489  j->vrange[i][k]=ADJUST_REAL(rPoints[i][k])-j->points[2*i][k];
490  nr+=(j->vrange[i][k]*j->vrange[i][k]);
491  }
492  nr=sqrt(nr);
493  if (nr<ZERO)
494  Error("Null reference vector in NewSphericalJoint");
495  for(k=0;k<3;k++)
496  j->vrange[i][k]/=nr;
497  }
498 
499  if (IntervalSize(&(j->range))>0)
500  {
501  j->avoidLimits=avoidLimits;
502  j->avoidLimitsWeight=avoidLimitsWeight;
503  }
504  else
505  {
506  j->avoidLimits=FALSE;
507  j->avoidLimitsWeight=0;
508  }
509  }
510 
511  HTransformTxyz(j->points[0][0],j->points[0][1],j->points[0][2],
512  &(j->preT));
513  if (j->hasLimits)
514  {
515  THTransform ref;
516 
517  HTransformX2Vect(1,1,zero,j->vrange[0],&ref);
518  HTransformProduct(&(j->preT),&ref,&(j->preT));
519  }
520 
521  HTransformTxyz(j->points[2][0],j->points[2][1],j->points[2][2],
522  &(j->postT));
523  if (j->hasLimits)
524  {
525  THTransform ref;
526 
527  HTransformX2Vect(1,1,zero,j->vrange[1],&ref);
528  HTransformProduct(&(j->postT),&ref,&(j->postT));
529  }
530  HTransformInverse(&(j->postT),&(j->postT));
531 }
532 
533 void NewPrismaticJoint(unsigned int id,
534  unsigned int linkID1,Tlink *link1,
535  unsigned int linkID2,Tlink *link2,
536  double **points,Tinterval *range,
537  boolean avoidLimits,double avoidLimitsWeight,
538  Tjoint *j)
539 {
540  unsigned int i,k;
541  double nr,c;
542  //double *x,v[3],z[3];
543 
544  InitJoint(PRS_JOINT,id,linkID1,link1,linkID2,link2,j);
545 
546  j->maxCoord=0;
547  for(i=0;i<4;i++)
548  {
549  for(k=0;k<3;k++)
550  j->points[i][k]=ADJUST_REAL(points[i][k]);
551 
552  c=Norm(3,j->points[i]);
553  if (c>j->maxCoord) j->maxCoord=c;
554  }
555 
556  for(i=0;i<2;i++)
557  {
558  nr=0.0;
559  for(k=0;k<3;k++)
560  {
561  j->normals[i][k]=j->points[2*i+1][k]-j->points[2*i][k];
562  nr+=(j->normals[i][k]*j->normals[i][k]);
563  }
564  nr=sqrt(nr);
565  if (nr<ZERO)
566  Error("Null axis in NewPrismaticJoint");
567  for(k=0;k<3;k++)
568  j->normals[i][k]/=nr;
569  }
570 
571  j->hasLimits=TRUE;
572  CopyInterval(&(j->range),range);
573  c=IntervalSize(range);
574  if (c>j->maxCoord) j->maxCoord=c;
575 
576  if (IntervalSize(&(j->range))>0)
577  {
578  j->avoidLimits=avoidLimits;
579  j->avoidLimitsWeight=avoidLimitsWeight;
580  }
581 
582  HTransformTxyz(j->points[0][0],j->points[0][1],j->points[0][2],
583  &(j->preT));
584  HTransformTxyz(j->points[2][0],j->points[2][1],j->points[2][2],
585  &(j->postT));
586  HTransformInverse(&(j->postT),&(j->postT));
587  /*
588  x=j->normals[0];
589  DefineNormalVector(v,x);
590  CrossProduct(x,v,z);
591  HTransformFromVectors(x,v,z,j->points[0],&(j->preT));
592 
593  x=j->normals[1];
594  DefineNormalVector(v,x);
595  CrossProduct(x,v,z);
596  HTransformFromVectors(x,v,z,j->points[2],&(j->postT));
597  HTransformInverse(&(j->postT),&(j->postT));
598  */
599 }
600 
601 void NewSphSphLowJoint(unsigned int id,
602  unsigned int linkID1,Tlink *link1,
603  unsigned int linkID2,Tlink *link2,
604  double **points,
605  Tjoint *j)
606 {
607  NewSphericalJoint(id,linkID1,link1,linkID2,link2,points,
608  FALSE,INF,NULL,FALSE,1,j);
609  j->t=SPH_SPH_LOW_JOINT;
610 }
611 
612 void NewSphSphUpJoint(unsigned int id,
613  unsigned int linkID1,Tlink *link1,
614  unsigned int linkID2,Tlink *link2,
615  double **points,
616  Tjoint *j)
617 {
618  NewSphericalJoint(id,linkID1,link1,linkID2,link2,points,
619  FALSE,INF,NULL,FALSE,1,j);
620  /* If following a deform link, the deformation will already
621  take care of diaplacing the joints. */
622  if (IsVariableLengthLink(link1))
623  HTransformIdentity(&(j->preT));
624  j->t=SPH_SPH_UP_JOINT;
625 }
626 
627 void NewRevLowJoint(unsigned int id,
628  unsigned int linkID1,Tlink *link1,
629  unsigned int linkID2,Tlink *link2,
630  double **points,
631  Tjoint *j)
632 {
633  unsigned int i;
634  double **p;
635 
636  if ((fabs(points[0][2])>ZERO)||(fabs(points[1][2])>ZERO))
637  Error("REV_LOW_JOINT should be defined in the XY plane");
638 
639  NEW(p,4,double*);
640  for(i=0;i<4;i++)
641  NEW(p[i],3,double);
642 
643  /* no point should have Z */
644  for(i=0;i<3;i++)
645  {
646  p[0][i]=points[0][i];
647  p[1][i]=points[0][i];
648  p[2][i]=points[1][i]; /* This is likely to be 0,0,0 */
649  p[3][i]=points[1][i];
650  }
651  p[1][2]+=1; /* rotation in z */
652  p[3][2]+=1;
653 
654  NewRevoluteJoint(id,REP_JOINTS, /* only used when limits are given (not the case here) */
655  linkID1,link1,linkID2,link2,
656  p,
657  FALSE,NULL,NULL,FALSE,0,NULL,j);
658  j->t=REV_LOW_JOINT;
659 
660  HTransformTxyz(p[0][0],p[0][1],p[0][2],&(j->preT)); /* Txy displacement */
661  HTransformTxyz(p[2][0],p[2][1],p[2][2],&(j->postT)); /* Identity (in general) */
662 
663  for(i=0;i<4;i++)
664  free(p[i]);
665  free(p);
666 }
667 
668 void NewRevUpJoint(unsigned int id,
669  unsigned int linkID1,Tlink *link1,
670  unsigned int linkID2,Tlink *link2,
671  double **points,
672  Tjoint *j)
673 {
674  unsigned int i;
675  double **p;
676 
677  if ((fabs(points[0][2])>ZERO)||(fabs(points[1][2])>ZERO))
678  Error("REV_UP_JOINT should be defined in the XY plane");
679 
680  NEW(p,4,double*);
681  for(i=0;i<4;i++)
682  NEW(p[i],3,double);
683 
684  /* no point should have Z */
685  for(i=0;i<3;i++)
686  {
687  p[0][i]=points[0][i];
688  p[1][i]=points[0][i];
689  p[2][i]=points[1][i];
690  p[3][i]=points[1][i];
691  }
692  p[1][2]+=1; /* rotation in z */
693  p[3][2]+=1;
694 
695  NewRevoluteJoint(id,REP_JOINTS, /* only used when limits are given (not the case here) */
696  linkID1,link1,linkID2,link2,
697  p,
698  FALSE,NULL,NULL,FALSE,0,NULL,j);
699 
700  j->t=REV_UP_JOINT;
701 
702  /* If following a deform link, the deformation will already
703  take care of displacing the joints. */
704  if (IsVariableLengthLink(link1))
705  HTransformIdentity(&(j->preT));
706  else
707  HTransformTxyz(p[0][0],p[0][1],p[0][2],&(j->preT)); /* basically a Tx */
708  HTransformTxyz(p[2][0],p[2][1],p[2][2],&(j->postT)); /* basically 0 */
709 
710  for(i=0;i<4;i++)
711  free(p[i]);
712  free(p);
713 }
714 
715 void NewInPatchJoint(unsigned int id,
716  unsigned int linkID1,Tlink *link1,
717  unsigned int linkID2,Tlink *link2,
718  double **points,
719  double **patch,
720  boolean avoidLimits,double avoidLimitsWeight,
721  Tjoint *j)
722 {
723  unsigned int k;
724  double aux0[3],t1[3],t2[3];
725  double n1,n2;
726  Tinterval range,v,a;
727  double nr,c;
728  double vect[3];
729 
730  InitJoint(IN_PATCH_JOINT,id,linkID1,link1,linkID2,link2,j);
731 
732  /* Store the 2 points defining the point and normal on the first link (not
733  in the patch!)*/
734  nr=0.0;
735  for(k=0;k<3;k++)
736  {
737  j->points[0][k]=ADJUST_REAL(points[0][k]);
738  j->points[1][k]=ADJUST_REAL(points[1][k])-j->points[0][k];
739  nr+=(j->points[1][k]*j->points[1][k]);
740  }
741  nr=sqrt(nr);
742  if (nr<ZERO)
743  Error("Null normal vector in NewInPatchJoint");
744  for(k=0;k<3;k++)
745  {
746  j->points[1][k]/=nr;
747  vect[k]=j->points[0][k]+j->points[1][k]; /* Vector used to define preT */
748  }
749 
750  j->maxCoord=Norm(3,j->points[0]);
751  for(k=0;k<4;k++)
752  {
753  c=Norm(3,patch[k]);
754  if (c>j->maxCoord) j->maxCoord=c;
755  }
756 
757  /* Store the 4 points defining the patch in the second link. Actually we do
758  not directly store the points but some differences between them
759  With this we have that
760  p=po+u*(p0->p2)+v*(p0->p1)+w*(p0-p1-p2+p3)
761  p=points[2]+u*points[3]+v*points[4]+w*points[5]
762  where
763  w=u*v
764  */
765  for(k=0;k<3;k++)
766  {
767  /* p0 */
768  j->points[2][k]=patch[0][k];
769  /* (p0->p2)=p2-p0 */
770  j->points[3][k]=patch[2][k]-patch[0][k];
771  /* (p0->p1)=p1-p0 */
772  j->points[4][k]=patch[1][k]-patch[0][k];
773  /* d=(p0-p1-p2+p3) */
774  j->points[5][k]=patch[0][k]-patch[1][k]-patch[2][k]+patch[3][k];
775  }
776 
777  /* Size of the sides of the patch: must be larger than 0 */
778  n1=DotProduct(j->points[3],j->points[3]);
779  n2=DotProduct(j->points[4],j->points[4]);
780 
781  if ((n1<ZERO)||(n2<ZERO))
782  Error("Patch is too small");
783 
784  /*Store information to recover the normal at any point in the patch.
785  The normal is defined as
786  n=n0+u*n1+v*n2
787  with
788  n0=(p0->p2)x(p0->p1)
789  n1=(p0->p2)x d
790  n2=d x (p0->p1)
791  */
792  /* (p0->p2) x (p0->p1) */
793  CrossProduct(j->points[3],j->points[4],j->normals[0]);
794  /* (p0->p2) x d */
795  CrossProduct(j->points[3],j->points[5],j->normals[1]);
796  /* d x (p0->p1) */
797  CrossProduct(j->points[5],j->points[4],j->normals[2]);
798 
799  /*Check if the input points correctly define a patch.
800  Points defining a patch are given as
801  p2------p3
802  | |
803  | |
804  p0------p1
805  Thus, in a correct patch vector p0->p3 is enclosed in
806  vectors p0->p2 and p0->p1.
807  We check if this is so ensuring that angle p2-p0-p3 has the
808  same sign as angle p3-p0-p1
809  */
810  for(k=0;k<3;k++)
811  aux0[k]=patch[3][k]-patch[0][k]; /*This is p0->p3*/
812 
813  if ((DotProduct(aux0,j->points[3])<ZERO)||
814  (DotProduct(aux0,j->points[4])<ZERO))
815  Error("Patch with overlapping points");
816 
817  CrossProduct(j->points[3],aux0,t1); /* t1=(p0->p2) x (p0->p3) */
818  CrossProduct(aux0,j->points[4],t2); /* t2=(p0->p3) x (p0->p1) */
819 
820  /* Now we check that the above vectors have the same orientation */
821  if (DotProduct(t1,t2)<ZERO)
822  Error("Patch points given in the wrong order");
823 
824  /*Now we compute the range for the norm of the normal vector
825  n=n0+u*n1+v*n2
826  The norm is
827  l=sqrt(n0+u*n1+v*n2)*(n0+u*n1+v*n2)=
828  sqrt(n0*n0+u*n1*n0+v*n2*n0+n0*u*n1+u*n1*u*n1+v*n2*u*n1+v*n2*n0+v*n2*u*n1+v*n2*v*n2)=
829  sqrt(n0*n0+n1*n1*u^2+n2*n2*v^2+2(n1*n0)*u+2*(n2*n0)*v+2*(n2*n1)*u*v
830  The range for l is bounded via interval evaluation of the above expression
831  with u=v=u^2=v^3=u*v=[0,1]
832  */
833  NewInterval(0,1,&v); /* range for u,v,u^2,v^2,u*v */
834 
835  n1=DotProduct(j->normals[0],j->normals[0]); /*n0*n0*/
836  NewInterval(n1,n1,&range);
837 
838  n1=DotProduct(j->normals[1],j->normals[1]); /*+n1*n1*u^2*/
839  IntervalScale(&v,n1,&a);
840  IntervalAdd(&range,&a,&range);
841 
842  n1=DotProduct(j->normals[2],j->normals[2]); /*+n2*n2*v^2*/
843  IntervalScale(&v,n1,&a);
844  IntervalAdd(&range,&a,&range);
845 
846  n1=2*DotProduct(j->normals[0],j->normals[1]); /*+2*n0*n1*u*/
847  IntervalScale(&v,n1,&a);
848  IntervalAdd(&range,&a,&range);
849 
850  n1=2*DotProduct(j->normals[0],j->normals[2]); /*+2*n0*n2*v*/
851  IntervalScale(&v,n1,&a);
852  IntervalAdd(&range,&a,&range);
853 
854  n1=2*DotProduct(j->normals[1],j->normals[2]); /*+2*n1*n2*u*v*/
855  IntervalScale(&v,n1,&a);
856  IntervalAdd(&range,&a,&range);
857 
858  IntervalSqrt(&range,&(j->normRange)); /*final sqrt*/
859 
860  /*Now we store the avoid limit information, if any*/
861  j->hasLimits=TRUE; /*Limits are given by the patch*/
862 
863  NewInterval(0,1,&(j->range));
864  NewInterval(0,1,&(j->range2));
865 
866  /* For non-zero area patch considere avoidLimits */
867  if ((DotProduct(j->points[3],j->points[3])>0)&&
868  (DotProduct(j->points[4],j->points[4])>0))
869  {
870  j->avoidLimits=avoidLimits;
871  j->avoidLimitsWeight=avoidLimitsWeight;
872  }
873 
874  /* vect = points[0]+points[1] */
875  HTransformX2Vect(1,1,j->points[0],vect,&(j->preT));
876  HTransformIdentity(&(j->postT));
877 }
878 
879 void CopyJoint(Tjoint *j_dst,Tjoint *j_src)
880 {
881  unsigned int i,k;
882 
883  j_dst->t=j_src->t;
884 
885  j_dst->id=j_src->id;
886 
887  for(i=0;i<2;i++)
888  {
889  j_dst->linkID[i]=j_src->linkID[i];
890  j_dst->link[i]=j_src->link[i];
891  }
892 
893  for(i=0;i<6;i++)
894  {
895  for(k=0;k<3;k++)
896  j_dst->points[i][k]=j_src->points[i][k];
897  }
898 
899  for(i=0;i<3;i++)
900  {
901  for(k=0;k<3;k++)
902  j_dst->normals[i][k]=j_src->normals[i][k];
903  }
904 
905  j_dst->maxCoord=j_src->maxCoord;
906 
907  j_dst->hasLimits=j_src->hasLimits;
908 
909  j_dst->coupled=j_src->coupled;
910 
911  j_dst->avoidLimits=j_src->avoidLimits;
912  j_dst->avoidLimitsWeight=j_src->avoidLimitsWeight;
913 
914  CopyInterval(&(j_dst->normRange),&(j_src->normRange));
915 
916  CopyInterval(&(j_dst->range),&(j_src->range));
917  CopyInterval(&(j_dst->range2),&(j_src->range2));
918  j_dst->offset=j_src->offset;
919  j_dst->offset2=j_src->offset2;
920 
921  for(i=0;i<2;i++)
922  {
923  for(k=0;k<3;k++)
924  j_dst->vrange[i][k]=j_src->vrange[i][k];
925  }
926 
927  HTransformCopy(&(j_dst->preT),&(j_src->preT));
928  HTransformCopy(&(j_dst->postT),&(j_src->postT));
929 }
930 
931 unsigned int GetJointType(Tjoint *j)
932 {
933  return(j->t);
934 }
935 
937 {
938  return(j->maxCoord);
939 }
940 
941 unsigned int GetJointID(Tjoint *j)
942 {
943  return(j->id);
944 }
945 
946 unsigned int JointFromID(Tjoint *j)
947 {
948  return(j->linkID[0]);
949 }
950 
952 {
953  return(j->link[0]);
954 }
955 
956 unsigned int JointToID(Tjoint *j)
957 {
958  return(j->linkID[1]);
959 }
960 
962 {
963  return(j->link[1]);
964 }
965 
966 void GetJointName(char **name,Tjoint *j)
967 {
968  char *ln1,*ln2;
969 
970  ln1=GetLinkName(j->link[0]);
971  ln2=GetLinkName(j->link[1]);
972  NEW(*name,strlen(ln1)+strlen(ln2)+100,char);
973 
974  switch(j->t)
975  {
976  case FREE_JOINT:
977  sprintf(*name,"Free %s---%s",ln1,ln2);
978  break;
979  case FIX_JOINT:
980  sprintf(*name,"Fix %s---%s",ln1,ln2);
981  break;
982  case PRS_JOINT:
983  sprintf(*name,"Prismatic %s---%s",ln1,ln2);
984  break;
985  case SPH_JOINT:
986  case SPH_SPH_LOW_JOINT:
987  case SPH_SPH_UP_JOINT:
988  sprintf(*name,"Spheric %s---%s",ln1,ln2);
989  break;
990  case REV_JOINT:
991  case REV_LOW_JOINT:
992  case REV_UP_JOINT:
993  sprintf(*name,"Revolute %s---%s",ln1,ln2);
994  break;
995  case UNV_JOINT:
996  sprintf(*name,"Universal %s---%s",ln1,ln2);
997  break;
998  case IN_PATCH_JOINT:
999  sprintf(*name,"In patch %s---%s",ln1,ln2);
1000  break;
1001  default:
1002  Error("Undefined joint type in GetJointName");
1003  }
1004 }
1005 
1006 void GetJointDOFName(unsigned int ndof,char **name,Tjoint *j)
1007 {
1008  switch(j->t)
1009  {
1010  case FREE_JOINT:
1011  NEW(*name,5,char);
1012  switch(ndof)
1013  {
1014  case 0:
1015  sprintf(*name,"Tx");
1016  break;
1017  case 1:
1018  sprintf(*name,"Ty");
1019  break;
1020  case 2:
1021  sprintf(*name,"Tz");
1022  break;
1023  case 3:
1024  sprintf(*name,"Rz");
1025  break;
1026  case 4:
1027  sprintf(*name,"Ry");
1028  break;
1029  case 5:
1030  sprintf(*name,"Rx");
1031  break;
1032  default:
1033  Error("Wrong dof index in GetJointDOFName");
1034  }
1035  break;
1036  case FIX_JOINT:
1037  *name=NULL;
1038  break;
1039  case PRS_JOINT:
1040  *name=NULL;
1041  break;
1042  case SPH_JOINT:
1043  case SPH_SPH_LOW_JOINT:
1044  case SPH_SPH_UP_JOINT:
1045  NEW(*name,5,char);
1046  switch(ndof)
1047  {
1048  case 0:
1049  sprintf(*name,"Rz");
1050  break;
1051  case 1:
1052  sprintf(*name,"Ry");
1053  break;
1054  case 2:
1055  sprintf(*name,"Rx");
1056  break;
1057  default:
1058  Error("Wrong dof index in GetJointDOFName");
1059  }
1060  break;
1061  case REV_JOINT:
1062  case REV_LOW_JOINT:
1063  case REV_UP_JOINT:
1064  *name=NULL;
1065  break;
1066  case UNV_JOINT:
1067  NEW(*name,5,char);
1068  switch(ndof)
1069  {
1070  case 0:
1071  sprintf(*name,"R1");
1072  break;
1073  case 1:
1074  sprintf(*name,"R2");
1075  break;
1076  default:
1077  Error("Wrong dof index in GetJointDOFName");
1078  }
1079  break;
1080  case IN_PATCH_JOINT:
1081  NEW(*name,5,char);
1082  switch(ndof)
1083  {
1084  case 0:
1085  sprintf(*name,"u");
1086  break;
1087  case 1:
1088  sprintf(*name,"v");
1089  break;
1090  case 2:
1091  sprintf(*name,"phi");
1092  break;
1093  default:
1094  Error("Wrong dof index in GetJointDOFName");
1095  }
1096  break;
1097  default:
1098  Error("Undefined joint type in GetJointName");
1099  }
1100 }
1101 
1102 void GetJointPoint(unsigned int link,unsigned int point,double *p,Tjoint *j)
1103 {
1104  unsigned int i,k;
1105 
1106  i=link*2+point;
1107 
1108  for(k=0;k<3;k++)
1109  p[k]=j->points[i][k];
1110 }
1111 
1113 {
1114  return(j->hasLimits);
1115 }
1116 
1118 {
1119  return(&(j->range));
1120 }
1121 
1123 {
1124  return(&(j->range2));
1125 }
1126 
1127 void GetJointRangeN(unsigned int nr,double mt,Tinterval *r,Tjoint *j)
1128 {
1129  switch(j->t)
1130  {
1131  case FREE_JOINT:
1132  if (nr<6)
1133  {
1134  if (nr<3)
1135  NewInterval(-mt,mt,r);
1136  else
1137  NewInterval(-M_PI,M_PI,r);
1138  }
1139  else
1140  Error("Unknown range number in free joint (GetJointRangeN)");
1141  break;
1142  case FIX_JOINT:
1143  Error("Fix Joints have no DOFs");
1144  break;
1145  case PRS_JOINT:
1146  if (nr<1)
1147  CopyInterval(r,&(j->range));
1148  else
1149  Error("Unknown range number in prismatic joint (GetJointRangeN)");
1150  break;
1151  case SPH_JOINT:
1152  case SPH_SPH_LOW_JOINT: /* unlimited spherical */
1153  case SPH_SPH_UP_JOINT: /* unlimited spherical */
1154  if (nr<3)
1155  {
1156  if ((!j->hasLimits)||(nr==2))
1157  NewInterval(-M_PI,M_PI,r);
1158  else
1159  CopyInterval(r,&(j->range));
1160  }
1161  else
1162  Error("Unknown range number in spherical joint (GetJointRangeN)");
1163  break;
1164  case REV_JOINT:
1165  case REV_LOW_JOINT: /* unlimited revolute */
1166  case REV_UP_JOINT: /* unlimited revolute */
1167  if (nr<1)
1168  {
1169  if (!j->hasLimits)
1170  NewInterval(-M_PI,M_PI,r);
1171  else
1172  IntervalOffset(&(j->range),j->offset,r);
1173  }
1174  else
1175  Error("Unknown range number in revolute joint (GetJointRangeN)");
1176  break;
1177  case UNV_JOINT:
1178  if (nr<2)
1179  {
1180  if (!j->hasLimits)
1181  NewInterval(-M_PI,M_PI,r);
1182  else
1183  {
1184  if (nr==0)
1185  IntervalOffset(&(j->range),j->offset,r);
1186  else
1187  IntervalOffset(&(j->range2),j->offset2,r);
1188  }
1189  }
1190  else
1191  Error("Unknown range number in universal joint (GetJointRangeN)");
1192  break;
1193  case IN_PATCH_JOINT:
1194  if (nr<3)
1195  {
1196  if (nr==0)
1197  CopyInterval(r,&(j->range));
1198  else
1199  {
1200  if (nr==1)
1201  CopyInterval(r,&(j->range2));
1202  else
1203  NewInterval(-M_PI,M_PI,r);
1204  }
1205  }
1206  else
1207  Error("Unknown range number in in_patch joint (GetJointRangeN)");
1208  break;
1209  default:
1210  Error("Undefined joint type in GetJointRangeN");
1211  }
1212 }
1213 
1214 unsigned int GetJointRangeTopology(unsigned int nr,Tjoint *j)
1215 {
1216  unsigned int tp=0;
1217 
1218  switch(j->t)
1219  {
1220  case FREE_JOINT:
1221  if (nr<6)
1222  {
1223  if (nr<3)
1224  tp=TOPOLOGY_R;
1225  else
1226  tp=TOPOLOGY_S;
1227  }
1228  else
1229  Error("Unknown range number in free joint (GetJointRangeTopology)");
1230  break;
1231  case FIX_JOINT:
1232  Error("Fix Joints have no DOFs");
1233  break;
1234  case PRS_JOINT:
1235  if (nr<1)
1236  tp=TOPOLOGY_R;
1237  else
1238  Error("Unknown range number in prismatic joint (GetJointRangeTopology)");
1239  break;
1240  case SPH_JOINT:
1241  case SPH_SPH_LOW_JOINT: /* unlimited spherical */
1242  case SPH_SPH_UP_JOINT: /* unlimited spherical */
1243  if (nr<3)
1244  {
1245  if (nr<2)
1247  else
1248  tp=TOPOLOGY_S;
1249  }
1250  else
1251  Error("Unknown range number in spherical joint (GetJointRangeTopology)");
1252  break;
1253  case REV_JOINT:
1254  case REV_LOW_JOINT: /* unlimited revolute */
1255  case REV_UP_JOINT: /* unlimited revolute */
1256  if (nr<1)
1258  else
1259  Error("Unknown range number in revolute joint (GetJointRangeTopology)");
1260  break;
1261  case UNV_JOINT:
1262  if (nr<2)
1264  else
1265  Error("Unknown range number in universal joint (GetJointRangeTopology)");
1266  break;
1267  case IN_PATCH_JOINT:
1268  if (nr<3)
1269  {
1270  if (nr!=2)
1271  tp=TOPOLOGY_R;
1272  else
1273  tp=TOPOLOGY_S;
1274  }
1275  else
1276  Error("Unknown range number in in_patch joint (GetJointRangeTopology)");
1277  break;
1278  default:
1279  Error("Undefined joint type in GetJointRangeTopology");
1280  }
1281 
1282  return(tp);
1283 }
1284 
1285 unsigned int CoupledWith(Tjoint *j)
1286 {
1287  if (j->coupled==NULL)
1288  return(NO_UINT);
1289  else
1290  return(((Tjoint *)(j->coupled))->id);
1291 }
1292 
1293 unsigned int GetJointDOF(Tjoint *j)
1294 {
1295  signed int ndof=0;
1296 
1297  switch(j->t)
1298  {
1299  case FREE_JOINT:
1300  ndof=6;
1301  break;
1302  case FIX_JOINT:
1303  ndof=0;
1304  break;
1305  case PRS_JOINT:
1306  ndof=1;
1307  break;
1308  case SPH_JOINT:
1309  case SPH_SPH_LOW_JOINT: /* unlimited spherical */
1310  case SPH_SPH_UP_JOINT: /* unlimited spherical */
1311  ndof=3;
1312  break;
1313  case REV_JOINT:
1314  case REV_LOW_JOINT: /* unlimited, uncoupled revolute */
1315  case REV_UP_JOINT: /* unlimited, uncoupled revolute */
1316  if (j->coupled==NULL)
1317  ndof=1;
1318  else
1319  ndof=0;
1320  break;
1321  case UNV_JOINT:
1322  ndof=2;
1323  break;
1324  case IN_PATCH_JOINT:
1325  ndof=3;
1326  break;
1327  default:
1328  Error("Undefined joint type in GetJointDOF");
1329  }
1330  return(ndof);
1331 }
1332 
1334 {
1335  unsigned int r;
1336 
1337  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1338 
1339  if (r==REP_JOINTS)
1340  Error("GenerateJointRangeSingularityEquations not yet implemented for JOINT-based representations.");
1341 
1342  if (j->hasLimits)
1343  {
1344  unsigned int i,n;
1345  double a,b,c,r;
1346  Tinterval *range;
1347  Tequation eq;
1348  Tmonomial f;
1349  Tinterval r1;
1350  unsigned int vOrig,vID1,vID2;
1351  char *vname,*ln1,*ln2;
1352  Tvariable var;
1353 
1354  ln1=GetLinkName(j->link[0]);
1355  ln2=GetLinkName(j->link[1]);
1356  NEW(vname,strlen(ln1)+strlen(ln2)+100,char);
1357 
1358  InitMonomial(&f);
1359 
1360  switch (j->t)
1361  {
1362  case REV_JOINT:
1363  case SPH_JOINT:
1364  case UNV_JOINT:
1365  /* revolute ranges given as cosinus of variables */
1366  n=((j->t==UNV_JOINT)?2:1);
1367 
1368  for(i=0;i<n;i++)
1369  {
1370  range=(i==0?&(j->range):&(j->range2));
1371 
1372  /*Get the original 'cos' variable*/
1373  if (j->t==UNV_JOINT)
1374  COS_VAR_UNI(vname,j->id,ln1,ln2,i);
1375  else
1376  COS_VAR(vname,j->id,ln1,ln2);
1377 
1378  vOrig=GetCSVariableID(vname,cs);
1379  if (vOrig==NO_UINT)
1380  Error("Undefined variable in GenerateJointRangeSigularityEquations");
1381 
1382 
1383  /* introduce the new t var */
1384  if (j->t==UNV_JOINT)
1385  COS_VAR_UNI_SING(vname,j->id,ln1,ln2,i);
1386  else
1387  COS_VAR_SING(vname,j->id,ln1,ln2);
1388  NewInterval(0,1,&r1);
1389 
1390  NewVariable(SYSTEM_VAR,vname,&var);
1391  SetVariableInterval(&r1,&var);
1392 
1393  vID1=AddVariable2CS(&var,cs);
1394 
1395  DeleteVariable(&var);
1396 
1397  /*introduce the new equation: t^2-cos=-cos(lower(range))
1398  Here we assume that range is symmetrical w.r.t. zero
1399  and, thus lower(cos(range))= cos(lower(range))*/
1400  InitEquation(&eq);
1401  SetEquationValue(-cos(LowerLimit(range)),&eq);
1402 
1403  AddVariable2Monomial(NFUN,vID1,2,&f);
1404  AddMonomial(&f,&eq);
1405  ResetMonomial(&f);
1406 
1407  AddCt2Monomial(-1,&f);
1408  AddVariable2Monomial(NFUN,vOrig,1,&f);
1409  AddMonomial(&f,&eq);
1410  ResetMonomial(&f);
1411 
1412  SetEquationCmp(EQU,&eq);
1414 
1415  AddEquation2CS(p,&eq,cs);
1416  DeleteEquation(&eq);
1417  }
1418 
1419  break;
1420 
1421  case PRS_JOINT:
1422  case IN_PATCH_JOINT:
1423  /* lineal ranges */
1424  n=((j->t==IN_PATCH_JOINT)?2:1);
1425 
1426  for(i=0;i<n;i++)
1427  {
1428  range=(i==0?&(j->range):&(j->range2));
1429 
1430  a=LowerLimit(range);
1431  b=UpperLimit(range);
1432  c=(b+a)/2; /* center */
1433  r=(b-a)/2; /* radius */
1434 
1435  /*Get the original 'l' variable*/
1436  if (j->t==IN_PATCH_JOINT)
1437  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,ln1,ln2,i);
1438  else
1439  PRS_JOINT_VAR(vname,j->id,ln1,ln2);
1440 
1441  vOrig=GetCSVariableID(vname,cs);
1442  if (vOrig==NO_UINT)
1443  Error("Undefined variable in GenerateJointRangeSigularityEquations");
1444 
1445  /* introduce the new sin var */
1446  if (j->t==IN_PATCH_JOINT)
1447  IN_PATCH_JOINT_CTRL_VAR_SING_SIN(vname,j->id,ln1,ln2,i);
1448  else
1449  PRS_JOINT_VAR_SING_SIN(vname,j->id,ln1,ln2);
1450 
1451  NewVariable(SYSTEM_VAR,vname,&var);
1452  NewInterval(-1,1,&r1);
1453  SetVariableInterval(&r1,&var);
1454 
1455  vID1=AddVariable2CS(&var,cs);
1456 
1457  DeleteVariable(&var);
1458 
1459  /* introduce the new cos var */
1460  if (j->t==IN_PATCH_JOINT)
1461  IN_PATCH_JOINT_CTRL_VAR_SING_COS(vname,j->id,ln1,ln2,i);
1462  else
1463  PRS_JOINT_VAR_SING_COS(vname,j->id,ln1,ln2);
1464 
1465  NewVariable(SYSTEM_VAR,vname,&var);
1466  NewInterval(0,1,&r1);
1467  SetVariableInterval(&r1,&var);
1468 
1469  vID2=AddVariable2CS(&var,cs);
1470 
1471  DeleteVariable(&var);
1472 
1473  /*Add two new equations*/
1474 
1475  /*vOrig-r*vSin=c*/
1476  InitEquation(&eq);
1477  SetEquationValue(c,&eq);
1478 
1479  AddVariable2Monomial(NFUN,vOrig,1,&f);
1480  AddMonomial(&f,&eq);
1481  ResetMonomial(&f);
1482 
1483  AddCt2Monomial(-r,&f);
1484  AddVariable2Monomial(NFUN,vID1,1,&f);
1485  AddMonomial(&f,&eq);
1486  ResetMonomial(&f);
1487 
1488  SetEquationCmp(EQU,&eq);
1490 
1491  AddEquation2CS(p,&eq,cs);
1492  ResetEquation(&eq);
1493 
1494  /* s^2+c^2=1*/
1495  SetEquationValue(1,&eq);
1496 
1497  AddVariable2Monomial(NFUN,vID1,2,&f);
1498  AddMonomial(&f,&eq);
1499  ResetMonomial(&f);
1500 
1501  AddVariable2Monomial(NFUN,vID2,2,&f);
1502  AddMonomial(&f,&eq);
1503  ResetMonomial(&f);
1504 
1505  SetEquationCmp(EQU,&eq);
1507  AddEquation2CS(p,&eq,cs);
1508  ResetMonomial(&f);
1509  }
1510  DeleteEquation(&eq);
1511  break;
1512 
1513  default:
1514  Error("Wrong joint type in GenerateJointRangeSingularityEquations");
1515  }
1516  free(vname);
1517  DeleteMonomial(&f);
1518  }
1519 }
1520 
1522 {
1523  unsigned int r;
1524 
1525  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1526 
1527  if (r!=REP_JOINTS)
1528  {
1529  /* Equations associated with the joint
1530  (not joint equations as in the paper :) */
1531 
1532  char *vname;
1533  unsigned int i,k,id,nv;
1534  Tequation eq[3],eq1;
1535  Tinterval rangeOne,rangeInf;
1536  Tmonomial f;
1537  unsigned int jointVars[4][3]; /*Reference vector used in REVOLUTE and
1538  SPHERICAL joints*/
1539  Tvariable var;
1540  char *ln1,*ln2;
1541  Tinterval ic;
1542  double r;
1543 
1544  NewInterval(-1.0,1.0,&rangeOne);
1545  NewInterval(-INF,INF,&rangeInf);
1546 
1547  InitMonomial(&f);
1548 
1549  ln1=GetLinkName(j->link[0]);
1550  ln2=GetLinkName(j->link[1]);
1551 
1552  NEW(vname,strlen(ln1)+strlen(ln2)+100,char);
1553 
1554  switch(j->t)
1555  {
1556  case FREE_JOINT:
1557  /* variables already generated in GenerateJointEquations */
1558  break;
1559 
1560  case FIX_JOINT:
1561  /* no variables necessary for fix joints */
1562  break;
1563 
1564  case PRS_JOINT:
1565  /*Add one variable for the displacement along the prismatic axis*/
1566  PRS_JOINT_VAR(vname,j->id,ln1,ln2);
1567 
1568  NewVariable(SYSTEM_VAR,vname,&var);
1569  SetVariableInterval(&(j->range),&var);
1570 
1571  nv=AddVariable2CS(&var,cs);
1572 
1573  DeleteVariable(&var);
1574 
1575  if (j->avoidLimits)
1576  {
1577  r=IntervalSize(&(j->range))/2;
1579  IntervalCenter(&(j->range)),cs);
1580  }
1581 
1582  break;
1583 
1584  case UNV_JOINT:
1585  case REV_JOINT:
1586  case SPH_JOINT:
1587  case SPH_SPH_LOW_JOINT: /* unlimited spherical joint -> nothing will be done */
1588  case SPH_SPH_UP_JOINT: /* unlimited spherical joint -> nothing will be done */
1589  case REV_LOW_JOINT: /* unlimited revolute -> nothing will be done */
1590  case REV_UP_JOINT: /* unlimited revolute -> nothing will be done */
1591  if (j->hasLimits)
1592  {
1593  /*We define two vectors normal to the rotation axis, one attached
1594  to link1 (k==0) and another attached to link2 (k==1)*/
1595  for(k=0;k<2;k++)
1596  {
1597  /*Define the variables for the rotation reference vectors*/
1598  for(i=0;i<3;i++)
1599  {
1600  InitEquation(&(eq[i]));
1601  SetEquationValue(0.0,&(eq[i]));
1602 
1603  if (j->t==REV_JOINT)
1604  ROT_JOINT_VAR_REF(vname,j->id,k,ln1,ln2,i);
1605  else
1606  {
1607  if (j->t==SPH_JOINT)
1608  SPH_JOINT_VAR_REF(vname,j->id,k,ln1,ln2,i);
1609  else
1610  UNV_JOINT_VAR_REF(vname,j->id,k,ln1,ln2,i);
1611  }
1612 
1613  NewVariable(SECONDARY_VAR,vname,&var);
1614  SetVariableInterval(&rangeOne,&var);
1615 
1616  id=AddVariable2CS(&var,cs);
1617 
1618  DeleteVariable(&var);
1619 
1620  jointVars[k][i]=id;
1621  AddVariable2Monomial(NFUN,id,1,&f);
1622  AddMonomial(&f,&(eq[i]));
1623  ResetMonomial(&f);
1624  }
1625 
1626  ApplyLinkRot(p,-1.0,NO_UINT,j->vrange[k],eq,cs,
1627  IsGroundLink(j->linkID[k]),j->link[k]);
1628 
1629  for(i=0;i<3;i++)
1630  {
1631  SetEquationCmp(EQU,&(eq[i]));
1632  SetEquationType(SYSTEM_EQ,&(eq[i]));
1633 
1634  AddEquation2CS(p,&(eq[i]),cs);
1635  DeleteEquation(&(eq[i]));
1636  }
1637  }
1638 
1639  if (j->t==UNV_JOINT)
1640  {
1641  /* The angles for a universal joint are defined from the two
1642  vectors defining the two copunctual, orthogonal rotation
1643  axis towards the two reference vectors given by the user.
1644  The first angle is from the 1st reference vector to the
1645  second rotation vector. The second angle is from the
1646  2nd reference vector to the 1st rotation vector.
1647 
1648  Above we defined variables for the two reference vectors.
1649  Below we retrive the variable identifiers for the two
1650  vectors defining the copunctual, orthogonal rotation
1651  axis (those variables are defined in function
1652  GenerateJointEquations.
1653  */
1654  for(k=2;k<4;k++)
1655  {
1656  for(i=0;i<3;i++)
1657  {
1658  UNV_JOINT_VAR(vname,j->id,ln1,ln2,k-2,i);
1659  jointVars[k][i]=GetCSVariableID(vname,cs);
1660  if (jointVars[k][i]==NO_UINT)
1661  Error("Undefined variables when defining universal joint range equations");
1662  }
1663  }
1664 
1665  for(k=0;k<2;k++)
1666  {
1667  GenerateDotProductEquation(jointVars[3-k][0],
1668  jointVars[3-k][1],
1669  jointVars[3-k][2],
1670  jointVars[k][0],
1671  jointVars[k][1],
1672  jointVars[k][2],
1673  NO_UINT,0,&eq1);
1674 
1675  COS_VAR_UNI(vname,j->id,ln1,ln2,k);
1676  NewVariable(SECONDARY_VAR,vname,&var);
1677  if (k==0)
1678  IntervalCosine(&(j->range),&ic);
1679  else
1680  IntervalCosine(&(j->range2),&ic);
1681  SetVariableInterval(&ic,&var);
1682  DeleteInterval(&ic);
1683  id=AddVariable2CS(&var,cs);
1684  DeleteVariable(&var);
1685 
1686  AddVariable2Monomial(NFUN,id,1,&f);
1687  AddCt2Monomial(-1,&f);
1688  AddMonomial(&f,&eq1);
1689  ResetMonomial(&f);
1690 
1691  SetEquationCmp(EQU,&eq1);
1692  SetEquationType(SYSTEM_EQ,&eq1);
1693  AddEquation2CS(p,&eq1,cs);
1694  DeleteEquation(&eq1);
1695 
1696  if (j->avoidLimits)
1697  {
1698  r=IntervalSize(&ic);
1699  AddTerm2SearchCriterion(j->avoidLimitsWeight/(r*r),id,1,cs);
1700  }
1701  }
1702  }
1703  else
1704  {
1705  /* Revolute and spherical */
1706 
1707  GenerateDotProductEquation(jointVars[0][0],
1708  jointVars[0][1],
1709  jointVars[0][2],
1710  jointVars[1][0],
1711  jointVars[1][1],
1712  jointVars[1][2],
1713  NO_UINT,0,&eq1);
1714 
1715  COS_VAR(vname,j->id,ln1,ln2);
1716  NewVariable(SECONDARY_VAR,vname,&var);
1717  IntervalCosine(&(j->range),&ic);
1718  SetVariableInterval(&ic,&var);
1719  DeleteInterval(&ic);
1720  id=AddVariable2CS(&var,cs);
1721  DeleteVariable(&var);
1722 
1723  AddVariable2Monomial(NFUN,id,1,&f);
1724  AddCt2Monomial(-1,&f);
1725  AddMonomial(&f,&eq1);
1726  ResetMonomial(&f);
1727 
1728  SetEquationCmp(EQU,&eq1);
1729  SetEquationType(SYSTEM_EQ,&eq1);
1730  AddEquation2CS(p,&eq1,cs);
1731  DeleteEquation(&eq1);
1732 
1733  if (j->avoidLimits)
1734  {
1735  r=IntervalSize(&ic);
1736  AddTerm2SearchCriterion(j->avoidLimitsWeight/(r*r),id,1,cs);
1737  }
1738 
1739  if ((j->t==REV_JOINT)&&(j->coupled!=NULL))
1740  {
1741  char *ln1p,*ln2p,*vnamep;
1742  unsigned int c1,c2;
1743  Tjoint *jp;
1744 
1745  jp=(Tjoint *)j->coupled;
1746 
1747  COS_VAR(vname,j->id,ln1,ln2);
1748  c1=GetCSVariableID(vname,cs);
1749  if (c1==NO_UINT)
1750  Error("Trying to couple a non-limited revolute joint");
1751 
1752  ln1p=GetLinkName(jp->link[0]);
1753  ln2p=GetLinkName(jp->link[1]);
1754  NEW(vnamep,strlen(ln1p)+strlen(ln2p)+100,char);
1755  COS_VAR(vnamep,jp->id,ln1p,ln2p);
1756  c2=GetCSVariableID(vnamep,cs);
1757  if (c2==NO_UINT)
1758  Error("Trying to couple to a non-limited revolute joint");
1759  free(vnamep);
1760 
1761  /* Add the equation cos1=cos2 */
1762  InitEquation(&eq1);
1763  SetEquationValue(0.0,&eq1);
1764 
1765  AddVariable2Monomial(NFUN,c1,1,&f);
1766  AddMonomial(&f,&eq1);
1767  ResetMonomial(&f);
1768 
1769  AddVariable2Monomial(NFUN,c2,1,&f);
1770  AddCt2Monomial(-1,&f);
1771  AddMonomial(&f,&eq1);
1772  ResetMonomial(&f);
1773 
1774  SetEquationCmp(EQU,&eq1);
1775  SetEquationType(SYSTEM_EQ,&eq1);
1776  AddEquation2CS(p,&eq1,cs);
1777  DeleteEquation(&eq1);
1778  }
1779  }
1780 
1781  }
1782  break;
1783 
1784  case IN_PATCH_JOINT:
1785  /*In patch joints are limited by the 4 points defining the patch.
1786  These limits are implicitly given by the ranges for the control
1787  variables giving the patch. */
1788  if (j->avoidLimits)
1789  {
1790  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,ln1,ln2,0);
1791  nv=GetCSVariableID(vname,cs);
1793 
1794  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,ln1,ln2,1);
1795  nv=GetCSVariableID(vname,cs);
1797  }
1798  break;
1799 
1800  default:
1801  Error("Undefined joint type in GenerateJointRangeEquations");
1802  }
1803 
1804  DeleteInterval(&rangeOne);
1805  DeleteInterval(&rangeInf);
1806 
1807  free(vname);
1808  DeleteMonomial(&f);
1809  }
1810 }
1811 
1813  Tequation *eq,Tjoint *j)
1814 {
1815  unsigned int r;
1816 
1817  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1818 
1819  if (r==REP_JOINTS)
1820  Error("GenerateJointEquationsInBranch should not be used with JOINT-based representation");
1821  else
1822  {
1823  char *l1name,*l2name,*vname;
1824  unsigned int i,vID,d;
1825  Tmonomial f;
1826 
1827  l1name=GetLinkName(j->link[0]);
1828  l2name=GetLinkName(j->link[1]);
1829 
1830  switch (j->t)
1831  {
1832  case FREE_JOINT:
1833 
1834  NEW(vname,strlen(l1name)+strlen(l2name)+100,char);
1835  InitMonomial(&f);
1836  for(i=0;i<3;i++)
1837  {
1838  FREE_JOINT_VAR(vname,j->id,j->linkID[0],l1name,j->linkID[1],l2name,i);
1839 
1840  vID=GetCSVariableID(vname,cs);
1841  if (vID==NO_UINT)
1842  Error("Undefined FREE_JOINT variable in GenerateJointEquationsInBranch");
1843 
1844  AddVariable2Monomial(NFUN,vID,1,&f);
1845  AddCt2Monomial(s,&f);
1846  AddMonomial(&f,&(eq[i]));
1847  ResetMonomial(&f);
1848  }
1849  DeleteMonomial(&f);
1850  free(vname);
1851 
1852  break;
1853 
1854  case FIX_JOINT:
1855  /*The translation part of the homogeneous transform between the two
1856  links has been stored in points[0] (see NewFixJoint). We apply
1857  it here. The rotation constraints are imposed in
1858  GenerateJointEquations. */
1859  ApplyLinkRot(p, s,NO_UINT,j->points[0],eq,cs,
1860  IsGroundLink(j->linkID[0]),j->link[0]);
1861  break;
1862 
1863  case UNV_JOINT:
1864  case REV_JOINT:
1865  case SPH_JOINT:
1866  case SPH_SPH_LOW_JOINT:
1867  case SPH_SPH_UP_JOINT:
1868  case REV_LOW_JOINT:
1869  case REV_UP_JOINT:
1870  /* for SPH_SPH_UP_JOINT link[0] is
1871  an axisX or even a deformX link */
1872  ApplyLinkRot(p, s,NO_UINT,j->points[0],eq,cs,
1873  IsGroundLink(j->linkID[0]),j->link[0]);
1874  /* for SPH_SPH_LOW_JOINT points[2]
1875  is zero and link[1] is an axisX link, but anyway*/
1876  ApplyLinkRot(p,-s,NO_UINT,j->points[2],eq,cs,
1877  IsGroundLink(j->linkID[1]),j->link[1]);
1878  break;
1879 
1880  case PRS_JOINT:
1881  ApplyLinkRot(p, s,NO_UINT,j->points[0],eq,cs,
1882  IsGroundLink(j->linkID[0]),j->link[0]);
1883 
1884  NEW(vname,strlen(l1name)+strlen(l2name)+100,char);
1885  PRS_JOINT_VAR(vname,j->id,l1name,l2name);
1886 
1887  d=GetCSVariableID(vname,cs);
1888  free(vname);
1889  if (d==NO_UINT)
1890  Error("Undefined PRS_JOINT variable in GenerateJointEquationsInBranch");
1891 
1892  ApplyLinkRot(p, s,d,j->normals[0],eq,cs,
1893  IsGroundLink(j->linkID[0]),j->link[0]);
1894 
1895  ApplyLinkRot(p,-s,NO_UINT,j->points[2],eq,cs,
1896  IsGroundLink(j->linkID[1]),j->link[1]);
1897  break;
1898 
1899  case IN_PATCH_JOINT:
1900  ApplyLinkRot(p, s,NO_UINT,j->points[0],eq,cs,
1901  IsGroundLink(j->linkID[0]),j->link[0]);
1902 
1903  ApplyLinkRot(p,-s,NO_UINT,j->points[2],eq,cs,
1904  IsGroundLink(j->linkID[1]),j->link[1]);
1905  NEW(vname,strlen(l1name)+strlen(l2name)+100,char);
1906  for(i=0;i<3;i++)
1907  {
1908  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,l1name,l2name,i);
1909  vID=GetCSVariableID(vname,cs);
1910  if (vID==NO_UINT)
1911  Error("Undefined IN_PATCH_JOINT variable in GenerateJointEquationsInBranch");
1912 
1913  ApplyLinkRot(p,-s,vID,j->points[3+i],eq,cs,
1914  IsGroundLink(j->linkID[1]),j->link[1]);
1915  }
1916  free(vname);
1917  break;
1918 
1919  default:
1920  Error("Unkownd joint type");
1921  }
1922  }
1923 }
1924 
1925 void JointForceEquation(Tparameters *pr,unsigned int linkID,TCuikSystem *cs,Tequation *eq,Tjoint *j)
1926 {
1927  /* This only works for link-based representation. This is checked at a higher-level */
1928 
1929  /* only joints incident wth the current link should be considered */
1930  if ((j->linkID[0]==linkID)||(j->linkID[1]==linkID))
1931  {
1932  Tlink *linkBase; /* link defining the director vector */
1933 
1934  /* linkBase = the "other" link in the joint (link != from linkID) */
1935  if (j->linkID[0]==linkID)
1936  linkBase=j->link[1];
1937  else
1938  linkBase=j->link[0];
1939 
1940  if (GetLinkForceModel(linkBase)!=NO_FORCE)
1941  {
1942  double sg;
1943  unsigned int fID; /* force variables */
1944  char *lname,*vname;
1945  double vectX[3]={1,0,0};
1946 
1947  /* different signs depending if the joint is a the beginning or
1948  at the end of the link exerting the force */
1949  if (j->linkID[0]==linkID)
1950  sg=+1;
1951  else
1952  sg=-1;
1953 
1954  lname=GetLinkName(linkBase);
1955  NEW(vname,strlen(lname)+100,char);
1956 
1957  LINK_MAX_FORCE(vname,lname);
1958  fID=GetCSVariableID(vname,cs);
1959 
1960  ApplyLinkRotNoDeform(pr,sg,fID,vectX,eq,cs,FALSE,linkBase);
1961 
1962  free(vname);
1963  }
1964  }
1965 }
1966 
1967 void GenerateJointEquations(Tparameters *p,double maxCoord,
1968  TCuikSystem *cs,Tjoint *j)
1969 {
1970  unsigned int r;
1971 
1972  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
1973 
1974  if (r==REP_JOINTS)
1975  {
1976  unsigned int i,n;
1977  char *vname;
1978  Tvariable var;
1979  Tinterval range;
1980  char *ln1,*ln2;
1981  unsigned int tp;
1982 
1983  ln1=GetLinkName(j->link[0]);
1984  ln2=GetLinkName(j->link[1]);
1985 
1986  NEW(vname,strlen(ln1)+strlen(ln2)+100,char);
1987 
1988  n=GetJointDOF(j);
1989  for(i=0;i<n;i++)
1990  {
1991  DOF_VAR(vname,j->id,ln1,ln2,i);
1992 
1993  NewVariable(SYSTEM_VAR,vname,&var);
1994  GetJointRangeN(i,maxCoord,&range,j);
1995  SetVariableInterval(&range,&var);
1996  tp=GetJointRangeTopology(i,j);
1997  if (tp==TOPOLOGY_S)
1999 
2000  AddVariable2CS(&var,cs);
2001  DeleteVariable(&var);
2002  DeleteInterval(&range);
2003  }
2004  free(vname);
2005  }
2006  else
2007  {
2008  double v[3];
2009  unsigned int i,k;
2010  Tequation eq[3],eq1;
2011  char *ln1,*ln2,*vname;
2012  Tinterval rangeOne,rangeInf,rangeZeroOne;
2013  Tmonomial f;
2014  unsigned int vID[3]; /* variables generated */
2015  unsigned int vIDuni[2][3]; /* for the universal joints -> 2 vectors*/
2016  unsigned int l; /*scale variable of the normal vectors in_patch_joint*/
2017  Tvariable var;
2018 
2019  ln1=GetLinkName(j->link[0]);
2020  ln2=GetLinkName(j->link[1]);
2021 
2022  NEW(vname,strlen(ln1)+strlen(ln2)+100,char);
2023 
2024  NewInterval(-1,1,&rangeOne);
2025  NewInterval(0,1,&rangeZeroOne);
2026 
2027  InitMonomial(&f);
2028 
2029  switch(j->t)
2030  {
2031  case FREE_JOINT:
2032  /*We generate 3 new variables representing the (unlimited)
2033  displacement from the origin of the first link to the
2034  origin of the second link.
2035  No equations constraint these variables. */
2036  NewInterval(-maxCoord,maxCoord,&rangeInf);
2037  for(i=0;i<3;i++)
2038  {
2039  FREE_JOINT_VAR(vname,j->id,j->linkID[0],ln1,j->linkID[1],ln2,i);
2040 
2041  NewVariable(SYSTEM_VAR,vname,&var);
2042  SetVariableInterval(&rangeInf,&var);
2043  AddVariable2CS(&var,cs);
2044 
2045  DeleteVariable(&var);
2046  }
2047  break;
2048 
2049  case FIX_JOINT:
2050  /* link1 * transform = link2 * identity */
2051  /* link1 * transform - link2 * identity = 0 */
2052  for(i=0;i<3;i++)
2053  {
2054  for(k=0;k<3;k++)
2055  InitEquation(&(eq[k]));
2056 
2057  for(k=0;k<3;k++)
2058  v[k]=HTransformGetElement(k,i,&(j->preT));
2059 
2060  ApplyLinkRot(p,1,NO_UINT,v,eq,cs,
2061  IsGroundLink(j->linkID[0]),j->link[0]);
2062 
2063  v[0]=v[1]=v[2]=0;
2064  v[i]=1;
2065 
2066  ApplyLinkRot(p,-1,NO_UINT,v,eq,cs,
2067  IsGroundLink(j->linkID[1]),j->link[1]);
2068 
2069  for(k=0;k<3;k++)
2070  {
2071  SetEquationType(SYSTEM_EQ,&(eq[k]));
2072  SetEquationCmp(EQU,&(eq[k]));
2073  AddEquation2CS(p,&(eq[k]),cs);
2074  DeleteEquation(&(eq[k]));
2075  }
2076  }
2077  break;
2078 
2079  case PRS_JOINT:
2080  /* The three reference vectors (X,Y,Z) for the two links
2081  are the same when transformed to global coordinates. */
2082  for(k=0;k<3;k++)
2083  InitEquation(&(eq[k]));
2084 
2085  for(i=0;i<(j->t==PRS_JOINT?3:1);i++)
2086  {
2087  v[0]=v[1]=v[2]=0.0;
2088  v[i]=1.0;
2089 
2090  for(k=0;k<3;k++)
2091  InitEquation(&(eq[k]));
2092 
2093  for(k=0;k<2;k++)
2094  ApplyLinkRot(p,(k==0?+1.0:-1.0),NO_UINT,v,eq,cs,
2095  IsGroundLink(j->linkID[k]),j->link[k]);
2096 
2097  for(k=0;k<3;k++)
2098  {
2099  SetEquationType(SYSTEM_EQ,&(eq[k]));
2100  SetEquationCmp(EQU,&(eq[k]));
2101  AddEquation2CS(p,&(eq[k]),cs);
2102  DeleteEquation(&(eq[k]));
2103  }
2104  }
2105  break;
2106 
2107  case REV_LOW_JOINT:
2108  case REV_UP_JOINT:
2109  /* When using REV_LOW or REP_UP joints all links are in the XY plane and, thus
2110  no equation is actually necessary */
2111  break;
2112 
2113  case REV_JOINT:
2114  /* The vector defining the rotation axis is the same as seen
2115  from the two links. */
2116  for(k=0;k<3;k++)
2117  InitEquation(&(eq[k]));
2118 
2119  for(k=0;k<2;k++) /* for the two links involved in the joint */
2120  ApplyLinkRot(p,(k==0?+1.0:-1.0),NO_UINT,j->normals[k],eq,cs,
2121  IsGroundLink(j->linkID[k]),j->link[k]);
2122 
2123  for(k=0;k<3;k++)
2124  {
2125  SetEquationType(SYSTEM_EQ,&(eq[k]));
2126  SetEquationCmp(EQU,&(eq[k]));
2127  AddEquation2CS(p,&(eq[k]),cs);
2128  DeleteEquation(&(eq[k]));
2129  }
2130  break;
2131 
2132  case UNV_JOINT:
2133  /* Two vectors one attached to link1 and another attached to link2 */
2134  for(i=0;i<2;i++)
2135  {
2136  for(k=0;k<3;k++)
2137  InitEquation(&(eq[k]));
2138 
2139  ApplyLinkRot(p,1,NO_UINT,j->normals[i],eq,cs,
2140  IsGroundLink(j->linkID[i]),j->link[i]);
2141 
2142  for(k=0;k<3;k++)
2143  {
2144  UNV_JOINT_VAR(vname,j->id,ln1,ln2,i,k);
2145 
2146  NewVariable(SECONDARY_VAR,vname,&var);
2147  SetVariableInterval(&rangeOne,&var);
2148 
2149  vIDuni[i][k]=AddVariable2CS(&var,cs);
2150 
2151  DeleteVariable(&var);
2152 
2153  AddCt2Monomial(-1.0,&f);
2154  AddVariable2Monomial(NFUN,vIDuni[i][k],1,&f);
2155  AddMonomial(&f,&(eq[k]));
2156  ResetMonomial(&f);
2157 
2158  SetEquationType(SYSTEM_EQ,&(eq[k]));
2159  SetEquationCmp(EQU,&(eq[k]));
2160  AddEquation2CS(p,&(eq[k]),cs);
2161  DeleteEquation(&(eq[k]));
2162  }
2163 
2164  }
2165 
2166  /* the two vectors must be orthogonal */
2167  GenerateDotProductEquation(vIDuni[0][0],vIDuni[0][1],vIDuni[0][2],
2168  vIDuni[1][0],vIDuni[1][1],vIDuni[1][2],
2169  NO_UINT,0,&eq1);
2170  AddEquation2CS(p,&eq1,cs);
2171  DeleteEquation(&eq1);
2172  break;
2173 
2174  case SPH_JOINT:
2175  case SPH_SPH_LOW_JOINT:
2176  case SPH_SPH_UP_JOINT:
2177  /*spherical joints introduce no joint equations (all the constraints
2178  of a spherical joint are in the loop equations.*/
2179  break;
2180 
2181  case IN_PATCH_JOINT:
2182  /* Define the path control variables (u,v) and the dummy w=u*w */
2183  for(i=0;i<3;i++)
2184  {
2185  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,ln1,ln2,i);
2186 
2187  NewVariable((i<2?SYSTEM_VAR:DUMMY_VAR),vname,&var);
2188  SetVariableInterval(&rangeZeroOne,&var);
2189 
2190  vID[i]=AddVariable2CS(&var,cs);
2191 
2192  DeleteVariable(&var);
2193  }
2194 
2195  /* define the variable for the norm of the normal vector */
2196  IN_PATCH_JOINT_SCALE_VAR(vname,j->id,ln1,ln2);
2197 
2198  NewVariable(SECONDARY_VAR,vname,&var);
2199  SetVariableInterval(&(j->normRange),&var);
2200  l=AddVariable2CS(&var,cs);
2201  DeleteVariable(&var);
2202 
2203  /* define the equation for the dummy variable w=u*v */
2204  GenerateSaddleEquation(vID[0],vID[1],vID[2],&eq1);
2205  AddEquation2CS(p,&eq1,cs);
2206  DeleteEquation(&eq1);
2207 
2208  /*Define the equation giving the (square) norm of the normal vector
2209  (i.e., the equation defining 'l')*/
2210  InitEquation(&eq1);
2211  SetEquationValue(0.0,&eq1);
2212  /*n0*n0*/
2213  AddCt2Monomial(DotProduct(j->normals[0],j->normals[0]),&f);
2214  AddMonomial(&f,&eq1);
2215  ResetMonomial(&f);
2216  /*+n1*n1*u^2*/
2217  AddCt2Monomial(DotProduct(j->normals[1],j->normals[1]),&f);
2218  AddVariable2Monomial(NFUN,vID[0],2,&f);
2219  AddMonomial(&f,&eq1);
2220  ResetMonomial(&f);
2221  /*+n2*n2*v^2*/
2222  AddCt2Monomial(DotProduct(j->normals[2],j->normals[2]),&f);
2223  AddVariable2Monomial(NFUN,vID[1],2,&f);
2224  AddMonomial(&f,&eq1);
2225  ResetMonomial(&f);
2226  /*+2*n0*n1*u*/
2227  AddCt2Monomial(2*DotProduct(j->normals[0],j->normals[1]),&f);
2228  AddVariable2Monomial(NFUN,vID[0],1,&f);
2229  AddMonomial(&f,&eq1);
2230  ResetMonomial(&f);
2231  /*+2*n0*n2*v*/
2232  AddCt2Monomial(2*DotProduct(j->normals[0],j->normals[2]),&f);
2233  AddVariable2Monomial(NFUN,vID[1],1,&f);
2234  AddMonomial(&f,&eq1);
2235  ResetMonomial(&f);
2236  /*+2*n1*n2*u*v=2*n1*n2*w*/
2237  AddCt2Monomial(2*DotProduct(j->normals[1],j->normals[2]),&f);
2238  AddVariable2Monomial(NFUN,vID[2],1,&f);
2239  AddMonomial(&f,&eq1);
2240  ResetMonomial(&f);
2241 
2242  AddCt2Monomial(-1.0,&f); /*-l^2*/
2243  AddVariable2Monomial(NFUN,l,2,&f);
2244  AddMonomial(&f,&eq1);
2245  ResetMonomial(&f);
2246 
2247  SetEquationType(SYSTEM_EQ,&eq1);
2248  SetEquationCmp(EQU,&eq1);
2249  AddEquation2CS(p,&eq1,cs);
2250 
2251  DeleteEquation(&eq1);
2252 
2253  /* Define the equations aligning the unitary vector on non-patch
2254  link with the normal vector on the patch. Note that the vector
2255  on the non-patch link is scaled by the norm of the patch
2256  normal vector. */
2257  for(k=0;k<3;k++)
2258  InitEquation(&(eq[k]));
2259 
2260  ApplyLinkRot(p, 1,l,j->points[1],eq,cs,
2261  IsGroundLink(j->linkID[0]),j->link[0]);
2262 
2263  ApplyLinkRot(p,-1,NO_UINT,j->normals[0],eq,cs,
2264  IsGroundLink(j->linkID[1]),j->link[1]);
2265  ApplyLinkRot(p,-1, vID[0],j->normals[1],eq,cs,
2266  IsGroundLink(j->linkID[1]),j->link[1]);
2267  ApplyLinkRot(p,-1, vID[1],j->normals[2],eq,cs,
2268  IsGroundLink(j->linkID[1]),j->link[1]);
2269 
2270  for(k=0;k<3;k++)
2271  {
2272  SetEquationType(SYSTEM_EQ,&(eq[k]));
2273  SetEquationCmp(EQU,&(eq[k]));
2274  AddEquation2CS(p,&(eq[k]),cs);
2275  DeleteEquation(&(eq[k]));
2276  }
2277 
2278  break;
2279 
2280  default:
2281  Error("Unknown joint type in GenerateJointEquations");
2282  }
2283 
2284  free(vname);
2285  DeleteInterval(&rangeOne);
2286  DeleteMonomial(&f);
2287  }
2288 }
2289 
2290 
2292  Tjoint *j)
2293 {
2294  unsigned int r;
2295 
2296  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
2297 
2298  /* for DOF representations -> nothing to reconstruct */
2299  if (r!=REP_JOINTS)
2300  {
2301  unsigned int i;
2302  unsigned int vID[3];
2303  char *vname,*ln1,*ln2;
2304 
2305  ln1=GetLinkName(j->link[0]);
2306  ln2=GetLinkName(j->link[1]);
2307 
2308  NEW(vname,strlen(ln1)+strlen(ln2)+100,char);
2309 
2310  switch(j->t)
2311  {
2312  case IN_PATCH_JOINT:
2313 
2314  for(i=0;i<3;i++)
2315  {
2316  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,ln1,ln2,i);
2317  vID[i]=GetCSVariableID(vname,cs);
2318  }
2319 
2320  sol[vID[2]]=sol[vID[0]]*sol[vID[1]];
2321  break;
2322  }
2323  free(vname);
2324  }
2325 }
2326 
2328 {
2329  unsigned int r;
2330  char *vname,*ln1,*ln2;
2331 
2332  ln1=GetLinkName(j->link[0]);
2333  ln2=GetLinkName(j->link[1]);
2334  NEW(vname,strlen(ln1)+strlen(ln2)+100,char);
2335 
2336  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
2337 
2338  /* for DOF representations -> nothing to reconstruct */
2339  if (r!=REP_JOINTS)
2340  {
2341  unsigned int i;
2342  unsigned int vID[3];
2343  Tinterval r;
2344 
2345  switch(j->t)
2346  {
2347  case IN_PATCH_JOINT:
2348  for(i=0;i<3;i++)
2349  {
2350  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,ln1,ln2,i);
2351  vID[i]=GetCSVariableID(vname,cs);
2352  }
2353 
2354  IntervalProduct(GetBoxInterval(vID[0],b),
2355  GetBoxInterval(vID[1],b),&r);
2356 
2357  SetBoxInterval(vID[2],&r,b);
2358 
2359  break;
2360  }
2361  }
2362  free(vname);
2363 }
2364 
2366  THTransform *t1,THTransform *t2,
2367  TCuikSystem *cs,double *sol,
2368  Tjoint *j)
2369 {
2370  unsigned int r;
2371 
2372  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
2373 
2374  if (r==REP_JOINTS)
2375  Error("GenerateJointSolution is not defined for JOINTS-based representations");
2376  else
2377  {
2378  char *vname,*ln1,*ln2;
2379  unsigned int i,k,vID;
2380  double vector[4][3];
2381 
2382  ln1=GetLinkName(j->link[0]);
2383  ln2=GetLinkName(j->link[1]);
2384 
2385  NEW(vname,strlen(ln1)+strlen(ln2)+100,char);
2386 
2387  switch(j->t)
2388  {
2389  case FREE_JOINT:
2390  for(i=0;i<3;i++)
2391  {
2392  FREE_JOINT_VAR(vname,j->id,j->linkID[0],ln1,j->linkID[1],ln2,i);
2393 
2394  vID=GetCSVariableID(vname,cs);
2395  if (vID==NO_UINT)
2396  Error("Undefined variable in GenerateJointSolution");
2397 
2398  sol[vID]=dof[i];
2399  }
2400  break;
2401 
2402  case FIX_JOINT:
2403  /* Fix joints do not define any variable */
2404  break;
2405 
2406  case PRS_JOINT:
2407 
2408  PRS_JOINT_VAR(vname,j->id,ln1,ln2);
2409 
2410  vID=GetCSVariableID(vname,cs);
2411  if (vID==NO_UINT)
2412  Error("Undefined variable in GenerateJointSolution");
2413 
2414  sol[vID]=dof[0];
2415  break;
2416 
2417  case UNV_JOINT:
2418  for(i=0;i<2;i++)
2419  {
2420  /* We only rotate vectors (do not use the translation in
2421  the homogeneous matrix). */
2422  HTransformApplyRot(j->normals[i],vector[2+i],(i==0?t1:t2));
2423 
2424  for(k=0;k<3;k++)
2425  {
2426  UNV_JOINT_VAR(vname,j->id,ln1,ln2,i,k);
2427 
2428  vID=GetCSVariableID(vname,cs);
2429  if (vID==NO_UINT)
2430  Error("Undefined variable in GenerateJointSolution");
2431  sol[vID]=vector[2+i][k];
2432  }
2433  }
2434  /* we continue to the following block (no break here) */
2435 
2436  case REV_JOINT:
2437  case SPH_JOINT:
2438  case SPH_SPH_LOW_JOINT: /* unlimited spherical -> nothing will be done */
2439  case SPH_SPH_UP_JOINT: /* unlimited spherical -> nothing will be done */
2440  case REV_LOW_JOINT: /* unlimited revolute -> nothing will be done */
2441  case REV_UP_JOINT: /* unlimited revolute -> nothing will be done */
2442  if (j->hasLimits)
2443  {
2444  for(i=0;i<2;i++)
2445  {
2446  /* We only rotate vectors (do not use the translation in
2447  the homogeneous matrix). */
2448  HTransformApplyRot(j->vrange[i],vector[i],(i==0?t1:t2));
2449 
2450  for(k=0;k<3;k++)
2451  {
2452  if (j->t==REV_JOINT)
2453  ROT_JOINT_VAR_REF(vname,j->id,i,ln1,ln2,k);
2454  else
2455  {
2456  if (j->t==SPH_JOINT)
2457  SPH_JOINT_VAR_REF(vname,j->id,i,ln1,ln2,k);
2458  else
2459  UNV_JOINT_VAR_REF(vname,j->id,i,ln1,ln2,k);
2460  }
2461 
2462  vID=GetCSVariableID(vname,cs);
2463  if (vID==NO_UINT)
2464  Error("Undefined variable in GenerateJointSolution");
2465 
2466  sol[vID]=vector[i][k];
2467  }
2468  }
2469  if (j->t==UNV_JOINT)
2470  {
2471  for(k=0;k<2;k++)
2472  {
2473  COS_VAR_UNI(vname,j->id,ln1,ln2,k);
2474  vID=GetCSVariableID(vname,cs);
2475  if (vID==NO_UINT)
2476  Error("Undefined variable in GenerateJointSolution");
2477 
2478  sol[vID]=DotProduct(vector[3-k],vector[k]);
2479  }
2480  }
2481  else
2482  {
2483  COS_VAR(vname,j->id,ln1,ln2);
2484  vID=GetCSVariableID(vname,cs);
2485  if (vID==NO_UINT)
2486  Error("Undefined variable in GenerateJointSolution");
2487 
2488  sol[vID]=DotProduct(vector[0],vector[1]);
2489  }
2490  }
2491  break;
2492 
2493  case IN_PATCH_JOINT:
2494  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,ln1,ln2,0);
2495  vID=GetCSVariableID(vname,cs);
2496  if (vID==NO_UINT)
2497  Error("Undefined variable in GenerateJointSolution");
2498 
2499  sol[vID]=dof[0];
2500 
2501  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,ln1,ln2,1);
2502  vID=GetCSVariableID(vname,cs);
2503  if (vID==NO_UINT)
2504  Error("Undefined variable in GenerateJointSolution");
2505 
2506  sol[vID]=dof[1];
2507 
2508  IN_PATCH_JOINT_CTRL_VAR(vname,j->id,ln1,ln2,2);
2509  vID=GetCSVariableID(vname,cs);
2510  if (vID==NO_UINT)
2511  Error("Undefined variable in GenerateJointSolution");
2512 
2513  sol[vID]=dof[0]*dof[1];
2514 
2515  IN_PATCH_JOINT_SCALE_VAR(vname,j->id,ln1,ln2);
2516  vID=GetCSVariableID(vname,cs);
2517  if (vID==NO_UINT)
2518  Error("Undefined variable in GenerateJointSolution");
2519 
2520  sol[vID]=sqrt(DotProduct(j->normals[0],j->normals[0])+
2521  DotProduct(j->normals[1],j->normals[1])*dof[0]*dof[0]+
2522  DotProduct(j->normals[2],j->normals[2])*dof[1]*dof[1]+
2523  2*DotProduct(j->normals[0],j->normals[1])*dof[0]+
2524  2*DotProduct(j->normals[0],j->normals[2])*dof[1]+
2525  2*DotProduct(j->normals[1],j->normals[2])*dof[0]*dof[1]);
2526 
2527  break;
2528 
2529  default:
2530  Error("Unknown joint type in GenerateJointSolution");
2531 
2532  }
2533  free(vname);
2534  }
2535 }
2536 
2537 void GetJointTransform(double *dof,THTransform *t,Tjoint *j)
2538 {
2539  THTransform T;
2540 
2541  switch(j->t)
2542  {
2543  case FREE_JOINT:
2544  HTransformRx(dof[5],t);
2545  HTransformRy(dof[4],&T);HTransformProduct(&T,t,t);
2546  HTransformRz(dof[3],&T);HTransformProduct(&T,t,t);
2547  HTransformTxyz(dof[0],dof[1],dof[2],&T);HTransformProduct(&T,t,t);
2548  HTransformDelete(&T);
2549  break;
2550 
2551  case FIX_JOINT:
2552  HTransformCopy(t,&(j->preT));
2553  break;
2554 
2555  case REV_LOW_JOINT:
2556  case REV_UP_JOINT:
2557  HTransformCopy(t,&(j->preT));
2558  HTransformAcumRot(RZ,sin(dof[0]),cos(dof[0]),t);
2559  HTransformProduct(t,&(j->postT),t);
2560  break;
2561 
2562  case REV_JOINT:
2563  HTransformCopy(t,&(j->preT));
2564  HTransformAcumRot(RX,sin(dof[0]),cos(dof[0]),t);
2565  HTransformProduct(t,&(j->postT),t);
2566  break;
2567 
2568  case UNV_JOINT:
2569  HTransformRx(dof[0],&T);
2570  HTransformAcumRot(RZ,1,0,&T);
2571  HTransformRx(M_PI+dof[1],t);
2572  HTransformProduct(&T,t,&T);
2573 
2574  HTransformProduct(&(j->preT),&T,t);
2575  HTransformProduct(t,&(j->postT),t);
2576 
2577  HTransformDelete(&T);
2578  break;
2579 
2580  case SPH_JOINT:
2581  case SPH_SPH_LOW_JOINT:
2582  case SPH_SPH_UP_JOINT:
2583  HTransformCopy(t,&(j->preT));
2584  HTransformAcumRot(RZ,sin(dof[0]),cos(dof[0]),t);
2585  HTransformAcumRot(RY,sin(dof[1]),cos(dof[1]),t);
2586  HTransformAcumRot(RX,sin(dof[2]),cos(dof[2]),t);
2587  HTransformProduct(t,&(j->postT),t);
2588  break;
2589 
2590  case PRS_JOINT:
2591  HTransformTxyz(dof[0]*j->normals[0][0],
2592  dof[0]*j->normals[0][1],
2593  dof[0]*j->normals[0][2],&T);
2594 
2595  HTransformProduct(&(j->preT),&T,t);
2596  HTransformProduct(t,&(j->postT),t);
2597 
2598  HTransformDelete(&T);
2599  break;
2600 
2601  case IN_PATCH_JOINT:
2602  {
2603  double x[3],y[3],z[3],p[3];
2604 
2605  HTransformRx(dof[2],t);
2606 
2607  /* x=n0+u*n1+v*n2 */
2608  SumVectorScale(3,j->normals[0],dof[0],j->normals[1],x);
2609  SumVectorScale(3,x,dof[1],j->normals[2],x);
2610  Normalize(3,x);
2611 
2612  /* y=p02+v*d */
2613  SumVectorScale(3,j->points[3],dof[1],j->points[5],y);
2614  Normalize(3,y);
2615 
2616  /* z=x X y */
2617  CrossProduct(x,y,z);
2618 
2619  /* p=p0+u*p02+v*p01+u*v*d */
2620  SumVectorScale(3,j->points[2],dof[0],j->points[3],p);
2621  SumVectorScale(3,p,dof[1],j->points[4],p);
2622  SumVectorScale(3,p,dof[0]*dof[1],j->points[5],p);
2623 
2624  HTransformFromVectors(x,y,z,p,&T);
2625  HTransformInverse(&T,&T);
2626 
2627  HTransformProduct(t,&T,t);
2628 
2629  HTransformProduct(&(j->preT),t,t);
2630  }
2631  break;
2632 
2633  default:
2634  Error("Unknown joint type in GetJointTransform");
2635  }
2636 }
2637 
2639 {
2640  THTransform it1,rel,it;
2641  double s,c;
2642 
2643  /* Get the parameters from the relative transfrom from t1 to t2 */
2644  /* t1*rel=t2 -> rel = inv(t1)*t2 */
2645  HTransformInverse(t1,&it1);
2646  HTransformProduct(&it1,t2,&rel);
2647  HTransformDelete(&it1);
2648 
2649  /* Discount the pre-post matrices */
2650  HTransformInverse(&(j->preT),&it);
2651  HTransformProduct(&it,&rel,&rel);
2652  HTransformDelete(&it1);
2653 
2654  HTransformInverse(&(j->postT),&it);
2655  HTransformProduct(&rel,&it,&rel);
2656  HTransformDelete(&it);
2657 
2658  switch(j->t)
2659  {
2660  case FREE_JOINT:
2661  /* Translation is direct */
2662  dof[0]=HTransformGetElement(AXIS_X,AXIS_H,&rel);
2663  dof[1]=HTransformGetElement(AXIS_Y,AXIS_H,&rel);
2664  dof[2]=HTransformGetElement(AXIS_Z,AXIS_H,&rel);
2665  /* Euler Angles from a Transform matrix */
2666  GetYawPitchRoll(&(dof[3]),&(dof[4]),&(dof[5]),&rel);
2667  break;
2668 
2669  case SPH_JOINT:
2670  case SPH_SPH_LOW_JOINT:
2671  case SPH_SPH_UP_JOINT:
2672  /* Euler Angles from a Transform matrix */
2673  GetYawPitchRoll(&(dof[0]),&(dof[1]),&(dof[2]),&rel);
2674  break;
2675 
2676  case FIX_JOINT:
2677  /* Check if 'rel' is actually Id? */
2678  break;
2679 
2680  case REV_LOW_JOINT:
2681  case REV_UP_JOINT:
2682  /* Check if 'rel' is actually a Rz transform? */
2685 
2686  dof[0]=atan2(s,c);
2687  break;
2688 
2689  case REV_JOINT:
2690  if (j->coupled==NULL)
2691  {
2692  /* Check if 'rel' is actually a Rx transform? */
2695 
2696  dof[0]=atan2(s,c);
2697  }
2698  break;
2699 
2700  case UNV_JOINT:
2701  /* An universal joint with a1, and a2 the dof is
2702  Rx(a1)*Rz(pi/2)*Rx(pi)*Rx(a2)
2703  that evaluates to
2704  [ 0, cos(a2), -sin(a2), 0]
2705  [ cos(a1), sin(a1)*sin(a2), cos(a2)*sin(a1), 0]
2706  [ sin(a1), -cos(a1)*sin(a2), -cos(a1)*cos(a2), 0]
2707  [ 0, 0, 0, 1]
2708  */
2711  dof[0]=atan2(s,c);
2712 
2715  dof[1]=atan2(s,c);
2716  break;
2717 
2718  case PRS_JOINT:
2719  {
2720  double d[3];
2721 
2722  d[0]=HTransformGetElement(AXIS_X,AXIS_H,&rel);
2723  d[1]=HTransformGetElement(AXIS_Y,AXIS_H,&rel);
2724  d[2]=HTransformGetElement(AXIS_Z,AXIS_H,&rel);
2725 
2726  dof[0]=DotProduct(j->normals[0],d);
2727 
2728  /* Check that fabs(dof[0]) is Norm(3,d) -> d and j->normals[0] are aligned */
2729  }
2730  break;
2731 
2732  case IN_PATCH_JOINT:
2733  {
2734  double x[3],y[3],z[3],t[3];
2735  THTransform R,P;
2736  double d;
2737 
2738  /* Here rel = Rx * P\inv
2739  = Rx * (T(u,v) * R(u,v))\inv
2740  = Rx * R(u,v)\tr * (-T(u,v))
2741  = R * (-T(u,v))
2742  where R is a rotation resulting from Rx * R(u,v)\tr
2743  That is, R is the rotation part of 'rel'
2744  and T(u,v) = -R\inv * rel
2745  and Rx=rel*P(u,v)
2746  */
2747  HTransformCopy(&R,&rel);
2751  HTransformInverse(&R,&R);
2752  HTransformProduct(&R,&rel,&R);
2753 
2757  HTransformDelete(&R);
2758  DifferenceVector(3,t,j->points[2],t);
2759 
2760  if (Norm(3,j->points[5])<ZERO)
2761  {
2762  double c1[2],c2[2],c3[2];
2763 
2764  /* t-p0=u*p02+v*p01 */
2765  /* solve the overconstrained system */
2766  c1[0]=DotProduct(j->points[3],j->points[3]);
2767  c1[1]=DotProduct(j->points[4],j->points[3]);
2768 
2769  c2[0]=c1[1];
2770  c2[1]=DotProduct(j->points[4],j->points[4]);
2771 
2772  c3[0]=DotProduct(j->points[3],t);
2773  c3[1]=DotProduct(j->points[4],t);
2774 
2775  d=Det2x2(c1,c2);
2776  dof[0]=Det2x2(c3,c2)/d;
2777  dof[1]=Det2x2(c1,c3)/d;
2778  }
2779  else
2780  {
2781  /* t-p0=u*p02+v*p01+u*v*d */
2782  /* solve the lineal system to recover u,v, and w=u*v */
2783  d=Det3x3(j->points[3],j->points[4],j->points[5]);
2784  dof[0]=Det3x3(t,j->points[4],j->points[5])/d;
2785  dof[1]=Det3x3(j->points[3],t,j->points[5])/d;
2786  /* There is no need to recover the last variable
2787  (it is u*v) */
2788  }
2789 
2790  /*Now define P(u,v) to recover Rx*/
2791 
2792  /* x=n0+u*n1+v*n2 */
2793  SumVectorScale(3,j->normals[0],dof[0],j->normals[1],x);
2794  SumVectorScale(3,x,dof[1],j->normals[2],x);
2795  Normalize(3,x);
2796 
2797  /* y=p02+v*d */
2798  SumVectorScale(3,j->points[3],dof[1],j->points[5],y);
2799  Normalize(3,y);
2800 
2801  /* z=x X y */
2802  CrossProduct(x,y,z);
2803 
2804  /* t=p0+u*p02+v*p01+u*v*d */
2805  SumVectorScale(3,j->points[2],dof[0],j->points[3],t);
2806  SumVectorScale(3,t,dof[1],j->points[4],t);
2807  SumVectorScale(3,t,dof[0]*dof[1],j->points[5],t);
2808 
2809  HTransformFromVectors(x,y,z,t,&P);
2810 
2811  HTransformProduct(&rel,&P,&rel);
2812  HTransformDelete(&P);
2813 
2814  /* Chec that rel is actually a Rx? */
2815 
2816  /* Now just recover the rotation */
2819  dof[2]=atan2(s,c);
2820  }
2821  break;
2822 
2823  default:
2824  Error("Unknow joint type in GetJointDOFValues");
2825  }
2826  HTransformDelete(&rel);
2827 }
2828 
2830 {
2831  unsigned int r;
2832 
2833  r=(unsigned int)(GetParameter(CT_REPRESENTATION,p));
2834 
2835  if (r!=REP_JOINTS)
2836  Error("GetJointSTransform is only defined for JOINT-based representations");
2837  else
2838  {
2839  THTransform cT;
2840  char *vname;
2841  unsigned int uID,vID;
2842  unsigned int i,id;
2843  char *ln1,*ln2;
2844 
2845  InitTransSeq(ts);
2846 
2847  if ((j->t==REV_JOINT)&&(j->coupled!=NULL))
2848  {
2849  ln1=GetLinkName(((Tjoint *)j->coupled)->link[0]);
2850  ln2=GetLinkName(((Tjoint *)j->coupled)->link[1]);
2851  id=((Tjoint *)j->coupled)->id;
2852  }
2853  else
2854  {
2855  ln1=GetLinkName(j->link[0]);
2856  ln2=GetLinkName(j->link[1]);
2857  id=j->id;
2858  }
2859  NEW(vname,strlen(ln1)+strlen(ln2)+100,char);
2860 
2861  switch(j->t)
2862  {
2863  case FREE_JOINT:
2864  for(i=0;i<6;i++)
2865  {
2866  DOF_VAR(vname,id,ln1,ln2,i);
2867  vID=GetCSVariableID(vname,cs);
2868  if (vID==NO_UINT)
2869  Error("Undefined variable in GetJointTransSeq");
2870  switch(i)
2871  {
2872  case 0:
2873  case 1:
2874  case 2:
2875  AddVarTrans2TransSeq(i,1,vID,ts);
2876  break;
2877  case 3:
2878  AddVarTrans2TransSeq(RZ,1,vID,ts);
2879  break;
2880  case 4:
2881  AddVarTrans2TransSeq(RY,1,vID,ts);
2882  break;
2883  case 5:
2884  AddVarTrans2TransSeq(RX,1,vID,ts);
2885  break;
2886  }
2887  }
2888  break;
2889 
2890  case FIX_JOINT:
2891  AddCtTrans2TransSeq(&(j->preT),ts);
2892  break;
2893 
2894  case REV_LOW_JOINT:
2895  case REV_UP_JOINT:
2896  AddCtTrans2TransSeq(&(j->preT),ts);
2897  DOF_VAR(vname,id,ln1,ln2,0);
2898  vID=GetCSVariableID(vname,cs);
2899  if (vID==NO_UINT)
2900  Error("Undefined variable in GetJointTransSeq");
2901  AddVarTrans2TransSeq(RZ,1,vID,ts);
2902 
2903  AddCtTrans2TransSeq(&(j->postT),ts);
2904  break;
2905 
2906  case REV_JOINT:
2907  AddCtTrans2TransSeq(&(j->preT),ts);
2908  DOF_VAR(vname,id,ln1,ln2,0);
2909  vID=GetCSVariableID(vname,cs);
2910  if (vID==NO_UINT)
2911  Error("Undefined variable in GetJointTransSeq");
2912  AddVarTrans2TransSeq(RX,1,vID,ts);
2913 
2914  AddCtTrans2TransSeq(&(j->postT),ts);
2915  break;
2916 
2917  case UNV_JOINT:
2918  AddCtTrans2TransSeq(&(j->preT),ts);
2919 
2920  DOF_VAR(vname,id,ln1,ln2,0);
2921  vID=GetCSVariableID(vname,cs);
2922  if (vID==NO_UINT)
2923  Error("Undefined variable in GetJointTransSeq");
2924  AddVarTrans2TransSeq(RX,1,vID,ts);
2925 
2926  HTransformRz2(1,0,&cT); /* Rz(pi/2) */
2927  AddCtTrans2TransSeq(&cT,ts);
2928 
2929  HTransformRx2(0,-1,&cT); /* Rx(pi) */
2930  AddCtTrans2TransSeq(&cT,ts);
2931 
2932  DOF_VAR(vname,id,ln1,ln2,1);
2933  vID=GetCSVariableID(vname,cs);
2934  if (vID==NO_UINT)
2935  Error("Undefined variable in GetJointTransSeq");
2936  AddVarTrans2TransSeq(RX,1,vID,ts);
2937 
2938  AddCtTrans2TransSeq(&(j->postT),ts);
2939  break;
2940 
2941  case SPH_JOINT:
2942  case SPH_SPH_LOW_JOINT:
2943  case SPH_SPH_UP_JOINT:
2944  AddCtTrans2TransSeq(&(j->preT),ts);
2945 
2946  for(i=0;i<3;i++)
2947  {
2948  DOF_VAR(vname,id,ln1,ln2,i);
2949  vID=GetCSVariableID(vname,cs);
2950  if (vID==NO_UINT)
2951  Error("Undefined variable in GetJointTransSeq");
2952  AddVarTrans2TransSeq(RZ-i,1,vID,ts); /* Rz Ry Rx */
2953  }
2954 
2955  AddCtTrans2TransSeq(&(j->postT),ts);
2956  break;
2957 
2958  case PRS_JOINT:
2959  AddCtTrans2TransSeq(&(j->preT),ts);
2960 
2961  DOF_VAR(vname,id,ln1,ln2,0);
2962  vID=GetCSVariableID(vname,cs);
2963  if (vID==NO_UINT)
2964  Error("Undefined variable in GetJointTransSeq");
2965  AddDispTrans2TransSeq(1,vID,j->normals[0],ts);
2966 
2967  AddCtTrans2TransSeq(&(j->postT),ts);
2968  break;
2969 
2970  case IN_PATCH_JOINT:
2971  AddCtTrans2TransSeq(&(j->preT),ts);
2972 
2973  DOF_VAR(vname,id,ln1,ln2,2);
2974  vID=GetCSVariableID(vname,cs);
2975  AddVarTrans2TransSeq(RX,1,vID,ts);
2976 
2977  DOF_VAR(vname,id,ln1,ln2,0);
2978  uID=GetCSVariableID(vname,cs);
2979 
2980  DOF_VAR(vname,id,ln1,ln2,1);
2981  vID=GetCSVariableID(vname,cs);
2982 
2983  /* The patch transform inverted */
2984  {
2985  /* Get the combination of points defined from the patch vertices */
2986  unsigned int k;
2987  double **p;
2988 
2989  NEW(p,4,double*);
2990  for(k=0;k<4;k++)
2991  { NEW(p[k],3,double); }
2992  memcpy(p[0],j->points[2],3*sizeof(double)); /* p_0=p_0 */
2993  SumVector(3,j->points[4],j->points[2],p[1]); /* p_1=p_01+p_0 */
2994  SumVector(3,j->points[3],j->points[2],p[2]); /* p_2=p_02+p_0 */
2995  SumVector(3,j->points[5],j->points[2],p[3]); /* p_3=d+p_01+p_02+p_0 */
2996  SumVector(3,p[3],j->points[3],p[3]);
2997  SumVector(3,p[3],j->points[4],p[3]);
2998 
2999  AddPatchTrans2TransSeq(PA,-1,uID,vID,p,ts);
3000 
3001  for(k=0;k<4;k++)
3002  free(p[k]);
3003  free(p);
3004  }
3005  break;
3006 
3007  default:
3008  Error("Unknow joint type in GetJointTransSeq");
3009  }
3010  free(vname);
3011  }
3012 }
3013 
3014 void PrintJointAxes(Tparameters *p,FILE *f,TCuikSystem *cs,double *sol,
3015  double *r,Tjoint *j)
3016 {
3017  THTransform t;
3018  TLinkConf def;
3019  double point[3];
3020 
3021  switch(j->t)
3022  {
3023  case REV_JOINT:
3024  case PRS_JOINT:
3025  GetTransform2Link(p,cs,sol,IsGroundLink(j->linkID[0]),&(r[j->linkID[0]*3]),
3026  &t,&def,j->link[0]);
3027  HTransformApply(j->points[0],point,&t);
3028  fprintf(f,"%.12f %.12f %.12f ",point[0],point[1],point[2]);
3029  HTransformApplyRot(j->normals[0],point,&t);
3030  fprintf(f,"%.12f %.12f %.12f ",point[0],point[1],point[2]);
3031  break;
3032  case UNV_JOINT:
3033  GetTransform2Link(p,cs,sol,IsGroundLink(j->linkID[0]),&(r[j->linkID[0]*3]),
3034  &t,&def,j->link[0]);
3035  HTransformApply(j->points[0],point,&t);
3036  fprintf(f,"%.12f %.12f %.12f ",point[0],point[1],point[2]);
3037  HTransformApplyRot(j->normals[0],point,&t);
3038  fprintf(f,"%.12f %.12f %.12f ",point[0],point[1],point[2]);
3039 
3040  GetTransform2Link(p,cs,sol,IsGroundLink(j->linkID[1]),&(r[j->linkID[1]*3]),
3041  &t,&def,j->link[1]);
3042  HTransformApply(j->points[2],point,&t);
3043  fprintf(f,"%.12f %.12f %.12f ",point[0],point[1],point[2]);
3044  HTransformApplyRot(j->normals[1],point,&t);
3045  fprintf(f,"%.12f %.12f %.12f ",point[0],point[1],point[2]);
3046  break;
3047  case FREE_JOINT:
3048  break;
3049  default:
3050  Error("PrintJointAxes is not fully implemented yet");
3051  }
3052 }
3053 
3054 void PrintJoint(FILE *f,Tjoint *j)
3055 {
3056  char *ln1,*ln2;
3057 
3058  ln1=GetLinkName(j->link[0]);
3059  ln2=GetLinkName(j->link[1]);
3060 
3061  switch(j->t)
3062  {
3063  case FREE_JOINT:
3064  break;
3065 
3066  case FIX_JOINT:
3067  fprintf(f," fix: %s %s ",ln1,ln2);
3068  HTransformPrettyPrint(f,&(j->preT));
3069  fprintf(f,"\n\n");
3070  break;
3071 
3072  case PRS_JOINT:
3073  fprintf(f," prismatic: %s (%.16f,%.16f,%.16f) (%.16f,%.16f,%.16f)\n",ln1,
3074  j->points[0][0],j->points[0][1],j->points[0][2],
3075  j->points[1][0],j->points[1][1],j->points[1][2]);
3076  fprintf(f," %s (%.16f,%.16f,%.16f) (%.16f,%.16f,%.16f)\n",ln2,
3077  j->points[2][0],j->points[2][1],j->points[2][2],
3078  j->points[3][0],j->points[3][1],j->points[3][2]);
3079  fprintf(f," range ");
3080  PrintInterval(f,&(j->range));
3081  fprintf(f,"\n");
3082  if (j->avoidLimits)
3083  fprintf(f," avoid limits\n");
3084  fprintf(f,"\n");
3085  break;
3086 
3087  case SPH_JOINT:
3088  fprintf(f," spherical: %s (%.16f,%.16f,%.16f)\n",ln1,
3089  j->points[0][0],j->points[0][1],j->points[0][2]);
3090  fprintf(f," %s (%.16f,%.16f,%.16f)\n",ln2,
3091  j->points[2][0],j->points[2][1],j->points[2][2]);
3092  if (j->hasLimits)
3093  {
3094  fprintf(f," range ");
3095  PrintInterval(f,&(j->range));
3096  fprintf(f," +(%.16f,%.16f,%.16f)",
3097  j->vrange[0][0],j->vrange[0][1],j->vrange[0][2]);
3098  fprintf(f," +(%.16f,%.16f,%.16f)\n",
3099  j->vrange[1][0],j->vrange[2][1],j->vrange[3][2]);
3100  }
3101  if (j->avoidLimits)
3102  fprintf(f," avoid limits\n");
3103  fprintf(f,"\n");
3104  break;
3105 
3106  case REV_JOINT:
3107  fprintf(f," revolute: %s (%.16f,%.16f,%.16f) (%.16f,%.16f,%.16f)\n",ln1,
3108  j->points[0][0],j->points[0][1],j->points[0][2],
3109  j->points[1][0],j->points[1][1],j->points[1][2]);
3110  fprintf(f," %s (%.16f,%.16f,%.16f) (%.16f,%.16f,%.16f)\n",ln2,
3111  j->points[2][0],j->points[2][1],j->points[2][2],
3112  j->points[3][0],j->points[3][1],j->points[3][2]);
3113 
3114  if (j->hasLimits)
3115  {
3116  fprintf(f," range ");
3117  PrintInterval(f,&(j->range));
3118  fprintf(f," +(%.16f,%.16f,%.16f)",
3119  j->vrange[0][0],j->vrange[0][1],j->vrange[0][2]);
3120  fprintf(f," +(%.16f,%.16f,%.16f)\n",
3121  j->vrange[1][0],j->vrange[1][1],j->vrange[1][2]);
3122  }
3123  if (j->avoidLimits)
3124  fprintf(f," avoid limits\n");
3125  fprintf(f,"\n");
3126  break;
3127 
3128  case UNV_JOINT:
3129  fprintf(f," universal: %s (%.16f,%.16f,%.16f) (%.16f,%.16f,%.16f)\n",ln1,
3130  j->points[0][0],j->points[0][1],j->points[0][2],
3131  j->points[1][0],j->points[1][1],j->points[1][2]);
3132  fprintf(f," %s (%.16f,%.16f,%.16f) (%.16f,%.16f,%.16f)\n",ln2,
3133  j->points[2][0],j->points[2][1],j->points[2][2],
3134  j->points[3][0],j->points[3][1],j->points[3][2]);
3135  if (j->hasLimits)
3136  {
3137  fprintf(f," range ");
3138  PrintInterval(f,&(j->range));
3139  fprintf(f," +(%.16f,%.16f,%.16f)",
3140  j->vrange[0][0],j->vrange[0][1],j->vrange[0][2]);
3141  PrintInterval(f,&(j->range2));
3142  fprintf(f," +(%.16f,%.16f,%.16f)\n",
3143  j->vrange[1][0],j->vrange[1][1],j->vrange[1][2]);
3144  }
3145  if (j->avoidLimits)
3146  fprintf(f," avoid limits\n");
3147  fprintf(f,"\n");
3148  break;
3149 
3150  case SPH_SPH_LOW_JOINT:
3151  case SPH_SPH_UP_JOINT:
3152  case REV_LOW_JOINT:
3153  case REV_UP_JOINT:
3154  /* nothing to print */
3155  Error("Composite joint are printed at a higher level");
3156  break;
3157 
3158  case IN_PATCH_JOINT:
3159  {
3160  double v[3];
3161 
3162  fprintf(f," in_patch: %s (%.16f,%.16f,%.16f) (%.16f,%.16f,%.16f)\n",ln1,
3163  j->points[0][0],j->points[0][1],j->points[0][2],
3164  j->points[1][0],j->points[1][1],j->points[1][2]);
3165  /* p_0 is directly stored */
3166  fprintf(f," %s (%.16f,%.16f,%.16f)",ln2,
3167  j->points[2][0],j->points[2][1],j->points[2][2]);
3168  /* p_1=p_01+p_0 */
3169  SumVector(3,j->points[4],j->points[2],v);
3170  fprintf(f," (%.16f,%.16f,%.16f)",v[0],v[1],v[2]);
3171  /* p_2=p_02+p_0 */
3172  SumVector(3,j->points[3],j->points[2],v);
3173  fprintf(f," (%.16f,%.16f,%.16f)",v[0],v[1],v[2]);
3174  /* p_3=d+p_01+p_02+p_0 */
3175  SumVector(3,j->points[5],j->points[2],v);
3176  SumVector(3,v,j->points[3],v);
3177  SumVector(3,v,j->points[4],v);
3178  fprintf(f," (%.16f,%.16f,%.16f)\n",v[0],v[1],v[2]);
3179  if (j->avoidLimits)
3180  fprintf(f," avoid limits\n");
3181  fprintf(f,"\n");
3182  }
3183  break;
3184 
3185  default:
3186  Error("Undefined joint type in PrintJoint");
3187  }
3188 }
3189 
3191 {
3192  DeleteInterval(&(j->range));
3193  DeleteInterval(&(j->range2));
3194  HTransformDelete(&(j->preT));
3195  HTransformDelete(&(j->postT));
3196 }
#define SPH_SPH_UP_JOINT
One of the possible type of joints.
Definition: joint.h:93
void NewFreeJoint(unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, Tjoint *j)
Constructor.
Definition: joint.c:93
#define AXIS_X
One of the dimension of R^3.
Definition: htransform.h:83
#define FIX_JOINT
One of the possible type of joints.
Definition: joint.h:51
#define COS_VAR_UNI_SING(vname, id, ln1, ln2, k)
End-range singularity variable for each universal joint.
Definition: varnames.h:398
Tinterval * GetBoxInterval(unsigned int n, Tbox *b)
Returns a pointer to one of the intervals defining the box.
Definition: box.c:270
#define UNV_JOINT
One of the possible type of joints.
Definition: joint.h:67
#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
void HTransformRz2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:232
void PrintJoint(FILE *f, Tjoint *j)
Stores the joint information into a file.
Definition: joint.c:3054
#define FALSE
FALSE.
Definition: boolean.h:30
double maxCoord
Definition: joint.h:230
#define IN_PATCH_JOINT_CTRL_VAR_SING_COS(vname, id, ln1, ln2, i)
End-range singularity variable for each in_patch joint.
Definition: varnames.h:280
void HTransformApply(double *p_in, double *p_out, THTransform *t)
Multiply a homogeneous transform and a vector.
Definition: htransform.c:782
void HTransformTxyz(double tx, double ty, double tz, THTransform *t)
Constructor.
Definition: htransform.c:146
void GenerateSaddleEquation(unsigned int vx, unsigned int vy, unsigned int vz, Tequation *eq)
Construtor. Generates a saddle equation.
Definition: equation.c:1455
void HTransformRx(double rx, THTransform *t)
Constructor.
Definition: htransform.c:161
void HTransformPrettyPrint(FILE *f, THTransform *t)
Prints a homogenoeus transform compactly.
Definition: htransform.c:863
#define PRS_JOINT_VAR_SING_SIN(vname, id, ln1, ln2)
One end-range singularity variable for each prismatic joint.
Definition: varnames.h:212
Relation between two links.
Definition: joint.h:168
void JointForceEquation(Tparameters *pr, unsigned int linkID, TCuikSystem *cs, Tequation *eq, Tjoint *j)
Add the force terms derived from a given joint.
Definition: joint.c:1925
void NewRevoluteJoint(unsigned int id, unsigned int r, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, double **points, boolean hasLimits, Tinterval *range, double **rPoints, boolean avoidLimits, double avoidLimitsWeight, Tjoint *coupled, Tjoint *j)
Constructor.
Definition: joint.c:124
void SetEquationType(unsigned int type, Tequation *eq)
Changes the type of the equation (SYSTEM_EQ, CARTESIAN_EQ, DUMMY_EQ, DERIVED_EQ). ...
Definition: equation.c:1076
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
Tlink * link[2]
Definition: joint.h:178
void DeleteEquation(Tequation *eq)
Destructor.
Definition: equation.c:1859
void GenerateJointEquationsInBranch(Tparameters *p, double s, TCuikSystem *cs, Tequation *eq, Tjoint *j)
Generate the constraints of a joint in a sequence.
Definition: joint.c:1812
void AddPatchTrans2TransSeq(unsigned int t, int s, unsigned int u, unsigned int v, double **p, TTransSeq *ts)
Adds a Parametrized-Patch transform to a transform sequence.
Definition: trans_seq.c:615
boolean avoidLimits
Definition: joint.h:208
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
void NewRevLowJoint(unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, double **points, Tjoint *j)
Constructor.
Definition: joint.c:627
double Det3x3(double *c1, double *c2, double *c3)
Determinant of a 3x3 matrix.
Definition: geom.c:739
#define AXIS_Y
One of the dimension of R^3.
Definition: htransform.h:91
#define SYSTEM_VAR
One of the possible type of variables.
Definition: variable.h:24
#define RZ
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:75
boolean hasLimits
Definition: joint.h:203
CBLAS_INLINE double Norm(unsigned int s, double *v)
Computes the norm of a vector.
unsigned int AddVariable2CS(Tvariable *v, TCuikSystem *cs)
Adds a variable to the system.
Definition: cuiksystem.c:2532
void IntervalAdd(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Addition of two intervals.
Definition: interval.c:423
void NewFixJoint(unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, THTransform *t, Tjoint *j)
Constructor.
Definition: joint.c:102
Definition of variable names.
CBLAS_INLINE void SumVector(unsigned int s, double *v1, double *v2, double *v)
Adds two vectors.
Definition: basic_algebra.c:67
void HTransformApplyRot(double *p_in, double *p_out, THTransform *t)
Multiply the rotation part of the homogeneous transform and a vector.
Definition: htransform.c:801
void NewSphericalJoint(unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, double **points, boolean hasLimits, double range, double **rPoints, boolean avoidLimits, double avoidLimitsWeight, Tjoint *j)
Constructor.
Definition: joint.c:444
#define EQU
In a Tequation, the equation relational operator is equal.
Definition: equation.h:202
void GetJointDOFName(unsigned int ndof, char **name, Tjoint *j)
Label for a specific dof of a joint.
Definition: joint.c:1006
#define FREE_JOINT
One of the possible type of joints.
Definition: joint.h:40
#define REV_LOW_JOINT
One of the possible type of joints.
Definition: joint.h:101
#define RY
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:67
void SetVariableInterval(Tinterval *i, Tvariable *v)
Sets the new range for the variable.
Definition: variable.c:68
#define TRUE
TRUE.
Definition: boolean.h:21
CBLAS_INLINE void Normalize(unsigned int s, double *v)
Normalizes a vector.
double Det2x2(double *c1, double *c2)
Determinant of a 2x2 matrix.
Definition: geom.c:734
double offset2
Definition: joint.h:218
void GenerateJointRangeSingularityEquations(Tparameters *p, TCuikSystem *cs, Tjoint *j)
Modifies the cuik system to detect end range singularities.
Definition: joint.c:1333
void InitEquation(Tequation *eq)
Constructor.
Definition: equation.c:86
void Error(const char *s)
General error function.
Definition: error.c:80
void InitTransSeq(TTransSeq *ts)
Constructor.
Definition: trans_seq.c:450
#define NFUN
No trigonometric function for the variable.
Definition: variable_set.h:36
#define TOPOLOGY_R
One of the possible topologies.
Definition: defines.h:122
void NewUniversalJoint(unsigned int id, unsigned int r, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, double **points, boolean hasLimits, Tinterval *range1, Tinterval *range2, double **rPoints, boolean avoidLimits, double avoidLimitsWeight, Tjoint *j)
Constructor.
Definition: joint.c:280
void GetJointDOFValues(Tparameters *p, THTransform *t1, THTransform *t2, double *dof, Tjoint *j)
Recovers the joint DOFs from the absolute poses of the links.
Definition: joint.c:2638
void NewInPatchJoint(unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, double **points, double **patch, boolean avoidLimits, double avoidLimitsWeight, Tjoint *j)
Constructor.
Definition: joint.c:715
boolean LimitedJoint(Tjoint *j)
Checks if a joint has limits.
Definition: joint.c:1112
#define SPH_JOINT
One of the possible type of joints.
Definition: joint.h:75
#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:410
#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
#define COS_VAR_UNI(vname, id, ln1, ln2, k)
Cosinus between two links for universal joints.
Definition: varnames.h:384
void SetEquationValue(double v, Tequation *eq)
Changes the right-hand value of the equation.
Definition: equation.c:1089
void HTransformX2Vect(double sy, double sz, double *p1, double *p2, THTransform *t)
Transform a unitary vector along the X axis to a generic vector.
Definition: htransform.c:574
void AddMonomial(Tmonomial *f, Tequation *eq)
Adds a new monomial to the equation.
Definition: equation.c:1419
void AddTerm2SearchCriterion(double w, unsigned int v, double val, TCuikSystem *cs)
Adds penalty terms to the search criterion.
Definition: cuiksystem.c:2456
double points[6][3]
Definition: joint.h:180
void GenerateJointEquations(Tparameters *p, double maxCoord, TCuikSystem *cs, Tjoint *j)
Generate the constraints related with the joint.
Definition: joint.c:1967
void NewSphSphUpJoint(unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, double **points, Tjoint *j)
Constructor.
Definition: joint.c:612
void GetJointRangeN(unsigned int nr, double mt, Tinterval *r, Tjoint *j)
Returns one of the ranges of the joint.
Definition: joint.c:1127
#define SPH_JOINT_VAR_REF(vname, id, v, ln1, ln2, k)
Two vectors defined for when limiting the movement of a spherical joints.
Definition: varnames.h:413
void GetJointTransSeq(Tparameters *p, TCuikSystem *cs, TTransSeq *ts, Tjoint *j)
Build the sequence of transforms passing through the joint.
Definition: joint.c:2829
Error and warning functions.
unsigned int JointToID(Tjoint *j)
Gets the identifier of the second link involved in the joint.
Definition: joint.c:956
boolean IntervalSqrt(Tinterval *i, Tinterval *i_out)
Interval square root.
Definition: interval.c:530
double HTransformGetElement(unsigned int i, unsigned int j, THTransform *t)
Gets an element in a homogeneous transform.
Definition: htransform.c:329
void RegenerateJointBox(Tparameters *p, TCuikSystem *cs, Tbox *b, Tjoint *j)
Computes the values for the dummy variables used in the joint equations.
Definition: joint.c:2327
Tinterval range
Definition: joint.h:212
double normals[3][3]
Definition: joint.h:194
void HTransformFromVectors(double *x, double *y, double *z, double *h, THTransform *t)
Defines a homogeneous transform from 4 vectors.
Definition: htransform.c:341
void SetEquationCmp(unsigned int cmp, Tequation *eq)
Changes the relational operator (LEQ, GEQ, EQU) of the equation.
Definition: equation.c:1081
void ResetMonomial(Tmonomial *f)
Reset the monomial information.
Definition: monomial.c:24
void HTransformRz(double rz, THTransform *t)
Constructor.
Definition: htransform.c:195
double DotProduct(double *v1, double *v2)
Computes the dot product of two 3d vectors.
Definition: geom.c:652
double LowerLimit(Tinterval *i)
Gets the lower limit.
Definition: interval.c:79
void HTransformInverse(THTransform *t, THTransform *ti)
Inverse of a homogeneous transform.
Definition: htransform.c:503
unsigned int id
Definition: joint.h:172
#define PRS_JOINT
One of the possible type of joints.
Definition: joint.h:117
#define AXIS_Z
One of the dimension of R^3.
Definition: htransform.h:99
void GetJointPoint(unsigned int link, unsigned int point, double *p, Tjoint *j)
Gets one of the points defining the rotation/sliding axis for the joint.
Definition: joint.c:1102
#define IN_PATCH_JOINT
One of the possible type of joints.
Definition: joint.h:132
#define UNV_JOINT_VAR(vname, id, ln1, ln2, i, k)
Two vectors for each universal joint.
Definition: varnames.h:239
#define IN_PATCH_JOINT_SCALE_VAR(vname, id, ln1, ln2)
Scale factor for the normal vector to a first order Bezier patch.
Definition: varnames.h:296
An equation.
Definition: equation.h:237
unsigned int CoupledWith(Tjoint *j)
Returns the identifier of the joint coupled with the query joint.
Definition: joint.c:1285
#define DOF_VAR(vname, id, ln1, ln2, i)
Name for the degrees of freedom.
Definition: varnames.h:52
void DeleteVariable(Tvariable *v)
Destructor.
Definition: variable.c:93
double GetJointMaxCoordinate(Tjoint *j)
Gets the maximum coordinate.
Definition: joint.c:936
Definitions of constants and macros used in several parts of the cuik library.
void * coupled
Definition: joint.h:204
Definition of the Tjoint type and the associated functions.
void GetYawPitchRoll(double *a, double *b, double *c, THTransform *t)
Recovers the Euler angles from a rotation matrix.
Definition: htransform.c:634
THTransform postT
Definition: joint.h:226
void DifferenceVector(unsigned int s, double *v1, double *v2, double *v)
Substracts two vectors.
void GenerateJointRangeEquations(Tparameters *p, TCuikSystem *cs, Tjoint *j)
Generate the constraints related with the joint limits.
Definition: joint.c:1521
void NewVariable(unsigned int type, char *name, Tvariable *v)
Constructor.
Definition: variable.c:20
#define SECONDARY_VAR
One of the possible type of variables.
Definition: variable.h:44
void InitJoint(unsigned int t, unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, Tjoint *j)
Initializes all fields for a joint with dummy values.
Definition: joint.c:42
void DeleteInterval(Tinterval *i)
Destructor.
Definition: interval.c:1021
void AddEquation2CS(Tparameters *p, Tequation *eq, TCuikSystem *cs)
Adds an equation to the system.
Definition: cuiksystem.c:2502
A scaled product of powers of variables.
Definition: monomial.h:32
A table of parameters.
unsigned int GetJointDOF(Tjoint *j)
Computes the degrees of freedom allowed by a given joint.
Definition: joint.c:1293
THTransform preT
Definition: joint.h:222
#define COS_VAR(vname, id, ln1, ln2)
Cosinus between two links for rotation/spherical joints.
Definition: varnames.h:354
double UpperLimit(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:87
#define ADJUST_REAL(a)
Adjust a real to 0,1,-1, if possible.
Definition: defines.h:195
void NewRevUpJoint(unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, double **points, Tjoint *j)
Constructor.
Definition: joint.c:668
A sequence of transforms.
Definition: trans_seq.h:319
double vrange[2][3]
Definition: joint.h:219
unsigned int linkID[2]
Definition: joint.h:177
CBLAS_INLINE void HTransformAcumRot(unsigned int type, double s, double c, THTransform *t)
Computes the result of multiplying a homogeneous transform by a rotation matrix.
Definition: htransform.c:727
void GetJointName(char **name, Tjoint *j)
Returns a string identifying the joint.
Definition: joint.c:966
#define UNV_JOINT_VAR_REF(vname, id, k, ln1, ln2, i)
Two vectors to define the angle in a universal joint.
Definition: varnames.h:337
Tlink * JointTo(Tjoint *j)
Gets a pointer to the second link involved in the joint.
Definition: joint.c:961
void GetJointTransform(double *dof, THTransform *t, Tjoint *j)
Computes the transform induced by the joint.
Definition: joint.c:2537
#define IN_PATCH_JOINT_CTRL_VAR(vname, id, ln1, ln2, i)
Control variables defining a first order Bezier patch.
Definition: varnames.h:254
#define COS_VAR_SING(vname, id, ln1, ln2)
One end-range singularity variable for each revolute joint.
Definition: varnames.h:367
#define M_PI
Pi.
Definition: defines.h:83
#define CT_REPRESENTATION
Representation.
Definition: parameters.h:215
void AddVarTrans2TransSeq(unsigned int t, int s, unsigned int v, TTransSeq *ts)
Adds a variable transform to the sequence.
Definition: trans_seq.c:578
#define REV_JOINT
One of the possible type of joints.
Definition: joint.h:59
void ResetEquation(Tequation *eq)
Reset equation information.
Definition: equation.c:442
A box.
Definition: box.h:83
Data associated with each variable in the problem.
Definition: variable.h:84
#define ROT_JOINT_VAR_REF(vname, id, k, ln1, ln2, i)
Two vectors to define the angle in a revolute joint.
Definition: varnames.h:316
A cuiksystem, i.e., a set of variables and equations defining a position analysis problem...
Definition: cuiksystem.h:181
void PrintInterval(FILE *f, Tinterval *i)
Prints an interval.
Definition: interval.c:1006
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
Tinterval normRange
Definition: joint.h:200
CBLAS_INLINE void SumVectorScale(unsigned int s, double *v1, double w, double *v2, double *v)
Adds two vectors with a scale.
Definition: basic_algebra.c:86
#define RX
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:59
Tinterval * GetJointRange(Tjoint *j)
Checks the limits of a joint.
Definition: joint.c:1117
void IntervalScale(Tinterval *i1, double e, Tinterval *i_out)
Scales an interval.
Definition: interval.c:360
void AddVariable2Monomial(unsigned int fn, unsigned int varid, unsigned int p, Tmonomial *f)
Adds a power variable to the monomial.
Definition: monomial.c:171
double IntervalCenter(Tinterval *i)
Gets the interval center.
Definition: interval.c:129
void DeleteJoint(Tjoint *j)
Destructor.
Definition: joint.c:3190
void CopyJoint(Tjoint *j_dst, Tjoint *j_src)
Copy constructor.
Definition: joint.c:879
#define REV_UP_JOINT
One of the possible type of joints.
Definition: joint.h:109
void NewSphSphLowJoint(unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, double **points, Tjoint *j)
Constructor.
Definition: joint.c:601
void SetVariableTopology(unsigned int t, Tvariable *v)
Sets the topology of the variable.
Definition: variable.c:42
void AddDispTrans2TransSeq(int s, unsigned int v, double *vect, TTransSeq *ts)
Adds a displacement transform to the sequence.
Definition: trans_seq.c:601
void NewPrismaticJoint(unsigned int id, unsigned int linkID1, Tlink *link1, unsigned int linkID2, Tlink *link2, double **points, Tinterval *range, boolean avoidLimits, double avoidLimitsWeight, Tjoint *j)
Constructor.
Definition: joint.c:533
void HTransformDelete(THTransform *t)
Destructor.
Definition: htransform.c:887
#define PA
Point on a patch.
Definition: trans_seq.h:31
double GetParameter(unsigned int n, Tparameters *p)
Gets the value for a particular parameter.
Definition: parameters.c:93
#define SPH_SPH_LOW_JOINT
One of the possible type of joints.
Definition: joint.h:84
void IntervalProduct(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Product of two intervals.
Definition: interval.c:389
unsigned int GetJointID(Tjoint *j)
Gets the joint identifier.
Definition: joint.c:941
#define FREE_JOINT_VAR(vname, id, id1, ln1, id2, ln2, k)
Variables for a free joint.
Definition: varnames.h:187
void RegenerateJointSolution(Tparameters *p, TCuikSystem *cs, double *sol, Tjoint *j)
Computes the values for the dummy variables used in the joint equations.
Definition: joint.c:2291
#define PRS_JOINT_VAR(vname, id, ln1, ln2)
One variable for each prismatic joint.
Definition: varnames.h:200
Tlink * JointFrom(Tjoint *j)
Gets a pointer to the first link involved in the joint.
Definition: joint.c:951
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:312
#define INF
Infinite.
Definition: defines.h:70
void AddCt2Monomial(double k, Tmonomial *f)
Scales a monomial.
Definition: monomial.c:158
void AddCtTrans2TransSeq(THTransform *t, TTransSeq *ts)
Adds a constant transform to the sequence.
Definition: trans_seq.c:550
#define PRS_JOINT_VAR_SING_COS(vname, id, ln1, ln2)
One end-range singularity variable for each prismatic joint.
Definition: varnames.h:224
void HTransformCopy(THTransform *t_dst, THTransform *t_src)
Copy constructor.
Definition: htransform.c:83
double avoidLimitsWeight
Definition: joint.h:210
void DefineNormalVector(double *v, double *n)
Defines a unitary vector normal to a given vector.
Definition: geom.c:571
unsigned int GetCSVariableID(char *name, TCuikSystem *cs)
Gets the numerical identifier of a variable given its name.
Definition: cuiksystem.c:2607
unsigned int t
Definition: joint.h:169
void IntervalCosine(Tinterval *i, Tinterval *i_out)
Interval cosine.
Definition: interval.c:702
double offset
Definition: joint.h:215
Tinterval range2
Definition: joint.h:213
Defines a interval.
Definition: interval.h:33
void HTransformRy(double ry, THTransform *t)
Constructor.
Definition: htransform.c:178
#define LINK_MAX_FORCE(vname, linkName)
Max force variable.
Definition: varnames.h:119
void HTransformIdentity(THTransform *t)
Constructor.
Definition: htransform.c:69
void InitMonomial(Tmonomial *f)
Constructor.
Definition: monomial.c:17
double IntervalSize(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:96
void CrossProduct(double *v1, double *v2, double *v3)
Computes the cross product of two 3d vectors.
Definition: geom.c:639
unsigned int JointFromID(Tjoint *j)
Gets the identifier of the first link involved in the joint.
Definition: joint.c:946
unsigned int GetJointRangeTopology(unsigned int nr, Tjoint *j)
Returns the topology of one of the ranges of the joint.
Definition: joint.c:1214
#define IN_PATCH_JOINT_CTRL_VAR_SING_SIN(vname, id, ln1, ln2, i)
End-range singularity variable for each in_patch joint.
Definition: varnames.h:267
#define DUMMY_VAR
One of the possible type of variables.
Definition: variable.h:53
void HTransformRx2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:212
void PrintJointAxes(Tparameters *p, FILE *f, TCuikSystem *cs, double *sol, double *r, Tjoint *j)
Prints the joint axis in world coordinates.
Definition: joint.c:3014
void GenerateJointSolution(Tparameters *p, double *dof, THTransform *t1, THTransform *t2, TCuikSystem *cs, double *sol, Tjoint *j)
Generates a solution point from degrees of freedom.
Definition: joint.c:2365
void DeleteMonomial(Tmonomial *f)
Destructor.
Definition: monomial.c:289
unsigned int GetJointType(Tjoint *j)
Gets the joint type.
Definition: joint.c:931
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:1588
Tinterval * GetJointSecondRange(Tjoint *j)
Checks the second limit of a universal joint.
Definition: joint.c:1122
#define TOPOLOGY_S
One of the possible topologies.
Definition: defines.h:139
void IntervalOffset(Tinterval *i, double offset, Tinterval *i_out)
Interval offset.
Definition: interval.c:627
Link configuration.
Definition: link.h:276