cuikexplore.c
Go to the documentation of this file.
1 #include "cuikexplore.h"
2 
3 #include "world.h"
4 #include "interval.h"
5 #include "chart.h"
6 #include "defines.h"
7 #include "jacobian.h"
8 #include "samples.h"
9 #include "error.h"
10 #include "algebra.h"
11 
12 #include "cuikexplore_interface.h"
13 #include "cuikplay_support.h"
14 
15 #include <gtk/gtk.h>
16 
17 #include <string.h>
18 #include <unistd.h>
19 #include <time.h>
20 
72 int main(int argc, char **arg)
73 {
74 
75  if (argc>1)
76  {
77  TAtlasBase world;
78  Tworld *worldBase;
79  Tparameters parameters;
80 
81  Tfilename fparam;
82 
83  Tplot3d pt;
84 
85  TCuikexploreControl status;
86  unsigned int i,j,me;
87  double epsilon,delta;
88 
89  unsigned int k,m,ms,d,nit;
90  double r,e,ce;
91 
92  TJacobian J;
93 
94  GtkWidget *window_cuikexplore;
95 
96  Tchart chart,chartTmp;
97  Tbox ambient;
98  unsigned int *tp;
99  boolean hasS;
100  boolean collide,in;
101 
102  Tinterval range;
103 
104  /* We differentiate between the internal representation of the equations
105  and the DOF-based representation. They are not necessarily the same. */
106  double *newPointDOF;
107  double *simpPoint;
108  double *t;
109  double *initialPoint,*initialPointDOF,*initialSimpPoint;
110 
111  boolean ndxOK;
112  boolean outside,outsideInit;
113  boolean collision,collisionInit;
114  double *pointWithDummies;
115 
116  status.fw=arg[1];
117 
118  CreateFileName(NULL,arg[1],NULL,PARAM_EXT,&fparam);
119  fprintf(stderr,"Reading parameters from : %s\n",GetFileFullName(&fparam));
120  InitParametersFromFile(GetFileFullName(&fparam),&parameters);
121 
122  status.dynamics=(GetParameter(CT_DYNAMICS,&parameters)>0);
123  if (status.dynamics)
124  {
125  /* De-activate the dynamics (assume zero velocity) */
126  ChangeParameter(CT_DYNAMICS,0,&parameters);
127  }
128 
129  nit=(unsigned int)(GetParameter(CT_MAX_NEWTON_ITERATIONS,&parameters));
130  if (nit==0)
132 
133  /* Read the equation info from world */
134  NEW(worldBase,1,Tworld);
135  InitWorldFromFile(&parameters,TRUE,TRUE,arg[1],worldBase);
136  InitWorldCD(&parameters,1,worldBase);
137  CS_WD_FROM_WORLD(worldBase,&world); /* Necessary to generate charts */
138 
139  /* Number of system variables */
140  m=GetWorldNumSystemVariables(worldBase);
141  status.m=m;
142 
143  /* Read the initial point */
144  ReadOneSample(&parameters,arg[1],m,&status.point);
145 
146  /* anotate the underlying representation */
147  status.rep=(unsigned int)(GetParameter(CT_REPRESENTATION,&parameters));
148 
149  epsilon=GetParameter(CT_EPSILON,&parameters);
150  delta=GetParameter(CT_DELTA,&parameters);
151  r=GetParameter(CT_R,&parameters);
152  e=GetParameter(CT_E,&parameters);
153  ce=GetParameter(CT_CE,&parameters);
154  k=(unsigned int)GetParameter(CT_N_DOF,&parameters); /* DOF of the manifold */
155  if (k==0)
156  k=WorldManifoldDimension(&parameters,status.point,worldBase);
157  else
158  {
159  if (status.dynamics)
160  k=k/2;
161  }
162  if (k>=m)
163  Error("The mobility is larger than the number of variables?");
164  status.k=k;
165 
166  /* space for projections to the charts */
167  NEW(t,k,double);
168 
169  /* number of degrees of freedom */
170  d=GetWorldNDOF(worldBase);
171  if (k>d) /* k can be equal to d for non-constrained system */
172  Error("The mobility is larger than the number of dof?");
173  status.d=d;
174 
175  /* number of simplified variables and topology */
176  ms=GetWorldSimpTopology(&parameters,&tp,worldBase);
177 
178  /* Space for the vector of displacements in DOF space */
179  NEW(status.vectDOF,d,double);
180  NEW(status.e2d,d,unsigned int); /* menu entry to dof */
181  NEW(status.d2e,d,unsigned int) /* dof to meny entry */
182  me=0;
183  for(i=0;i<d;i++)
184  {
185  status.vectDOF[i]=0;
186  GetWorldRangeDOF(i,&range,worldBase);
187  if (IntervalSize(&range)<ZERO)
188  {
189  /* fixed dof -> not to be shown in the menu */
190  status.d2e[i]=NO_UINT;
191  }
192  else
193  {
194  status.d2e[i]=me;
195  status.e2d[me]=i;
196  me++;
197  }
198  DeleteInterval(&range);
199  }
200  if (me<k)
201  Error("Insuficient non-fixed degrees of freedom");
202 
203  /* simplify the initial point */
204 
205  RegenerateWorldSolutionPoint(&parameters,status.point,&pointWithDummies,worldBase);
206  WorldGenerateSimplifiedPoint(&parameters,pointWithDummies,&(status.simpPoint),worldBase);
207  free(pointWithDummies);
208  /* convert the start configuration to DOF */
209  NEW(status.pointDOF,d,double);
210  WorldSample2DOF(&parameters,status.point,status.pointDOF,worldBase);
211 
212  /* Temporary space for the new points/dofs */
213  NEW(newPointDOF,d,double);
214 
215  /* Copy of the initial point/DOF used in the reset */
216  NEW(initialPointDOF,d,double);
217  memcpy(initialPointDOF,status.pointDOF,d*sizeof(double));
218  NEW(initialPoint,m,double);
219  memcpy(initialPoint,status.point,m*sizeof(double));
220  NEW(initialSimpPoint,ms,double);
221  memcpy(initialSimpPoint,status.simpPoint,ms*sizeof(double));
222 
223  /* Initialize the chart */
224  GetWorldSimpInitialBox(&parameters,&ambient,worldBase);
225 
226  /* Search for a non-real variable */
227  hasS=FALSE;
228  i=0;
229  while((i<ms)&&(!hasS))
230  {
231  hasS=(tp[i]==TOPOLOGY_S);
232  i++;
233  }
234  if (!hasS)
235  {
236  free(tp);
237  tp=NULL;
238  }
239  GetWorldSimpJacobian(&parameters,&J,worldBase);
240 
241  if (InitChart(&parameters,TRUE,&ambient,tp,ms,k,status.simpPoint,e,ce,r,
242  &J,&world,&chart)!=0)
243  Error("Could not define a chart in the start configuration.");
244 
245  /* It can be the case that the initial point is out of the domain or in collision
246  In this case, we initially ignore the inDocmain and inCollision checks.
247  When we finally find a inDomain and collision-free configuration, these
248  checks are activated again. */
249  outside=(!PointInBoxTopology(NULL,TRUE,ms,status.simpPoint,epsilon,tp,&ambient));
250  outsideInit=outside;
251  if (outside)
252  fprintf(stderr,"Initial point is out of domain\n");
253 
254  CS_WD_ALL_COLLISIONS(collision,&parameters,status.simpPoint,NULL,&world);
255  collisionInit=collision;
256  if (collision)
257  fprintf(stderr,"Initial point is in collision\n");
258 
259  /* indices of the dofs used as a parameters */
260  NEW(status.ndx,k,unsigned int);
261  ndxOK=TRUE;
262  if ((unsigned int)argc>1+k)
263  {
264  for(i=0;((ndxOK)&&(i<k));i++)
265  {
266  status.ndx[i]=atoi(arg[2+i]);
267  ndxOK=(status.d2e[status.ndx[i]]!=NO_UINT);
268  }
269  }
270 
271  if ((!ndxOK)||((unsigned int)argc<=1+k))
272  {
273  i=0;
274  /* Select the 'k' actuated (effort-limited) dof */
275  j=0;
276  while((i<status.d)&&(j<k)&&(0))
277  {
278  if ((status.d2e[i]!=NO_UINT)&&(GetJointEffort(GetWorldJoint(i,worldBase))<INF))
279  {
280  status.ndx[j]=i;
281  j++;
282  }
283  i++;
284  }
285 
286  /* if not enough actuated degrees of freedom are available, just select the first 'k' non-fixed dof */
287  if (i<k)
288  {
289  i=0;
290  j=0;
291  while((i<status.d)&&(j<k))
292  {
293  if (status.d2e[i]!=NO_UINT)
294  {
295  status.ndx[j]=i;
296  j++;
297  }
298  i++;
299  }
300  if (i<k)
301  Error("Can not select enough input parameters");
302  }
303  }
304 
305  status.changed=FALSE;
306  status.end=FALSE;
307  status.reset=FALSE;
308  status.step=delta; /* default value is 0.05 */
309 
310  status.p=&parameters;
311  status.w=&world;
312 
313  gtk_disable_setlocale();
314  gtk_init(&argc,&arg);
315 
316  window_cuikexplore=create_window_cuikexplore((gpointer)(&status));
317  gtk_widget_show(window_cuikexplore);
318 
319  InitPlot3d(NULL,FALSE,argc,arg,&pt);
320 
321  PlotWorld(&parameters,&pt,0.0,worldBase);
322  MoveWorldDOF(&parameters,&pt,status.pointDOF,worldBase);
323  LookPlot3d(&pt);
324 
325  while(!status.end)
326  {
327  if (status.changed)
328  {
329  /* Change the DOF */
330  for(i=0;i<d;i++)
331  newPointDOF[i]=status.pointDOF[i]+status.vectDOF[i];
332  /* Generate the solution point form the DOF. The result is not a solution
333  of the system of equations */
334  WorldDOF2Sol(&parameters,newPointDOF,&pointWithDummies,NULL,worldBase);
335  /* and simplify the solution point (even if 'pointWithDummies' is not a solution) */
336  WorldGenerateSimplifiedPoint(&parameters,pointWithDummies,&simpPoint,worldBase);
337  free(pointWithDummies);
338 
339  /* Verify that we are not moving orthogonaly to the tangent space */
340  Manifold2Chart(simpPoint,tp,t,&chart);
341  if (Norm(k,t)>(1e-3*status.step))
342  {
343  /* Enforce the equations */
344  if (Chart2Manifold(&parameters,&J,t,tp,NULL,simpPoint,&chart)<INF)
345  {
346  /* Check that the solution point is in domain. Only after we are inside the
347  domain for the first time */
348  in=PointInBoxTopology(NULL,TRUE,ms,simpPoint,epsilon,tp,&ambient);
349  if ((outside)||(in))
350  {
351  /* and not in collision. Collision are not considered, thouth, while ouside
352  the domain */
353  CS_WD_ALL_COLLISIONS(collide,&parameters,simpPoint,status.simpPoint,&world);
354  if ((collision)||(!collide))
355  {
356  /* here we have a new valid solution point where it should be possible
357  to generate a new chart */
358  CopyChart(&chartTmp,&chart);
359  DeleteChart(&chart);
360 
361  if (InitChart(&parameters,TRUE,&ambient,tp,ms,k,simpPoint,e,ce,r,
362  &J,&world,&chart)==0)
363  {
364  memcpy(status.simpPoint,simpPoint,sizeof(double)*ms);
365  free(status.point);
366  /* chart2manifold changed the simpPoint -> regenerate the original form it */
367  RegenerateWorldOriginalSystemPoint(&parameters,simpPoint,&(status.point),worldBase);
368  /* and the DOF from the original */
369  WorldSample2DOF(&parameters,status.point,status.pointDOF,worldBase);
370  /* and plot using DOF */
371  MoveWorldDOF(&parameters,&pt,status.pointDOF,worldBase);
372 
373  if (outside)
374  {
375  /* Check if whe already reached the valid domain */
376  outside=(!in);
377  if (!outside)
378  fprintf(stderr,"Entering the domain-----------------------------------------------------------\n"); /* outside flag will remain to false from now on */
379  }
380  if (collision)
381  {
382  collision=collide;
383  if (!collision)
384  fprintf(stderr,"Entering C-free -----------------------------------------------------------\n"); /* outside flag will remain to false from now on */
385  }
386  }
387  else
388  {
389  CopyChart(&chart,&chartTmp);
390  fprintf(stderr,"Error defining chart. Staying in previous point.\n");
391  }
392  DeleteChart(&chartTmp);
393  }
394  else
395  fprintf(stderr,"Collision\n");
396  }
397  else
398  fprintf(stderr,"Out of the ambient space\n");
399  }
400  else
401  fprintf(stderr,"Error in parametrization. Change it?\n");
402  }
403  else
404  fprintf(stderr,"Singularity (%f). Change the parametrization?\n",Norm(k,t));
405 
406  free(simpPoint);
407 
408  /* Reset the displacement vector (if only one step must be executed) */
409  if (status.oneStep)
410  {
411  for(i=0;i<d;i++)
412  status.vectDOF[i]=0;
413  status.changed=FALSE;
414  status.oneStep=FALSE;
415  }
416  else
417  usleep(10000);
418  }
419  if (status.reset)
420  {
421  memcpy(status.pointDOF,initialPointDOF,d*sizeof(double));
422  memcpy(status.point,initialPoint,m*sizeof(double));
423  memcpy(status.simpPoint,initialSimpPoint,ms*sizeof(double));
424  DeleteChart(&chart);
425  if (InitChart(&parameters,TRUE,&ambient,tp,ms,k,status.simpPoint,e,ce,r,
426  &J,&world,&chart)!=0)
427  Error("Can not move to the initial point?");
428 
429  MoveWorldDOF(&parameters,&pt,status.pointDOF,worldBase);
430  status.reset=FALSE;
431  outside=outsideInit;
432  collision=collisionInit;
433  }
434  gtk_main_iteration_do(FALSE);
435  }
436 
437  ClosePlot3d(TRUE,&pt);
438 
439  DeleteChart(&chart);
440  DeleteBox(&ambient);
441  if (tp!=NULL)
442  free(tp);
443  DeleteJacobian(&J);
444 
445  free(newPointDOF);
446  free(t);
447  free(initialPointDOF);
448  free(initialPoint);
449  free(initialSimpPoint);
450 
451  free(status.pointDOF);
452  free(status.point);
453  free(status.simpPoint);
454  free(status.ndx);
455  free(status.vectDOF);
456  free(status.d2e);
457  free(status.e2d);
458 
459  CS_WD_DELETE(&world);
460  DeleteParameters(&parameters);
461 
462  DeleteFileName(&fparam);
463  }
464  else
465  {
466  fprintf(stdout," Wrong number of parameters.\n");
467  fprintf(stdout," Use:\n");
468  fprintf(stdout," cuikexplore <world>.world [dof_1 ... dof_k]\n");
469  fprintf(stdout," Where:\n");
470  fprintf(stdout," <world>: File describing the problem.\n");
471  fprintf(stdout," [dof_1 ... dof_k] Index of the variables to be used\n");
472  fprintf(stdout," as parameters.\n");
473  fprintf(stdout," File extensions are not required\n");
474  }
475 
476  return(EXIT_SUCCESS);
477 }