00001 /*!@file ArmControl/ArmController.H Control motors and pid */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003 // 00005 // by the 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 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/ArmControl/ArmController.H $ 00035 // $Id: ArmController.H 10794 2009-02-08 06:21:09Z itti $ 00036 // 00037 00038 #ifndef ArmController_H_DEFINED 00039 #define ArmController_H_DEFINED 00040 00041 #include "Component/ModelComponent.H" 00042 #include "Component/ModelParam.H" 00043 #include "rutz/shared_ptr.h" 00044 #include "Util/Types.H" 00045 #include "Util/Timer.H" 00046 #include "Util/WorkThreadServer.H" 00047 #include "Util/JobWithSemaphore.H" 00048 #include "Controllers/PID.H" 00049 #include "Devices/Scorbot.H" 00050 #include "Image/Image.H" 00051 #include "Image/Pixels.H" 00052 #include "ArmControl/ArmSim.H" 00053 00054 #include <list> 00055 00056 00057 00058 // ###################################################################### 00059 class ArmController : public ModelComponent 00060 { 00061 public: 00062 00063 //NOTE: Do not change these motor mappings! Just plug in the cables correctly, please. 00064 // If for some reason these mappings must be changed, then you need to also change the order 00065 // in which ArmController::setMotor and ArmController::updatePID sendd their motor packets 00066 #define ERR_THRESH 10 00067 #define BASE_THRESH_POS 30 00068 #define BASE_THRESH_NEG -30 00069 00070 #define SHOLDER_THRESH_POS 30 00071 #define SHOLDER_THRESH_NEG -60 00072 00073 #define ELBOW_THRESH_POS 44 00074 #define ELBOW_THRESH_NEG -25 00075 00076 #define WRIST1_THRESH_POS 30 00077 #define WRIST1_THRESH_NEG -30 00078 00079 #define WRIST2_THRESH_POS 30 00080 #define WRIST2_THRESH_NEG -30 00081 00082 00083 struct JointPos 00084 { 00085 int base; 00086 int sholder; 00087 int elbow; 00088 int wrist1; 00089 int wrist2; 00090 int gripper; 00091 bool reachable; 00092 }; 00093 00094 // ###################################################################### 00095 /*! @name Constructors and Destructors */ 00096 //@{ 00097 00098 //! Constructor 00099 ArmController(OptionManager& mgr, 00100 const std::string& descrName = "ArmController", 00101 const std::string& tagName = "ArmController", 00102 nub::soft_ref<RobotArm> robotArm = nub::soft_ref<RobotArm>()); //(new RobotArm(mgr))); 00103 00104 //! Destructor 00105 ~ArmController(); 00106 00107 00108 bool setBasePos(int base, bool rel=false); //maintain a base 00109 bool setSholderPos(int sholder, bool rel=false); //maintain a sholder 00110 bool setElbowPos(int elbow, bool rel=false); //maintain a elbow 00111 bool setWrist1Pos(int wrist1, bool rel=false); //maintain a wrist1 00112 bool setWrist2Pos(int wrist2, bool rel=false); //maintain a wrist2 00113 bool setSpeed(int speed); //maintain a speed 00114 00115 void setGripper(int pos); 00116 00117 void start2(); 00118 00119 int getElbow() { return itsCurrentElbow; } 00120 int getElbowErr(); 00121 int getBase() { return itsCurrentBase; } 00122 int getSholder() { return itsCurrentSholder; } 00123 int getWrist1() { return itsCurrentWrist1; } 00124 int getWrist2() { return itsCurrentWrist2; } 00125 00126 bool getKillSwitch() { return false; } 00127 00128 void setMotor(int motor, int val); 00129 00130 const int* getBasePtr() { return &itsCurrentBase; } 00131 const int* getSholderPtr() { return &itsCurrentSholder; } 00132 const int* getElbowPtr() { return &itsCurrentElbow; } 00133 const int* getWrist1Ptr() { return &itsCurrentWrist1; } 00134 const int* getWrist2Ptr() { return &itsCurrentWrist2; } 00135 00136 const int* getMotor_Base_Ptr() { return &itsCurrentMotor_Base; } 00137 const int* getMotor_Sholder_Ptr() { return &itsCurrentMotor_Sholder; } 00138 const int* getMotor_Elbow_Ptr() { return &itsCurrentMotor_Elbow; } 00139 const int* getMotor_Wrist1_Ptr() { return &itsCurrentMotor_Wrist1; } 00140 const int* getMotor_Wrist2_Ptr() { return &itsCurrentMotor_Wrist2; } 00141 00142 nub::soft_ref<RobotArm> getRobotArm(){return itsRobotArm;} 00143 00144 void setMotorsOn(bool val) { motorsOn.setVal(val);} 00145 void setPidOn(bool val) {pidOn.setVal(val); } 00146 void setControllerOn(bool val) {controllerOn.setVal(val); } 00147 bool isControllerOn() {return controllerOn.getVal(); } 00148 00149 void updateBase(int currentBase); 00150 void updateSholder(int currentSholder); 00151 void updateElbow(unsigned int currentElbow); 00152 void updateWrist1(unsigned int currentWrist1); 00153 void updateWrist2(unsigned int currentWrist2); 00154 void updatePID(); 00155 void sendHeartBeat(); 00156 00157 //! Wait until all joint finish move 00158 bool isFinishMove(); 00159 //! Get the joint positions 00160 JointPos getJointPos(); 00161 00162 //! Reset the joint positions to a particuler val 00163 void resetJointPos(JointPos &jointPos, int val = 0); 00164 00165 //! Set the joint positions 00166 bool setJointPos(const JointPos &jointPos, bool block = true); 00167 00168 //! Set the min joint positions 00169 void setMinJointPos(const JointPos &jointPos); 00170 00171 //! Set the max joint positions 00172 void setMaxJointPos(const JointPos &jointPos); 00173 00174 //!Stop all motors 00175 void killMotors(); 00176 00177 void genPIDImage(); 00178 const Image<PixRGB<byte> >* getPIDImagePtr() { return &itsPIDImage; } 00179 00180 //@} 00181 00182 // ###################################################################### 00183 /*! @name member functions */ 00184 //@{ 00185 00186 00187 private: 00188 int itsDesiredBase; 00189 int itsDesiredSholder; 00190 int itsDesiredElbow; 00191 int itsDesiredWrist1; 00192 int itsDesiredWrist2; 00193 int itsDesiredGripper; 00194 int itsDesiredSpeed; 00195 00196 int itsCurrentBase; 00197 int itsCurrentSholder; 00198 int itsCurrentElbow; 00199 int itsCurrentWrist1; 00200 int itsCurrentWrist2; 00201 int itsCurrentGripper; 00202 int itsCurrentSpeed; 00203 00204 00205 PID<float> itsBasePID; 00206 PID<float> itsSholderPID; 00207 PID<float> itsElbowPID; 00208 PID<float> itsWrist1PID; 00209 PID<float> itsWrist2PID; 00210 00211 JointPos itsMaxJointPos; 00212 JointPos itsMinJointPos; 00213 00214 int itsCurrentMotor_Base; 00215 int itsCurrentMotor_Sholder; 00216 int itsCurrentMotor_Elbow; 00217 int itsCurrentMotor_Wrist1; 00218 int itsCurrentMotor_Wrist2; 00219 00220 int itsMoveCount_Base; 00221 int itsMoveCount_Sholder; 00222 int itsMoveCount_Elbow; 00223 int itsMoveCount_Wrist1; 00224 int itsMoveCount_Wrist2; 00225 00226 00227 void paramChanged(ModelParamBase* const param, const bool valueChanged, ParamClient::ChangeStatus* status); 00228 00229 NModelParam<int> setCurrentMotor_Base; 00230 NModelParam<int> setCurrentMotor_Sholder; 00231 NModelParam<int> setCurrentMotor_Elbow; 00232 NModelParam<int> setCurrentMotor_Wrist1; 00233 NModelParam<int> setCurrentMotor_Wrist2; 00234 00235 NModelParam<float> baseP; 00236 NModelParam<float> baseI; 00237 NModelParam<float> baseD; 00238 00239 NModelParam<float> sholderP; 00240 NModelParam<float> sholderI; 00241 NModelParam<float> sholderD; 00242 00243 NModelParam<float> elbowP; 00244 NModelParam<float> elbowI; 00245 NModelParam<float> elbowD; 00246 00247 NModelParam<float> wrist1P; 00248 NModelParam<float> wrist1I; 00249 NModelParam<float> wrist1D; 00250 00251 NModelParam<float> wrist2P; 00252 NModelParam<float> wrist2I; 00253 NModelParam<float> wrist2D; 00254 00255 NModelParam<bool> motorsOn; 00256 NModelParam<bool> pidOn; 00257 NModelParam<bool> guiOn; 00258 NModelParam<bool> controllerOn; 00259 NModelParam<int> motorsSpeed; 00260 NModelParam<bool> basePIDDisplay; 00261 NModelParam<bool> sholderPIDDisplay; 00262 NModelParam<bool> elbowPIDDisplay; 00263 NModelParam<bool> wrist1PIDDisplay; 00264 NModelParam<bool> wrist2PIDDisplay; 00265 00266 00267 NModelParam<int> basePos; 00268 NModelParam<int> sholderPos; 00269 NModelParam<int> elbowPos; 00270 NModelParam<int> wrist1Pos; 00271 NModelParam<int> wrist2Pos; 00272 00273 00274 00275 /// GUI Related 00276 Image<PixRGB<byte> > itsPIDImage; 00277 00278 00279 rutz::shared_ptr<WorkThreadServer> itsThreadServer; 00280 00281 nub::soft_ref<RobotArm> itsRobotArm; 00282 00283 /// Running Time Related 00284 int itsAvgn; 00285 uint64 itsAvgtime; 00286 double itsLps; 00287 Timer itsTimer; 00288 void getLps(){ 00289 itsAvgn++; 00290 itsAvgtime += itsTimer.getReset(); 00291 if(itsAvgn == 20) 00292 { 00293 itsLps = 1000.0F / double(itsAvgtime) * double(itsAvgn); 00294 itsAvgtime = 0; 00295 itsAvgn = 0; 00296 00297 } 00298 LINFO("Loop per sec %.1f lps",itsLps); 00299 00300 } 00301 00302 }; 00303 00304 #endif 00305 00306 // ###################################################################### 00307 /* So things look consistent in everyone's emacs... */ 00308 /* Local Variables: */ 00309 /* indent-tabs-mode: nil */ 00310 /* End: */