Пример #1
0
static void Method_p(CTX, ksfp_t *sfp, int pos, kwb_t *wb, int level)
{
	kMethod *mtd = sfp[pos].mtd;
	kParam *pa = kMethod_param(mtd);
	DBG_ASSERT(IS_Method(mtd));
	if(level != 0) {
		MethodAttribute_p(_ctx, mtd, wb);
	}
	kwb_printf(wb, "%s %s.%s%s", TY_t(pa->rtype), TY_t(mtd->cid), T_mn(mtd->mn));
	if(level != 0) {
		size_t i;
		kwb_putc(wb, '(');
		for(i = 0; i < pa->psize; i++) {
			if(i > 0) {
				kwb_putc(wb, ',', ' ');
			}
			if(FN_isCOERCION(pa->p[i].fn)) {
				kwb_printf(wb, "@Coercion ");
			}
			kwb_printf(wb, "%s %s", TY_t(pa->p[i].ty), SYM_t(pa->p[i].fn));
		}
//		if(Param_isVARGs(DP(mtd)->mp)) {
//			knh_write_delimdots(_ctx, w);
//		}
		kwb_putc(wb, ')');
	}
}
Пример #2
0
static void DumpVisitor_init(KonohaContext *kctx, struct IRBuilder *builder, kMethod *mtd)
{
	unsigned i;
	KGrowingBuffer wb;
	KLIB Kwb_init(&(kctx->stack->cwb), &wb);
	kParam *pa = Method_param(mtd);
	KLIB Kwb_printf(kctx, &wb, "METHOD %s%s(", T_mn(mtd->mn));
	for (i = 0; i < pa->psize; i++) {
		if(i != 0) {
			KLIB Kwb_write(kctx, &wb, ", ", 2);
		}
		KLIB Kwb_printf(kctx, &wb, "%s %s", TY_t(pa->paramtypeItems[i].ty), SYM_t(pa->paramtypeItems[i].fn));
	}
	emit_string(KLIB Kwb_top(kctx, &wb, 1), "", ") {", 0);
	builder->local_fields = (void *) KMalloc_UNTRACE(sizeof(int));
	DUMPER(builder)->indent = 0;
}
Пример #3
0
static void DumpVisitor_visitCallExpr(KonohaContext *kctx, IRBuilder *self, kExpr *expr)
{
	KGrowingBuffer wb;
	KLIB Kwb_init(&(kctx->stack->cwb), &wb);
	kMethod *mtd = CallExpr_getMethod(expr);
	KLIB Kwb_printf(kctx, &wb, "CALL: '%s%s'", T_mn(mtd->mn));
	DUMPER(self)->indent++;
	emit_string(KLIB Kwb_top(kctx, &wb, 1), "(", "", DUMPER(self)->indent);
	DUMPER(self)->indent++;
	unsigned i;
	for (i = 1; i < kArray_size(expr->cons); ++i) {
		handleExpr(kctx, self, kExpr_at(expr, i));
	}
	DUMPER(self)->indent--;
	emit_string(")", "", "", DUMPER(self)->indent);
	DUMPER(self)->indent--;
	KLIB Kwb_free(&wb);
}
Пример #4
0
int do_mode_mu()
{
   int err;         /* Generic error variable for function calls */
   int busCount;    /* Number of WAMs defined in the configuration file */
   int j;
   
   /* Stuff that's filled in once */
   vect_n ** poses;
   int num_poses;
   int pose;
   vect_n * angle_diff;
   
   /* Stuff that's used once for each pose in measure mode */
   vect_n * torques_top;
   vect_n * positions_top;
   vect_n * torques_bottom;
   vect_n * positions_bottom;
   
   /* For storing the results from measure mode, one vector per pose  */
   vect_n ** torques;
   vect_n ** positions;
   /* For storing the results from computation mode, one vector per joint */
   vect_3 ** mus;
   
   /* Make a list of phases for each pose*/
   enum {
      MU_P_START,
      MU_P_TO_TOP,
      MU_P_FROM_TOP,
      MU_P_MEAS_TOP,
      MU_P_TO_BOT,
      MU_P_FROM_BOT,
      MU_P_MEAS_BOT,
      MU_P_DONE
   } phase;
   char * phasenm[] = {
      "START",
      "TO_TOP",
      "FROM_TOP",
      "MEAS_TOP",
      "TO_BOT",
      "FROM_BOT",
      "MEAS_BOT",
      "DONE"
   };
   
   clear();
   mvprintw(0,0,"Starting Gravity Calibration Mode");
   
   /* Ensure the WAM is set up, power cycled, and in the home position */
   mvprintw(2,0,"To begin the calibration, follow the following steps:");
   mvprintw(3,0,"  a) Ensure that all WAM power and signal cables are securely fastened.");
   mvprintw(4,0,"  b) Ensure that the WAM is powered on (receiving power).");
   mvprintw(5,0,"  c) Ensure that all E-STOPs are released.");
   mvprintw(6,0,"  d) Place the WAM in Shift+Idle mode.");
   mvprintw(7,0,"  e) Carefully ensure that the WAM is in its home (folded) position.");
   mvprintw(8,0,"Press [Enter] to continue.");
   refresh();
   while (btkey_get()!=BTKEY_ENTER) usleep(10000);
   
   /* Initialize system buses */
   err = ReadSystemFromConfig("../../wam.conf", &busCount);
   if(err) return -1;
   
   /* Spin off the CAN thread */
   startDone = 0;
   btrt_thread_create(&can_thd,"can",45,(void*)can_thd_function,NULL);
   while (!startDone) usleep(10000);
   
   /* Allocate the global variables */
   mu_jts = (double **) malloc( wam->dof * sizeof(double *) );
   mu_jps = (double **) malloc( wam->dof * sizeof(double *) );
   for (j=0; j<wam->dof; j++)
   {
      mu_jts[j] = (double *) malloc( NUM_POINTS * sizeof(double) );
      mu_jps[j] = (double *) malloc( NUM_POINTS * sizeof(double) );
   }
   
   /* Spin off the WAM thread */
   mu_n = NUM_POINTS;
   wam_thd.period = 0.002; /* Control loop period in seconds */
   registerWAMcallback(wam, mu_callback);
   btrt_thread_create(&wam_thd,"ctrl",90,(void*)WAMControlThread,(void*)wam);
   
   /* Grab poses from the configuration file */
   do {
      btparser parser;
      char key[256];
      
      err = btParseFile(&parser,"cal.conf");
      if (err)
      {
         syslog(LOG_ERR,"Calibration configuration file cal.conf not found.");
         printf("Calibration configuration file cal.conf not found.\n");
         break;
      }
      
      sprintf(key,"calibration-poses-wam%d.poseCount",wam->dof);
      err = btParseGetVal(&parser,INT, key, &num_poses);
      if (err || num_poses < 4)
      {
         syslog(LOG_ERR,"Configuration group calibration-poses-wam%d not found,",wam->dof);
         syslog(LOG_ERR,"numPoses not present, or numPoses not at least 4.");
         printf("Configuration group calibration-poses-wam%d not found,\n",wam->dof);
         printf("numPoses not present, or numPoses not at least 4.");
         btParseClose(&parser);
         break;
      }
      
      poses = (vect_n **) btmalloc( num_poses * sizeof(vect_n *) );
      for (pose=0; pose<num_poses; pose++)
      {
         poses[pose] = new_vn(wam->dof);
         sprintf(key, "calibration-poses-wam%d.pose[%d]", wam->dof, pose);
         err = btParseGetVal(&parser, VECTOR, key, (void*)poses[pose]);
         if (err)
         {
            syslog(LOG_ERR,"Not enough poses found! (%d expected, found only %d)",
                   num_poses, pose);
            printf("Not enough poses found! (%d expected, found only %d)\n",
                   num_poses, pose);
            break;
         }
      }
      
      btParseClose(&parser);
   } while (0);
   
   if (err)
   {
      /* Free the variables */
      for (j=0; j<wam->dof; j++)
      {
         free(mu_jts[j]);
         free(mu_jps[j]);
      }
      free(mu_jts);
      free(mu_jps);
      /* Stop threads ... */
      wam_thd.done = 1;
      usleep(10000);
      can_thd.done = 1;
      usleep(50000);
      /* End ncurses */
      endwin();
      return 0;
   }
   
   angle_diff = new_vn(wam->dof);
   fill_vn(angle_diff,ANGLE_DIFF);
   torques_top = new_vn(wam->dof);
   positions_top = new_vn(wam->dof);
   torques_bottom = new_vn(wam->dof);
   positions_bottom = new_vn(wam->dof);
   torques = (vect_n **) malloc( num_poses * sizeof(vect_n *) );
   positions = (vect_n **) malloc( num_poses * sizeof(vect_n *) );
   for (pose=0; pose<num_poses; pose++)
   {
      torques[pose] = new_vn(wam->dof);
      positions[pose] = new_vn(wam->dof);
   }
   mus = (vect_3 **) malloc( wam->dof * sizeof(vect_3 *) );
   for (j=0; j<wam->dof; j++)
      mus[j] = new_v3();
   
   /* Allow the user to shift-activate */
   mvprintw(10,0,"IMPORTANT: Once gravity compensation begins, the WAM will begin");
   mvprintw(11,0,"to move to a set of %d predefined poses (defined in cal.conf).",num_poses);
   
   mvprintw(13,0,"DO NOT TOUCH the WAM during the measurement process, or the");
   mvprintw(14,0,"calibration computations will be sigificantly wrong, and");
   mvprintw(15,0,"any subsequent gravity compensation will fail spectacularly!");
   
   mvprintw(17,0,"Place the WAM in Shift+Activate mode,");
   mvprintw(18,0,"and press [Enter] to start.");
   refresh();
   while (btkey_get()!=BTKEY_ENTER) usleep(10000);
   
   /* Start the GUI! */
   pose = 0;
   phase = MU_P_START;
   
   clear();
   mvprintw(1,0,"Note: Press [Control+C] at any time to cancel the calibration.");
   mvprintw(2,0,"DO NOT TOUCH the WAM during the calibration process!");
   done = 0;
   signal(SIGINT, sigint);  
   while (!done)
   {
      
      /* Print current state */
      mvprintw(0, 0,"Current Pose: %d of %d.  ",pose+1,num_poses);
      mvprintw(0,30,"Current Phase: %s        ",phasenm[phase]);
      
      /* Print current joint position and torque */
      mvprintw(4,0, "      Joint:");
      mvprintw(5,0, "   Position:");
      mvprintw(6,0, "     Torque:");
      for (j=0; j<wam->dof; j++)
      {
         mvprintw(4, 13 + 9*j, " Joint %d ",j+1);
         mvprintw(5, 13 + 9*j, "% 08.5f ",wam->Jpos->q[j]);
         mvprintw(6, 13 + 9*j, "% 08.4f ",wam->Jtrq->q[j]);
      }
      
      /* Line 9 - Status Updates */
      mvprintw(8,0,"Current Status:");
      
      /* Note - lines 12-?? reserved for printing statistics */
      mvprintw(11,0,"Recent Statistics:");
      
      refresh();
      usleep(5E4);
      
      /* Move through the state machine */
      switch (phase)
      {
         case MU_P_START:
            mvprintw(9,3,"Moving to above position ...           ");
            MoveSetup(wam, 1.0, 1.0);
            MoveWAM(wam,add_vn(poses[pose],angle_diff));
            phase++;
            break;
         case MU_P_TO_TOP:
            if (!MoveIsDone(wam)) break;
            mvprintw(9,3,"Moving to position (from above) ...    ");
            MoveSetup(wam, 0.05, 0.05);
            MoveWAM(wam,poses[pose]);
            phase++;
         case MU_P_FROM_TOP:
            if (!MoveIsDone(wam)) break;
            mvprintw(9,3,"Starting a measurement ...             ");
            mu_n = 0;
            phase++;
            break;
         case MU_P_MEAS_TOP:
            if (mu_n < NUM_POINTS) break;
            mu_stats( torques_top, positions_top );
            mvprintw(9,3,"Moving to below position ...           ");
            MoveSetup(wam, 1.0, 1.0);
            MoveWAM(wam,sub_vn(poses[pose],angle_diff));
            phase++;
            break;
         case MU_P_TO_BOT:
            if (!MoveIsDone(wam)) break;
            mvprintw(9,3,"Moving to position (from below) ...    ");
            MoveSetup(wam, 0.05, 0.05);
            MoveWAM(wam,poses[pose]);
            phase++;
            break;
         case MU_P_FROM_BOT:
            if (!MoveIsDone(wam)) break;
            mvprintw(9,3,"Starting a measurement ...             ");
            mu_n = 0;
            phase++;
            break;
         case MU_P_MEAS_BOT:
            if (mu_n < NUM_POINTS) break;
            mu_stats( torques_bottom, positions_bottom );
            phase++;
            break;
         case MU_P_DONE:
            /* Get the midpoint position and torque ... */
            set_vn(torques[pose],scale_vn(0.5,add_vn(torques_top,torques_bottom)));
            set_vn(positions[pose],scale_vn(0.5,add_vn(positions_top,positions_bottom)));
            pose++;
            phase = MU_P_START;
            if (pose == num_poses)
               done = 1;
            break;
      }
   }
   
   /* Re-fold, print, and exit */
   clear();
   mvprintw(0,0,"Moving back to the park location ...");
   refresh();
   MoveSetup(wam, 1.0, 1.0);
   MoveWAM(wam,wam->park_location);
   while (!MoveIsDone(wam)) usleep(10000);
   mvprintw(1,0,"Shift+Idle, and press [Enter] to continue.");
   refresh();
   while (btkey_get()!=BTKEY_ENTER) usleep(10000);
   
   /* Stop threads ... */
   wam_thd.done = 1;
   usleep(10000);
   can_thd.done = 1;
   usleep(50000);
   
   /* Free unneeded variables */
   for (j=0; j<wam->dof; j++)
   {
      free(mu_jts[j]);
      free(mu_jps[j]);
   }
   free(mu_jts);
   free(mu_jps);
   destroy_vn(&angle_diff);
   destroy_vn(&torques_top);
   destroy_vn(&positions_top);
   destroy_vn(&torques_bottom);
   destroy_vn(&positions_bottom);
   
   /* End ncurses */
   endwin();
   
   if (done == 1)
   {
      /* Here we have the "Iterative Algorithm"
       * described in the Chris Dellin document entitled
       * "Newton-Euler First-Moment Gravity Compensation" */

      /* Here we have the matrix composed of L matrices (negative) */
      matr_mn * nLL;
      
      /* We have a GT matrix and a Y vector for each link */
      matr_mn ** GT;
      vect_n ** Y;
      
      /* We have a solution vector P for each link */
      vect_n ** P;
      
      vect_n * grav_torques;
      
      /* Start calculating ...
       * We have vectors of torque and position
       * in torques[] and positions[] */
      printf("\n");
      printf("Calculating ...\n");
      
      /* Make the LL matrix */
      nLL = new_mn( 3*num_poses, 3+2*num_poses );
      zero_mn(nLL);
      for (pose=0; pose<num_poses; pose++)
      {
         setval_mn(nLL, 3*pose+0, 3+2*pose+0, -1.0 );
         setval_mn(nLL, 3*pose+1, 3+2*pose+1, -1.0 );
      }
        
      /* Make each link's GT matrix */
      /* Make each link's Y torque solution matrix */
      Y = (vect_n **) btmalloc( wam->dof * sizeof(vect_n *) );
      GT = (matr_mn **) btmalloc( wam->dof * sizeof(matr_mn *) );
      for (j=0; j<wam->dof; j++)
      {
         Y[j] = new_vn( 3*num_poses );
         GT[j] = new_mn( 3*num_poses, 3+2*num_poses );
         zero_mn(GT[j]);
      }
      grav_torques = new_vn(wam->dof);
      for (pose=0; pose<num_poses; pose++)
      {
         /* Put the robot in the pose (by position) */
         set_vn(wam->robot.q,positions[pose]);
         eval_fk_bot(&wam->robot);
         get_gravity_torques(&wam->robot,grav_torques);
         for (j=0; j<wam->dof; j++)
         {
            /* GT: Gravity skew matrix */
            setval_mn(GT[j], 3*pose+0, 1, -getval_v3(wam->robot.links[j].g,2) );
            setval_mn(GT[j], 3*pose+0, 2,  getval_v3(wam->robot.links[j].g,1) );
            setval_mn(GT[j], 3*pose+1, 0,  getval_v3(wam->robot.links[j].g,2) );
            setval_mn(GT[j], 3*pose+1, 2, -getval_v3(wam->robot.links[j].g,0) );
            setval_mn(GT[j], 3*pose+2, 0, -getval_v3(wam->robot.links[j].g,1) );
            setval_mn(GT[j], 3*pose+2, 1,  getval_v3(wam->robot.links[j].g,0) );
            /* GT: -R*L */
            setval_mn(GT[j], 3*pose+0, 3+2*pose+0, -getval_mh(wam->robot.links[j].trans,0,0) );
            setval_mn(GT[j], 3*pose+0, 3+2*pose+1, -getval_mh(wam->robot.links[j].trans,1,0) );
            setval_mn(GT[j], 3*pose+1, 3+2*pose+0, -getval_mh(wam->robot.links[j].trans,0,1) );
            setval_mn(GT[j], 3*pose+1, 3+2*pose+1, -getval_mh(wam->robot.links[j].trans,1,1) );
            setval_mn(GT[j], 3*pose+2, 3+2*pose+0, -getval_mh(wam->robot.links[j].trans,0,2) );
            setval_mn(GT[j], 3*pose+2, 3+2*pose+1, -getval_mh(wam->robot.links[j].trans,1,2) );
            /* Y */
            setval_vn(Y[j], 3*pose+0, getval_vn(torques[pose],j) * getval_mh(wam->robot.links[j].trans,2,0) );
            setval_vn(Y[j], 3*pose+1, getval_vn(torques[pose],j) * getval_mh(wam->robot.links[j].trans,2,1) );
            setval_vn(Y[j], 3*pose+2, getval_vn(torques[pose],j) * getval_mh(wam->robot.links[j].trans,2,2) );
            if (j < wam->dof-1)
               setval_vn(Y[j], 3*pose+2, getval_vn(Y[j],3*pose+2) - getval_vn(torques[pose],j+1) );
         }
      }
      destroy_vn(&grav_torques);
      
      /* Make a space for each link's P solution vector */
      P = (vect_n **) btmalloc( wam->dof * sizeof(vect_n *) );
      for (j=0; j<wam->dof; j++)
         P[j] = new_vn( 3+2*num_poses );
      
      /* Do the regression for each link */
      {
         int i;
         matr_mn * m2x2;
         matr_mn * m2x3;
         vect_n * Yi;
         vect_n * index;
         vect_n * col;
         
         m2x2 = new_mn( 3+2*num_poses, 3+2*num_poses );
         m2x3 = new_mn( 3+2*num_poses,   3*num_poses );
         Yi = new_vn( 3*num_poses );
         index = new_vn( 3+2*num_poses );
         col = new_vn( 3+2*num_poses );
         
         for (j=wam->dof-1; j>=0; j--)
         {
            mul_mn( m2x2, T_mn(GT[j]), GT[j] );
            for (i=0; i<3+2*num_poses; i++)
               setval_mn(m2x2,i,i, getval_mn(m2x2,i,i) + CALC_LAMBDA );
            mul_mn( m2x3, inv_mn(m2x2,index,col), T_mn(GT[j]) );
            if (j < wam->dof-1)
               matXvec_mn(nLL,P[j+1],Yi);
            else
               fill_vn(Yi,0.0);
            set_vn(Yi, add_vn(Yi,Y[j]) );
            matXvec_mn( m2x3, Yi, P[j] );
         }
         
         destroy_mn(&m2x2);
         destroy_mn(&m2x3);
         destroy_vn(&Yi);
         destroy_vn(&index);
         destroy_vn(&col);
         
         /* Copy the results */
         for (j=0; j<wam->dof; j++)
         {
            setval_v3(mus[j],0, getval_vn(P[j],0) );
            setval_v3(mus[j],1, getval_vn(P[j],1) );
            setval_v3(mus[j],2, getval_vn(P[j],2) );
         }
         
         /* Clean up */
         destroy_mn(&nLL);
         for (j=0; j<wam->dof; j++)
         {
            destroy_mn(&GT[j]);
            destroy_vn(&Y[j]);
            destroy_vn(&P[j]);
         }
         btfree((void **)&GT);
         btfree((void **)&Y);
         btfree((void **)&P);
      }
      
      /* Print results */
      printf("\n");
      printf("Gravity calibration ended.\n");
      printf("\n");
      printf("Copy the following lines into your wam.conf file, in the %s{} group.\n",wam->name);
      printf("It is usually placed above the safety{} group.\n");
      printf("--------\n");
      printf("    # Calibrated gravity vectors\n");
      printf("    calibrated-gravity{\n");
      for (j=0; j<wam->dof; j++)
      {
         printf("        mu%d = < % .6f, % .6f, % .6f >\n", j+1,
                getval_v3(mus[j],0),
                getval_v3(mus[j],1),
                getval_v3(mus[j],2));
      }
      printf("    }\n");
      printf("--------\n");
      {
         FILE * logfile;
         logfile = fopen("cal-gravity.log","w");
         if (logfile)
         {
            fprintf(logfile,"    # Calibrated gravity vectors\n");
            fprintf(logfile,"    calibrated-gravity{\n");
            for (j=0; j<wam->dof; j++)
               fprintf(logfile,"        mu%d = < % .6f, % .6f, % .6f >\n", j+1,
                               getval_v3(mus[j],0),
                               getval_v3(mus[j],1),
                               getval_v3(mus[j],2));
            fprintf(logfile,"    }\n");
            fclose(logfile);
            printf("This text has been saved to cal-gravity.log.\n");
         }
         else
         {
            syslog(LOG_ERR,"Could not write to cal-gravity.log.");
            printf("Error: Could not write to cal-gravity.log.\n");
         }
      }
      printf("\n");
      
   }
   
   /* Free the variables */
   for (pose=0; pose<num_poses; pose++)
   {
      destroy_vn(&torques[pose]);
      destroy_vn(&positions[pose]);
   }
   free(torques);
   free(positions);
   for (j=0; j<wam->dof; j++)
      destroy_vn((vect_n **)&mus[j]);
   free(mus);
   
   return 0;
}