00001 /*!@file Devices/Scorbot.H Interface to 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/Devices/Scorbot.H $ 00035 // $Id: Scorbot.H 13955 2010-09-17 00:59:56Z lior $ 00036 // 00037 00038 #ifndef Scorbot_H_DEFINED 00039 #define Scorbot_H_DEFINED 00040 00041 #include "Image/Layout.H" 00042 #include "Image/MatrixOps.H" 00043 #include "ArmControl/RobotArm.H" 00044 #include "Component/ModelComponent.H" 00045 #include "Component/ModelParam.H" 00046 #include "Devices/Serial.H" 00047 #include "Controllers/PID.H" 00048 #include "Util/Types.H" 00049 #include "Util/Timer.H" 00050 #include "Image/Point3D.H" 00051 #include <deque> 00052 #include <pthread.h> 00053 #include <stdarg.h> 00054 00055 #define MAX_PWM 100 00056 00057 #define BASE_POS_THRESH 12 00058 #define BASE_NEG_THRESH -12 00059 00060 #define SHOLDER_POS_THRESH 12 00061 #define SHOLDER_NEG_THRESH -12 00062 00063 #define ELBOW_POS_THRESH 12 00064 #define ELBOW_NEG_THRESH -12 00065 00066 #define GRIPPER_POS_THRESH 12 00067 #define GRIPPER_NEG_THRESH -12 00068 00069 #define WRIST_PITCH_POS_THRESH 12 00070 #define WRIST_PITCH_NEG_THRESH -12 00071 00072 #define WRIST_ROLL_POS_THRESH 12 00073 #define WRIST_ROLL_NEG_THRESH -12 00074 00075 #define EX1_POS_THRESH 12 00076 #define EX1_NEG_THRESH -12 00077 00078 class Scorbot : public RobotArm 00079 { 00080 public: 00081 //Constructor 00082 Scorbot(OptionManager& mgr, 00083 const std::string& descrName = "Scorbot", 00084 const std::string& tagName = "Scorbot", 00085 const char *defdev = "/dev/ttyUSB0"); 00086 00087 ~Scorbot(); 00088 00089 struct ArmPos 00090 { 00091 int base; 00092 int sholder; 00093 int elbow; 00094 int gripper; 00095 int wristRoll; 00096 int wristPitch; 00097 int wrist1; 00098 int wrist2; 00099 int ex1; 00100 int ex2; 00101 int duration; 00102 00103 bool baseMS; 00104 bool sholderMS; 00105 bool elbowMS; 00106 bool wrist1MS; 00107 bool wrist2MS; 00108 bool gripperMS; 00109 00110 ArmPos() : 00111 base(0), sholder(0), elbow(0), gripper(0), 00112 wristRoll(0), wristPitch(0), wrist1(0), wrist2(0), 00113 ex1(0), ex2(0), duration(0) 00114 {} 00115 }; 00116 00117 struct VelParam 00118 { 00119 double a; 00120 double b; 00121 double c; 00122 double d; 00123 }; 00124 00125 struct ArmVelParam 00126 { 00127 VelParam base; 00128 VelParam sholder; 00129 VelParam elbow; 00130 VelParam gripper; 00131 VelParam wristRoll; 00132 VelParam wristPitch; 00133 VelParam wrist1; 00134 VelParam wrist2; 00135 VelParam ex1; 00136 VelParam ex2; 00137 }; 00138 00139 //########################################################### 00140 void start2(); 00141 void stop1(); 00142 00143 //servo definition 00144 00145 //enum MOTOR {BASE, SHOLDER, ELBOW, WRIST1, WRIST2, GRIPPER, WRIST_ROLL, WRIST_PITCH, EX1, EX2}; 00146 00147 //enum COMMANDS {SAFE_MODE=9, SET_MOTORS=10, MOTORS_OFF=11, 00148 // GET_ENCODER=12, RESET_ENCODER=13, GET_PWM=14, GET_MS=15}; 00149 00150 bool setMotor(MOTOR m, int pwm); 00151 void setMotorPos(MOTOR m, int pos); 00152 bool setJointPos(MOTOR joint, int position, bool relative = false, int duration = 2000); 00153 00154 00155 int getEncoder(MOTOR m); 00156 float getEncoderAng(MOTOR m); 00157 int getPWM(MOTOR m); 00158 00159 bool resetEncoders(); 00160 void resetMotorPos(void); 00161 00162 bool stopAllMotors(); 00163 00164 // Image<PixRGB<unsigned char> > getFrame(int camera){return NULL;} 00165 // Image<PixRGB<byte> > getFrame(int camera){return NULL;} 00166 void simLoop(){}; 00167 00168 void setSafety(bool val); 00169 00170 void getEF_pos(float &x, float &y, float &z); 00171 00172 void homeMotors(); 00173 void homeMotor(RobotArm::MOTOR axis, int LimitSeekSpeed, int MSJumpSpeed, float MSJumpDelay, int MSSeekSpeed, bool MSStopCondition, bool checkMS); 00174 00175 bool motorsOff(); 00176 bool motorsOn(); 00177 00178 int getMicroSwitch(); 00179 char *getMicroSwitchByte(); 00180 bool getMicroSwitchMotor(RobotArm::MOTOR m); 00181 00182 void tunePID(MOTOR m, float p, float i, float d, bool relative); 00183 00184 void stopControl() { itsStopControl = true; } 00185 void startControl() { itsStopControl = false; } 00186 bool controlStoped() { return itsStopControl; } 00187 00188 double enc2ang(int encoderTicks); 00189 int ang2enc(double degrees); 00190 double enc2mm(int encoderTicks); 00191 int mm2enc(double mm); 00192 00193 void controlLoop(); //the main control loop 00194 00195 void setArmPos(ArmPos &armPos); 00196 ArmPos getArmPos(); 00197 00198 //Read the entire arm state using only one serial write, 00199 //and (hopefully) one serial read 00200 ArmPos readArmState(); 00201 00202 //! Get the End Effector pos 00203 Point3D<float> getEFPos(const ArmPos &armPos); 00204 00205 //! Get the arm position from desired end effector posision 00206 ArmPos getIKArmPos(const Point3D<float>& efPos); 00207 00208 bool set3DPos(bool relative = false, int duration = 2000); 00209 00210 00211 //! gravity compensator 00212 double gravityComp(int sholderPos, int elbowPos); 00213 00214 00215 ArmPos getDesiredArmPos(); 00216 00217 int getJointPos(MOTOR m); 00218 00219 00220 00221 bool moveDone() { return itsMoveDone; } 00222 00223 //Propeller PID commands 00224 bool setInternalPIDGain(MOTOR m, int P, int I, int D); 00225 bool setInternalPos(ArmPos pos); 00226 bool internalPidEn() { return itsInternalPIDen.getVal(); } 00227 00228 00229 //Read and write to raw serial data 00230 int write(const void* buffer, const int nbytes); 00231 int read(void* buffer, const int nbytes); 00232 00233 //Set the motors of at shutdown 00234 void shutdownMotorsOff(bool val) { itsShutdownMotorsOff = val; } 00235 00236 private: 00237 00238 bool enableInternalPID(); 00239 bool disableInternalPID(); 00240 00241 virtual void paramChanged(ModelParamBase* const param, 00242 const bool valueChanged, 00243 ParamClient::ChangeStatus* status); 00244 00245 char ms[9];//for micro switch binary display 00246 int msi[5];//for micro switch binary display 00247 nub::soft_ref<Serial> itsSerial; //our serial controller 00248 Timer itsTimer; 00249 00250 PID<float> pidBase; 00251 PID<float> pidSholder; 00252 PID<float> pidElbow; 00253 PID<float> pidWrist1; 00254 PID<float> pidWrist2; 00255 PID<float> pidGripper; 00256 PID<float> pidEx1; 00257 PID<float> pidEx2; 00258 00259 //ArmParameters 00260 float itsUpperarmLength; 00261 float itsForearmLength; 00262 float itsUpperarmCOM; 00263 float itsUpperarmMass; 00264 float itsForearmCOM; 00265 float itsForearmMass; 00266 float itsRadPerSholderEncoder; 00267 float itsRadPerElbowEncoder; 00268 float itsMMPerSlideEncoder; 00269 float itsBaseXOffset; 00270 float itsBaseZOffset; 00271 00272 int itsHomeBaseOffset; //the oiffset from the home location to 0 00273 int itsHomeSholderOffset; //the oiffset from the home location to 0 00274 int itsHomeElbowOffset; //the oiffset from the home location to 0 00275 int itsHomeWristRollBaseOffset; //the oiffset from the home location to 0 00276 int itsHomeWristPitchBaseOffset; //the oiffset from the home location to 0 00277 00278 NModelParam<int> itsBasePos; 00279 NModelParam<int> itsSholderPos; 00280 NModelParam<int> itsElbowPos; 00281 NModelParam<int> itsWrist1Pos; 00282 NModelParam<int> itsWrist2Pos; 00283 NModelParam<int> itsGripperPos; 00284 NModelParam<int> itsEX1Pos; 00285 NModelParam<int> itsEX2Pos; 00286 NModelParam<float> itsArmXPos; 00287 NModelParam<float> itsArmYPos; 00288 NModelParam<float> itsArmZPos; 00289 NModelParam<bool> itsMoveTo3D; 00290 NModelParam<int> itsDuration; 00291 NModelParam<bool> itsInternalPIDen; 00292 00293 00294 pthread_t itsControlThread; 00295 pthread_mutex_t itsLock; 00296 pthread_mutex_t itsSerialLock; 00297 pthread_mutex_t itsPosLock; 00298 00299 mutable bool itsRunControl; //the control loop thread 00300 mutable bool itsStopControl; //start/stop control 00301 mutable bool itsReadEncoders; //start/stop control 00302 mutable bool itsMoveDone; 00303 mutable bool itsShutdownMotorsOff; 00304 00305 00306 mutable bool itsTemp; 00307 00308 ArmPos itsCurrentPos; 00309 ArmPos itsDesiredPos; 00310 ArmVelParam itsArmVelParams; 00311 00312 00313 //! Bring motor to a predefined position 00314 char *int2byte(int x) 00315 { 00316 int n; 00317 for(n=0; n<8; n++) 00318 { 00319 if((x & 0x80) !=0) 00320 { 00321 ms[n]='1'; 00322 } 00323 else 00324 { 00325 ms[n]='0'; 00326 } 00327 x = x<<1; 00328 } 00329 ms[8]='\0'; 00330 return ms; 00331 } 00332 int int2array(int x,int index) 00333 { 00334 int n; 00335 x = x<<3; 00336 for(n=0; n<5; n++) 00337 { 00338 if((x & 0x80) !=0) 00339 { 00340 msi[n]=1; 00341 } 00342 else 00343 { 00344 msi[n]=0; 00345 } 00346 x = x<<1; 00347 } 00348 return msi[index]; 00349 } 00350 00351 00352 }; 00353 00354 #endif 00355 00356 // ###################################################################### 00357 /* So things look consistent in everyone's emacs... */ 00358 /* Local Variables: */ 00359 /* indent-tabs-mode: nil */ 00360 /* End: */