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