Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

ArmController.cc

Go to the documentation of this file.
00001 #include "Shared/RobotInfo.h"
00002 #include "Behaviors/Controller.h"
00003 
00004 #ifndef TGT_HAS_ARMS
00005 class ArmController : public BehaviorBase {
00006   virtual void doStart() {
00007     // This will popup a message in the ControllerGUI, if one is connected
00008     std::vector<std::string> errmsg;
00009     errmsg.push_back("The selected robot doesn't have an arm...");
00010     Controller::loadGUI("org.tekkotsu.mon.ControllerErr","",0,errmsg);
00011     stop();
00012   }
00013 };
00014 #else
00015 
00016 #include "ArmController.h"
00017 #include "Motion/MMAccessor.h"
00018 #include "Motion/ArmMC.h"
00019 #include "Shared/RobotInfo.h"
00020 #include "Motion/PIDMC.h"
00021 
00022 ArmController* ArmController::theOne = NULL;
00023 
00024 void ArmController::doStart() {
00025   // Set up ArmMC and PIDMC for controlling and relaxing the arm
00026   SharedObject<ArmMC> arm;
00027   arm->setHold(false);
00028   arm_id = motman->addPersistentMotion(arm);
00029   SharedObject<PIDMC> pid;
00030   pidMCID = motman->addPersistentMotion(pid,MotionManager::kHighPriority);
00031   
00032   // Identify the initial sequence of pitch and yaw joints using alpha, theta, and jointType
00033   gripperFrameKJ->getRoot()->buildChildMap(KJjoints, ArmOffset, NumArmJoints);
00034   
00035   int counter = 0;
00036   float alphaCum = 0;
00037   for (unsigned int i = 0; i < NumArmJoints; i++) {
00038     if (KJjoints[i] == NULL) break;
00039     if ( counter > 0    // don't worry about any rotation from base frame to first arm joint
00040       && KJjoints[i]->theta != 0 ) // we're leaving the domain of pure yaw and pitch joints: punt
00041       break;
00042     
00043     alphaCum += KJjoints[i]->alpha;
00044     if ( std::abs(alphaCum) < 1e-5  && KJjoints[i]->jointType.get() == "revolute" ) {
00045       numYawJoints++;
00046       armConfig[counter++] = 'H';
00047     }
00048     else if ( std::abs(alphaCum) > 0.99*(M_PI/2) && KJjoints[i]->jointType.get() == "revolute" ) {
00049       numPitchJoints++;
00050       armConfig[counter++] = 'V';
00051     }
00052   }
00053   linksToDisplay = numPitchJoints + numYawJoints;
00054   
00055 #ifdef TGT_LYNXARM6
00056   horScale = 20;
00057 #endif
00058 
00059   // Find the dimensions of the arm.  Must work from the gripper
00060   // backward because the kinematic chain may branch going forward (as in
00061   // Calliope2 with its four-bar linkage).
00062   fmat::Column<3> armDims;
00063   fmat::Transform gripperToArm;
00064   const KinematicJoint* armJ = kine->getKinematicJoint(ArmOffset);
00065   const KinematicJoint* tmpJ = kine->getKinematicJoint(GripperFrameOffset);
00066   if ( armJ == NULL || tmpJ == NULL )
00067     std::cout << "Error in Arm Controller: can't find arm or gripper frame!\n";
00068   else
00069     while (tmpJ != armJ && tmpJ != NULL) {
00070         tmpJ = tmpJ->getParent();
00071         gripperToArm *= tmpJ->getTo().rigidInverse();
00072     }
00073   gripperToArm = gripperToArm.rigidInverse();
00074   armDims = gripperToArm.translation();
00075   horScale = verScale = armDims.norm();
00076   horScale /= 0.85;
00077   
00078   // determine transformation from first horizontal and vertical joint to base, for IK
00079   int horIndex = 0, verIndex = 0;
00080   fmat::Transform horT, verT;
00081   if (numYawJoints != 0) {
00082     while (armConfig[horIndex] != 'H')
00083       horIndex++;
00084     while (horIndex) {
00085       horT *= KJjoints[horIndex--]->getTo();
00086     }
00087   }
00088   if (numPitchJoints != 0) {
00089     while (armConfig[verIndex] != 'V')
00090       verIndex++;
00091     while (verIndex) {
00092       verT *= KJjoints[verIndex--]->getTo();
00093     }
00094   }
00095   horToBase = horT.translation();
00096   verToBase = verT.translation();
00097   
00098   // Turn on wireless
00099   theLastOne=theOne;
00100   theOne=this;
00101   cmdsock=wireless->socket(Socket::SOCK_STREAM, 2048, 2048);
00102   wireless->setReceiver(cmdsock->sock, mechacmd_callback);
00103   wireless->setDaemon(cmdsock,true);  
00104   wireless->listen(cmdsock->sock, config->main.armControl_port);  
00105   // Open the ArmGUI on the desktop 
00106   Controller::loadGUI("org.tekkotsu.mon.ArmGUI","ArmGUI",config->main.armControl_port);
00107 }
00108 
00109 void ArmController::doStop() {
00110   Controller::closeGUI("ArmGUI");
00111   erouter->removeListener(this);
00112   wireless->setDaemon(cmdsock,false);
00113   wireless->close(cmdsock);
00114   theOne=theLastOne;
00115   motman->removeMotion(arm_id);
00116   motman->removeMotion(pidMCID);
00117 }
00118 
00119 void ArmController::doEvent() {
00120   if(event->getGeneratorID()==EventBase::timerEGID) {
00121     float normJointVal, jointAngle;
00122     for(unsigned int joint = 0; joint < NumArmJoints; joint++) {
00123       jointAngle = state->outputs[ArmOffset + joint]; //When using mirage
00124       //  % = (Max - Val) / (Max - Min)  //
00125       normJointVal = (outputRanges[ArmOffset + joint][MaxRange] - jointAngle)/(outputRanges[ArmOffset + joint][MaxRange] - outputRanges[ArmOffset + joint][MinRange]);
00126       cmdsock->printf( "Value %d %d %f\n", -1, joint, normJointVal );
00127     }
00128     
00129     computeCoords();
00130     sendCoords();
00131     
00132     //RValue set the red point in the plane #1 & plane #2 when the joints are reset to their original values
00133     if (displayMode == pitchAndYaw) {
00134       cmdsock->printf("RValue %f %f\n", -yawCoords[numYawJoints -1][0] / horScale, yawCoords[numYawJoints -1][1] / horScale);
00135       cmdsock->printf("RValue1 %f %f\n",  pitchCoords[numPitchJoints - 1][0] / verScale, pitchCoords[numPitchJoints - 1][1] / verScale);
00136     }
00137     
00138     //RValue set the red point in the plane #1 when the joints are reset to their original values
00139     if (displayMode == yawOnly) {
00140       cmdsock->printf("RValue %f %f\n", -yawCoords[numYawJoints -1][0] / horScale, yawCoords[numYawJoints -1][1] / horScale);
00141     }
00142     
00143     //RValue set the red point in the plane #2 when the joints are reset to their original values
00144     if (displayMode == pitchOnly) {
00145       cmdsock->printf("Rvalue1 %f %f\n",  pitchCoords[numPitchJoints - 1][0] / verScale, pitchCoords[numPitchJoints - 1][1] / verScale);
00146     }
00147   }
00148 }
00149 
00150 // The command packet reassembly mechanism
00151 int ArmController::mechacmd_callback(char *buf, int bytes) {
00152   static char cb_buf[19];
00153   static int cb_buf_filled;
00154   
00155   // If there's an incomplete command in the command buffer, fill
00156   // up as much of the command buffer as we can and then execute it
00157   // if possible
00158   if(cb_buf_filled) {
00159     while((cb_buf_filled < 19) && bytes) {
00160       cb_buf[cb_buf_filled++] = *buf++; // copy incoming buffer byte
00161       --bytes;        // decrement remaining byte ct.
00162     }
00163     // did we fill it? if so, execute! and mark buffer empty.
00164     if(cb_buf_filled == 9 && ((unsigned char*)cb_buf)[0] != 'x') {
00165       if(ArmController::theOne) ArmController::theOne->runCommand((unsigned char*) cb_buf);
00166       cb_buf_filled = 0;
00167     }
00168     
00169     if(cb_buf_filled == 19) {
00170       if(ArmController::theOne) ArmController::theOne->runCommand((unsigned char*) cb_buf);
00171       cb_buf_filled = 0;
00172     }
00173   }
00174   
00175   // now execute all complete bytes in the incoming buffer
00176   while(bytes >= 9) {
00177     if (((unsigned char*)buf)[0] != 'x') {
00178       if(ArmController::theOne) ArmController::theOne->runCommand((unsigned char *) buf);
00179       bytes -= 9;
00180       buf += 9;
00181     } else if (((unsigned char*)buf)[0] == 'x') {
00182       if(ArmController::theOne) ArmController::theOne->runCommand((unsigned char *) buf);
00183       bytes -= 19;
00184       buf += 19;
00185     }
00186   }
00187   
00188   // finally, store all remaining bytes in the command buffer
00189   while(bytes) {
00190     cb_buf[cb_buf_filled++] = *buf++;
00191     --bytes;
00192   }
00193   
00194   return 0;
00195 }
00196 
00197 void ArmController::runCommand(unsigned char *command) {
00198   // Extract the command parameter
00199   float param;
00200   float param2;
00201   float param3;
00202   int cmdno;
00203   unsigned char *paramp = (unsigned char *) &param;
00204   unsigned char *paramp2 = (unsigned char *) &param2;
00205   unsigned char *paramp3 = (unsigned char *) &param3;
00206   unsigned char *cmdnop = (unsigned char *) &cmdno;
00207   
00208 #if defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN
00209   paramp[0] = command[4];
00210   paramp[1] = command[3];
00211   paramp[2] = command[2];
00212   paramp[3] = command[1];
00213   
00214   if (command[0] == 'x') {
00215     paramp2[0] = command[9];
00216     paramp2[1] = command[8];
00217     paramp2[2] = command[7];
00218     paramp2[3] = command[6];
00219     
00220     paramp3[0] = command[14];
00221     paramp3[1] = command[13];
00222     paramp3[2] = command[12];
00223     paramp3[3] = command[11];
00224     
00225     cmdnop[0] = command[18];
00226     cmdnop[1] = command[17];
00227     cmdnop[2] = command[16];
00228     cmdnop[3] = command[15];
00229   } else {
00230     cmdnop[0] = command[8];
00231     cmdnop[1] = command[7];
00232     cmdnop[2] = command[6];
00233     cmdnop[3] = command[5];
00234   }
00235 #else
00236   paramp[0] = command[1];
00237   paramp[1] = command[2];
00238   paramp[2] = command[3];
00239   paramp[3] = command[4];
00240   
00241   if (command[0] == 'x') {
00242     paramp2[0] = command[6];
00243     paramp2[1] = command[7];
00244     paramp2[2] = command[8];
00245     paramp2[3] = command[9];
00246     
00247     paramp3[0] = command[11];
00248     paramp3[1] = command[12];
00249     paramp3[2] = command[13];
00250     paramp3[3] = command[14];
00251     
00252     cmdnop[0] = command[15];
00253     cmdnop[1] = command[16];
00254     cmdnop[2] = command[17];
00255     cmdnop[3] = command[18];
00256   } else {
00257     cmdnop[0] = command[5];
00258     cmdnop[1] = command[6];
00259     cmdnop[2] = command[7];
00260     cmdnop[3] = command[8];
00261   }
00262   
00263 #endif   // byte order
00264   
00265   // Find out what type of command this is
00266   switch(command[0]) {
00267     case CMD_connect: // Connect to ArmGUI -> z command 
00268       cmdConnect();
00269       break;  
00270     case CMD_point:   // Point Picker plane #1 & plane#2-> x command
00271       cmdPointPicker(param, param2, param3, cmdno); 
00272       break;
00273     case CMD_gripper: // Gripper -> w command 
00274       cmdGripper(param, cmdno);
00275       break;    
00276     case CMD_speed:   // Speed parameter -> y command 
00277       speed = param;
00278       break;
00279     case CMD_relax:   // Relax Button -> v command 
00280       cmdRelax();
00281       break;
00282     case CMD_unrelax: // Unrelax Button -> u command 
00283       cmdUnrelax();
00284       break;
00285     default: {
00286       setJoint( command[0], param );
00287     }
00288   }
00289 }
00290 
00291 //Setup function
00292 void ArmController::cmdConnect() {
00293   
00294   //Code that validates the plane to be used in the interface 
00295   if(numYawJoints > 0 && numPitchJoints > 0)
00296     displayMode = pitchAndYaw; //create both planes 
00297   else if(numYawJoints > 0 && numPitchJoints == 0)
00298     displayMode = yawOnly; //create just the horizontal plane
00299   else
00300     displayMode = pitchOnly; //create just the vertical plane
00301   
00302   // Send out the number of joints on the arm, and the display mode
00303   cmdsock->printf("NOJ %d %d\n", NumArmJoints, displayMode);
00304   
00305   //Send the joint config
00306   for(unsigned int i = 0; i < NumArmJoints; i++)
00307     cmdsock->printf("Config %u %c\n", i, armConfig[i]); 
00308   
00309   // Must find out what OriJoint is for.
00310   OriJoint = linksToDisplay - 1;
00311   
00312   //Send out which joint is the one that control the orientation
00313   cmdsock->printf("OriJoint %d %d %d\n", OriJoint, numYawJoints, numPitchJoints);
00314   
00315   //Send Names, Max Ouput Ranges, Min output Ranges, Current Value
00316   float jointVal, normJointVal;
00317   
00318   for(unsigned int joint = 0; joint < NumArmJoints; joint++) {
00319     jointVal = state->outputs[ArmOffset + joint];
00320     normJointVal = (outputRanges[ArmOffset + joint][MaxRange] - jointVal) /
00321       (outputRanges[ArmOffset + joint][MaxRange] - outputRanges[ArmOffset + joint][MinRange]);
00322     cmdsock->printf("JointParam %s %f %f %f\n", outputNames[ArmOffset + joint], 
00323             outputRanges[ArmOffset + joint][MaxRange], outputRanges[ArmOffset + joint][MinRange], normJointVal);
00324   }
00325   
00326   //Set the red point in the plane 
00327   if(numYawJoints > 0)
00328     cmdsock->printf("IRGValue %f %f\n", -yawCoords[numYawJoints - 1][0] / horScale, yawCoords[numYawJoints - 1][1] / horScale);
00329   if(numPitchJoints > 0)
00330     cmdsock->printf("IRGValue1 %f %f\n", pitchCoords[numPitchJoints - 1][0] / verScale, pitchCoords[numPitchJoints - 1][1] / verScale);
00331   
00332   // Compute / send
00333   computeCoords();
00334   sendCoords();
00335   
00336 }
00337 
00338 // Command to the Point Picker
00339 void ArmController::cmdPointPicker(float param, float param2, float param3, int cmdno) {
00340 #if TGT_TENTACLE
00341   //== Setup (x,y,z) so they are relative to 'ARM:5' ==//
00342 #else
00343   fmat::Column<3> tgtPoint;
00344   if (param3 == 1.0) { // horizontal plane
00345     theta = std::atan2(-param,param2);
00346     tgtPoint[0] = param2 * horScale + horToBase[0];
00347     tgtPoint[1] = -param * horScale + horToBase[1];
00348     tgtPoint[2] = verZ * verScale;
00349   }
00350   else if (param3 == 2.0) { // vertical plane
00351     verZ = param2;
00352     tgtPoint[0] = (param * verScale + verToBase[0]) * std::cos(theta);
00353     tgtPoint[1] = tgtPoint[0] * std::tan(theta);
00354     tgtPoint[2] = param2 * verScale + verToBase[2];
00355   }
00356   
00357   const KinematicJoint* tmpKJ = KJjoints[0];
00358   // transform to base
00359   while (tmpKJ->getParent() != NULL) {
00360     tgtPoint += tmpKJ->getTo().translation();
00361     tmpKJ = tmpKJ->getParent();
00362   }
00363   
00364   // perform IK
00365   gripperFrameKJ->getIK().solve(fmat::Column<3>(), *gripperFrameKJ, IKSolver::Point(tgtPoint));
00366   
00367   for(int joint = 0; joint < linksToDisplay; joint++) {
00368     // angle, mapped from 0 - 1, based on joint limits
00369     float normJointVal;
00370     
00371     // set the new angles
00372     float q = KJjoints[joint]->getQ();
00373     // we can't be outside the limits
00374     if (q > outputRanges[ArmOffset + joint][MaxRange]) {
00375       q = outputRanges[ArmOffset + joint][MaxRange];
00376       normJointVal = 0;
00377     }
00378     else if (q < outputRanges[ArmOffset + joint][MinRange]) {
00379       q = outputRanges[ArmOffset + joint][MinRange];
00380       normJointVal = 1;
00381     }
00382     else {
00383       //  % = (Max - Val) / (Max - Min)
00384       normJointVal = (outputRanges[ArmOffset + joint][MaxRange] - q)/(outputRanges[ArmOffset + joint][MaxRange] - outputRanges[ArmOffset + joint][MinRange]);
00385     }
00386     
00387     if(!std::isfinite(normJointVal))
00388       normJointVal = state->outputs[ArmOffset + joint]; // TODO: will this work?
00389     cmdsock->printf("CValue %d %d %f\n", cmdno, joint, normJointVal);
00390   }
00391 #endif
00392 }
00393 
00394 void ArmController::cmdGripper(float param, int cmdno) {
00395 #ifdef TGT_HAS_GRIPPER
00396   float gripper = (1.0f - param) / 2.0f;
00397 #  ifdef TGT_HAS_FINGERS
00398   float right = gripper;
00399   float left = 1.0f - gripper;
00400   
00401   cmdsock->printf("CValue %d %d %f\n", cmdno, RightFingerOffset - ArmOffset, right);
00402   cmdsock->printf("CValue %d %d %f\n", cmdno, LeftFingerOffset - ArmOffset, left);
00403 #  else
00404   cmdsock->printf("CValue %d %d %f\n", cmdno, GripperOffset - ArmOffset, gripper);
00405 #  endif
00406 #endif
00407 }
00408 
00409 void ArmController::cmdRelax() {
00410   MMAccessor<PIDMC> relaxer(pidMCID);
00411   for(unsigned int joint = 0; joint < NumArmJoints; joint++)
00412     relaxer->setJointPowerLevel(ArmOffset + joint, 0);
00413   processEvent(EventBase(EventBase::timerEGID,1,EventBase::statusETID,0));
00414   erouter->addTimer(this,0,500);
00415 }
00416 
00417 void ArmController::cmdUnrelax() {
00418   erouter->removeTimer(this);
00419   MMAccessor<PIDMC> unrelaxer(pidMCID);
00420   for(unsigned int joint = 0; joint < NumArmJoints; joint++) 
00421     unrelaxer->setJointPowerLevel(ArmOffset + joint, 1.0);
00422 }
00423 
00424 void ArmController::setJoint(unsigned int joint, float param) {
00425   unsigned int jointNo = joint < NumArmJoints ? joint : joint - NumArmJoints;
00426   if (jointNo >= NumArmJoints) {
00427     std::cerr << "Illegal command to ArmController " << joint << " " << jointNo << " "  << NumArmJoints << std::endl;
00428     return;
00429   }
00430   
00431   MMAccessor<ArmMC> arm(arm_id);
00432   arm->setMaxSpeed(jointNo, speed);
00433   // Val = -(% * (Max - Min)) + Max 
00434   float jointVal = -( param * (outputRanges[ArmOffset + jointNo][MaxRange] - outputRanges[ArmOffset + jointNo][MinRange]) ) + outputRanges[ArmOffset + jointNo][MaxRange];
00435   arm->setJointValue(jointNo, jointVal); //change the value of the arm physically
00436   
00437   if(KJjoints[jointNo] != NULL)
00438     KJjoints[jointNo]->setQ(jointVal);
00439   
00440   computeCoords();
00441   sendCoords();
00442   
00443   if ( joint < NumArmJoints ) {
00444     switch (displayMode) {
00445       case pitchAndYaw:
00446         //RValue set the red point in the plane #1 & plane #2 when the joints are reset to their original values
00447         cmdsock->printf("RValue %f %f\n", -yawCoords[numYawJoints -1][0] / horScale, yawCoords[numYawJoints -1][1] / horScale);
00448         cmdsock->printf("RValue1 %f %f\n",  pitchCoords[numPitchJoints - 1][0] / verScale, pitchCoords[numPitchJoints - 1][1] / verScale);
00449         break;
00450       case yawOnly:
00451         //RValue set the red point in the plane #1 when the joints are reset to their original values
00452         cmdsock->printf("RValue %f %f\n", -yawCoords[numYawJoints -1][0] / horScale, yawCoords[numYawJoints -1][1] / horScale);
00453         break;
00454       case pitchOnly:
00455         //RValue set the red point in the plane #2 when the joints are reset to their original values
00456         cmdsock->printf("Rvalue1 %f %f\n",  pitchCoords[numPitchJoints - 1][0] / verScale, pitchCoords[numPitchJoints - 1][1] / verScale);
00457         break;
00458     }
00459   }
00460 }
00461 
00462 // Validate this function with the projection of joint
00463 void ArmController::computeCoords() {
00464   // Works for the Calliope, Chiara, Chiara2 and Handeye and almost for the Lynxarm. 
00465   fmat::Column<3> baseHorizontal;
00466   fmat::Column<3> baseVertical;
00467   
00468   // Looking for the first horizontal joint 
00469   for(int i = 0; i < linksToDisplay; i++){
00470     if(armConfig[i] == 'H'){
00471       baseHorizontal = KJjoints[i]->getWorldPosition();
00472       break;
00473     }
00474   }
00475   // Looking for the first vertical joint 
00476   for(int i = 0; i < linksToDisplay; i++){
00477     if(armConfig[i] == 'V'){
00478       baseVertical = KJjoints[i]->getWorldPosition();
00479       break;
00480     }
00481   }
00482   
00483   int yawCount = 0, pitchCount = 0;
00484   
00485   // Calculate the coordinates without projections
00486   for (int links = 0; links < linksToDisplay; links++){
00487     if (armConfig[links] == 'H'){
00488       KinematicJoint* relPosJoint;
00489       if (yawCount == numYawJoints - 1)
00490         relPosJoint = gripperFrameKJ;
00491       else
00492         relPosJoint = KJjoints[links+1];
00493       fmat::Column<3> relPos = relPosJoint->getWorldPosition() - baseHorizontal;
00494       yawCoords[yawCount][0] = relPos[1]; // y-axis 
00495       yawCoords[yawCount][1] = relPos[0]; // x-axis
00496       yawCount++;
00497     }
00498     else if (armConfig[links] == 'V'){
00499       KinematicJoint* relPosJoint;
00500       if (pitchCount == numPitchJoints - 1)
00501         relPosJoint = gripperFrameKJ;
00502       else
00503         relPosJoint = KJjoints[links+1];
00504       fmat::Column<3> relPos = relPosJoint->getWorldPosition() - baseVertical;
00505       std::cout << relPos << " = " << relPosJoint->getWorldPosition() << " - " << baseVertical << std::endl;
00506       pitchCoords[pitchCount][0] = fmat::SubVector<2>(relPos).norm() * (yawCoords[yawCount-1][1] * relPos[0] > 0 ? 1 : -1); // x-axis
00507       pitchCoords[pitchCount][1] = relPos[2]; // z-axis
00508       pitchCount++;
00509     }
00510   }
00511 }
00512 
00513 void ArmController::sendCoords() {
00514   //Send out the coordinates of the links to planes 
00515   switch (displayMode) {
00516     case pitchAndYaw:
00517       for(int links = 0; links < numYawJoints; links++)
00518         cmdsock->printf("Coord %d %f %f\n", links, -yawCoords[links][0]/horScale, yawCoords[links][1]/horScale);
00519       for(int links = 0; links < numPitchJoints; links++)
00520         cmdsock->printf("Coord1 %d %f %f\n", links, pitchCoords[links][0] / verScale, pitchCoords[links][1] / verScale);
00521       //GValue set the green point in the plane #1
00522       cmdsock->printf("GValue %f %f\n", -yawCoords[numYawJoints - 1][0] / horScale, yawCoords[numYawJoints - 1][1] / horScale);
00523       
00524       //GValue1 set the green point in the plane #2
00525       cmdsock->printf("GValue1 %f %f\n", pitchCoords[numPitchJoints - 1][0] / verScale, pitchCoords[numPitchJoints - 1][1] / verScale);
00526       break;
00527     case yawOnly:
00528       for(int links = 0; links < numYawJoints; links++)
00529         cmdsock->printf("Coord %d %f %f\n", links, -yawCoords[links][0]/horScale, yawCoords[links][1]/horScale);
00530       //GValue set the green point in the plane #1
00531       cmdsock->printf("GValue %f %f\n", -yawCoords[numYawJoints - 1][0] / horScale, yawCoords[numYawJoints - 1][1] / horScale);
00532       break;
00533     case pitchOnly:
00534       for(int links = 0; links < numPitchJoints; links++)
00535         cmdsock->printf("Coord1 %d %f %f\n", links, pitchCoords[links][0] / verScale, pitchCoords[links][1] / verScale);
00536       //GValue1 set the green point in the plane #2
00537       cmdsock->printf("GValue1 %f %f\n", pitchCoords[numPitchJoints - 1][0] / verScale, pitchCoords[numPitchJoints - 1][1] / verScale);
00538   }
00539 }
00540 
00541 #endif // TGT_HAS_ARMS
00542 
00543 REGISTER_BEHAVIOR_MENU_OPT(ArmController,"TekkotsuMon",BEH_NONEXCLUSIVE);
00544 
00545 /*! @file
00546  * @brief Implements ArmController, listens to control commands coming in from the command port for remotely controlling the arm
00547  * @author tss (Creator)
00548  */

Tekkotsu v5.1CVS
Generated Tue Jan 31 04:31:47 2012 by Doxygen 1.6.3