ArmSim.C

Go to the documentation of this file.
00001 /*!@file ArmControl/ArmSim.C Interfaces to the robot arm */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Lior Elazary <elazary@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/ArmControl/ArmSim.C $
00035 // $Id: ArmSim.C 10794 2009-02-08 06:21:09Z itti $
00036 //
00037 
00038 
00039 #include "ArmControl/RobotArm.H"
00040 #include "ArmControl/ArmSim.H"
00041 #include "Component/OptionManager.H"
00042 #include "Util/MathFunctions.H"
00043 #include "Util/Assert.H"
00044 #include "Util/Angle.H"
00045 #include "rutz/compat_snprintf.h"
00046 
00047 #include <stdio.h>
00048 #include <stdlib.h>
00049 #include <signal.h>
00050 
00051 namespace {
00052 
00053   void nearCallback (void *data, dGeomID o1, dGeomID o2){
00054     ArmSim *armSim = (ArmSim *)data;
00055     const int MaxContacts = 10;
00056 
00057     //create a contact joint to simulate collisions
00058     dContact contact[MaxContacts];
00059     int nContacts = dCollide (o1,o2,MaxContacts,
00060         &contact[0].geom,sizeof(dContact));
00061     for (int i=0; i<nContacts; i++) {
00062       contact[i].surface.mode = dContactSoftCFM ; //| dContactBounce; // | dContactSoftCFM;
00063       contact[i].surface.mu = 3.5;
00064       contact[i].surface.mu2 = 2.0;
00065       contact[i].surface.bounce = 0; //0.01;
00066       contact[i].surface.bounce_vel = 0; //0.01;
00067       contact[i].surface.soft_cfm = 0.001;
00068 
00069       dJointID c = dJointCreateContact (armSim->getWorld(),
00070           armSim->getContactgroup(),&contact[i]);
00071       dJointAttach (c,
00072           dGeomGetBody(contact[i].geom.g1),
00073           dGeomGetBody(contact[i].geom.g2));
00074     }
00075   }
00076 }
00077 
00078 // ######################################################################
00079 
00080 ArmSim::ArmSim(OptionManager& mgr,
00081 
00082     const std::string& descrName,
00083     const std::string& tagName,
00084     const double l0,
00085     const double l1,
00086     const double l2,
00087     const double l3,
00088     const double l4
00089     ) :
00090   RobotArm(mgr, descrName, tagName),
00091   vp(new ViewPort("ArmSim")
00092     )
00093 {
00094 
00095   //in meters
00096   itsTableSize[0] = 1.215;//W
00097   itsTableSize[1] = 0.75;//L
00098   itsTableSize[2] = 0.02;
00099 
00100   itsArmParam.armLoc[0] = -1*itsTableSize[0]/2+0.145;
00101   itsArmParam.armLoc[1] = -1*itsTableSize[1]/2+0.12;
00102   itsArmParam.armLoc[2] = 0;
00103 
00104   itsArmParam.base[0] = 0.230/2; //radius
00105   itsArmParam.base[1] = 0.210 + 0.05; //length, the real height is 0.210 but it's too low in armSim
00106   itsArmParam.baseMass = 9;
00107 
00108   itsArmParam.body[0] = 0.200; //x
00109   itsArmParam.body[1] = 0.200; //y
00110   itsArmParam.body[2] = 0.174; //z
00111   itsArmParam.bodyMass = 0.2;
00112 
00113   itsArmParam.upperarm[0] = 0.065; //x
00114   itsArmParam.upperarm[1] = 0.15; //y
00115   itsArmParam.upperarm[2] = 0.220; //z
00116   itsArmParam.upperarmMass = 0.2;
00117 
00118   itsArmParam.forearm[0] = 0.06; //x
00119   itsArmParam.forearm[1] = 0.13; //y
00120   itsArmParam.forearm[2] = 0.220; //z
00121   itsArmParam.forearmMass = 0.2;
00122 
00123   itsArmParam.wrist1[0] = 0.02; //r
00124   itsArmParam.wrist1[1] = 0.17; //length
00125   itsArmParam.wrist1Mass = 0.2;
00126 
00127   itsArmParam.wrist2[0] = 0.032; //x
00128   itsArmParam.wrist2[1] = 0.115; //y
00129   itsArmParam.wrist2[2] = 0.067; //z
00130   itsArmParam.wrist2Mass = 0.2;
00131 
00132   itsArmParam.gripper[0] = 0.015; //x
00133   itsArmParam.gripper[1] = 0.020; //y
00134   itsArmParam.gripper[2] = 0.070; //z
00135   itsArmParam.gripperMass = 0.2;
00136 
00137 
00138   vp->setTextures(false);
00139   vp->setShadows(false);
00140 
00141 }
00142 
00143 ArmSim::~ArmSim()
00144 {
00145         dSpaceDestroy(space);
00146         dWorldDestroy(world);
00147 
00148         delete vp;
00149 }
00150 
00151 void ArmSim::start2()
00152 {
00153 //        setDrawStuff();
00154         world = dWorldCreate();
00155         space = dHashSpaceCreate(0);
00156         contactgroup = dJointGroupCreate(0);
00157         ground = dCreatePlane(space, 0, 0, 1, 0);
00158   dGeomSetCategoryBits(ground, GROUND_BITFIELD);
00159         dWorldSetGravity(world,0,0,-9.8);
00160         //dWorldSetContactMaxCorrectingVel(world,0.9);
00161         dWorldSetContactSurfaceLayer(world,0.001);
00162         makeArm();
00163         //set the viewpoint
00164   //For fish eye lens
00165   //double xyz[3]={0.490837, -0.184382, 0.490000};
00166   //double hpr[3] = {174.500000, -20.500000, 0.000000};
00167   //For regular lens
00168   //double xyz[3]={0.087279, -0.112716, 0.300000};
00169   //double hpr[3] = {163.000000, -46.500000, 0.000000};
00170 
00171   //for world view
00172 
00173   double xyz[3]={0.289603, -1.071132, 0.710000};
00174   double hpr[3] = {110.500000, -10.500000, 0.000000};
00175 
00176 
00177         vp->dsSetViewpoint (xyz,hpr);
00178 
00179 }
00180 
00181 
00182 void ArmSim::setMotor(MOTOR m, int val)
00183 {
00184   float speed = (float)val/50;
00185   switch (m)
00186   {
00187     case RobotArm::BASE:
00188       dJointSetHingeParam(itsBody.joint, dParamVel , speed);
00189       break;
00190     case RobotArm::SHOLDER:
00191       dJointSetHingeParam(itsUpperArm.joint, dParamVel , speed);
00192       break;
00193     case RobotArm::ELBOW:
00194       dJointSetHingeParam(itsForearm.joint, dParamVel , speed);
00195       break;
00196     case RobotArm::WRIST1:
00197       dJointSetHingeParam(itsWrist1.joint, dParamVel , speed);
00198       break;
00199     case RobotArm::WRIST2:
00200       dJointSetHingeParam(itsWrist2.joint, dParamVel , speed);
00201       break;
00202     case RobotArm::GRIPPER:
00203       dJointSetHingeParam(itsGripper1.joint, dParamVel , speed);
00204       dJointSetHingeParam(itsGripper2.joint, dParamVel , -1*speed);
00205       break;
00206     default:
00207       break;
00208   }
00209 
00210 }
00211 
00212 void ArmSim::stopAllMotors()
00213 {
00214 
00215   LINFO("Stop all motors");
00216   dJointSetHingeParam(itsBody.joint, dParamVel , 0);
00217   dJointSetHingeParam(itsUpperArm.joint, dParamVel , 0);
00218   dJointSetHingeParam(itsForearm.joint, dParamVel , 0);
00219   dJointSetHingeParam(itsWrist1.joint, dParamVel , 0);
00220   dJointSetHingeParam(itsWrist2.joint, dParamVel , 0);
00221   dJointSetHingeParam(itsGripper1.joint, dParamVel , 0);
00222   dJointSetHingeParam(itsGripper2.joint, dParamVel , 0);
00223 
00224 }
00225 
00226 int ArmSim::getEncoder(MOTOR m)
00227 {
00228   //From real Scorbot, when all joint angle are 0(all arm in one line)
00229   //The encoder value are 0,-3520,3904,617,-2008
00230   //The move 90 degree will have encoder value 3013~3091
00231   //Move 1 degree in the joint, the real encoder should move 34.33
00232   dReal ang = 0;
00233   switch(m)
00234   {
00235     case RobotArm::BASE:
00236       ang = dJointGetHingeAngle(itsBody.joint);
00237       break;
00238     case RobotArm::SHOLDER:
00239       ang = dJointGetHingeAngle(itsUpperArm.joint);
00240       break;
00241     case RobotArm::ELBOW:
00242       ang = dJointGetHingeAngle(itsForearm.joint);
00243       ang -= M_PI/2;
00244       break;
00245     case RobotArm::WRIST1:
00246       ang = dJointGetHingeAngle(itsWrist1.joint);
00247       break;
00248     case RobotArm::WRIST2:
00249       ang = dJointGetHingeAngle(itsWrist2.joint);
00250       break;
00251     case RobotArm::GRIPPER:
00252       ang = dJointGetHingeAngle(itsGripper1.joint); //TODO: the angle betwwen the joints
00253       break;
00254     default:
00255       break;
00256   }
00257   int pos = ang2encoder(ang,m);
00258 //  if(m==RobotArm::BASE)
00259 //    pos -=2306;
00260   return pos;
00261 }
00262 double ArmSim::encoder2ang(int eng,MOTOR m)
00263 {
00264 
00265   switch(m)
00266   {
00267     case RobotArm::BASE:
00268       break;
00269     case RobotArm::SHOLDER:
00270       break;
00271     case RobotArm::ELBOW:
00272       break;
00273     case RobotArm::WRIST1:
00274       break;
00275     case RobotArm::WRIST2:
00276       break;
00277     case RobotArm::GRIPPER:
00278       break;
00279     default:
00280       break;
00281   }
00282   double ang = (eng*M_PI)/(2975*2);
00283 
00284 //  if(m==RobotArm::BASE)
00285 //    pos -=2306;
00286   return ang;
00287 }
00288 int ArmSim::ang2encoder(double ang,MOTOR m)
00289 {
00290 
00291   switch(m)
00292   {
00293     case RobotArm::BASE:
00294       break;
00295     case RobotArm::SHOLDER:
00296       break;
00297     case RobotArm::ELBOW:
00298       break;
00299     case RobotArm::WRIST1:
00300       break;
00301     case RobotArm::WRIST2:
00302       break;
00303     case RobotArm::GRIPPER:
00304       break;
00305     default:
00306       break;
00307   }
00308   int pos = (int)(ang*2975*2/M_PI);
00309 //  if(m==RobotArm::BASE)
00310 //    pos -=2306;
00311   return pos;
00312 }
00313 void ArmSim::setSafety(bool val)
00314 {
00315 }
00316 
00317 void ArmSim::resetEncoders()
00318 {
00319 }
00320 
00321 float ArmSim::getPWM(MOTOR m)
00322 {
00323         return 0;
00324 }
00325 
00326 void ArmSim::homeMotor()
00327 {
00328   /*
00329         int pwm = 0;
00330 
00331         switch(m)
00332         {
00333                 case ELBOW: pwm = -80; break;
00334                 default: pwm = 0; break;
00335         }
00336 
00337         setMotor(m, pwm);
00338         for(int i=0; i<100 && pwm != 0; i++)
00339         {
00340                 pwm = (int) getPWM(m);
00341                 LDEBUG("PWM %i", pwm);
00342                 sleep(1);
00343         }
00344         LDEBUG("Done\n");
00345         setMotor(m, 0);
00346 */
00347 }
00348 
00349 void ArmSim::makeArm()
00350 {
00351         dMass mass;
00352         dReal fMax = 100.0;
00353 
00354   const dReal *pos;
00355   //Base
00356   itsBase.body = dBodyCreate(world);
00357   dBodySetPosition(itsBase.body,
00358       itsArmParam.armLoc[0], itsArmParam.armLoc[1],
00359       itsArmParam.armLoc[2] + itsArmParam.base[1]/2); //Body initial position
00360   dMassSetZero(&mass);
00361   dMassSetCylinderTotal(&mass,itsArmParam.baseMass,3,itsArmParam.base[0],itsArmParam.base[1]);
00362   dBodySetMass(itsBase.body,&mass);
00363   //itsBase.geom = dCreateCylinder(space, itsArmParam.base[0],itsArmParam.base[1]);
00364   //dGeomSetBody(itsBase.geom, itsBase.body);
00365   dBodySetGravityMode(itsBase.body, ARM_GRAVITYMODE);
00366   //dGeomSetCategoryBits(itsBase.geom,ARM_BITFIELD);
00367   //dGeomSetCollideBits(itsBase.geom,!ARM_BITFIELD && !GROUND_BITFIELD); //don't colide with the arm itself and the Ground
00368 
00369   //Body
00370   itsBody.body = dBodyCreate(world);
00371   dBodySetPosition(itsBody.body,
00372       itsArmParam.armLoc[0],itsArmParam.armLoc[1], itsArmParam.armLoc[2] + itsArmParam.base[1] + itsArmParam.body[2]/2);
00373   dMassSetZero(&mass);
00374   dMassSetBoxTotal(&mass,itsArmParam.baseMass,
00375       itsArmParam.body[0], itsArmParam.body[1], itsArmParam.body[2]);
00376   dBodySetMass(itsBody.body,&mass);
00377   itsBody.geom = dCreateBox(space,
00378       itsArmParam.body[0], itsArmParam.body[1], itsArmParam.body[2]);
00379   dGeomSetBody(itsBody.geom, itsBody.body);
00380   dBodySetGravityMode(itsBody.body, ARM_GRAVITYMODE);
00381   dGeomSetCategoryBits(itsBody.geom,ARM_BITFIELD);
00382   dGeomSetCollideBits(itsBody.geom,!ARM_BITFIELD); //don't colide with the arm itself
00383 
00384   itsBody.joint = dJointCreateHinge(world,0);
00385   dJointAttach(itsBody.joint,itsBody.body,0);
00386   dJointSetHingeAnchor(itsBody.joint,
00387       itsArmParam.armLoc[0],itsArmParam.armLoc[1],
00388       itsArmParam.base[2]);
00389   dJointSetHingeAxis(itsBody.joint,0,0,1);
00390   dJointSetHingeParam(itsBody.joint, dParamFMax, fMax);
00391   dJointSetHingeParam(itsBody.joint, dParamVel , 0);
00392 
00393   //upperarm
00394   itsUpperArm.body = dBodyCreate(world);
00395   pos = dBodyGetPosition(itsBody.body);
00396   dBodySetPosition(itsUpperArm.body,pos[0]+0.03,pos[1], pos[2] + itsArmParam.body[2]/2 + itsArmParam.upperarm[2]/2);
00397   dMassSetZero(&mass);
00398   dMassSetBoxTotal(&mass,itsArmParam.baseMass,
00399       itsArmParam.upperarm[0], itsArmParam.upperarm[1], itsArmParam.upperarm[2]);
00400   dBodySetMass(itsUpperArm.body,&mass);
00401   itsUpperArm.geom = dCreateBox(space,
00402       itsArmParam.upperarm[0], itsArmParam.upperarm[1], itsArmParam.upperarm[2]);
00403   dGeomSetBody(itsUpperArm.geom, itsUpperArm.body);
00404   dBodySetGravityMode(itsUpperArm.body, ARM_GRAVITYMODE);
00405   dGeomSetCategoryBits(itsUpperArm.geom,ARM_BITFIELD);
00406   dGeomSetCollideBits(itsUpperArm.geom,!ARM_BITFIELD); //don't colide with the arm itself
00407 
00408 
00409   itsUpperArm.joint = dJointCreateHinge(world,0);
00410   dJointAttach(itsUpperArm.joint,itsUpperArm.body,itsBody.body);
00411   dJointSetHingeAnchor(itsUpperArm.joint,
00412       pos[0]+0.03, pos[1], pos[2] + itsArmParam.body[2]/2);
00413   dJointSetHingeAxis(itsUpperArm.joint,0,1,0);
00414   dJointSetHingeParam(itsUpperArm.joint, dParamFMax, fMax);
00415   dJointSetHingeParam(itsUpperArm.joint, dParamVel , 0);
00416 
00417   //forearm
00418   itsForearm.body = dBodyCreate(world);
00419   pos = dBodyGetPosition(itsUpperArm.body);
00420   dBodySetPosition(itsForearm.body,
00421       pos[0],pos[1], pos[2] + itsArmParam.upperarm[2]/2 + itsArmParam.forearm[2]/2);
00422   dMassSetZero(&mass);
00423   dMassSetBoxTotal(&mass,itsArmParam.forearmMass,
00424       itsArmParam.forearm[0], itsArmParam.forearm[1], itsArmParam.forearm[2]);
00425   dBodySetMass(itsForearm.body,&mass);
00426   itsForearm.geom = dCreateBox(space,
00427       itsArmParam.forearm[0], itsArmParam.forearm[1], itsArmParam.forearm[2]);
00428   dGeomSetBody(itsForearm.geom, itsForearm.body);
00429   dBodySetGravityMode(itsForearm.body, ARM_GRAVITYMODE);
00430   dGeomSetCategoryBits(itsForearm.geom,ARM_BITFIELD);
00431   dGeomSetCollideBits(itsForearm.geom,!ARM_BITFIELD);
00432 
00433   itsForearm.joint = dJointCreateHinge(world,0);
00434   dJointAttach(itsForearm.joint,itsForearm.body,itsUpperArm.body);
00435   dJointSetHingeAnchor(itsForearm.joint,
00436       pos[0], pos[1], pos[2] + itsArmParam.forearm[2]/2);
00437   dJointSetHingeAxis(itsForearm.joint,0,1,0);
00438   dJointSetHingeParam(itsForearm.joint, dParamFMax, fMax);
00439   dJointSetHingeParam(itsForearm.joint, dParamVel , 0);
00440 
00441 
00442   //Wrist
00443   itsWrist1.body = dBodyCreate(world);
00444   pos = dBodyGetPosition(itsForearm.body);
00445   dBodySetPosition(itsWrist1.body,
00446       pos[0],pos[1], pos[2] + itsArmParam.forearm[2]/2 + 0.04 - itsArmParam.wrist1[1]/2);
00447   dMassSetZero(&mass);
00448   dMassSetCylinderTotal(&mass,itsArmParam.wrist1Mass,3,itsArmParam.wrist1[0],itsArmParam.wrist1[1]);
00449   dBodySetMass(itsWrist1.body,&mass);
00450   itsWrist1.geom = dCreateCylinder(space,
00451       itsArmParam.wrist1[0], itsArmParam.wrist1[1]);
00452   dGeomSetBody(itsWrist1.geom, itsWrist1.body);
00453   dBodySetGravityMode(itsWrist1.body, ARM_GRAVITYMODE);
00454   dGeomSetCategoryBits(itsWrist1.geom,ARM_BITFIELD);
00455   dGeomSetCollideBits(itsWrist1.geom,!ARM_BITFIELD);
00456 
00457   itsWrist1.joint = dJointCreateHinge(world,0);
00458   dJointAttach(itsWrist1.joint,itsWrist1.body,itsForearm.body);
00459   dJointSetHingeAnchor(itsWrist1.joint,
00460       pos[0], pos[1], pos[2] + itsArmParam.forearm[2]/2-0.04);
00461   dJointSetHingeAxis(itsWrist1.joint,0,1,0);
00462   dJointSetHingeParam(itsWrist1.joint, dParamFMax, fMax);
00463   dJointSetHingeParam(itsWrist1.joint, dParamVel , 0);
00464 
00465 
00466   //Wrist2
00467   itsWrist2.body = dBodyCreate(world);
00468   pos = dBodyGetPosition(itsWrist1.body);
00469   dBodySetPosition(itsWrist2.body,
00470       pos[0],pos[1], pos[2] + itsArmParam.wrist1[1]/2 + itsArmParam.wrist2[2]/2);
00471   dMassSetZero(&mass);
00472   dMassSetBoxTotal(&mass,itsArmParam.wrist2Mass,
00473       itsArmParam.wrist2[0], itsArmParam.wrist2[1], itsArmParam.wrist2[2]);
00474   dBodySetMass(itsWrist2.body,&mass);
00475   itsWrist2.geom = dCreateBox(space,
00476       itsArmParam.wrist2[0], itsArmParam.wrist2[1], itsArmParam.wrist2[2]);
00477   dGeomSetBody(itsWrist2.geom, itsWrist2.body);
00478   dBodySetGravityMode(itsWrist2.body, ARM_GRAVITYMODE);
00479   dGeomSetCategoryBits(itsWrist2.geom,ARM_BITFIELD);
00480   dGeomSetCollideBits(itsWrist2.geom,!ARM_BITFIELD);
00481 
00482   itsWrist2.joint = dJointCreateHinge(world,0);
00483   dJointAttach(itsWrist2.joint,itsWrist2.body,itsWrist1.body);
00484   dJointSetHingeAnchor(itsWrist2.joint,
00485       pos[0], pos[1], pos[2] + itsArmParam.wrist1[1]/2);
00486   dJointSetHingeAxis(itsWrist2.joint,0,0,1);
00487   dJointSetHingeParam(itsWrist2.joint, dParamFMax, fMax);
00488   dJointSetHingeParam(itsWrist2.joint, dParamVel , 0);
00489 
00490   //Grippers
00491   itsGripper1.body = dBodyCreate(world);
00492   itsGripper2.body = dBodyCreate(world);
00493 
00494   pos = dBodyGetPosition(itsWrist2.body);
00495   dBodySetPosition(itsGripper1.body,
00496       pos[0],pos[1]+itsArmParam.wrist2[0], pos[2] + itsArmParam.wrist2[1]/2); // + itsArmParam.gripper[2]/2);
00497   dBodySetPosition(itsGripper2.body,
00498       pos[0],pos[1]-itsArmParam.wrist2[0], pos[2] + itsArmParam.wrist2[1]/2); // + itsArmParam.gripper[2]/2);
00499   dMassSetZero(&mass);
00500   dMassSetBoxTotal(&mass,itsArmParam.gripperMass,
00501       itsArmParam.gripper[0], itsArmParam.gripper[1], itsArmParam.gripper[2]);
00502 
00503   dBodySetMass(itsGripper1.body,&mass);
00504   dBodySetMass(itsGripper2.body,&mass);
00505 
00506   itsGripper1.geom = dCreateBox(space,
00507       itsArmParam.gripper[0], itsArmParam.gripper[1], itsArmParam.gripper[2]);
00508   dGeomSetBody(itsGripper1.geom, itsGripper1.body);
00509   itsGripper2.geom = dCreateBox(space,
00510       itsArmParam.gripper[0], itsArmParam.gripper[1], itsArmParam.gripper[2]);
00511   dGeomSetBody(itsGripper2.geom, itsGripper2.body);
00512 
00513   dBodySetGravityMode(itsGripper1.body, ARM_GRAVITYMODE);
00514   dGeomSetCategoryBits(itsGripper1.geom,GRIPPER_BITFIELD);
00515   dGeomSetCollideBits(itsGripper1.geom,!ARM_BITFIELD);
00516   dBodySetGravityMode(itsGripper2.body, ARM_GRAVITYMODE);
00517   dGeomSetCategoryBits(itsGripper2.geom,GRIPPER_BITFIELD);
00518   dGeomSetCollideBits(itsGripper2.geom,!ARM_BITFIELD);
00519 
00520   itsGripper1.joint = dJointCreateHinge(world,0);
00521   dJointAttach(itsGripper1.joint,itsGripper1.body,itsWrist2.body);
00522   dJointSetHingeAnchor(itsGripper1.joint,
00523       pos[0], pos[1] + itsArmParam.wrist2[0], pos[2]); // + itsArmParam.wrist2[1]/2);
00524   dJointSetHingeAxis(itsGripper1.joint,1,0,0);
00525   dJointSetHingeParam(itsGripper1.joint, dParamFMax, fMax);
00526   dJointSetHingeParam(itsGripper1.joint, dParamVel , 0);
00527 
00528   itsGripper2.joint = dJointCreateHinge(world,0);
00529   dJointAttach(itsGripper2.joint,itsGripper2.body,itsWrist2.body);
00530   dJointSetHingeAnchor(itsGripper2.joint,
00531       pos[0], pos[1] - itsArmParam.wrist2[0], pos[2]); // + itsArmParam.wrist2[1]/2);
00532   dJointSetHingeAxis(itsGripper2.joint,1,0,0);
00533   dJointSetHingeParam(itsGripper2.joint, dParamFMax, fMax);
00534   dJointSetHingeParam(itsGripper2.joint, dParamVel , 0);
00535 
00536 }
00537 
00538 void ArmSim::drawLine(double pos[3])
00539 {
00540 
00541   vp->dsSetColor(0,255,255);
00542   vp->dsDrawLine(pos,getEndPos());
00543   //LINFO("Line Length %f ",getDistance(pos,getEndPos()));
00544 }
00545 void ArmSim::drawArm()
00546 {
00547 
00548   double boxSize[3]={0.01,0.01,0.01};
00549   double R[12];
00550   //Base
00551   vp->dsSetColor(0,0,0);
00552   vp->dsDrawCylinderD(
00553       dBodyGetPosition(itsBase.body),
00554       dBodyGetRotation(itsBase.body),
00555       itsArmParam.base[1],
00556       itsArmParam.base[0]);
00557 
00558   //Body
00559   vp->dsSetColor(1,0.5,0);
00560   vp->dsDrawBox(
00561       dBodyGetPosition(itsBody.body),
00562       dBodyGetRotation(itsBody.body),
00563       itsArmParam.body);
00564 
00565   ////Upperarm
00566   vp->dsSetColor(1,0.5,0);
00567   vp->dsDrawBox(
00568       dBodyGetPosition(itsUpperArm.body),
00569       dBodyGetRotation(itsUpperArm.body),
00570       itsArmParam.upperarm);
00571 
00572 
00573   //Forearm
00574   vp->dsSetColor(1,0.5,0);
00575   vp->dsDrawBox(
00576       dBodyGetPosition(itsForearm.body),
00577       dBodyGetRotation(itsForearm.body),
00578       itsArmParam.forearm);
00579 
00580   //Wrist
00581   vp->dsSetColor(0,0,0);
00582   vp->dsDrawCylinderD(
00583       dBodyGetPosition(itsWrist1.body),
00584       dBodyGetRotation(itsWrist1.body),
00585       itsArmParam.wrist1[1],
00586       itsArmParam.wrist1[0]);
00587 
00588   //Wrist2
00589   vp->dsSetColor(0,0,0);
00590   vp->dsDrawBox(
00591       dBodyGetPosition(itsWrist2.body),
00592       dBodyGetRotation(itsWrist2.body),
00593       itsArmParam.wrist2);
00594 
00595   //Gripper
00596   vp->dsSetColor(0,0,0);
00597   vp->dsDrawBox(
00598       dBodyGetPosition(itsGripper1.body),
00599       dBodyGetRotation(itsGripper1.body),
00600       itsArmParam.gripper);
00601 
00602   vp->dsSetColor(0,0,0);
00603   vp->dsDrawBox(
00604       dBodyGetPosition(itsGripper2.body),
00605       dBodyGetRotation(itsGripper2.body),
00606       itsArmParam.gripper);
00607 
00608   //Draw The end point
00609   dRFromAxisAndAngle (R,0,0,1,0);
00610   vp->dsSetColor(1,0,0);
00611 
00612   vp->dsDrawBox(getEndPos(), R, boxSize);
00613 }
00614 
00615 void ArmSim::getArmLoc(double loc[3])
00616 {
00617 
00618   loc[0] = itsArmParam.armLoc[0];
00619   loc[1] = itsArmParam.armLoc[1];
00620   loc[2] = itsArmParam.armLoc[2];
00621 
00622 }
00623 //We get end pos by 3 object position
00624 //
00625 //                   @ = p[i] = middle of two gripper
00626 //    _  #   _       # = endPos
00627 //   | |    | |
00628 // g1|*| @  |*|g2    _
00629 //   |_|____|_|      | length l
00630 //   |        |      |
00631 //   |   * m  |      V
00632 //   |________|
00633 //
00634 
00635 dReal * ArmSim::getEndPos()
00636 {
00637   const dReal*g1 = dBodyGetPosition(itsGripper1.body);//gripper 1 center point
00638   const dReal*g2 = dBodyGetPosition(itsGripper2.body);//gripper 2 center point
00639   const dReal*m = dBodyGetPosition(itsWrist2.body);//wrist center point
00640 
00641   //Half gripper length + half wrist length
00642   //const dReal x = itsArmParam.wrist2[2]/2 ;
00643   const dReal l = itsArmParam.gripper[2]/2 +itsArmParam.wrist2[2]/2 ;
00644   const dReal w = itsArmParam.gripper[2]/2;//half gripper length
00645         dReal v[3],p[3];
00646   for(int i=0;i<3;i++){
00647     p[i] = (g1[i]+g2[i])/2;
00648     v[i] = p[i]-m[i];
00649     v[i] = v[i]/l;//v hat, unit vector
00650     endPoint[i]=m[i]+((l+w)*v[i]);
00651     //x = half length of wrist2
00652     //l+w = length from center of wrist to the end of gripper
00653   }
00654   return endPoint;
00655 
00656 }
00657 void ArmSim::drawTable()
00658 {
00659 
00660   double ori = 0;
00661   double pos[3] = {0,0,0};
00662   double R[12];
00663   double pt0[3] = {0,0,0.0};
00664   double pt1[3] = {-1*itsTableSize[0]/4,0,0.0};
00665   double pt2[3] = {-1*itsTableSize[0]/4,itsTableSize[0]/4,0.0};
00666   double pt3[3] = {0,itsTableSize[0]/4,0.0};
00667   double pt4[3] = {-1*itsTableSize[0]/4,-1*itsTableSize[0]/4,0.0};
00668   double pt5[3] = {0,-1*itsTableSize[0]/4,0.0};
00669   double boxSize[3]={0.03,0.03,0.03};
00670 
00671   dRFromAxisAndAngle (R,0,0,1,ori);
00672 
00673   vp->dsSetColor(1,1,1);
00674   vp->dsDrawBox(pos, R, itsTableSize); // sides[3] = {75, 1.215, 0.001};
00675 
00676   vp->dsSetColor(0,0,255);//Blue
00677   vp->dsDrawBox(pt0, R, boxSize);
00678   vp->dsSetColor(1,0,0);//Read
00679   vp->dsDrawBox(pt1, R, boxSize);
00680   vp->dsSetColor(0,255,255);//cyan
00681   vp->dsDrawBox(pt2, R, boxSize);
00682   vp->dsSetColor(255,0,255);//magenta
00683   vp->dsDrawBox(pt3, R, boxSize);
00684   vp->dsSetColor(1,0,1);//black
00685   vp->dsDrawBox(pt4, R, boxSize);
00686   vp->dsSetColor(1,1,0);//black
00687   vp->dsDrawBox(pt5, R, boxSize);
00688 //  Table Layout
00689 //  T = itsTableSize[0] = 1.215
00690 //  W = itsTableSize[1] = 0.75
00691 //  Arm location (-T/2+0.145,-W/2+0.12)
00692 //  ---------------------------------------
00693 //  |RobotArm |      |                |   |
00694 //  |         |      |                |   |
00695 //  |  (O)    |      |                |   |
00696 //  |         |      |                |   |
00697 //  |_________|      |                |   |
00698 //  | |pt4           |pt1(-T/4,0)     |pt2|(-T/4,T/4)
00699 //  |-X--------------X----------------X----
00700 //  | |(-T/4,-T/4)   |                |   |
00701 //  | |              |                |   |
00702 //  | |              |                |   |
00703 //  | |              |                |   |
00704 //  | |              |                |   |
00705 //  | |pt5(0,-T/4)   |pt0(0,0)        |pt3| (0,T/4)
00706 //  |-X--------------X----------------X----
00707 //  |                                     |
00708 //  |                                     |
00709 //  |                      /(((())))\     |
00710 //  |                    ((          ))   |
00711 //  |                   ((  (0)  (0)  ))  |
00712 //  |                    ((          ))   |
00713 //  |                     ((][][][][))    |
00714 //  |                          ][         |
00715 //  |                       __/][\__      |
00716 //  |                      Robot Head     |
00717 //  |                        Camera       |
00718 //  |                                     |
00719 //  ---------------------------------------
00720 }
00721 
00722 
00723 
00724 void ArmSim::simLoop()
00725 {
00726          dSpaceCollide(space,this,&nearCallback);
00727   dWorldStep(world,0.01);
00728   dJointGroupEmpty(contactgroup);
00729 
00730   ////For get Current xyz & hpr test only
00731   //double xyz[3],hpr[3];
00732   //vp->dsGetViewpoint (xyz,hpr);
00733   //LINFO("double xyz[3]={%f, %f, %f};\ndouble hpr[3] = {%f, %f, %f};",
00734   //    xyz[0], xyz[1], xyz[2],
00735   //    hpr[0], hpr[1], hpr[2]);
00736 
00737 }
00738 
00739 Image<PixRGB<byte> > ArmSim::getFrame(int camera)
00740 {
00741 
00742   XEvent event = vp->initFrame();
00743   drawArm();
00744   drawTable();
00745   drawObjects();
00746   vp->updateFrame();
00747 
00748   return vp->getFrame();
00749 
00750 }
00751 
00752 void ArmSim::drawObjects()
00753 {
00754 
00755   for(uint i=0; i<itsObjects.size(); i++)
00756   {
00757     Object obj = itsObjects[i];
00758 
00759     vp->dsSetColor(obj.color[0],obj.color[1],obj.color[2]);
00760     switch(obj.type)
00761     {
00762       case BOX:
00763         dReal size[3];
00764         dGeomBoxGetLengths(obj.geom,size);
00765         vp->dsDrawBox(
00766             dBodyGetPosition(obj.body),
00767             dBodyGetRotation(obj.body),
00768             size);
00769         drawLine((double*)dBodyGetPosition(obj.body));
00770         break;
00771       default:
00772         break;
00773     }
00774 
00775   }
00776 
00777   for(uint i=0; i<itsDrawObjects.size(); i++)
00778   {
00779     DrawObject obj = itsDrawObjects[i];
00780     switch(obj.type)
00781     {
00782       case SPHERE:
00783         vp->dsSetColor(1.0,0,0);
00784         vp->dsDrawSphere(obj.loc, obj.rot, 0.005);
00785         break;
00786       default:
00787         break;
00788     }
00789   }
00790 
00791 }
00792 
00793 void ArmSim::getObjLoc(const int x, const int y, double loc[3])
00794 {
00795   LINFO("Getting obj loc from %ix%i\n", x, y);
00796 
00797   vp->unProjectPoint(x,y,loc);
00798 
00799 }
00800 void ArmSim::moveObject(double pos[3],int objID)
00801 {
00802   if(itsObjects.size() == 0)
00803     return ;
00804   Object obj = itsObjects[objID];
00805     dBodySetPosition(obj.body,pos[0],pos[1],pos[2]);
00806 
00807 
00808 }
00809 void ArmSim::addObject(OBJECT_TYPE objType,double initPos[3])
00810 {
00811       double boxSize[3];
00812       boxSize[0] = 0.040;
00813       boxSize[1] = 0.040;
00814       boxSize[2] = 0.080;
00815       addObject(objType,initPos,boxSize);
00816 }
00817 void ArmSim::addObject(OBJECT_TYPE objType,double initPos[3],double objSize[3])
00818 {
00819 
00820   //double initPos[3] = {0.3, 0.2, 0.1}; //10cm above flooor and infornt of the robot
00821   dMass m;
00822   switch(objType)
00823   {
00824     case BOX:
00825       Object obj;
00826       obj.body = dBodyCreate(world);
00827       dBodySetPosition(obj.body, initPos[0], initPos[1], initPos[2]);
00828       dMassSetBoxTotal(&m, 1, objSize[0], objSize[1], objSize[2]);
00829       dBodySetMass(obj.body, &m);
00830       obj.geom = dCreateBox(space, objSize[0], objSize[1], objSize[2]);
00831       dGeomSetBody(obj.geom, obj.body);
00832       dGeomSetCategoryBits(obj.geom,OBJ_BITFIELD);
00833       dGeomSetCollideBits(obj.geom,!GRIPPER_BITFIELD && !ARM_BITFIELD);
00834       //50 216 73 green block
00835       obj.color[0] = 0; obj.color[1] = 196; obj.color[2] = 127; //1 0 0 Red object
00836       obj.type = BOX;
00837       itsObjects.push_back(obj);
00838       break;
00839     default:
00840       LINFO("Unknown object");
00841       break;
00842   }
00843 
00844 }
00845 
00846 void ArmSim::addDrawObject(OBJECT_TYPE objType,double pos[3])
00847 {
00848   switch(objType)
00849   {
00850     case SPHERE:
00851       DrawObject obj;
00852       obj.type = SPHERE;
00853       obj.loc[0] = pos[0];
00854       obj.loc[1] = pos[1];
00855       obj.loc[2] = pos[2];
00856 
00857       dRSetIdentity(obj.rot);
00858       itsDrawObjects.push_back(obj);
00859       break;
00860     default:
00861       LINFO("Unknown object");
00862       break;
00863   }
00864 
00865 }
00866 
00867 
00868 int ArmSim::getGradientEncoder(MOTOR m,double *targetPos)
00869 {
00870   return ang2encoder(getGradient(m,targetPos),m);
00871 }
00872 double ArmSim::getGradient(MOTOR m,double *targetPos)
00873 {
00874   dReal axis[3],joint_center[3];
00875   dReal *tip;
00876   dReal toTip[3],toTarget[3];
00877   dReal movement[3];
00878   double gradient;
00879   dJointID joint = getJointID(m);
00880   dJointGetHingeAxis(joint,axis);
00881   dJointGetHingeAnchor(joint,joint_center);
00882   tip = getEndPos();
00883   for(int i = 0;i < 3;i++)
00884   {
00885     toTip[i] = tip[i] -joint_center[i];
00886     toTarget[i] = targetPos[i] - tip[i];
00887   }
00888   crossproduct(toTip,axis,movement);
00889   gradient = (double)dotproduct(movement,toTarget);
00890 
00891   return gradient;
00892 }
00893 void ArmSim::getJointAxis(MOTOR m,dReal axis[3])
00894 {
00895   dJointGetHingeAxis(getJointID(m),axis);
00896 }
00897 void ArmSim::getJointCenter(MOTOR m,dReal joint[3])
00898 {
00899   dJointGetHingeAnchor(getJointID(m),joint);
00900 }
00901 dJointID ArmSim::getJointID(MOTOR m)
00902 {
00903   dJointID joint = 0;
00904   switch(m)
00905   {
00906     case RobotArm::BASE:
00907       joint = itsBody.joint;
00908       break;
00909     case RobotArm::SHOLDER:
00910       joint = itsUpperArm.joint;
00911       break;
00912     case RobotArm::ELBOW:
00913       joint = itsForearm.joint;
00914       break;
00915     case RobotArm::WRIST1:
00916       joint = itsWrist1.joint;
00917       break;
00918     case RobotArm::WRIST2:
00919       joint = itsWrist2.joint;
00920       break;
00921     case RobotArm::GRIPPER:
00922       joint = itsGripper1.joint;
00923       break;
00924     default:
00925       break;
00926   }
00927   return joint;
00928 
00929 }
00930 // ######################################################################
00931 /* So things look consistent in everyone's emacs... */
00932 /* Local Variables: */
00933 /* indent-tabs-mode: nil */
00934 /* End: */
Generated on Sun May 8 08:40:11 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3