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, ')'); } }
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; }
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); }
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(>[j]); destroy_vn(&Y[j]); destroy_vn(&P[j]); } btfree((void **)>); 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; }