00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include <cob_camera_axis/ElmoCtrl.h>
00054
00055 #include <iostream>
00056
00057 using namespace std;
00058
00059 void Sleep(int msecs){usleep(1000*msecs);}
00060
00061 bool ElmoCtrl::sendNetStartCanOpen(CanItf* canCtrl) {
00062 bool ret = false;
00063
00064 CanMsg msg;
00065
00066 msg.m_iID = 0;
00067 msg.m_iLen = 2;
00068 msg.set(1,0,0,0,0,0,0,0);
00069 ret = canCtrl->transmitMsg(msg, false);
00070
00071 usleep(100000);
00072
00073 return ret;
00074 }
00075
00076
00077 ElmoCtrl::ElmoCtrl() {
00078 m_Joint = NULL;
00079 m_JointParams = NULL;
00080 m_CanCtrl = NULL;
00081 m_CanBaseAddress = NULL;
00082 m_MotionCtrlType = POS_CTRL;
00083 m_MaxVel = 2.0;
00084 m_Params = NULL;
00085 }
00086
00087 ElmoCtrl::~ElmoCtrl() {
00088 if (m_Joint)
00089 m_Joint->shutdown();
00090 delete m_Joint;
00091 if (m_JointParams)
00092 delete m_JointParams;
00093 if (m_CanCtrl)
00094 delete m_CanCtrl;
00095 }
00096
00097 bool ElmoCtrl::Home()
00098 {
00099 bool success = false;
00100 if (m_Joint != NULL) {
00101
00102
00103 m_Joint->IntprtSetInt(8, 'I', 'L', 2, 7);
00104 usleep(20000);
00105
00106
00107
00108 m_Joint->IntprtSetInt(8, 'I', 'L', 1, 6);
00109 usleep(20000);
00110
00111 m_Joint->initHoming();
00112 }
00113
00114
00115 Sleep(10);
00116 printf("ElmoCtrl: Home(): Homing Vel = %f\n",m_HomingDir*0.3);
00117 m_Joint->setGearVelRadS(m_HomingDir*0.3);
00118
00119 Sleep(750);
00120 success = m_Joint->execHoming();
00121 m_Joint->setGearVelRadS(0.0);
00122
00123 return success;
00124 }
00125
00126
00127 int ElmoCtrl::evalCanBuffer() {
00128 bool bRet;
00129
00130
00131
00132
00133 while(m_CanCtrl->receiveMsg(&m_CanMsgRec) == true) {
00134 bRet = false;
00135
00136 bRet |= m_Joint->evalReceivedMsg(m_CanMsgRec);
00137
00138 if (bRet == true) {
00139 } else std::cout << "cob_camera_axis: Unknown CAN-msg: " << m_CanMsgRec.m_iID << " " << (int)m_CanMsgRec.getAt(0) << " " << (int)m_CanMsgRec.getAt(1) << std::endl;
00140 }
00141
00142
00143
00144 return 0;
00145 }
00146
00147 bool ElmoCtrl::RecoverAfterEmergencyStop() {
00148
00149 bool success = false;
00150 printf("Resetting motor ...\n");
00151 success = m_Joint->start();
00152 if (!success) {
00153 printf("failed!\n");
00154 } else {
00155 printf("successful\n");
00156 m_Joint->setGearVelRadS(0);
00157 }
00158 Sleep(1000);
00159 return success;
00160 }
00161
00162
00163 bool ElmoCtrl::Init(ElmoCtrlParams * params, bool home) {
00164 bool success = false;
00165 string CanIniFile;
00166 string CanDevice;
00167 int baudrate = 0;
00168
00169 m_Params = params;
00170
00171 if (params == NULL) {
00172 printf("ElmoCtrlParams:Error:%s:%d:, invalid parameters!\n",__FILE__,__LINE__);
00173 success = false;
00174 } else {
00175 success = true;
00176 }
00177
00178 if (success) {
00179 printf( "------------ ElmoCtrl Init ---------------\n");
00180
00181
00182 m_Joint = new CanDriveHarmonica();
00183 m_JointParams = new DriveParam();
00184 m_CanBaseAddress = params->GetModuleID();
00185 CanIniFile = params->GetCanIniFile();
00186 m_MaxVel = params->GetMaxVel();
00187 m_HomingDir = params->GetHomingDir();
00188 m_HomingDigIn = params->GetHomingDigIn();
00189
00190 m_EncIncrPerRevMot = params->GetEncoderIncrements();
00191 m_MotorDirection = params->GetMotorDirection();
00192 m_GearRatio = params->GetGearRatio();
00193
00194 if (CanIniFile.length() == 0) {
00195 printf("%s,%d:Error: Parameter 'CanIniFile' not given!\n",__FILE__,__LINE__);
00196 success = false;
00197 }
00198
00199 CanDevice = params->GetCanDevice();
00200 if (CanDevice.length() == 0) {
00201 printf("%s,%d:Error: Parameter 'Can-Device' not given!\n",__FILE__,__LINE__);
00202 success = false;
00203 }
00204
00205 baudrate = params->GetBaudRate();
00206 if (baudrate == 0) {
00207 printf("%s,%d:Error: Parameter 'Baud-Rate' not given!\n",__FILE__,__LINE__);
00208 success = false;
00209 }
00210
00211
00212 if (success) {
00213 m_JointOffset = params->GetAngleOffset();
00214 m_UpperLimit = params->GetUpperLimit();
00215 m_LowerLimit = params->GetLowerLimit();
00216 }
00217
00218 if (success) {
00219 printf("The following parameters were successfully read from the parameter server (given through *params): \n");
00220 printf("CanIniFile: %s\n",CanIniFile.c_str());
00221 printf("CanDieODvice: %s\n",CanDevice.c_str());
00222 printf("Baudrate: %d\n",baudrate);
00223 printf("Module ID: %d\n",m_CanBaseAddress);
00224 printf("Max Vel: %f\n",m_MaxVel);
00225 printf("Homing Dir: %d\n",m_HomingDir);
00226 printf("HomingDigIn: %d\n",m_HomingDigIn);
00227 printf("Offset/Limit(min/max) %f/(%f,%f)\n",m_JointOffset,m_LowerLimit,m_UpperLimit);
00228 }
00229 }
00230
00231
00232
00233 if (success) {
00234
00235 m_CanCtrl = new CANPeakSysUSB(CanIniFile.c_str());
00236 if (m_CanCtrl == NULL) {
00237 printf("%s,%d:Error: Could not open Can Device!\n",__FILE__,__LINE__);
00238 success = false;
00239 }
00240 }
00241
00242 if (success) {
00243
00244
00245
00246
00247
00248
00249
00250
00251 m_CanAddress.TxPDO1 = 0x181 + m_CanBaseAddress -1;
00252 m_CanAddress.TxPDO2 = 0x281 + m_CanBaseAddress -1;
00253 m_CanAddress.RxPDO2 = 0x301 + m_CanBaseAddress -1;
00254 m_CanAddress.TxSDO = 0x581 + m_CanBaseAddress -1;
00255 m_CanAddress.RxSDO = 0x601 + m_CanBaseAddress -1;
00256 m_Joint->setCanItf(m_CanCtrl);
00257 m_Joint->setCanOpenParam(m_CanAddress.TxPDO1,
00258 m_CanAddress.TxPDO2,
00259 m_CanAddress.RxPDO2,
00260 m_CanAddress.TxSDO,
00261 m_CanAddress.RxSDO );
00262
00263 printf("CanAdresses set to %d (Base), %x, %x, %x, %x, %x...\n", m_CanBaseAddress,
00264 m_CanAddress.TxPDO1,
00265 m_CanAddress.TxPDO2,
00266 m_CanAddress.RxPDO2,
00267 m_CanAddress.TxSDO,
00268 m_CanAddress.RxSDO);
00269
00270 }
00271
00272 if (success) {
00273 success = sendNetStartCanOpen(m_CanCtrl);
00274 }
00275
00276 if (success) {
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 m_JointParams->setParam(
00315 0,
00316 m_EncIncrPerRevMot,
00317 1,
00318 1,
00319 m_GearRatio,
00320 m_MotorDirection,
00321 74000000,
00322 1000000,
00323 1000000,
00324 0,
00325 true,
00326 0,
00327 0,
00328 m_HomingDigIn
00329 );
00330
00331
00332 m_Joint->setDriveParam(*m_JointParams);
00333 }
00334
00335 if (success)
00336 {
00337 printf("Init motor ...\n");
00338 success = m_Joint->init();
00339 if (!success)
00340 {
00341 printf("failed!\n");
00342 }
00343 else
00344 {
00345 printf("successful\n");
00346 }
00347 }
00348
00349 if (success)
00350 success = SetMotionCtrlType(m_MotionCtrlType);
00351 if(!success) std::cout << "Failed to SetMotionCtrlType to " << m_MotionCtrlType << std::endl;
00352
00353 if (success)
00354 {
00355 printf("Starting motor ..\n");
00356 success = m_Joint->start();
00357 if (!success)
00358 {
00359 printf("failed!\n");
00360 }
00361 else
00362 {
00363 printf("successful\n");
00364 m_Joint->setGearVelRadS(0);
00365 }
00366 }
00367
00368 Sleep(1000);
00369
00370 if (success && home)
00371 {
00372 std::cout << "Start homing procedure now.." << std::endl;
00373 success = Home();
00374 }
00375
00376 if (success)
00377 {
00378 pthread_mutex_init(&m_Mutex,NULL);
00379 }
00380
00381
00382 return success;
00383 }
00384
00385 bool ElmoCtrl::SetMotionCtrlType(int type)
00386 {
00387 m_MotionCtrlType = type;
00388 bool success = false;
00389 if (type == POS_CTRL)
00390 {
00391 success = m_Joint->shutdown();
00392 if (success)
00393 success = m_Joint->setTypeMotion(CanDriveHarmonica::MOTIONTYPE_POSCTRL);
00394
00395
00396 Sleep(100);
00397 success = m_Joint->start();
00398
00399 }
00400 else if (type == VEL_CTRL)
00401 {
00402
00403 printf("%s%d:Error: Velocity control not implemented yet!\n",__FILE__,__LINE__);
00404 success = false;
00405 }
00406 return success;
00407 };
00408
00409
00410 int ElmoCtrl::GetMotionCtrlType()
00411 {
00412 return m_MotionCtrlType;
00413 }
00414
00415 int ElmoCtrl::getGearPosVelRadS( double* pdAngleGearRad, double* pdVelGearRadS)
00416 {
00417
00418
00419 *pdAngleGearRad = 0;
00420 *pdVelGearRadS = 0;
00421
00422 m_Joint->getGearPosVelRadS(pdAngleGearRad, pdVelGearRadS);
00423 *pdAngleGearRad = *pdAngleGearRad - m_JointOffset;
00424
00425 return 0;
00426 }
00427
00428
00429
00430 int ElmoCtrl:: setGearPosVelRadS(double dPosRad, double dVelRadS)
00431 {
00432
00433 if(dPosRad< m_LowerLimit) {
00434 std::cout << "Position under LowerBound -> set up" << std::endl;
00435 dPosRad = m_LowerLimit;
00436 } else if(dPosRad > m_UpperLimit) {
00437 std::cout << "Position over UpperBound -> set down" << std::endl;
00438 dPosRad = m_UpperLimit;
00439 }
00440
00441 if(dVelRadS > m_MaxVel)
00442 dVelRadS = m_MaxVel;
00443 else if(dVelRadS < -m_MaxVel)
00444 dVelRadS = -m_MaxVel;
00445
00446
00447
00448
00449 printf("ElmoCtrl:setGearPosVelRadS: dPosRad %f with vel %f\n",dPosRad, dVelRadS);
00450 m_Joint->setGearPosVelRadS(m_HomingDir * dPosRad + m_JointOffset, dVelRadS);
00451 return 0;
00452 }
00453
00454 bool ElmoCtrl::Stop()
00455 {
00456
00457 double pos = 0.0;
00458 double vel = 0.0;
00459 m_Joint->getGearPosVelRadS(&pos,&vel);
00460 m_Joint->setGearPosVelRadS(pos,0);
00461
00462 return true;
00463
00464
00465 }