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
00054 #include <cob_powercube_chain/PowerCubeCtrl.h>
00055 #include <string>
00056 #include <sstream>
00057 #include <time.h>
00058 #include <cmath>
00059 #ifdef PYTHON_THREAD
00060 #include <Python.h>
00061 #endif
00062
00063
00064 #define DEG 57.295779524
00065 #define MANUAL_AXES0_OFFSET 1.8
00066 #define MANUAL_AXES6_OFFSET 1.5
00067
00068 #define PCTRL_CHECK_INITIALIZED() \
00069 if ( isInitialized()==false ) \
00070 { \
00071 m_ErrorMessage.assign("Manipulator not initialized."); \
00072 return false; \
00073 }
00074
00075 using namespace std;
00076
00077
00078
00079
00080 PowerCubeCtrl::PowerCubeCtrl()
00081 {
00082 m_Dev=0;
00083 m_DOF = 1;
00084 m_CANDeviceOpened = false;
00085 m_Initialized = false;
00086 }
00087
00088
00089 bool PowerCubeCtrl::Init(PowerCubeCtrlParams * params)
00090 {
00091 std::string CanModule = "";
00092 std::string CanDevice = "";
00093 int CanBaudRate = 0;
00094 std::vector<double> offsets;
00095 std::vector<double> upperLimits;
00096 std::vector<double> lowerLimits;
00097 if (params != NULL)
00098 {
00099 m_DOF=params->GetNumberOfDOF();
00100 m_IdModules = params->GetModuleIDVector();
00101 CanModule = params->GetCanModule();
00102 CanDevice = params->GetCanDevice();
00103 CanBaudRate = params->GetBaudRate();
00104 m_maxAcc = params->GetMaxAcc();
00105 upperLimits = params->GetUpperLimits();
00106 lowerLimits = params->GetLowerLimits();
00107 m_maxVel = params->GetMaxVel();
00108 offsets = params->GetAngleOffsets();
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 }
00119 else
00120 {
00121 std::cout <<"PowerCubeCtrl::Init: Error, parameters == NULL"<<endl;
00122 return false;
00123 }
00124 std::cout<<"=========================================================================== "<<endl;
00125 std::cout<<"PowerCubeCtrl:Init: Successfully initialized with the following parameters: "<<endl;
00126 std::cout<<"DOF: "<<m_DOF<<endl;
00127 std::cout<<"CanModule: "<<CanModule<<endl;
00128 std::cout<<"CanDevice: "<<CanDevice<<endl;
00129 std::cout<<"CanBaudRate: "<<CanBaudRate<<endl;
00130 std::cout<<"Ids: ";
00131 for (int i = 0; i< m_DOF; i++)
00132 {
00133 std::cout<<m_IdModules[i]<<" ";
00134 }
00135 std::cout<<endl<<"maxVel: ";
00136 for (int i = 0; i< m_DOF; i++)
00137 {
00138 std::cout<<m_maxVel[i]<<" ";
00139 }
00140 std::cout<<endl<<"maxAcc: ";
00141 for (int i = 0; i< m_DOF; i++)
00142 {
00143 std::cout<<m_maxAcc[i]<<" ";
00144 }
00145 std::cout<<endl<<"upperLimits: ";
00146 for (int i = 0; i< m_DOF; i++)
00147 {
00148 std::cout<<upperLimits[i]<<" ";
00149 }
00150 std::cout<<endl<<"lowerLimits: ";
00151 for (int i = 0; i< m_DOF; i++)
00152 {
00153 std::cout<<lowerLimits[i]<<" ";
00154 }
00155 std::cout<<endl<<"offsets: ";
00156 for (int i = 0; i< m_DOF; i++)
00157 {
00158 std::cout<<offsets[i]<<" ";
00159 }
00160 std::cout<<endl<<"=========================================================================== "<<endl;
00161 ostringstream initStr;
00162 initStr << CanModule << ":" << CanDevice << "," << CanBaudRate;
00163 std::cout << "initstring = " << initStr.str().c_str() << std::endl;
00164 int ret = 0;
00165 ret = PCube_openDevice (&m_Dev, initStr.str().c_str());
00166
00167 if (ret != 0)
00168 {
00169 ostringstream errorMsg;
00170 errorMsg << "Could not open device, m5api error code: " << ret;
00171 m_ErrorMessage = errorMsg.str();
00172 return false;
00173 }
00174 m_CANDeviceOpened = true;
00175
00176 PCube_resetAll(m_Dev);
00177
00178
00179 m_IdModules.clear();
00180
00181 for(int i=0; i<m_DOF; i++)
00182 {
00183
00184
00185 unsigned long serNo;
00186
00187 int ret = PCube_getModuleSerialNo( m_Dev, m_IdModules[i], &serNo );
00188
00189
00190 if( ret != 0 )
00191 {
00192 ostringstream errorMsg;
00193 errorMsg << "Could not find Module with ID " << m_IdModules[i];
00194 m_ErrorMessage = errorMsg.str();
00195 return false;
00196 }
00197
00198
00199 cout << "found module " << m_IdModules[i] << endl;
00200 }
00201
00202 vector<string> errorMessages;
00203 PC_CTRL_STATE status;
00204 getStatus(status, errorMessages);
00205 if ((status != PC_CTRL_OK) && (status != PC_CTRL_NOT_REFERENCED))
00206 {
00207 m_ErrorMessage.assign("");
00208 for (int i=0; i<m_DOF; i++)
00209 {
00210 m_ErrorMessage.append(errorMessages[i]);
00211 m_ErrorMessage.append("\n");
00212 }
00213 return false;
00214 }
00215 else if (status == PC_CTRL_NOT_REFERENCED)
00216 {
00217 std::cout << "PowerCubeCtrl:Init: Homing is executed ...\n";
00218 bool successful = false;
00219 successful = doHoming();
00220 if (!successful)
00221 {
00222 std::cout << "PowerCubeCtrl:Init: homing not successful, aborting ...\n";
00223 return false;
00224 }
00225 }
00226
00227
00228
00229 for (int i = 0; i < m_DOF; i++)
00230 {
00231 PCube_setHomeOffset(m_Dev,m_IdModules[i],offsets[i]);
00232 }
00233
00234
00235 for (int i = 0; i < m_DOF; i++)
00236 {
00237 PCube_setMinPos(m_Dev, m_IdModules[i], lowerLimits[i]);
00238 PCube_setMaxPos(m_Dev, m_IdModules[i], upperLimits[i]);
00239 }
00240
00241
00242 setMaxVelocity(m_maxVel);
00243 setMaxAcceleration(m_maxAcc);
00244
00245
00246 waitForSync();
00247
00248 m_Initialized = true;
00249
00250 return true;
00251 }
00252
00255 PowerCubeCtrl::~PowerCubeCtrl()
00256 {
00257 if (m_CANDeviceOpened)
00258 {
00259 PCube_closeDevice(m_Dev);
00260 }
00261 }
00262
00264 bool PowerCubeCtrl::getConfig(std::vector<double>& result)
00265 {
00266 PCTRL_CHECK_INITIALIZED();
00267
00268 result.resize(m_DOF);
00269
00270 PCube_savePosAll(m_Dev);
00271
00272 for (int i=0; i < m_DOF; i++)
00273 {
00274 float pos;
00275 PCube_getSavePos(m_Dev, m_IdModules[i], &pos);
00276 result[i]=pos;
00277 }
00278
00279 return true;
00280 }
00281
00283 bool PowerCubeCtrl::getJointVelocities(std::vector<double>& result)
00284 {
00285 PCTRL_CHECK_INITIALIZED();
00286
00287 result.resize(m_DOF);
00288
00289 for (int i=0; i < m_DOF; i++)
00290 {
00291 float pos;
00292 PCube_getVel(m_Dev, m_IdModules[i], &pos);
00293 result[i] = pos;
00294 }
00295
00296 return true;
00297 }
00298
00299 bool PowerCubeCtrl::MoveJointSpaceSync(const std::vector<double>& target)
00300 {
00301 PCTRL_CHECK_INITIALIZED();
00302
00303 vector<string> errorMessages;
00304 PC_CTRL_STATE status;
00305 getStatus(status, errorMessages);
00306 if ((status != PC_CTRL_OK))
00307 {
00308 m_ErrorMessage.assign("");
00309 for (int i=0; i<m_DOF; i++)
00310 {
00311 m_ErrorMessage.append(errorMessages[i]);
00312 m_ErrorMessage.append("\n");
00313 }
00314 return false;
00315 }
00316
00317
00318 std::vector<double> acc(m_DOF);
00319 std::vector<double> vel(m_DOF);
00320
00321 double TG = 0;
00322
00323 try
00324 {
00325
00326
00327 int DOF = m_DOF;
00328
00329 std::vector<double> posnow;
00330 if ( getConfig(posnow) == false )
00331 return false;
00332
00333
00334 std::vector<double> velnow;
00335 if ( getJointVelocities(velnow) == false )
00336 return false;
00337
00338 std::vector<double> times(DOF);
00339
00340 for (int i=0; i < DOF; i++)
00341 {
00342 RampCommand rm(posnow[i], velnow[i], target[i], m_maxAcc[i], m_maxVel[i]);
00343 times[i] = rm.getTotalTime();
00344 }
00345
00346
00347 int furthest = 0;
00348
00349 double max = times[0];
00350
00351 for (int i=1; i<m_DOF; i++)
00352 {
00353 if (times[i] > max)
00354 {
00355 max = times[i];
00356 furthest = i;
00357 }
00358 }
00359
00360 RampCommand rm_furthest(posnow[furthest], velnow[furthest], target[furthest], m_maxAcc[furthest], m_maxVel[furthest]);
00361
00362 double T1 = rm_furthest.T1();
00363 double T2 = rm_furthest.T2();
00364 double T3 = rm_furthest.T3();
00365
00366
00367 TG = T1 + T2 + T3;
00368
00369
00370 acc[furthest] = m_maxAcc[furthest];
00371 vel[furthest] = m_maxVel[furthest];
00372
00373 for (int i = 0; i < DOF; i++)
00374 {
00375 if (i != furthest)
00376 {
00377 double a; double v;
00378
00379 RampCommand::calculateAV(
00380 posnow[i],
00381 velnow[i],
00382 target[i],
00383 TG, T3,
00384 m_maxAcc[i],
00385 m_maxVel[i],
00386 a,
00387 v);
00388
00389 acc[i] = a;
00390 vel[i] = v;
00391 }
00392 }
00393 }
00394 catch(...)
00395 {
00396 return false;
00397 }
00398
00399
00400 for (int i=0; i < m_DOF; i++)
00401 {
00402 PCube_moveRamp(m_Dev, m_IdModules[i], target[i], fabs(vel[i]), fabs(acc[i]));
00403 }
00404
00405 PCube_startMotionAll(m_Dev);
00406
00407 return true;
00408 }
00409
00410 bool PowerCubeCtrl::MoveVel(const std::vector<double>& vel)
00411 {
00412 PCTRL_CHECK_INITIALIZED();
00413
00414 vector<string> errorMessages;
00415 PC_CTRL_STATE status;
00416 getStatus(status, errorMessages);
00417 if ((status != PC_CTRL_OK))
00418 {
00419 m_ErrorMessage.assign("");
00420 for (int i=0; i<m_DOF; i++)
00421 {
00422 m_ErrorMessage.append(errorMessages[i]);
00423 m_ErrorMessage.append("\n");
00424 }
00425 return false;
00426 }
00427
00428 for (int i=0; i < m_DOF; i++)
00429 {
00430 PCube_moveVel(m_Dev, m_IdModules[i], vel[i] );
00431 }
00432 PCube_startMotionAll(m_Dev);
00433
00434 return true;
00435 }
00436
00437
00439 bool PowerCubeCtrl::Stop()
00440 {
00441
00442 PCube_haltAll(m_Dev);
00443
00444
00445
00446
00447 millisleep(50);
00448
00449 PCube_resetAll(m_Dev);
00450
00451 return true;
00452 }
00453
00456 bool PowerCubeCtrl::setMaxVelocity(double radpersec)
00457 {
00458 PCTRL_CHECK_INITIALIZED();
00459 for (int i=0; i<m_DOF; i++)
00460 {
00461 m_maxVel[i] = radpersec;
00462 PCube_setMaxVel(m_Dev, m_IdModules[i], radpersec);
00463 }
00464
00465 return true;
00466 }
00467
00468 bool PowerCubeCtrl::setMaxVelocity(const std::vector<double>& radpersec)
00469 {
00470 PCTRL_CHECK_INITIALIZED();
00471
00472 for (int i=0; i<m_DOF; i++)
00473 {
00474 m_maxVel[i] = radpersec[i];
00475 PCube_setMaxVel(m_Dev, m_IdModules[i], radpersec[i]);
00476 }
00477
00478 return true;
00479 }
00480
00483 bool PowerCubeCtrl::setMaxAcceleration(double radPerSecSquared)
00484 {
00485 PCTRL_CHECK_INITIALIZED();
00486
00487 for (int i=0; i<m_DOF; i++)
00488 {
00489 m_maxAcc[i] = radPerSecSquared;
00490 PCube_setMaxAcc(m_Dev, m_IdModules[i], radPerSecSquared);
00491 }
00492
00493 return true;
00494 }
00495
00496 bool PowerCubeCtrl::setMaxAcceleration(const std::vector<double>& radPerSecSquared)
00497 {
00498 PCTRL_CHECK_INITIALIZED();
00499
00500 for (int i=0; i<m_DOF; i++)
00501 {
00502 m_maxAcc[i] = radPerSecSquared[i];
00503 PCube_setMaxAcc(m_Dev, m_IdModules[i], radPerSecSquared[i]);
00504 }
00505
00506 return true;
00507 }
00508
00509
00510
00512 bool PowerCubeCtrl::statusMoving()
00513 {
00514 PCTRL_CHECK_INITIALIZED();
00515
00516 for(int i=0; i<m_DOF; i++)
00517 {
00518 unsigned long status;
00519
00520 PCube_getModuleState(m_Dev,m_IdModules[i], &status);
00521
00522 if (status & STATEID_MOD_MOTION)
00523 return true;
00524 }
00525 return false;
00526 }
00527
00529 bool PowerCubeCtrl::statusDec()
00530 {
00531 PCTRL_CHECK_INITIALIZED();
00532
00533 for (int i=0; i<m_DOF; i++)
00534 {
00535 unsigned long status;
00536
00537 PCube_getModuleState(m_Dev,m_IdModules[i], &status);
00538
00539 if (status & STATEID_MOD_RAMP_DEC)
00540 return true;
00541 }
00542 return false;
00543 }
00544
00545
00547 bool PowerCubeCtrl::statusAcc()
00548 {
00549 PCTRL_CHECK_INITIALIZED();
00550
00551 for (int i=0; i<m_DOF; i++)
00552 {
00553 unsigned long status;
00554
00555 PCube_getModuleState(m_Dev,m_IdModules[i], &status);
00556
00557 if (status & STATEID_MOD_RAMP_ACC)
00558 return true;
00559 }
00560 return false;
00561 }
00562
00564 bool PowerCubeCtrl::doHoming()
00565 {
00566
00567
00568 for(int i=0; i<m_DOF; i++)
00569 {
00570 cout << "Module " << m_IdModules[i] << " homed" << endl;
00571 PCube_homeModule(m_Dev, m_IdModules[i]);
00572 }
00573
00574 return true;
00575 }
00576
00579 bool PowerCubeCtrl::HomingDone()
00580 {
00581 PCTRL_CHECK_INITIALIZED();
00582
00583 for(int i=0; i<m_DOF; i++)
00584 {
00585 unsigned long int help;
00586 do
00587 {
00588 PCube_getModuleState(m_Dev, m_IdModules[i], &help);
00589
00590 millisleep(100);
00591 } while ( (help & STATEID_MOD_HOME) == 0 );
00592 }
00593
00594 return true;
00595 }
00596
00597 bool PowerCubeCtrl::waitForSync()
00598 {
00599 if (m_CANDeviceOpened)
00600 {
00601 for (int i=0; i < m_DOF; i++)
00602 {
00603 unsigned long confword;
00604
00605 PCube_getConfig(m_Dev, m_IdModules[i], &confword );
00606 PCube_setConfig(m_Dev, m_IdModules[i], confword | CONFIGID_MOD_SYNC_MOTION);
00607 }
00608 return true;
00609 }
00610 else
00611 {
00612 return false;
00613 }
00614 }
00615
00616 bool PowerCubeCtrl::dontWaitForSync()
00617 {
00618 if (m_CANDeviceOpened)
00619 {
00620 for (int i=0; i < m_DOF; i++)
00621 {
00622 unsigned long confword;
00623
00624 PCube_getConfig(m_Dev, m_IdModules[i], &confword );
00625 PCube_setConfig(m_Dev, m_IdModules[i], confword & (~CONFIGID_MOD_SYNC_MOTION));
00626 }
00627 return true;
00628 }
00629 else
00630 {
00631 return false;
00632 }
00633 }
00634
00635 bool PowerCubeCtrl::getStatus(PC_CTRL_STATE& error, vector<string>& errorMessages)
00636 {
00637 errorMessages.clear();
00638 errorMessages.resize(m_DOF);
00639
00640 error = PC_CTRL_OK;
00641
00642 for(int i=0; i<m_DOF; i++)
00643 {
00644 unsigned long int state;
00645
00646 PCube_getModuleState(m_Dev, m_IdModules[i], &state);
00647
00648 if (state & STATEID_MOD_POW_VOLT_ERR)
00649 {
00650 ostringstream errorMsg;
00651 errorMsg << "Error in Module " << m_IdModules[i] << ": ";
00652 errorMsg << "Motor voltage below minimum value!";
00653 errorMessages[i] = errorMsg.str();
00654 error = PC_CTRL_POW_VOLT_ERR;
00655 }
00656 else if (!(state & STATEID_MOD_HOME))
00657 {
00658 ostringstream errorMsg;
00659 errorMsg << "Warning: Module " << m_IdModules[i];
00660 errorMsg << " is not referenced!";
00661 errorMessages[i] = errorMsg.str();
00662 error = PC_CTRL_NOT_REFERENCED;
00663 }
00664 else if (state & STATEID_MOD_ERROR)
00665 {
00666 ostringstream errorMsg;
00667 errorMsg << "Error in Module " << m_IdModules[i];
00668 errorMsg << " : Status code: " << hex << state;
00669 errorMessages[i] = errorMsg.str();
00670 error = PC_CTRL_ERR;
00671 }
00672 else
00673 {
00674 ostringstream errorMsg;
00675 errorMsg << "Module with Id " << m_IdModules[i];
00676 errorMsg << ": Status OK.";
00677 errorMessages[i] = errorMsg.str();
00678 }
00679 }
00680 return true;
00681 }
00682
00683 bool PowerCubeCtrl::Close()
00684 {
00685 if (m_CANDeviceOpened)
00686 {
00687 m_Initialized = false;
00688 m_CANDeviceOpened = false;
00689
00690 PCube_closeDevice(m_Dev);
00691
00692 return true;
00693 }
00694 else
00695 {
00696 return false;
00697 }
00698 }
00699
00700 void PowerCubeCtrl::millisleep(unsigned int milliseconds) const
00701 {
00702 timespec warten;
00703
00704 warten.tv_sec = milliseconds / 1000;
00705 warten.tv_nsec = (milliseconds % 1000) * 1000000;
00706 timespec gewartet;
00707 nanosleep(&warten, &gewartet);
00708 }
00709
00710 bool PowerCubeCtrl::Recover()
00711 {
00712
00713 vector<string> errorMessages;
00714 PC_CTRL_STATE status;
00715 getStatus(status, errorMessages);
00716 if (status == PC_CTRL_NOT_REFERENCED)
00717 {
00718 std::cout << "PowerCubeCtrl:Init: Homing is executed ...\n";
00719 bool successful = false;
00720 successful = doHoming();
00721 if (!successful)
00722 {
00723 std::cout << "PowerCubeCtrl:Init: homing not successful, aborting ...\n";
00724 }
00725 }
00726 PCube_resetAll(m_Dev);
00727
00728 getStatus(status, errorMessages);
00729 if ((status != PC_CTRL_OK))
00730 {
00731 m_ErrorMessage.assign("");
00732 for (int i=0; i<m_DOF; i++)
00733 {
00734 m_ErrorMessage.append(errorMessages[i]);
00735 m_ErrorMessage.append("\n");
00736 }
00737 return false;
00738 }
00739 else
00740 {
00741 return true;
00742 }
00743
00744
00745 }