00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include "controlAllegroHand.h"
00009 #include <iostream>
00010 #include <math.h>
00011 #include <stdio.h>
00012 using namespace std;
00013 
00014 void PRINT_INFO(const char *msg)
00015 {
00016         cout << msg << endl;
00017 }
00018 
00019 controlAllegroHand::controlAllegroHand()
00020 {
00021         mEmergencyStop = false;
00022 
00023         mPWM_MAX[eJOINTNAME_INDEX_0] = PWM_LIMIT_ROLL;
00024         mPWM_MAX[eJOINTNAME_INDEX_1] = PWM_LIMIT_NEAR;
00025         mPWM_MAX[eJOINTNAME_INDEX_2] = PWM_LIMIT_MIDDLE;
00026         mPWM_MAX[eJOINTNAME_INDEX_3] = PWM_LIMIT_FAR;
00027 
00028         mPWM_MAX[eJOINTNAME_MIDDLE_0] = PWM_LIMIT_ROLL;
00029         mPWM_MAX[eJOINTNAME_MIDDLE_1] = PWM_LIMIT_NEAR;
00030         mPWM_MAX[eJOINTNAME_MIDDLE_2] = PWM_LIMIT_MIDDLE;
00031         mPWM_MAX[eJOINTNAME_MIDDLE_3] = PWM_LIMIT_FAR;
00032 
00033         mPWM_MAX[eJOINTNAME_PINKY_0] = PWM_LIMIT_ROLL;
00034         mPWM_MAX[eJOINTNAME_PINKY_1] = PWM_LIMIT_NEAR;
00035         mPWM_MAX[eJOINTNAME_PINKY_2] = PWM_LIMIT_MIDDLE;
00036         mPWM_MAX[eJOINTNAME_PINKY_3] = PWM_LIMIT_FAR;
00037 
00038         mPWM_MAX[eJOINTNAME_THUMB_0] = PWM_LIMIT_THUMB_ROLL;
00039         mPWM_MAX[eJOINTNAME_THUMB_1] = PWM_LIMIT_THUMB_NEAR;
00040         mPWM_MAX[eJOINTNAME_THUMB_2] = PWM_LIMIT_THUMB_MIDDLE;
00041         mPWM_MAX[eJOINTNAME_THUMB_3] = PWM_LIMIT_THUMB_FAR;
00042 
00043 
00044 mEncoderOffset[eJOINTNAME_INDEX_0] = -199;
00045 mEncoderOffset[eJOINTNAME_INDEX_1] = -66044;
00046 mEncoderOffset[eJOINTNAME_INDEX_2] = -632;
00047 mEncoderOffset[eJOINTNAME_INDEX_3] = 1517;
00048 mEncoderOffset[eJOINTNAME_MIDDLE_0] = 497;
00049 mEncoderOffset[eJOINTNAME_MIDDLE_1] = -66232;
00050 mEncoderOffset[eJOINTNAME_MIDDLE_2] = -190;
00051 mEncoderOffset[eJOINTNAME_MIDDLE_3] = 1031;
00052 mEncoderOffset[eJOINTNAME_PINKY_0] = -777;
00053 mEncoderOffset[eJOINTNAME_PINKY_1] = -66787;
00054 mEncoderOffset[eJOINTNAME_PINKY_2] = 548;
00055 mEncoderOffset[eJOINTNAME_PINKY_3] = 1358;
00056 mEncoderOffset[eJOINTNAME_THUMB_0] = -64803;
00057 mEncoderOffset[eJOINTNAME_THUMB_1] = -66346;
00058 mEncoderOffset[eJOINTNAME_THUMB_2] = 682;
00059 mEncoderOffset[eJOINTNAME_THUMB_3] = 574;
00060 
00061 mEncoderDirection[eJOINTNAME_INDEX_0] = 1;
00062 mEncoderDirection[eJOINTNAME_INDEX_1] = -1;
00063 mEncoderDirection[eJOINTNAME_INDEX_2] = 1;
00064 mEncoderDirection[eJOINTNAME_INDEX_3] = 1;
00065 mEncoderDirection[eJOINTNAME_MIDDLE_0] = 1;
00066 mEncoderDirection[eJOINTNAME_MIDDLE_1] = -1;
00067 mEncoderDirection[eJOINTNAME_MIDDLE_2] = 1;
00068 mEncoderDirection[eJOINTNAME_MIDDLE_3] = 1;
00069 mEncoderDirection[eJOINTNAME_PINKY_0] = 1;
00070 mEncoderDirection[eJOINTNAME_PINKY_1] = -1;
00071 mEncoderDirection[eJOINTNAME_PINKY_2] = 1;
00072 mEncoderDirection[eJOINTNAME_PINKY_3] = 1;
00073 mEncoderDirection[eJOINTNAME_THUMB_0] = -1;
00074 mEncoderDirection[eJOINTNAME_THUMB_1] = -1;
00075 mEncoderDirection[eJOINTNAME_THUMB_2] = 1;
00076 mEncoderDirection[eJOINTNAME_THUMB_3] = 1;
00077 
00078 mMotorDirection[eJOINTNAME_INDEX_0] = 1;
00079 mMotorDirection[eJOINTNAME_INDEX_1] = -1;
00080 mMotorDirection[eJOINTNAME_INDEX_2] = 1;
00081 mMotorDirection[eJOINTNAME_INDEX_3] = 1;
00082 mMotorDirection[eJOINTNAME_MIDDLE_0] = 1;
00083 mMotorDirection[eJOINTNAME_MIDDLE_1] = -1;
00084 mMotorDirection[eJOINTNAME_MIDDLE_2] = 1;
00085 mMotorDirection[eJOINTNAME_MIDDLE_3] = 1;
00086 mMotorDirection[eJOINTNAME_PINKY_0] = 1;
00087 mMotorDirection[eJOINTNAME_PINKY_1] = -1;
00088 mMotorDirection[eJOINTNAME_PINKY_2] = 1;
00089 mMotorDirection[eJOINTNAME_PINKY_3] = 1;
00090 mMotorDirection[eJOINTNAME_THUMB_0] = -1;
00091 mMotorDirection[eJOINTNAME_THUMB_1] = -1;
00092 mMotorDirection[eJOINTNAME_THUMB_2] = 1;
00093 mMotorDirection[eJOINTNAME_THUMB_3] = 1;
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151         
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 }
00218 
00219 controlAllegroHand::~controlAllegroHand()
00220 {
00221         PRINT_INFO("Setting System OFF");
00222         _writeDeviceMsg(ID_CMD_SET_SYSTEM_OFF, ID_DEVICE_MAIN, ID_COMMON);
00223         usleep(10000);
00224 
00225         if(CAN_Close(CanHandle))
00226         {
00227                 PRINT_INFO("Error in CAN_Close()");
00228         }
00229 }
00230 
00231 void controlAllegroHand::init(int mode)
00232 {
00233 
00234         unsigned char data[8];
00235         int ret;
00236 
00237         PRINT_INFO("Opening CAN device");
00238 
00239         CanHandle = LINUX_CAN_Open("/dev/pcan32", O_RDWR);
00240         if (!CanHandle)
00241         {
00242                 PRINT_INFO("Error in CAN_Open()");
00243         }
00244 
00245         char txt[VERSIONSTRING_LEN];
00246         ret = CAN_VersionInfo(CanHandle, txt);
00247         if (!ret)
00248         {
00249                 PRINT_INFO(txt);
00250         }
00251         else {
00252                 PRINT_INFO("Error getting CAN_VersionInfo()");
00253         }
00254 
00255         PRINT_INFO("Initializing CAN device");
00256         
00257         ret = CAN_Init(CanHandle, CAN_BAUD_1M, CAN_INIT_TYPE_ST);
00258         if (ret)
00259         {
00260                 PRINT_INFO("Error in CAN_Init()");
00261         }
00262 
00263         
00264         _writeDeviceMsg(ID_CMD_SET_SYSTEM_OFF, ID_DEVICE_MAIN, ID_COMMON);
00265         usleep(10000);
00266 
00267         PRINT_INFO("Setting loop period = 3 ms");
00268         data[0] = (char)(ALLEGRO_CONTROL_TIME_INTERVAL * 1000.);
00269         _writeDeviceMsg(ID_CMD_SET_PERIOD, ID_DEVICE_MAIN, ID_COMMON, 1, data );
00270         usleep(100000);
00271 
00272         PRINT_INFO("Setting task mode");
00273         _writeDeviceMsg(ID_CMD_SET_MODE_TASK, ID_DEVICE_MAIN, ID_COMMON);
00274         usleep(100000);
00275 
00276         PRINT_INFO("Setting joint query command");
00277         _writeDeviceMsg(ID_CMD_QUERY_STATE_DATA, ID_DEVICE_MAIN, ID_COMMON);
00278         usleep(100000);
00279 
00280         PRINT_INFO("Setting System ON");
00281         _writeDeviceMsg(ID_CMD_SET_SYSTEM_ON, ID_DEVICE_MAIN, ID_COMMON);
00282         usleep(100000);
00283 
00284         PRINT_INFO("Clear the CAN buffer");
00285 
00286         while( LINUX_CAN_Read_Timeout(CanHandle, &read_msg, 0) != 0 )
00287         {
00288                 usleep(1000);
00289         }
00290 
00291         
00292         _writeDeviceMsg(ID_CMD_QUERY_STATE_DATA, ID_DEVICE_MAIN, ID_COMMON);
00293 }
00294 
00295 int controlAllegroHand::update(void)
00296 {
00297         _readDevices();
00298         _writeDevices();
00299 
00300         if(mEmergencyStop == true)
00301         {
00302                 return -1;
00303         }
00304         else
00305         {
00306                 return 0;
00307         }
00308 }
00309 
00310 int  controlAllegroHand::command(const short& cmd, const int& arg)
00311 {
00312         return 0;
00313 }
00314 
00315 void controlAllegroHand::setTorque(double *torque)
00316 {
00317         for(int i=0; i<DOF_JOINTS; i++)
00318         {
00319                 desired_torque[i] = torque[i];
00320         }
00321 }
00322 
00323 void controlAllegroHand::getJointInfo(double *position, double *torque)
00324 {
00325         for(int i=0; i<DOF_JOINTS; i++)
00326         {
00327                 position[i] = curr_position[i];
00328                 torque[i] = curr_torque[i];
00329         }
00330 }
00331 
00332 
00333 void controlAllegroHand::_readDevices()
00334 {
00335         double q[4];
00336         char lID;
00337         int ret = 0;
00338         int itr = 0;
00339         static int errorcnt = 0;
00340 
00341         while( true )
00342         {
00343                 
00344                 ret=LINUX_CAN_Read_Timeout(CanHandle, &read_msg, 0); 
00345 
00346                 if (ret)
00347                 {
00348                         
00349                         break;
00350                 }
00351                 else
00352                 {
00353                         lID  = _parseCANMsg(read_msg.Msg, q);
00354                         if( (lID >= ID_DEVICE_SUB_01) && (lID <= ID_DEVICE_SUB_04) )
00355                         {
00356                                 for(int i=0; i<4; i++)
00357                                 {
00358                                         curr_position[i+4*(lID-ID_DEVICE_SUB_01)] = q[i];
00359                                 }
00360                                 itr++;
00361                         }
00362                         if( lID < 0 )
00363                         {
00364                                 mEmergencyStop = true;
00365                         }
00366                 }
00367         }
00368         if( itr < 4)
00369         {
00370                 errorcnt++;
00371                 if( errorcnt > 5 ){
00372                         cout << "read error" << endl;
00373                         mEmergencyStop = true;
00374                 }
00375         }
00376         else{
00377                 errorcnt = 0;
00378         }
00379 
00380 
00381 }
00382 
00383 void controlAllegroHand::_writeDevices()
00384 {
00385         double pwmDouble[DOF_JOINTS];
00386         short pwm[DOF_JOINTS];
00387         unsigned char data[8];
00388 
00389         
00390         for(int i=0; i<DOF_JOINTS; i++ ){
00391                 pwmDouble[i] =  desired_torque[i] *1.0 * (double)mMotorDirection[i] *800.0;
00392 
00393                 mPWM_MAX[i] = 800.0;
00394 
00395                 
00396                 if     ( pwmDouble[i] >  mPWM_MAX[i] )
00397                 {
00398                         pwmDouble[i] =  mPWM_MAX[i];
00399                         cout <<i << " max"<< endl;
00400                 }
00401                 else if( pwmDouble[i] < -mPWM_MAX[i] ) {
00402                         pwmDouble[i] = -mPWM_MAX[i];
00403                         cout <<i<< " min"<< endl;
00404                 }
00405 
00406                 pwm[i] = (short)pwmDouble[i];
00407         }
00408 
00409 
00410         for(int findex=0; findex<4; findex++ ){
00411                 data[0] = (unsigned char)( (pwm[0+findex*4] >> 8) & 0x00ff);
00412                 data[1] = (unsigned char)(  pwm[0+findex*4]       & 0x00ff);
00413                 data[2] = (unsigned char)( (pwm[1+findex*4] >> 8) & 0x00ff);
00414                 data[3] = (unsigned char)(  pwm[1+findex*4]       & 0x00ff);
00415                 data[4] = (unsigned char)( (pwm[2+findex*4] >> 8) & 0x00ff);
00416                 data[5] = (unsigned char)(  pwm[2+findex*4]       & 0x00ff);
00417                 data[6] = (unsigned char)( (pwm[3+findex*4] >> 8) & 0x00ff);
00418                 data[7] = (unsigned char)(  pwm[3+findex*4]       & 0x00ff);
00419 
00420                 _writeDeviceMsg( (unsigned long)(ID_CMD_SET_TORQUE_1 + findex), ID_DEVICE_MAIN, ID_COMMON, 8, data);
00421         }
00422 
00423         
00424         _writeDeviceMsg(ID_CMD_QUERY_STATE_DATA, ID_DEVICE_MAIN, ID_COMMON);
00425 
00426 }
00427 
00428 void controlAllegroHand::_writeDeviceMsg(unsigned long command, unsigned long from, unsigned long to, BYTE len, unsigned char *data)
00429 {
00430         TPCANMsg msg1;
00431         long Txid;
00432 
00433         Txid = ((unsigned long)command<<6) | ((unsigned long)to <<3) | ((unsigned long)from);
00434         msg1.ID  = Txid;
00435         msg1.MSGTYPE  = MSGTYPE_STANDARD;
00436         msg1.LEN  = len;
00437 
00438         for(BYTE i=0; i<len; i++)
00439         {
00440                 msg1.DATA[i] = data[i];
00441         }
00442 
00443         if(CAN_Write(CanHandle, &msg1))
00444         {
00445                 cout << "CAN communication error (write)" << endl;
00446         }
00447 
00448 }
00449 
00450 void controlAllegroHand::_writeDeviceMsg(unsigned long command, unsigned long from, unsigned long to)
00451 {
00452         _writeDeviceMsg(command, from, to, 0, NULL);
00453 }
00454 
00455 
00456 
00457 char controlAllegroHand::_parseCANMsg(TPCANMsg &read_msg,  double *values)
00458 {
00459         char cmd, src, to;
00460         int len;
00461         unsigned char tmpdata[8];
00462         int tmppos[4];
00463         int lIndexBase;
00464 
00465         cmd = (char)( (read_msg.ID >> 6) & 0x1f );
00466         to  = (char)( (read_msg.ID >> 3) & 0x07 );
00467         src = (char)( read_msg.ID & 0x07 );
00468         len = (int)( read_msg.LEN );
00469         for(int nd=0; nd<len; nd++)
00470                 tmpdata[nd] = read_msg.DATA[nd];
00471 
00472         switch (cmd)
00473         {
00474         case ID_CMD_QUERY_STATE_DATA:
00475                 if (src >= ID_DEVICE_SUB_01 && src <= ID_DEVICE_SUB_04)
00476                 {
00477 
00478                         tmppos[0] = (int)(tmpdata[0] | (tmpdata[1] << 8));
00479                         tmppos[1] = (int)(tmpdata[2] | (tmpdata[3] << 8));
00480                         tmppos[2] = (int)(tmpdata[4] | (tmpdata[5] << 8));
00481                         tmppos[3] = (int)(tmpdata[6] | (tmpdata[7] << 8));
00482 
00483                         lIndexBase = 4*(src-ID_DEVICE_SUB_01);
00484 
00485                         
00486                         
00487                         
00488                         
00489                         values[0] = (double)(mEncoderDirection[lIndexBase+0] *tmppos[0] - 32768 - mEncoderOffset[lIndexBase+0]) * ( 333.3 / 65536.0 ) * ( M_PI/180.0);
00490                         values[1] = (double)(mEncoderDirection[lIndexBase+1] *tmppos[1] - 32768 - mEncoderOffset[lIndexBase+1]) * ( 333.3 / 65536.0 ) * ( M_PI/180.0);
00491                         values[2] = (double)(mEncoderDirection[lIndexBase+2] *tmppos[2] - 32768 - mEncoderOffset[lIndexBase+2]) * ( 333.3 / 65536.0 ) * ( M_PI/180.0);
00492                         values[3] = (double)(mEncoderDirection[lIndexBase+3] *tmppos[3] - 32768 - mEncoderOffset[lIndexBase+3]) * ( 333.3 / 65536.0 ) * ( M_PI/180.0);
00493 
00494                         return src;
00495 
00496                 }
00497                 else
00498                 {
00499                         cout << "No subdevice match!" << endl;
00500                         return -1;
00501                 }
00502 
00503                 break;
00504                 
00505         case ID_CMD_QUERY_CONTROL_DATA:
00506                 return 0;
00507                 break;
00508         default:
00509                 printf("unknown command %d, src %d, to %d, len %d \n", cmd, src, to, len);
00510                 
00511 
00512 
00513 
00514 
00515 
00516                 return -1;
00517                 break;
00518         }
00519 
00520 }