PowerCubeCtrl.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 // ROS includes
00019 #include <ros/ros.h>
00020 
00021 // own includes
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  * \brief Constructor
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;  // sec
00046 
00047   m_last_time_pub = ros::Time::now();
00048 
00049   m_pc_status = PC_CTRL_OK;
00050 }
00051 
00052 /*
00053  * \brief Destructor
00054  */
00055 PowerCubeCtrl::~PowerCubeCtrl()
00056 {
00057   // stop all components
00058   Stop();
00059 
00060   // close CAN device
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         // little break
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         // return false;
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     // the typ -if PW or PRL- can be distinguished by the typ of encoder.
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     // Firmware version 4634 of PRL modules replies ABSOULTE_FEEDBACK, firmware 4638 replies RESOLVER_FEEDBACK.
00291     // Both means the same: Module is PRL. PW modules have encoders (ENCODER_FEEDBACK, s.M5API), but this bit is not set
00292     // is DefConfig word.
00293     // For new firmware versions this needs to be evaluated.
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   // modules should be initialized now
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   // update status variables
00319   updateStates();
00320 
00321   // grep updated status
00322   getStatus(status, errorMessages);
00323 
00324   // homing dependant on moduletype and if already homed
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   // All modules initialized successfully
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   // Questions about method: Felix.Geibel@gmx.de
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     // Calcute the joint which need longest time to the goal
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     // determine the joint index that has the greates value for time
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     // Sum of times:
00423     TG = T1 + T2 + T3;
00424 
00425     acc[furthest] = m_maxAcc[furthest];     //maximal acceleration for furthest
00426     vel[furthest] = m_maxVel[furthest];     //maximal speed for furthest
00427 
00428     for (int i = 0; i < DOF; i++)
00429     {
00430       if (i != furthest)
00431       {
00432         double a;
00433         double v;
00434         // a und v berechnen:
00435         RampCommand::calculateAV(           //TODO Berechnungsfehler! In dieser Methode wird die Geschw. und Beschl. falsch berechnet!
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         //              printf("i_a: %f \n", acc[i]);
00448         //              printf("i_v: %f \n", vel[i]);
00449       }
00450     }
00451   }
00452   catch (...)
00453   {
00454     return false;
00455   }
00456 
00457   // Send motion commands to hardware
00458   std::ostringstream errorMsg;
00459   int ret = 0;
00460   bool ok = true;
00461 
00462   //PCube_setDeviceDebug(m_Dev, 1, 2, -1);
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  * \brief Move joints with calculated velocities
00492  *
00493  * Calculating positions and times by desired value of the cob_trajectory_controller
00494  * \param velocities Vector
00495  */
00496 bool PowerCubeCtrl::MoveVel(const std::vector<double>& vel)
00497 {
00498   PCTRL_CHECK_INITIALIZED();
00499 
00500   //== init var ==================================================
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;  // temp var for velocity because of const reference of the function
00509 
00510   std::ostringstream errorMsg;  // temp error msg for being copied to m_errorMessage
00511 
00512   std::vector<std::string> errorMessages;  // temp error msg for call of getStatus()
00513   PC_CTRL_STATUS status;                   // PowerCube Ctrl status variable
00514 
00515   std::vector<float> delta_pos;  // traviling distance for next command
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;  // absolute target postion that is desired with this command
00521   std::vector<float> target_pos_horizon;
00522 
00523   target_pos.resize(DOF);
00524   target_pos_horizon.resize(DOF);
00525   float target_time;  // time in milliseconds
00526   float target_time_horizon = 0;
00527 
00528   float delta_t;  // time from the last moveVel cmd to now
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;    // temp return value holder
00539   float pos;  // temp position variable for PCube_move.. cmds
00540 
00541   //== calculate destination position ============================
00542   // needed for limit handling and MoveStep command
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     // limit step time to 50msec
00554     // TODO: set value 0.05 as parameter
00555     if (delta_t >= 0.050)
00556     {
00557       target_time = 0.050;  // sec
00558     }
00559     else
00560     {
00561       target_time = delta_t;  // sec
00562     }
00563 
00564     // add horizon to time before calculation of target position, to influence both time and position at the same time
00565     target_time_horizon = target_time + (float)m_horizon;  // sec
00566     // calculate travel distance
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     // calculate target position
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   //== check input parameter =====================================
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       // set velocities command to max value
00592       velocities[i] = maxVels[i];
00593 
00594       // TODO: add ros_warn
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     // TODO: add second limit "safty limit"
00601     // if target position is outer limits and the command velocity is in in direction away from working range, skip
00602     // command
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       // target position is set to actual position and velocity to Null. So only movement in the non limit direction is possible.
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     // if target position is outer limits and the command velocity is in in direction away from working range, skip command
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       // target position is set to actual position. So only movement in the non limit direction is possible.
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   //== check system status ======================================
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   //== send velocity cmd to modules ==============================
00645 
00646   // convert the time to int in [ms]
00647   unsigned short time4motion = (unsigned short)((target_time_horizon)*1000.0);
00648 
00649   for (unsigned int i = 0; i < DOF; i++)
00650   {
00651     // check module type sending command (PRL-Modules can be driven with moveStepExtended(), PW-Modules can only be driven with less safe moveVelExtended())
00652     if ((m_ModuleTypes.at(i) == "PRL") && (m_version[i] >= Ready4MoveStep) && !m_params->GetUseMoveVel())
00653     {
00654       // ROS_DEBUG("Modul_id = %i, ModuleType: %s, step=%f, time=%f", m_params->GetModuleID(i), m_ModuleTypes[i].c_str(), target_pos[i], target_time);
00655 
00656       // ROS_INFO("Modul_id = %i, ModuleType: %s, step=%f, time4motion=%i [ms], target_time=%f, horizon: %f", m_params->GetModuleID(i), m_ModuleTypes[i].c_str(), delta_pos[i], time4motion, target_time, m_horizon);
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       // m_pc_status = PC_CTRL_ERR;
00675       // TODO: add error msg for diagnostics if error occours often
00676     }
00677 
00678     // !!! Position in pos is position before moveStep movement, to get the expected position after the movement
00679     // (required as input to the next moveStep command) we add the delta position (cmd_pos) !!!
00680     m_positions[i] = (double)pos + delta_pos[i] + Offsets[i];
00681 
00682     pos_temp[i] = (double)pos;
00683     // ROS_INFO("After cmd (%X) :m_positions[%i] %f = pos: %f + delta_pos[%i]: %f",m_status[i], i, m_positions[i], pos, i, delta_pos[i]);
00684   }
00685 
00686   updateVelocities(pos_temp, delta_t);
00687 
00688   // std::cout << "vel_com: " << velocities[1] << " vel_hori: " << delta_pos_horizon[1]/target_time_horizon << " vel_real[1]: " << m_velocities.at(1) << std::endl;
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 // Calculation of velocities based on vel = 1/(6*dt) * (-pos(t-3) - 3*pos(t-2) + 3*pos(t-1) + pos(t))
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     // m_velocities[i] = (m_cached_pos[3][i] - m_cached_pos[2][i])/delta_t;
00725     // m_velocities[i] = (pos_temp.at(i)-last_pos.at(i))/delta_t;
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   // check for each module if reset is necessary
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     // if module is in error state --> reset
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   // time for reboot
00822   usleep(500000);
00823 
00824   // check is everything is ok now
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   // modules should be recovered now
00838   m_pc_status = PC_CTRL_OK;
00839 
00840   updateStates();
00841   // check if modules are really back to normal state
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     // std::cout << "------------------------------> PCube_setMaxVel()" << std::endl;
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     // std::cout << "------------------------------> PCube_setMaxAcc()" << std::endl;
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       // m_pc_status = PC_CTRL_ERR;
01100       ROS_DEBUG("Error on com in UpdateStates");
01101       return true;
01102       // errorMsg << "State: Error com with Module [" <<  i << "]";
01103       // ErrorMessages[i] = errorMsg.str();
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   double delta_t = ros::Time::now().toSec() - m_last_time_pub.toSec();
01117   m_last_time_pub = ros::Time::now();
01118 
01119   updateVelocities(m_positions, delta_t);
01120   */
01121 
01122   // evaluate state for translation for diagnostics msgs
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       // STOP the motion for each module
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();  // stop all motion
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   // search for worst status
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;  // seconds
01347   double homing_time = 999.0;     // set to 0 if any module is homed
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     // check and init m_position variable for trajectory controller
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     // check module type before homing (PRL-Modules need not to be homed by ROS)
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       // only do homing when necessary
01405       if (!(state & STATEID_MOD_HOME))
01406       {
01407         // homing timer
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           // reset module with the hope that homing works afterwards
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           // little break for reboot
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);  // convert sec to usec
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   // modules successfully homed
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 }


schunk_powercube_chain
Author(s): Florian Weisshardt
autogenerated on Sat Jun 8 2019 20:25:18