00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ros/ros.h>
00020
00021
00022 #include <schunk_powercube_chain/PowerCubeCtrl.h>
00023
00024 #define PCTRL_CHECK_INITIALIZED() \
00025 if (isInitialized() == false) \
00026 { \
00027 m_ErrorMessage.assign("Manipulator not initialized."); \
00028 return false; \
00029 }
00030
00031 #define Ready4MoveStep 4638
00032
00033
00034
00035
00036 PowerCubeCtrl::PowerCubeCtrl(PowerCubeCtrlParams* params)
00037 {
00038 m_mutex = PTHREAD_MUTEX_INITIALIZER;
00039
00040 m_CANDeviceOpened = false;
00041 m_Initialized = false;
00042
00043 m_params = params;
00044
00045 m_horizon = 0.01;
00046
00047 m_last_time_pub = ros::Time::now();
00048
00049 m_pc_status = PC_CTRL_OK;
00050 }
00051
00052
00053
00054
00055 PowerCubeCtrl::~PowerCubeCtrl()
00056 {
00057
00058 Stop();
00059
00060
00061 if (m_CANDeviceOpened)
00062 {
00063 pthread_mutex_lock(&m_mutex);
00064 PCube_closeDevice(m_DeviceHandle);
00065 pthread_mutex_unlock(&m_mutex);
00066 }
00067 }
00068
00070
00075 bool PowerCubeCtrl::Init(PowerCubeCtrlParams* params)
00076 {
00077 int ret = 0;
00078 int DOF = m_params->GetDOF();
00079 std::string CanModule = m_params->GetCanModule();
00080 std::string CanDevice = m_params->GetCanDevice();
00081 std::vector<int> ModulIDs = m_params->GetModuleIDs();
00082 int CanBaudrate = m_params->GetBaudrate();
00083 std::vector<double> MaxVel = m_params->GetMaxVel();
00084 std::vector<double> MaxAcc = m_params->GetMaxAcc();
00085 std::vector<double> Offsets = m_params->GetOffsets();
00086 std::vector<double> LowerLimits = m_params->GetLowerLimits();
00087 std::vector<double> UpperLimits = m_params->GetUpperLimits();
00088
00090 std::cout << " D O F :" << DOF << std::endl;
00091 m_status.resize(DOF);
00092 m_ModuleTypes.resize(DOF);
00093 m_version.resize(DOF);
00094 m_dios.resize(DOF);
00095 m_positions.resize(DOF);
00096 m_velocities.resize(DOF);
00097
00098 std::cout << "=========================================================================== " << std::endl;
00099 std::cout << "PowerCubeCtrl:Init: Trying to initialize with the following parameters: " << std::endl;
00100 std::cout << "DOF: " << DOF << std::endl;
00101 std::cout << "CanModule: " << CanModule << std::endl;
00102 std::cout << "CanDevice: " << CanDevice << std::endl;
00103 std::cout << "CanBaudrate: " << CanBaudrate << std::endl;
00104 std::cout << "ModulIDs: ";
00105 for (int i = 0; i < DOF; i++)
00106 {
00107 std::cout << ModulIDs[i] << " ";
00108 }
00109 std::cout << std::endl;
00110
00111 std::cout << std::endl << "maxVel: ";
00112 for (int i = 0; i < DOF; i++)
00113 {
00114 std::cout << MaxVel[i] << " ";
00115 }
00116
00117 std::cout << std::endl << "maxAcc: ";
00118 for (int i = 0; i < DOF; i++)
00119 {
00120 std::cout << MaxAcc[i] << " ";
00121 }
00122
00123 std::cout << std::endl << "upperLimits: ";
00124 for (int i = 0; i < DOF; i++)
00125 {
00126 std::cout << UpperLimits[i] << " ";
00127 }
00128
00129 std::cout << std::endl << "lowerLimits: ";
00130 for (int i = 0; i < DOF; i++)
00131 {
00132 std::cout << LowerLimits[i] << " ";
00133 }
00134
00135 std::cout << std::endl << "offsets: ";
00136 for (int i = 0; i < DOF; i++)
00137 {
00138 std::cout << Offsets[i] << " ";
00139 }
00140
00141 std::cout << std::endl << "=========================================================================== " << std::endl;
00142 std::ostringstream InitStr;
00143 InitStr << CanModule << ":" << CanDevice << "," << CanBaudrate;
00144 std::cout << "initstring = " << InitStr.str().c_str() << std::endl;
00145
00147 pthread_mutex_lock(&m_mutex);
00148 ret = PCube_openDevice(&m_DeviceHandle, InitStr.str().c_str());
00149 pthread_mutex_unlock(&m_mutex);
00150 if (ret != 0)
00151 {
00152 std::ostringstream errorMsg;
00153 errorMsg << "Could not open device " << CanDevice << ", m5api error code: " << ret;
00154 m_ErrorMessage = errorMsg.str();
00155 return false;
00156 }
00157
00158 m_CANDeviceOpened = true;
00159
00161 int max_tries = 3;
00162 for (int i = 0; i < DOF; i++)
00163 {
00164 for (int reset_try = 0; reset_try < max_tries; reset_try++)
00165 {
00166 pthread_mutex_lock(&m_mutex);
00167 ret = PCube_resetModule(m_DeviceHandle, ModulIDs.at(i));
00168 pthread_mutex_unlock(&m_mutex);
00169
00170 if (ret == 0)
00171 {
00172 break;
00173 }
00174 else if ((ret != 0) && (reset_try == (max_tries - 1)))
00175 {
00176 std::ostringstream errorMsg;
00177 errorMsg << "Could not reset module " << ModulIDs.at(i) << " during init. Errorcode during reset: " << ret << " Try to init once more.";
00178 m_ErrorMessage = errorMsg.str();
00179 return false;
00180 }
00181 else
00182 {
00183
00184 usleep(1500000);
00185 }
00186 }
00187 }
00188 std::cout << "number of moduleIDs" << ModulIDs.size() << std::endl;
00189
00191 pthread_mutex_lock(&m_mutex);
00192 int number_of_modules = PCube_getModuleCount(m_DeviceHandle);
00193 pthread_mutex_unlock(&m_mutex);
00194 std::cout << "found " << number_of_modules << " modules." << std::endl;
00195
00197 for (int i = 0; i < DOF; i++)
00198 {
00199 unsigned long serNo;
00200 unsigned short verNo;
00201 unsigned long defConfig;
00202 std::vector<std::string> Module_Types;
00203
00205 pthread_mutex_lock(&m_mutex);
00206 ret = PCube_getModuleSerialNo(m_DeviceHandle, ModulIDs[i], &serNo);
00207 pthread_mutex_unlock(&m_mutex);
00208 if (ret != 0)
00209 {
00210 std::ostringstream errorMsg;
00211 errorMsg << "Could not find Module with ID " << ModulIDs[i] << ", m5api error code: " << ret;
00212 m_ErrorMessage = errorMsg.str();
00213 return false;
00214 }
00215
00217 pthread_mutex_lock(&m_mutex);
00218 ret = PCube_getModuleVersion(m_DeviceHandle, ModulIDs[i], &verNo);
00219 pthread_mutex_unlock(&m_mutex);
00220 if (ret != 0)
00221 {
00222 std::ostringstream errorMsg;
00223 errorMsg << "Could not find Module with ID " << ModulIDs[i] << ", m5api error code: " << ret;
00224 m_ErrorMessage = errorMsg.str();
00225 return false;
00226 }
00227 else
00228 {
00229 m_version[i] = verNo;
00230 }
00231
00233 float gear_ratio;
00234 pthread_mutex_lock(&m_mutex);
00235 ret = PCube_getDefGearRatio(m_DeviceHandle, ModulIDs[i], &gear_ratio);
00236 pthread_mutex_unlock(&m_mutex);
00237 if (ret != 0)
00238 {
00239 std::ostringstream errorMsg;
00240 errorMsg << "Could not get Module type with ID " << ModulIDs[i] << ", m5api error code: " << ret;
00241 m_ErrorMessage = errorMsg.str();
00242 return false;
00243 }
00244 else
00245 {
00246 if (true)
00247 {
00248 std::cout << "gear ratio: " << gear_ratio << std::endl;
00249
00250 }
00251 }
00252
00254 unsigned char type;
00255 pthread_mutex_lock(&m_mutex);
00256 ret = PCube_getModuleType(m_DeviceHandle, ModulIDs[i], &type);
00257 pthread_mutex_unlock(&m_mutex);
00258 if (ret != 0)
00259 {
00260 std::ostringstream errorMsg;
00261 errorMsg << "Could not get Module type with ID " << ModulIDs[i] << ", m5api error code: " << ret;
00262 m_ErrorMessage = errorMsg.str();
00263 return false;
00264 }
00265 else
00266 {
00267 if (type != TYPEID_MOD_ROTARY)
00268 {
00269 std::cout << "wrong module type configured. Type must be rotary axis. Use Windows configuration software to change type." << std::endl;
00270 return false;
00271 }
00272 }
00273
00275
00276 pthread_mutex_lock(&m_mutex);
00277 ret = PCube_getDefSetup(m_DeviceHandle, ModulIDs[i], &defConfig);
00278 pthread_mutex_unlock(&m_mutex);
00279
00280 ROS_DEBUG("module type check: %li (std::dec)", defConfig);
00281
00282 if (ret != 0)
00283 {
00284 std::ostringstream errorMsg;
00285 errorMsg << "Error on communication with module " << ModulIDs[i] << ", m5api error code: " << ret;
00286 m_ErrorMessage = errorMsg.str();
00287 return false;
00288 }
00289
00290
00291
00292
00293
00294 if (((defConfig & CONFIG_ABSOLUTE_FEEDBACK) == CONFIG_ABSOLUTE_FEEDBACK) ||
00295 ((defConfig & CONFIG_RESOLVER_FEEDBACK) == CONFIG_RESOLVER_FEEDBACK))
00296 {
00297 m_ModuleTypes[i] = "PRL";
00298 ROS_DEBUG("Module %i is from type: PRL", i);
00299 }
00300 else
00301 {
00302 m_ModuleTypes[i] = "PW";
00303 ROS_DEBUG("Module %i is from type: PW", i);
00304 }
00305
00307 std::cout << "Found module " << std::dec << ModulIDs[i] << " Serial: " << serNo << " Version: " << std::hex << verNo << std::endl;
00308 }
00309
00310
00311 m_pc_status = PC_CTRL_OK;
00312 m_Initialized = true;
00313
00315 std::vector<std::string> errorMessages;
00316 PC_CTRL_STATUS status;
00317
00318
00319 updateStates();
00320
00321
00322 getStatus(status, errorMessages);
00323
00324
00325 bool successful = false;
00326 successful = doHoming();
00327 if (!successful)
00328 {
00329 std::cout << "PowerCubeCtrl:Init: homing not successful, aborting ...\n";
00330 return false;
00331 }
00332
00333
00334 m_pc_status = PC_CTRL_OK;
00335 return true;
00336 }
00337
00341 bool PowerCubeCtrl::Close()
00342 {
00343 if (m_CANDeviceOpened)
00344 {
00345 m_Initialized = false;
00346 m_CANDeviceOpened = false;
00347
00348 pthread_mutex_lock(&m_mutex);
00349 PCube_closeDevice(m_DeviceHandle);
00350 pthread_mutex_unlock(&m_mutex);
00351
00352 return true;
00353 }
00354
00355 else
00356 {
00357 return false;
00358 }
00359 }
00360
00366 bool PowerCubeCtrl::MoveJointSpaceSync(const std::vector<double>& target_pos)
00367 {
00368 PCTRL_CHECK_INITIALIZED();
00369
00370 unsigned int DOF = m_params->GetDOF();
00371 std::vector<int> ModulIDs = m_params->GetModuleIDs();
00372
00373 std::vector<double> m_maxVel = m_params->GetMaxVel();
00374 std::vector<double> m_maxAcc = m_params->GetMaxAcc();
00375
00376 std::cout << "Starting MoveJointSpaceSync(Jointd Angle) ... " << std::endl;
00377
00378
00379 std::vector<double> acc(DOF);
00380 std::vector<double> vel(DOF);
00381 std::vector<double> posnow(DOF);
00382 std::vector<double> velnow(DOF);
00383 double TG = 0;
00384
00385 try
00386 {
00387
00388 if (!getJointAngles(posnow))
00389 {
00390 return false;
00391 }
00392
00393 if (!getJointVelocities(velnow))
00394 {
00395 return false;
00396 }
00397
00398 std::vector<double> times(DOF);
00399 for (int i = 0; i < DOF; i++)
00400 {
00401 RampCommand rm(posnow[i], velnow[i], target_pos[i], m_maxAcc[i], m_maxVel[i]);
00402 times[i] = rm.getTotalTime();
00403 }
00404
00405
00406 int furthest = 0;
00407 double max = times[0];
00408 for (int i = 1; i < DOF; i++)
00409 {
00410 if (times[i] > max)
00411 {
00412 max = times[i];
00413 furthest = i;
00414 }
00415 }
00416
00417 RampCommand rm_furthest(posnow[furthest], velnow[furthest], target_pos[furthest], m_maxAcc[furthest], m_maxVel[furthest]);
00418
00419 double T1 = rm_furthest.T1();
00420 double T2 = rm_furthest.T2();
00421 double T3 = rm_furthest.T3();
00422
00423 TG = T1 + T2 + T3;
00424
00425 acc[furthest] = m_maxAcc[furthest];
00426 vel[furthest] = m_maxVel[furthest];
00427
00428 for (int i = 0; i < DOF; i++)
00429 {
00430 if (i != furthest)
00431 {
00432 double a;
00433 double v;
00434
00435 RampCommand::calculateAV(
00436 posnow[i],
00437 velnow[i],
00438 target_pos[i],
00439 TG, T3,
00440 m_maxAcc[i],
00441 m_maxVel[i],
00442 a,
00443 v);
00444
00445 acc[i] = a;
00446 vel[i] = v;
00447
00448
00449 }
00450 }
00451 }
00452 catch (...)
00453 {
00454 return false;
00455 }
00456
00457
00458 std::ostringstream errorMsg;
00459 int ret = 0;
00460 bool ok = true;
00461
00462
00463 for (int i = 0; i < DOF; i++)
00464 {
00465 if (fabs(posnow[i] - target_pos[i]) > 1e-3)
00466 {
00467 double v = fabs(vel[i]);
00468 double a = fabs(acc[i]);
00469 ret = PCube_moveRamp(m_DeviceHandle, ModulIDs[i], target_pos[i], v, a);
00470 if (ret != 0)
00471 {
00472 errorMsg << "Module " << ModulIDs[i] << " PCube_moveRamp returned " << ret << std::endl;
00473 m_ErrorMessage = errorMsg.str();
00474 ok = false;
00475 }
00476 }
00477 }
00478
00479 ret = PCube_startMotionAll(m_DeviceHandle);
00480 if (ret != 0)
00481 {
00482 errorMsg << "PCube_startMotionAll returned " << ret << std::endl;
00483 m_ErrorMessage = errorMsg.str();
00484 ok = false;
00485 }
00486
00487 return ok;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496 bool PowerCubeCtrl::MoveVel(const std::vector<double>& vel)
00497 {
00498 PCTRL_CHECK_INITIALIZED();
00499
00500
00501
00503 unsigned int DOF = m_params->GetDOF();
00504 std::vector<int> ModulIDs = m_params->GetModuleIDs();
00505
00506 std::vector<double> velocities;
00507 velocities.resize(DOF);
00508 velocities = vel;
00509
00510 std::ostringstream errorMsg;
00511
00512 std::vector<std::string> errorMessages;
00513 PC_CTRL_STATUS status;
00514
00515 std::vector<float> delta_pos;
00516 std::vector<float> delta_pos_horizon;
00517 delta_pos.resize(DOF);
00518 delta_pos_horizon.resize(DOF);
00519
00520 std::vector<float> target_pos;
00521 std::vector<float> target_pos_horizon;
00522
00523 target_pos.resize(DOF);
00524 target_pos_horizon.resize(DOF);
00525 float target_time;
00526 float target_time_horizon = 0;
00527
00528 float delta_t;
00529
00531 std::vector<double> LowerLimits = m_params->GetLowerLimits();
00532 std::vector<double> UpperLimits = m_params->GetUpperLimits();
00533 std::vector<double> maxVels = m_params->GetMaxVel();
00534
00536 std::vector<double> Offsets = m_params->GetOffsets();
00537
00538 int ret;
00539 float pos;
00540
00541
00542
00543
00544 delta_t = ros::Time::now().toSec() - m_last_time_pub.toSec();
00545
00546 m_last_time_pub = ros::Time::now();
00547
00548 std::vector<double> pos_temp;
00549 pos_temp.resize(DOF);
00550
00551 for (unsigned int i = 0; i < DOF; i++)
00552 {
00553
00554
00555 if (delta_t >= 0.050)
00556 {
00557 target_time = 0.050;
00558 }
00559 else
00560 {
00561 target_time = delta_t;
00562 }
00563
00564
00565 target_time_horizon = target_time + (float)m_horizon;
00566
00567 delta_pos_horizon[i] = target_time_horizon * velocities[i];
00568 delta_pos[i] = target_time * velocities[i];
00569
00570 ROS_DEBUG("delta_pos[%i]: %f target_time: %f velocitiy[%i]: %f", i, delta_pos[i], target_time, i, velocities[i]);
00571
00572
00573 target_pos_horizon[i] = m_positions[i] + delta_pos_horizon[i] - Offsets[i];
00574 ROS_DEBUG("target_pos[%i]: %f m_position[%i]: %f", i, target_pos[i], i, m_positions[i]);
00575 }
00576
00577
00578
00580 if (velocities.size() != DOF)
00581 {
00582 m_ErrorMessage = "Skipping command: Commanded velocities and DOF are not same dimension.";
00583 return false;
00584 }
00585
00586 for (unsigned int i = 0; i < DOF; i++)
00587 {
00589 if (velocities[i] > maxVels[i])
00590 {
00591
00592 velocities[i] = maxVels[i];
00593
00594
00595
00596 ROS_INFO("Velocity %f exceeds limit %f for axis %i. moving with max velocity %f instead", velocities[i], maxVels[i], i, maxVels[i]);
00597 }
00598
00600
00601
00602
00603 if ((target_pos[i] < LowerLimits[i] + Offsets[i]) && (velocities[i] < 0))
00604 {
00605 ROS_INFO("Skipping command: %f Target position exceeds lower limit (%f).", target_pos[i], LowerLimits[i]);
00606
00607
00608 pthread_mutex_lock(&m_mutex);
00609 PCube_haltModule(m_DeviceHandle, ModulIDs.at(i));
00610 pthread_mutex_unlock(&m_mutex);
00611
00612 return true;
00613 }
00614
00615
00616 if ((target_pos[i] > UpperLimits[i] + Offsets[i]) && (velocities[i] > 0))
00617 {
00618 ROS_INFO("Skipping command: %f Target position exceeds upper limit (%f).", target_pos[i], UpperLimits[i]);
00619
00620
00621 pthread_mutex_lock(&m_mutex);
00622 PCube_haltModule(m_DeviceHandle, ModulIDs.at(i));
00623 pthread_mutex_unlock(&m_mutex);
00624
00625 return true;
00626 }
00627 }
00628
00629
00630
00631 getStatus(status, errorMessages);
00632
00633 if ((status != PC_CTRL_OK))
00634 {
00635 m_ErrorMessage.assign("");
00636 for (unsigned int i = 0; i < DOF; i++)
00637 {
00638 m_ErrorMessage.append(errorMessages[i]);
00639 }
00640 ROS_INFO("Error during movement. Status: %i \n", status);
00641 return false;
00642 }
00643
00644
00645
00646
00647 unsigned short time4motion = (unsigned short)((target_time_horizon)*1000.0);
00648
00649 for (unsigned int i = 0; i < DOF; i++)
00650 {
00651
00652 if ((m_ModuleTypes.at(i) == "PRL") && (m_version[i] >= Ready4MoveStep) && !m_params->GetUseMoveVel())
00653 {
00654
00655
00656
00657
00658 pthread_mutex_lock(&m_mutex);
00659 ret = PCube_moveStepExtended(m_DeviceHandle, m_params->GetModuleID(i), target_pos_horizon[i], time4motion, &m_status[i], &m_dios[i], &pos);
00660 pthread_mutex_unlock(&m_mutex);
00661 }
00662 else
00663 {
00664 pthread_mutex_lock(&m_mutex);
00665 ret = PCube_moveVelExtended(m_DeviceHandle, m_params->GetModuleID(i), velocities[i], &m_status[i], &m_dios[i], &pos);
00666 pthread_mutex_unlock(&m_mutex);
00667 }
00668
00670 if (ret != 0)
00671 {
00672 ROS_DEBUG("Com Error: %i", ret);
00673 pos = m_positions[i];
00674
00675
00676 }
00677
00678
00679
00680 m_positions[i] = (double)pos + delta_pos[i] + Offsets[i];
00681
00682 pos_temp[i] = (double)pos;
00683
00684 }
00685
00686 updateVelocities(pos_temp, delta_t);
00687
00688
00689
00690 pthread_mutex_lock(&m_mutex);
00691 PCube_startMotionAll(m_DeviceHandle);
00692 pthread_mutex_unlock(&m_mutex);
00693
00694 return true;
00695 }
00696
00697
00698 void PowerCubeCtrl::updateVelocities(std::vector<double> pos_temp, double delta_t)
00699 {
00700 unsigned int DOF = m_params->GetDOF();
00701
00702 if (m_cached_pos.empty())
00703 {
00704 std::vector<double> null;
00705 for (unsigned int i = 0; i < DOF; i++)
00706 {
00707 null.push_back(0);
00708 }
00709
00710 m_cached_pos.push_back(null);
00711 m_cached_pos.push_back(null);
00712 m_cached_pos.push_back(null);
00713 m_cached_pos.push_back(null);
00714 }
00715
00716 m_cached_pos.push_back(pos_temp);
00717 m_cached_pos.pop_front();
00718
00719 std::vector<double> last_pos = m_cached_pos.front();
00720
00721 for (unsigned int i = 0; i < DOF; i++)
00722 {
00723 m_velocities[i] = 1 / (6 * delta_t) * (-m_cached_pos[0][i] - (3 * m_cached_pos[1][i]) + (3 * m_cached_pos[2][i]) + m_cached_pos[3][i]);
00724
00725
00726 }
00727 }
00728
00732 bool PowerCubeCtrl::Stop()
00733 {
00735 unsigned int DOF = m_params->GetDOF();
00736 std::vector<int> ModulIDs = m_params->GetModuleIDs();
00737
00739
00740 for (unsigned int i = 0; i < DOF; i++)
00741 {
00742 pthread_mutex_lock(&m_mutex);
00743 int ret = PCube_haltModule(m_DeviceHandle, ModulIDs.at(i));
00744 pthread_mutex_unlock(&m_mutex);
00745 if (ret != 0)
00746 {
00747 std::ostringstream errorMsg;
00748 errorMsg << "Could not reset all modules, m5api error code: " << ret;
00749 m_ErrorMessage = errorMsg.str();
00750 return false;
00751 }
00752 }
00753
00755 usleep(500000);
00756
00758 for (unsigned int i = 0; i < DOF; i++)
00759 {
00760 pthread_mutex_lock(&m_mutex);
00761 int ret = PCube_resetModule(m_DeviceHandle, ModulIDs.at(i));
00762 pthread_mutex_unlock(&m_mutex);
00763 if (ret != 0)
00764 {
00765 std::ostringstream errorMsg;
00766 errorMsg << "Could not reset all modules, m5api error code: " << ret;
00767 m_ErrorMessage = errorMsg.str();
00768 return false;
00769 }
00770 }
00771 return true;
00772 }
00773
00777 bool PowerCubeCtrl::Recover()
00778 {
00779 unsigned int DOF = m_params->GetDOF();
00780 std::vector<int> ModulIDs = m_params->GetModuleIDs();
00781 std::vector<double> MaxVel = m_params->GetMaxVel();
00782 std::vector<double> MaxAcc = m_params->GetMaxAcc();
00783 std::vector<double> Offsets = m_params->GetOffsets();
00784
00785 std::vector<std::string> errorMessages;
00786 PC_CTRL_STATUS status;
00787
00788 unsigned long state = PC_CTRL_OK;
00789 unsigned char dio;
00790 float position;
00791 int ret = 0;
00792
00793
00794 for (unsigned int i = 0; i < DOF; i++)
00795 {
00796 pthread_mutex_lock(&m_mutex);
00797 ret = getPositionAndStatus(i, &state, &dio, &position);
00798 pthread_mutex_unlock(&m_mutex);
00799 if (ret != 0)
00800 {
00801 m_pc_status = PC_CTRL_ERR;
00802 std::cout << "State: Error com with Module: " << i << " Time: " << ros::Time::now() << std::endl;
00803 return false;
00804 }
00805
00806
00807 if (state & STATEID_MOD_ERROR)
00808 {
00809 pthread_mutex_lock(&m_mutex);
00810 ret = PCube_resetModule(m_DeviceHandle, m_params->GetModuleID(i));
00811 pthread_mutex_unlock(&m_mutex);
00812 if (ret != 0)
00813 {
00814 m_pc_status = PC_CTRL_ERR;
00815 std::cout << "State: Error com with Module: " << i << " Time: " << ros::Time::now() << std::endl;
00816 return false;
00817 }
00818 }
00819 }
00820
00821
00822 usleep(500000);
00823
00824
00825 updateStates();
00826
00827 if (m_pc_status == PC_CTRL_NOT_HOMED)
00828 {
00829 if (!doHoming())
00830 {
00831 return false;
00832 }
00833 }
00834
00835 usleep(500000);
00836
00837
00838 m_pc_status = PC_CTRL_OK;
00839
00840 updateStates();
00841
00842 getStatus(status, errorMessages);
00843
00844 if ((status != PC_CTRL_OK))
00845 {
00846 m_ErrorMessage.assign("");
00847 for (int i = 0; i < m_params->GetDOF(); i++)
00848 {
00849 m_ErrorMessage.append(errorMessages[i]);
00850 }
00851 return false;
00852 }
00853
00855 m_pc_status = PC_CTRL_OK;
00856 return true;
00857 }
00858
00864 bool PowerCubeCtrl::setMaxVelocity(double maxVelocity)
00865 {
00866 std::vector<int> ModulIDs = m_params->GetModuleIDs();
00867
00868 PCTRL_CHECK_INITIALIZED();
00869 for (int i = 0; i < m_params->GetDOF(); i++)
00870 {
00871 pthread_mutex_lock(&m_mutex);
00872 int ret = PCube_setMaxVel(m_DeviceHandle, m_params->GetModuleID(i), maxVelocity);
00873 pthread_mutex_unlock(&m_mutex);
00874 if (ret != 0)
00875 {
00876 std::ostringstream errorMsg;
00877 errorMsg << "Could not set MaxVelocity in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
00878 m_ErrorMessage = errorMsg.str();
00879 return false;
00880 }
00881
00882 std::vector<double> maxVelocities(maxVelocity);
00883 m_params->SetMaxVel(maxVelocities);
00884 }
00885
00886 return true;
00887 }
00888
00892 bool PowerCubeCtrl::setMaxVelocity(const std::vector<double>& maxVelocities)
00893 {
00894 PCTRL_CHECK_INITIALIZED();
00895
00896 std::vector<int> ModulIDs = m_params->GetModuleIDs();
00897
00898 for (int i = 0; i < m_params->GetDOF(); i++)
00899 {
00900 pthread_mutex_lock(&m_mutex);
00901
00902 int ret = PCube_setMaxVel(m_DeviceHandle, m_params->GetModuleID(i), maxVelocities[i]);
00903 pthread_mutex_unlock(&m_mutex);
00904 if (ret != 0)
00905 {
00906 std::ostringstream errorMsg;
00907 errorMsg << "Could not set MaxVelocity in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
00908 m_ErrorMessage = errorMsg.str();
00909 return false;
00910 }
00911
00912 m_params->SetMaxVel(maxVelocities);
00913 }
00914
00915 return true;
00916 }
00917
00923 bool PowerCubeCtrl::setMaxAcceleration(double maxAcceleration)
00924 {
00925 PCTRL_CHECK_INITIALIZED();
00926
00927 std::vector<int> ModulIDs = m_params->GetModuleIDs();
00928
00929 for (int i = 0; i < m_params->GetDOF(); i++)
00930 {
00931 pthread_mutex_lock(&m_mutex);
00932
00933 int ret = PCube_setMaxAcc(m_DeviceHandle, m_params->GetModuleID(i), maxAcceleration);
00934 pthread_mutex_unlock(&m_mutex);
00935 if (ret != 0)
00936 {
00937 std::ostringstream errorMsg;
00938 errorMsg << "Could not set MaxAcceleration in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
00939 m_ErrorMessage = errorMsg.str();
00940 return false;
00941 }
00942
00943 std::vector<double> maxAccelerations(maxAcceleration);
00944 m_params->SetMaxAcc(maxAccelerations);
00945 }
00946
00947 return true;
00948 }
00949
00953 bool PowerCubeCtrl::setMaxAcceleration(const std::vector<double>& maxAccelerations)
00954 {
00955 PCTRL_CHECK_INITIALIZED();
00956
00957 std::vector<int> ModulIDs = m_params->GetModuleIDs();
00958
00959 for (int i = 0; i < m_params->GetDOF(); i++)
00960 {
00961 pthread_mutex_lock(&m_mutex);
00962 int ret = PCube_setMaxAcc(m_DeviceHandle, m_params->GetModuleID(i), maxAccelerations[i]);
00963 pthread_mutex_unlock(&m_mutex);
00964 if (ret != 0)
00965 {
00966 std::ostringstream errorMsg;
00967 errorMsg << "Could not set MaxAcceleration in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
00968 m_ErrorMessage = errorMsg.str();
00969 return false;
00970 }
00971
00972 m_params->SetMaxAcc(maxAccelerations);
00973 }
00974
00975 return true;
00976 }
00977
00984 bool PowerCubeCtrl::setHorizon(double horizon)
00985 {
00986 m_horizon = horizon;
00987
00988 return true;
00989 }
00990
00997 double PowerCubeCtrl::getHorizon()
00998 {
00999 return m_horizon;
01000 }
01001
01007 bool PowerCubeCtrl::setSyncMotion()
01008 {
01009 std::vector<int> ModulIDs = m_params->GetModuleIDs();
01010
01011 if (m_CANDeviceOpened)
01012 {
01013 for (int i = 0; i < m_params->GetDOF(); i++)
01014 {
01015 unsigned long confword;
01016
01018 pthread_mutex_lock(&m_mutex);
01019 PCube_getConfig(m_DeviceHandle, m_params->GetModuleID(i), &confword);
01020 pthread_mutex_unlock(&m_mutex);
01021
01023 pthread_mutex_lock(&m_mutex);
01024 int ret = PCube_setConfig(m_DeviceHandle, m_params->GetModuleID(i), confword | CONFIGID_MOD_SYNC_MOTION);
01025 pthread_mutex_unlock(&m_mutex);
01026 if (ret != 0)
01027 {
01028 std::ostringstream errorMsg;
01029 errorMsg << "Could not set SyncMotion in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
01030 m_ErrorMessage = errorMsg.str();
01031 return false;
01032 }
01033 }
01034 return true;
01035 }
01036 else
01037 {
01038 return false;
01039 }
01040 }
01046 bool PowerCubeCtrl::setASyncMotion()
01047 {
01048 if (m_CANDeviceOpened)
01049 {
01050 for (int i = 0; i < m_params->GetDOF(); i++)
01051 {
01052 unsigned long confword;
01053
01055 pthread_mutex_lock(&m_mutex);
01056 PCube_getConfig(m_DeviceHandle, m_params->GetModuleID(i), &confword);
01057 pthread_mutex_unlock(&m_mutex);
01058
01060 pthread_mutex_lock(&m_mutex);
01061 PCube_setConfig(m_DeviceHandle, m_params->GetModuleID(i), confword & (~CONFIGID_MOD_SYNC_MOTION));
01062 pthread_mutex_unlock(&m_mutex);
01063 }
01064 return true;
01065 }
01066
01067 else
01068 {
01069 return false;
01070 }
01071 }
01075 bool PowerCubeCtrl::updateStates()
01076 {
01077 PCTRL_CHECK_INITIALIZED();
01078
01079 unsigned int DOF = m_params->GetDOF();
01080 unsigned long state;
01081 PC_CTRL_STATUS pc_status = PC_CTRL_ERR;
01082 std::vector<std::string> ErrorMessages;
01083 std::vector<double> Offsets = m_params->GetOffsets();
01084 std::ostringstream errorMsg;
01085
01086 unsigned char dio;
01087 float position;
01088 int ret = 0;
01089
01090 for (unsigned int i = 0; i < DOF; i++)
01091 {
01092 state = m_status[i];
01093 pthread_mutex_lock(&m_mutex);
01094 ret = getPositionAndStatus(i, &state, &dio, &position);
01095 pthread_mutex_unlock(&m_mutex);
01096
01097 if (ret != 0)
01098 {
01099
01100 ROS_DEBUG("Error on com in UpdateStates");
01101 return true;
01102
01103
01104 }
01105 else
01106 {
01107 ROS_DEBUG("Module %i, State: %li, Time: %f", i, state, ros::Time::now().toSec());
01108
01109 m_status[i] = state;
01110 m_dios[i] = dio;
01111 m_positions[i] = position + Offsets[i];
01112 }
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123 getStatus(pc_status, ErrorMessages);
01124
01125 for (unsigned int i = 0; i < ErrorMessages.size(); i++)
01126 {
01127 m_ErrorMessage.clear();
01128 m_ErrorMessage.assign("");
01129 m_ErrorMessage.append(ErrorMessages[i]);
01130 }
01131
01132 return true;
01133 }
01134
01138 bool PowerCubeCtrl::getStatus(PC_CTRL_STATUS& status, std::vector<std::string>& errorMessages)
01139 {
01140 unsigned int DOF = m_params->GetDOF();
01141 std::vector<int> ModuleIDs = m_params->GetModuleIDs();
01142
01143 std::vector<PC_CTRL_STATUS> StatusArray;
01144 StatusArray.resize(DOF);
01145
01146 errorMessages.clear();
01147 errorMessages.resize(DOF);
01148
01149 status = PC_CTRL_OK;
01150
01151 for (unsigned int i = 0; i < DOF; i++)
01152 {
01153 std::ostringstream errorMsg;
01154
01155 if (m_status[i] & STATEID_MOD_POWERFAULT)
01156 {
01157 if (m_status[i] & STATEID_MOD_POW_VOLT_ERR)
01158 {
01159 errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
01160 errorMsg << "Motor voltage below minimum value! Check Emergency Stop!";
01161 errorMessages[i] = errorMsg.str();
01162 }
01163 else if (m_status[i] & STATEID_MOD_POW_FET_TEMP)
01164 {
01165 errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
01166 errorMsg << "Overheated power transitors! Power must be switched of to reset this error.";
01167 errorMessages[i] = errorMsg.str();
01168 }
01169 else if (m_status[i] & STATEID_MOD_POW_INTEGRALERR)
01170 {
01171 errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
01172 errorMsg << "The drive has been overloaded and the servo loop has been disabled. Power must be switched off to reset this error.";
01173 errorMessages[i] = errorMsg.str();
01174 }
01175 StatusArray[i] = PC_CTRL_POW_VOLT_ERR;
01176 }
01177 else if (m_status[i] & STATEID_MOD_TOW_ERROR)
01178 {
01179 errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
01180 errorMsg << "The servo loop was not able to follow the target position!";
01181 errorMessages[i] = errorMsg.str();
01182 StatusArray[i] = PC_CTRL_ERR;
01183 }
01184 else if (m_status[i] & STATEID_MOD_ERROR)
01185 {
01186
01187 pthread_mutex_lock(&m_mutex);
01188 PCube_haltModule(m_DeviceHandle, m_params->GetModuleID(i));
01189 pthread_mutex_unlock(&m_mutex);
01190
01191 errorMsg << "Error in Module " << ModuleIDs[i];
01192 errorMsg << " : Status code: " << std::hex << m_status[i];
01193 errorMessages[i] = errorMsg.str();
01194 StatusArray[i] = PC_CTRL_ERR;
01195 }
01196 else if (m_pc_status & PC_CTRL_ERR)
01197 {
01198 Stop();
01199 errorMsg << "PowerCubeCtrl is in global error state";
01200 errorMessages[i] = errorMsg.str();
01201 StatusArray[i] = PC_CTRL_ERR;
01202 }
01203 else
01204 {
01205 errorMsg << "Module with Id " << ModuleIDs[i];
01206 errorMsg << ": Status OK.";
01207 errorMessages[i] = errorMsg.str();
01208 StatusArray[i] = PC_CTRL_OK;
01209 }
01210 }
01211
01212
01213 for (unsigned int i = 0; i < DOF; i++)
01214 {
01215 if ((int)StatusArray[i] <= (int)status)
01216 {
01217 status = StatusArray[i];
01218 }
01219 }
01220
01221 m_pc_status = status;
01222
01223 return true;
01224 }
01225
01229 std::vector<unsigned long> PowerCubeCtrl::getVersion()
01230 {
01231 return m_version;
01232 }
01236 bool PowerCubeCtrl::statusMoving()
01237 {
01238 PCTRL_CHECK_INITIALIZED();
01239
01240 for (int i = 0; i < m_params->GetDOF(); i++)
01241 {
01242 if (m_status[i] & STATEID_MOD_MOTION)
01243 return true;
01244 }
01245 return false;
01246 }
01247
01251 std::vector<double> PowerCubeCtrl::getPositions()
01252 {
01253 return m_positions;
01254 }
01255
01259 std::vector<double> PowerCubeCtrl::getVelocities()
01260 {
01262 return m_velocities;
01263 }
01264
01268 std::vector<double> PowerCubeCtrl::getAccelerations()
01269 {
01271 return m_accelerations;
01272 }
01273
01277 bool PowerCubeCtrl::getJointAngles(std::vector<double>& result)
01278 {
01279 PCTRL_CHECK_INITIALIZED();
01280
01281 std::vector<int> ModulIDs = m_params->GetModuleIDs();
01282
01283 int ret = 0;
01284 float pos;
01285
01286 for (int i = 0; i < m_params->GetDOF(); i++)
01287 {
01288 pthread_mutex_lock(&m_mutex);
01289 ret = PCube_getPos(m_DeviceHandle, ModulIDs[i], &pos);
01290 pthread_mutex_unlock(&m_mutex);
01291 if (ret != 0)
01292 {
01293 std::cout << "PCubeCtrl::getConfig(): getPos(" << ModulIDs[i] << ") return " << ret << std::endl;
01294 return false;
01295 }
01296 result[i] = pos;
01297 }
01298
01299 return true;
01300 }
01301
01305 bool PowerCubeCtrl::getJointVelocities(std::vector<double>& result)
01306 {
01307 PCTRL_CHECK_INITIALIZED();
01308
01309 std::vector<int> ModulIDs = m_params->GetModuleIDs();
01310
01311 int ret = 0;
01312 float vel;
01313
01314 for (int i = 0; i < m_params->GetDOF(); i++)
01315 {
01316 pthread_mutex_lock(&m_mutex);
01317 ret = PCube_getVel(m_DeviceHandle, ModulIDs[i], &vel);
01318 pthread_mutex_unlock(&m_mutex);
01319 if (ret != 0)
01320 {
01321 std::cout << "PCubeCtrl::getConfig(): getVel(" << ModulIDs[i] << ") return " << ret << std::endl;
01322 return false;
01323 }
01324 result[i] = vel;
01325 }
01326
01327 return true;
01328 }
01329
01335 bool PowerCubeCtrl::doHoming()
01336 {
01337 unsigned int DOF = m_params->GetDOF();
01338 std::vector<int> ModuleIDs = m_params->GetModuleIDs();
01339 std::vector<double> LowerLimits = m_params->GetLowerLimits();
01340 std::vector<double> UpperLimits = m_params->GetUpperLimits();
01341
01343 std::vector<double> Offsets = m_params->GetOffsets();
01344
01346 double max_homing_time = 15.0;
01347 double homing_time = 999.0;
01348 double intervall = 0.1;
01349
01350 unsigned long state = PC_CTRL_ERR;
01351 unsigned char dio;
01352 float position;
01353 int ret = 0;
01354
01356 for (unsigned int i = 0; i < DOF; i++)
01357 {
01358 pthread_mutex_lock(&m_mutex);
01359 ret = getPositionAndStatus(i, &state, &dio, &position);
01360 pthread_mutex_unlock(&m_mutex);
01361
01362
01363 if ((position > UpperLimits[i] + Offsets[i]) || (position < LowerLimits[i] + Offsets[i]))
01364 {
01365 std::ostringstream errorMsg;
01366 errorMsg << "Module " << ModuleIDs[i] << " has position " << position << " that is outside limits (" << UpperLimits[i] + Offsets[i] << " <-> " << LowerLimits[i] + Offsets[i] << std::endl;
01367 if ((m_ModuleTypes.at(i) == "PW") || (m_ModuleTypes.at(i) == "other"))
01368 {
01369 std::cout << "Position error for PW-Module. Init is aborted. Try to reboot the robot." << std::endl;
01370 m_ErrorMessage = errorMsg.str();
01371 m_pc_status = PC_CTRL_ERR;
01372 return false;
01373 }
01374 else if (m_ModuleTypes.at(i) == "PRL")
01375 {
01376 ROS_INFO("Position of Module %i is outside limits. Module can only be moved in opposite direction.", i);
01377 ROS_INFO("Homing for Module: %i not necessary", m_params->GetModuleID(i));
01378 }
01379 else
01380 {
01381 ROS_INFO("Module type incorrect. (in func. PowerCubeCtrl::doHoming();)");
01382 return false;
01383 }
01384 }
01385 else
01386 {
01387 m_positions[i] = position + Offsets[i];
01388 }
01389
01390
01391 if ((m_ModuleTypes.at(i) == "PW") || (m_ModuleTypes.at(i) == "other"))
01392 {
01393 pthread_mutex_lock(&m_mutex);
01394 ret = getPositionAndStatus(i, &state, &dio, &position);
01395 pthread_mutex_unlock(&m_mutex);
01396
01397 if (ret != 0)
01398 {
01399 ROS_INFO("Error on communication with Module: %i.", m_params->GetModuleID(i));
01400 m_pc_status = PC_CTRL_ERR;
01401 return false;
01402 }
01403
01404
01405 if (!(state & STATEID_MOD_HOME))
01406 {
01407
01408 homing_time = 0.0;
01409
01410 pthread_mutex_lock(&m_mutex);
01411 ret = PCube_homeModule(m_DeviceHandle, ModuleIDs[i]);
01412 pthread_mutex_unlock(&m_mutex);
01413
01414 ROS_INFO("Homing started at: %f", ros::Time::now().toSec());
01415
01416 if (ret != 0)
01417 {
01418 ROS_INFO("Error while sending homing command to Module: %i. I try to reset the module.", i);
01419
01420
01421 pthread_mutex_lock(&m_mutex);
01422 ret = PCube_resetModule(m_DeviceHandle, ModuleIDs[i]);
01423 pthread_mutex_unlock(&m_mutex);
01424 if (ret != 0)
01425 {
01426 std::ostringstream errorMsg;
01427 errorMsg << "Can't reset module after homing error" << ModuleIDs[i] << ", m5api error code: " << ret;
01428 m_ErrorMessage = errorMsg.str();
01429 }
01430
01431
01432 usleep(200000);
01433
01434 pthread_mutex_lock(&m_mutex);
01435 ret = PCube_homeModule(m_DeviceHandle, ModuleIDs[i]);
01436 pthread_mutex_unlock(&m_mutex);
01437 if (ret != 0)
01438 {
01439 std::ostringstream errorMsg;
01440 errorMsg << "Can't start homing for module " << ModuleIDs[i] << ", tried reset with no success, m5api error code: " << ret;
01441 m_ErrorMessage = errorMsg.str();
01442 return false;
01443 }
01444 }
01445 }
01446 else
01447 {
01448 ROS_INFO("Homing for Module: %i not necessary", m_params->GetModuleID(i));
01449 }
01450 }
01451 else
01452 {
01453 ROS_INFO("Homing for PRL-Module %i not necessary", m_params->GetModuleID(i));
01454 }
01455 }
01456
01457 for (unsigned int i = 0; i < DOF; i++)
01458 {
01459 unsigned long int help;
01460 do
01461 {
01462 pthread_mutex_lock(&m_mutex);
01463 PCube_getModuleState(m_DeviceHandle, ModuleIDs[i], &help);
01464 pthread_mutex_unlock(&m_mutex);
01465 ROS_DEBUG("Homing active for Module: %i State: %li", ModuleIDs.at(i), help);
01466
01468 usleep(intervall * 1000000);
01469 homing_time += intervall;
01470 if (homing_time >= max_homing_time)
01471 {
01472 Stop();
01473 break;
01474 }
01475
01476 } while ((help & STATEID_MOD_HOME) == 0);
01477
01478 m_status[i] = help;
01479 ROS_DEBUG("State of Module %i : %li", ModuleIDs.at(i), help);
01480 }
01481
01482 for (unsigned int i = 0; i < DOF; i++)
01483 {
01485 if (!(m_status[i] & STATEID_MOD_HOME) || (m_status[i] & STATEID_MOD_ERROR))
01486 {
01487 std::cout << "Homing failed: Error in Module " << ModuleIDs[i] << std::endl;
01488 m_pc_status = PC_CTRL_NOT_HOMED;
01489 return false;
01490 }
01491
01492 ROS_INFO("Homing for Modul %i done.", ModuleIDs.at(i));
01493 }
01494
01495
01496 m_pc_status = PC_CTRL_OK;
01497 return true;
01498 }
01499
01500 bool PowerCubeCtrl::getPositionAndStatus(int i, unsigned long* state, unsigned char* dio, float* position)
01501 {
01502 int ret = 0;
01503
01504 if (m_version[i] > VERSION_ELECTR3_FIRST or
01505 (m_version[i] > VERSION_ELECTR2_FIRST and m_version[i] < VERSION_ELECTR2_LAST))
01506 {
01507 ret = PCube_getStateDioPos(m_DeviceHandle, m_params->GetModuleID(i), state, dio, position);
01508 }
01509 else
01510 {
01511 ret = PCube_getPos(m_DeviceHandle, m_params->GetModuleID(i), position);
01512 ret |= PCube_getModuleState(m_DeviceHandle, m_params->GetModuleID(i), state);
01513 unsigned long puiValue;
01514 ret |= PCube_getDioData(m_DeviceHandle, m_params->GetModuleID(i), &puiValue);
01515 *dio = (unsigned char)puiValue;
01516 }
01517
01518 return ret;
01519 }
01520
01524 bool m_TranslateError2Diagnosics(std::ostringstream* errorMsg)
01525 {
01526 return true;
01527 }