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: */