PowerCubeCtrl.cpp
Go to the documentation of this file.
00001 
00060 // ROS includes
00061 #include <ros/ros.h>
00062 
00063 // own includes
00064 #include <schunk_powercube_chain/PowerCubeCtrl.h>
00065 
00066 #define PCTRL_CHECK_INITIALIZED()                               \
00067   if ( isInitialized()==false )                                 \
00068     {                                                           \
00069       m_ErrorMessage.assign("Manipulator not initialized.");    \
00070       return false;                                             \
00071     }
00072 
00073 #define Ready4MoveStep 4638
00074 
00075 /*
00076  * \brief Constructor
00077  */
00078 PowerCubeCtrl::PowerCubeCtrl(PowerCubeCtrlParams * params)
00079 {
00080   m_mutex = PTHREAD_MUTEX_INITIALIZER;
00081 
00082   m_CANDeviceOpened = false;
00083   m_Initialized = false;
00084 
00085   m_params = params;
00086 
00087   m_horizon = 0.01; // sec
00088 
00089   m_last_time_pub = ros::Time::now();
00090 
00091         m_pc_status = PC_CTRL_OK; 
00092 }
00093 
00094 /*
00095  * \brief Destructor
00096  */
00097 PowerCubeCtrl::~PowerCubeCtrl()
00098 {               
00099   // stop all components
00100   Stop(); 
00101         
00102   // close CAN device
00103   if (m_CANDeviceOpened)
00104     {
00105       pthread_mutex_lock(&m_mutex);
00106       PCube_closeDevice(m_DeviceHandle);
00107       pthread_mutex_unlock(&m_mutex);
00108     }
00109 }
00110 
00112 
00117 bool PowerCubeCtrl::Init(PowerCubeCtrlParams * params)
00118 {
00119   int ret = 0;
00120   int DOF = m_params->GetDOF();
00121   std::string CanModule = m_params->GetCanModule();
00122   std::string CanDevice = m_params->GetCanDevice();
00123   std::vector<int> ModulIDs = m_params->GetModuleIDs();
00124   int CanBaudrate = m_params->GetBaudrate();
00125   std::vector<double> MaxVel = m_params->GetMaxVel();
00126   std::vector<double> MaxAcc = m_params->GetMaxAcc();
00127   std::vector<double> Offsets = m_params->GetOffsets();
00128   std::vector<double> LowerLimits = m_params->GetLowerLimits();
00129   std::vector<double> UpperLimits = m_params->GetUpperLimits();
00130 
00132   std::cout << " D  O  F  :" << DOF << std::endl;
00133   m_status.resize(DOF);
00134   m_ModuleTypes.resize(DOF);
00135   m_version.resize(DOF); 
00136   m_dios.resize(DOF);
00137   m_positions.resize(DOF);
00138   m_velocities.resize(DOF);
00139 
00140   std::cout << "=========================================================================== " << std::endl;
00141   std::cout << "PowerCubeCtrl:Init: Trying to initialize with the following parameters: " << std::endl;
00142   std::cout << "DOF: " << DOF << std::endl;
00143   std::cout << "CanModule: " << CanModule << std::endl;
00144   std::cout << "CanDevice: " << CanDevice << std::endl;
00145   std::cout << "CanBaudrate: " << CanBaudrate << std::endl;
00146   std::cout << "ModulIDs: ";
00147   for (int i = 0; i < DOF; i++)
00148     {
00149       std::cout << ModulIDs[i] << " ";
00150     }
00151   std::cout << std::endl;
00152 
00153   std::cout << std::endl << "maxVel: ";
00154   for (int i = 0; i < DOF; i++)
00155     {
00156       std::cout << MaxVel[i] << " ";
00157     }
00158 
00159   std::cout << std::endl << "maxAcc: ";
00160   for (int i = 0; i < DOF; i++)
00161     {
00162       std::cout << MaxAcc[i] << " ";
00163     }
00164 
00165   std::cout << std::endl << "upperLimits: ";
00166   for (int i = 0; i < DOF; i++)
00167     {
00168       std::cout << UpperLimits[i] << " ";
00169     }
00170 
00171   std::cout << std::endl << "lowerLimits: ";
00172   for (int i = 0; i < DOF; i++)
00173     {
00174       std::cout << LowerLimits[i] << " ";
00175     }
00176 
00177   std::cout << std::endl << "offsets: ";
00178   for (int i = 0; i < DOF; i++)
00179     {
00180       std::cout << Offsets[i] << " ";
00181     }
00182 
00183   std::cout << std::endl << "=========================================================================== " << std::endl;
00184   std::ostringstream InitStr;
00185   InitStr << CanModule << ":" << CanDevice << "," << CanBaudrate;
00186   std::cout << "initstring = " << InitStr.str().c_str() << std::endl;
00187 
00189   pthread_mutex_lock(&m_mutex);
00190   ret = PCube_openDevice(&m_DeviceHandle, InitStr.str().c_str());
00191   pthread_mutex_unlock(&m_mutex);
00192   if (ret != 0)
00193     {
00194       std::ostringstream errorMsg;
00195       errorMsg << "Could not open device " << CanDevice << ", m5api error code: " << ret;
00196       m_ErrorMessage = errorMsg.str();
00197       return false;
00198     }
00199 
00200   m_CANDeviceOpened = true;
00201 
00203         int max_tries = 3; 
00204         for (int i = 0; i < DOF; i++)
00205         {  
00206                 for (int reset_try = 0; reset_try < max_tries; i++)
00207                 {
00208                         pthread_mutex_lock(&m_mutex);
00209                         ret =  PCube_resetModule(m_DeviceHandle, ModulIDs.at(i));
00210                         pthread_mutex_unlock(&m_mutex);
00211                         
00212                         if (ret == 0)
00213                         {       
00214                                 break; 
00215                         }
00216                         else if ((ret != 0) && (reset_try == (max_tries-1)))
00217                         {
00218                                 std::ostringstream errorMsg;
00219         errorMsg << "Could not reset module " << i << " during init. Try to init once more.";
00220         m_ErrorMessage = errorMsg.str();
00221                                 return false;
00222                         }
00223                         else
00224                         {
00225                                 // little break
00226                                 usleep(1000000); 
00227                         }
00228                         
00229                 }
00230         }
00231 
00233   ModulIDs.clear();
00234 
00236   pthread_mutex_lock(&m_mutex);
00237   int number_of_modules = PCube_getModuleCount(m_DeviceHandle);
00238   pthread_mutex_unlock(&m_mutex);
00239   std::cout << "found " << number_of_modules << " modules." << std::endl;
00240 
00242   for (int i = 0; i < DOF; i++)
00243   {
00244       unsigned long serNo;
00245       unsigned short verNo;
00246       unsigned long defConfig;
00247       std::vector<std::string> Module_Types; 
00248                 
00250       pthread_mutex_lock(&m_mutex);
00251       ret = PCube_getModuleSerialNo(m_DeviceHandle, ModulIDs[i], &serNo);
00252       pthread_mutex_unlock(&m_mutex);
00253       if (ret != 0)
00254                         {
00255                                 std::ostringstream errorMsg;
00256                                 errorMsg << "Could not find Module with ID " << ModulIDs[i] << ", m5api error code: " << ret;
00257                                 m_ErrorMessage = errorMsg.str();        
00258                                 return false;
00259                         }
00260                 
00262       pthread_mutex_lock(&m_mutex);
00263       ret = PCube_getModuleVersion(m_DeviceHandle, ModulIDs[i], &verNo);
00264       pthread_mutex_unlock(&m_mutex);
00265       if (ret != 0)
00266                         {
00267                                 std::ostringstream errorMsg;
00268                                 errorMsg << "Could not find Module with ID " << ModulIDs[i] << ", m5api error code: " << ret;
00269                                 m_ErrorMessage = errorMsg.str();        
00270                                 return false;
00271                         }
00272                         else
00273                         {
00274                           m_version[i] = verNo; 
00275                         }       
00276                         
00278                         float gear_ratio;       
00279       pthread_mutex_lock(&m_mutex);
00280       ret = PCube_getDefGearRatio(m_DeviceHandle, ModulIDs[i], &gear_ratio);
00281       pthread_mutex_unlock(&m_mutex);
00282       if (ret != 0)
00283                         {
00284                                 std::ostringstream errorMsg;
00285                                 errorMsg << "Could not get Module type with ID " << ModulIDs[i] << ", m5api error code: " << ret;
00286                                 m_ErrorMessage = errorMsg.str();        
00287                                 return false;
00288                         }
00289                         else
00290                         {
00291                                 if (true)
00292                                 {
00293                                 std::cout << "gear ratio: " << gear_ratio << std::endl; 
00294                                         //return false; 
00295                                 } 
00296                         }       
00297                         
00299                         unsigned char type;     
00300       pthread_mutex_lock(&m_mutex);
00301       ret = PCube_getModuleType(m_DeviceHandle, ModulIDs[i], &type);
00302       pthread_mutex_unlock(&m_mutex);
00303       if (ret != 0)
00304                         {
00305                                 std::ostringstream errorMsg;
00306                                 errorMsg << "Could not get Module type with ID " << ModulIDs[i] << ", m5api error code: " << ret;
00307                                 m_ErrorMessage = errorMsg.str();        
00308                                 return false;
00309                         }
00310                         else
00311                         {
00312                                 if (type != TYPEID_MOD_ROTARY)
00313                                 {
00314                                 std::cout << "wrong module type configured. Type must be rotary axis. Use Windows configuration software to change type." << std::endl; 
00315                                         return false; 
00316                                 } 
00317                         }       
00318 
00320                         // the typ -if PW or PRL- can be distinguished by the typ of encoder. 
00321                         pthread_mutex_lock(&m_mutex);
00322                         ret = PCube_getDefSetup(m_DeviceHandle, ModulIDs[i], &defConfig);
00323                         pthread_mutex_unlock(&m_mutex);
00324 
00325                         ROS_DEBUG("module type check: %li (std::dec)",defConfig); 
00326                         
00327                 if (ret != 0)
00328                         {
00329                         std::ostringstream errorMsg;
00330                                 errorMsg << "Error on communication with module " << ModulIDs[i] << ", m5api error code: " << ret;
00331                                 m_ErrorMessage = errorMsg.str();        
00332                                 return false;
00333                         }       
00334                 
00335                         // Firmware version 4634 of PRL modules replies ABSOULTE_FEEDBACK, firmware 4638 replies RESOLVER_FEEDBACK. 
00336                         // Both means the same: Module is PRL. PW modules have encoders (ENCODER_FEEDBACK, s.M5API), but this bit is not set is DefConfig word.
00337                         // For new firmware versions this needs to be evaluated. 
00338                         if (((defConfig & CONFIG_ABSOLUTE_FEEDBACK)==CONFIG_ABSOLUTE_FEEDBACK) || ((defConfig & CONFIG_RESOLVER_FEEDBACK)==CONFIG_RESOLVER_FEEDBACK))
00339                         {
00340                                 m_ModuleTypes[i] = "PRL"; 
00341                                 ROS_DEBUG("Module %i is from type: PRL", i);
00342                         }
00343                 else
00344                         {
00345                                 m_ModuleTypes[i] = "PW"; 
00346                                 ROS_DEBUG("Module %i is from type: PW", i);
00347                         }
00348 
00350                         std::cout << "Found module " << std::dec << ModulIDs[i] << " Serial: " << serNo << " Version: " << std::hex << verNo << std::endl;
00351 
00352                 }
00353         
00354   // modules should be initialized now
00355   m_pc_status = PC_CTRL_OK;
00356   m_Initialized = true; 
00357 
00359   std::vector<std::string> errorMessages;
00360   PC_CTRL_STATUS status;
00361 
00362   // update status variables
00363   updateStates();
00364 
00365   // grep updated status 
00366   getStatus(status, errorMessages);
00367         
00368   // homing dependant on moduletype and if already homed
00369   bool successful = false;
00370   successful = doHoming();
00371   if (!successful)
00372     {
00373       std::cout << "PowerCubeCtrl:Init: homing not successful, aborting ...\n";
00374       return false;
00375     }
00376 
00378   for (int i = 0; i < DOF; i++)
00379   {
00380     pthread_mutex_lock(&m_mutex);
00381     ret = PCube_setHomeOffset(m_DeviceHandle, ModulIDs[i], Offsets[i]);
00382     pthread_mutex_unlock(&m_mutex);
00383 
00384                 if (ret!=0) 
00385                 {               // 2. chance
00386                                 pthread_mutex_lock(&m_mutex);
00387                 ret = PCube_setHomeOffset(m_DeviceHandle, ModulIDs[i], Offsets[i]);
00388                 pthread_mutex_unlock(&m_mutex);
00389                                 if (ret!=0)
00390                                 {return false;}
00391                 }
00392   }
00393 
00395         //TODO: add safty limit for hardware, that modules don't reach limits
00396   for (int i = 0; i < DOF; i++)
00397   {
00398     pthread_mutex_lock(&m_mutex);
00399     //ret = PCube_setMinPos(m_DeviceHandle, ModulIDs[i], LowerLimits[i]);
00400     pthread_mutex_unlock(&m_mutex);
00401                 if (ret!=0)
00402                 {return false;}
00403 
00404     pthread_mutex_lock(&m_mutex);
00405     //ret = PCube_setMaxPos(m_DeviceHandle, ModulIDs[i], UpperLimits[i]);
00406     pthread_mutex_unlock(&m_mutex);
00407                 if (ret!=0)
00408                 {return false;}
00409   }
00410 
00412   setMaxVelocity(MaxVel);
00413         
00415         setMaxAcceleration(MaxAcc);
00416 
00418   setSyncMotion();
00419 
00420   // All modules initialized successfully
00421   m_pc_status = PC_CTRL_OK;
00422 
00423   return true;
00424 }
00425 
00429 bool PowerCubeCtrl::Close()
00430 {
00431   if (m_CANDeviceOpened)
00432     {
00433       m_Initialized = false;
00434       m_CANDeviceOpened = false;
00435 
00436       pthread_mutex_lock(&m_mutex);
00437       PCube_closeDevice(m_DeviceHandle);
00438       pthread_mutex_unlock(&m_mutex);
00439 
00440       return true;
00441     }
00442 
00443   else
00444     {
00445       return false;
00446     }
00447 }
00448 
00450 
00455 bool PowerCubeCtrl::MoveJointSpaceSync(const std::vector<double>& target)
00456 {
00457   PCTRL_CHECK_INITIALIZED();
00458   unsigned int DOF = m_params->GetDOF();
00459 
00460   std::vector<std::string> errorMessages;
00461   PC_CTRL_STATUS status;
00462   getStatus(status, errorMessages);
00463   if ((status != PC_CTRL_OK))
00464     {
00465       m_ErrorMessage.assign("");
00466       for (unsigned int i = 0; i < DOF; i++)
00467         {
00468           m_ErrorMessage.append(errorMessages[i]);
00469         }
00470       return false;
00471     }
00472 
00473   std::vector<double> vel(DOF);
00474   std::vector<double> acc(DOF);
00475 
00476   double TG = 0;
00477 
00478   try
00479     {
00481       std::vector<double> times(DOF);
00482       for (unsigned int i = 0; i < DOF; i++)
00483         {
00484           RampCommand rm(m_positions[i], m_velocities[i], target[i], m_params->GetMaxAcc()[i],
00485                          m_params->GetMaxVel()[i]);
00486           times[i] = rm.getTotalTime();
00487         }
00488 
00490       int furthest = 0;
00491       double max = times[0];
00492       for (unsigned int i = 1; i < DOF; i++)
00493         {
00494           if (times[i] > max)
00495             {
00496               max = times[i];
00497               furthest = i;
00498             }
00499         }
00500 
00501       RampCommand rm_furthest(m_positions[furthest], m_velocities[furthest], target[furthest],
00502                               m_params->GetMaxAcc()[furthest], m_params->GetMaxVel()[furthest]);
00503 
00504       double T1 = rm_furthest.T1();
00505       double T2 = rm_furthest.T2();
00506       double T3 = rm_furthest.T3();
00507 
00509       TG = T1 + T2 + T3;
00510 
00512       acc[furthest] = m_params->GetMaxAcc()[furthest];
00513       vel[furthest] = m_params->GetMaxVel()[furthest];
00514       for (unsigned int i = 0; i < DOF; i++)
00515         {
00516           if (int(i) != furthest)
00517             {
00518               double a;
00519               double v;
00520               RampCommand::calculateAV(m_positions[i], m_velocities[i], target[i], TG, T3, m_params->GetMaxAcc()[i],
00521                                        m_params->GetMaxVel()[i], a, v);
00522 
00523               acc[i] = a;
00524               vel[i] = v;
00525             }
00526         }
00527     }
00528   catch (...)
00529     {
00530       return false;
00531     }
00532 
00534   for (unsigned int i = 0; i < DOF; i++)
00535     {
00536       pthread_mutex_lock(&m_mutex);
00537       PCube_moveRamp(m_DeviceHandle, m_params->GetModuleIDs()[i], target[i], fabs(vel[i]), fabs(acc[i]));
00538       pthread_mutex_unlock(&m_mutex);
00539     }
00540 
00541   pthread_mutex_lock(&m_mutex);
00542   PCube_startMotionAll(m_DeviceHandle);
00543   pthread_mutex_unlock(&m_mutex);
00544 
00545   return true;
00546 }
00547 
00548 /*
00549  * \brief Move joints with calculated velocities
00550  *
00551  * Calculating positions and times by desired value of the cob_trajectory_controller
00552  * \param velocities Vector
00553  */
00554 bool PowerCubeCtrl::MoveVel(const std::vector<double>& vel)
00555 {
00556   PCTRL_CHECK_INITIALIZED();
00557   
00558   //== init var ==================================================
00559 
00561         unsigned int DOF = m_params->GetDOF();
00562         std::vector<int> ModulIDs = m_params->GetModuleIDs();
00563         
00564         std::vector<double> velocities; 
00565         velocities.resize(DOF); 
00566         velocities = vel;                               // temp var for velocity because of const reference of the function
00567         
00568         std::ostringstream errorMsg;                    // temp error msg for being copied to m_errorMessage
00569         
00570         std::vector<std::string> errorMessages;         // temp error msg for call of getStatus()
00571         PC_CTRL_STATUS status;                                                                          // PowerCube Ctrl status variable
00572 
00573         std::vector<float> delta_pos;                   // traviling distance for next command
00574         std::vector<float> delta_pos_horizon;
00575         delta_pos.resize(DOF);
00576         delta_pos_horizon.resize(DOF);
00577         
00578         std::vector<float> target_pos;          // absolute target postion that is desired with this command
00579         std::vector<float> target_pos_horizon;  
00580         
00581         target_pos.resize(DOF); 
00582         target_pos_horizon.resize(DOF);
00583         float target_time;      // time in milliseconds
00584         float target_time_horizon = 0;
00585   
00586         float delta_t;                  // time from the last moveVel cmd to now
00587 
00589         std::vector<double> LowerLimits = m_params->GetLowerLimits();
00590         std::vector<double> UpperLimits = m_params->GetUpperLimits();
00591         std::vector<double> maxVels = m_params->GetMaxVel();
00592         
00593         int ret;                // temp return value holder
00594         float pos;      // temp position variable for PCube_move.. cmds 
00595 
00596         //== calculate destination position ============================
00597         // needed for limit handling and MoveStep command
00598         
00599   delta_t = ros::Time::now().toSec() - m_last_time_pub.toSec();
00600         
00601   m_last_time_pub = ros::Time::now();  
00602 
00603   std::vector<double> pos_temp;
00604   pos_temp.resize(DOF);
00605 
00606   for (unsigned int i = 0; i < DOF; i++)
00607   {
00608     // limit step time to 50msec
00609     //TODO: set value 0.05 as parameter
00610         if (delta_t >= 0.050)
00611           {
00612             target_time = 0.050; //sec
00613           }
00614         else
00615           {
00616             target_time = delta_t;      //sec
00617           }
00618         
00619         //add horizon to time before calculation of target position, to influence both time and position at the same time
00620         target_time_horizon = target_time + (float)m_horizon; //sec
00621         // calculate travel distance
00622         delta_pos_horizon[i] = target_time_horizon * velocities[i];
00623         delta_pos[i] = target_time * velocities[i];
00624         
00625                 ROS_DEBUG("delta_pos[%i]: %f target_time: %f velocitiy[%i]: %f",i ,delta_pos[i], target_time, i, velocities[i]);
00626  
00627                 // calculate target position   
00628                 target_pos_horizon[i] = m_positions[i] + delta_pos_horizon[i];
00629                 ROS_DEBUG("target_pos[%i]: %f m_position[%i]: %f",i ,target_pos[i], i, m_positions[i]);
00630         }
00631 
00632         //== check input parameter =====================================
00633   
00635   if (velocities.size() != DOF)
00636     {
00637       m_ErrorMessage = "Skipping command: Commanded velocities and DOF are not same dimension.";
00638       return false;
00639     }
00640 
00641   for (unsigned int i = 0; i < DOF; i++)
00642     {
00644       if(velocities[i] > maxVels[i])
00645                         { 
00646                                 // set velocities command to max value
00647                                 velocities[i] = maxVels[i];
00648                 
00649                                 //TODO: add ros_warn    
00650 
00651                                 ROS_INFO("Velocity %f exceeds limit %f for axis %i. moving with max velocity %f instead", velocities[i], maxVels[i], i, maxVels[i]);
00652                         }
00653 
00655                         // TODO: add second limit "safty limit" 
00656                         // if target position is outer limits and the command velocity is in in direction away from working range, skip command
00657       if ((target_pos[i] < LowerLimits[i]) && (velocities[i] < 0))
00658                         {       
00659                                 ROS_INFO("Skipping command: %f Target position exceeds lower limit (%f).", target_pos[i], LowerLimits[i]);              
00660                                 // target position is set to actual position and velocity to Null. So only movement in the non limit direction is possible.
00661         
00662                                 pthread_mutex_lock(&m_mutex);
00663                                 PCube_haltModule(m_DeviceHandle, ModulIDs.at(i));
00664                                 pthread_mutex_unlock(&m_mutex);
00665                                 
00666                                 return true; 
00667                         } 
00668                         
00669                         // if target position is outer limits and the command velocity is in in direction away from working range, skip command
00670                         if ((target_pos[i] > UpperLimits[i]) && (velocities[i] > 0))
00671                         {       
00672                                 ROS_INFO("Skipping command: %f Target position exceeds upper limit (%f).", target_pos[i], UpperLimits[i]);              
00673                                 // target position is set to actual position. So only movement in the non limit direction is possible.
00674                                 
00675                                 pthread_mutex_lock(&m_mutex);
00676                                 PCube_haltModule(m_DeviceHandle, ModulIDs.at(i));
00677                                 pthread_mutex_unlock(&m_mutex);
00678 
00679                                 return true; 
00680                         } 
00681                 }
00682 
00683   //== check system status ====================================== 
00684   
00685   getStatus(status, errorMessages);
00686         
00687   if ((status != PC_CTRL_OK))
00688   {
00689     m_ErrorMessage.assign("");
00690     for (unsigned int i = 0; i < DOF; i++)
00691                 {
00692                 m_ErrorMessage.append(errorMessages[i]);
00693                 }
00694                 ROS_INFO("Error during movement. Status: %i     \n", status);
00695     return false;
00696   }
00697 
00698   //== send velocity cmd to modules ============================== 
00699 
00700         //convert the time to int in [ms]
00701         unsigned short time4motion = (unsigned short)((target_time_horizon)*1000.0);
00702 
00703         for (unsigned int i = 0; i < DOF; i++)
00704         {
00705                 // check module type sending command (PRL-Modules can be driven with moveStepExtended(), PW-Modules can only be driven with less safe moveVelExtended())
00706                 if ((m_ModuleTypes.at(i) == "PRL") && (m_version[i] >= Ready4MoveStep) && !m_params->GetUseMoveVel())
00707                 {
00708                         //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);
00709 
00710                         //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);
00711                         
00712                         pthread_mutex_lock(&m_mutex);
00713                         ret = PCube_moveStepExtended(m_DeviceHandle, m_params->GetModuleID(i), target_pos_horizon[i], time4motion, &m_status[i], &m_dios[i], &pos);
00714                         pthread_mutex_unlock(&m_mutex);
00715                 }
00716                 else    
00717                 {               
00718                         pthread_mutex_lock(&m_mutex);
00719                         ret = PCube_moveVelExtended(m_DeviceHandle, m_params->GetModuleID(i), velocities[i], &m_status[i], &m_dios[i], &pos);
00720                         pthread_mutex_unlock(&m_mutex);
00721                 }
00722 
00724                 if (ret != 0)
00725                 {
00726                         ROS_DEBUG("Com Error: %i", ret);                  
00727                         pos = m_positions[i];
00728                         //m_pc_status = PC_CTRL_ERR;
00729                         //TODO: add error msg for diagnostics if error occours often
00730                 }
00731                 
00732                 // !!! Position in pos is position before moveStep movement, to get the expected position after the movement (required as input to the next moveStep command) we add the delta position (cmd_pos) !!!
00733                 m_positions[i] = (double)pos + delta_pos[i];
00734                 
00735                 pos_temp[i] = (double)pos;
00736                 //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]);
00737         }
00738 
00739         updateVelocities(pos_temp, delta_t);
00740         
00741         //std::cout << "vel_com: " << velocities[1] << " vel_hori: " << delta_pos_horizon[1]/   target_time_horizon << " vel_real[1]: " << m_velocities.at(1) << std::endl;
00742 
00743         pthread_mutex_lock(&m_mutex);
00744         PCube_startMotionAll(m_DeviceHandle);
00745         pthread_mutex_unlock(&m_mutex);
00746         
00747         return true;
00748 }
00749 
00750 // Calculation of velocities based on vel = 1/(6*dt) * (-pos(t-3) - 3*pos(t-2) + 3*pos(t-1) + pos(t))
00751 void PowerCubeCtrl::updateVelocities(std::vector<double> pos_temp, double delta_t)
00752 {
00753   unsigned int DOF = m_params->GetDOF();
00754 
00755         if (m_cached_pos.empty())
00756         {       
00757                 std::vector<double> null; 
00758                 for (unsigned int i=0;i<DOF;i++){       null.push_back(0); }  
00759 
00760                 m_cached_pos.push_back(null);
00761                 m_cached_pos.push_back(null);
00762                 m_cached_pos.push_back(null);
00763                 m_cached_pos.push_back(null);
00764         }
00765 
00766         m_cached_pos.push_back(pos_temp);
00767         m_cached_pos.pop_front();
00768 
00769         std::vector<double> last_pos = m_cached_pos.front();
00770 
00771     for(unsigned int i = 0; i < DOF; i++)
00772         {
00773                 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]);
00774                 //m_velocities[i] = (m_cached_pos[3][i] - m_cached_pos[2][i])/delta_t;          
00775                 //m_velocities[i] = (pos_temp.at(i)-last_pos.at(i))/delta_t; 
00776         }   
00777 }
00778 
00779 
00780 
00784 bool PowerCubeCtrl::Stop()
00785 {       
00787   unsigned int DOF = m_params->GetDOF();
00788         std::vector<int> ModulIDs = m_params->GetModuleIDs();
00789 
00791 
00792 
00793         for (unsigned int i = 0; i < DOF; i++)
00794   {  
00795                 pthread_mutex_lock(&m_mutex);
00796                 int ret =  PCube_haltModule(m_DeviceHandle, ModulIDs.at(i));
00797                 pthread_mutex_unlock(&m_mutex);
00798                 if (ret != 0)
00799                   {
00800                     std::ostringstream errorMsg;
00801                     errorMsg << "Could not reset all modules, m5api error code: " << ret;
00802                     m_ErrorMessage = errorMsg.str();
00803                     return false;
00804                   }
00805         }
00806 
00808   usleep(500000);
00809 
00811         for (unsigned int i = 0; i < DOF; i++)
00812   {  
00813                 pthread_mutex_lock(&m_mutex);
00814                 int ret =  PCube_resetModule(m_DeviceHandle, ModulIDs.at(i));
00815                 pthread_mutex_unlock(&m_mutex);
00816                 if (ret != 0)
00817                   {
00818                     std::ostringstream errorMsg;
00819                     errorMsg << "Could not reset all modules, m5api error code: " << ret;
00820                     m_ErrorMessage = errorMsg.str();
00821                     return false;
00822                   }
00823         }
00824   return true;
00825 }
00826 
00830 bool PowerCubeCtrl::Recover()
00831 {       
00832   unsigned int DOF = m_params->GetDOF();
00833         std::vector<int> ModulIDs = m_params->GetModuleIDs();
00834   std::vector<double> MaxVel = m_params->GetMaxVel();
00835   std::vector<double> MaxAcc = m_params->GetMaxAcc();
00836   std::vector<double> Offsets = m_params->GetOffsets();
00837   
00838   std::vector<std::string> errorMessages;
00839   PC_CTRL_STATUS status;
00840         
00841   unsigned long state = PC_CTRL_OK;
00842   unsigned char dio;
00843   float position;
00844   int ret = 0;
00845         
00846   // check for each module if reset is necessary
00847   for (unsigned int i = 0; i < DOF; i++)
00848   {     
00849     pthread_mutex_lock(&m_mutex);
00850     ret = PCube_getStateDioPos(m_DeviceHandle, m_params->GetModuleID(i), &state, &dio, &position);
00851     pthread_mutex_unlock(&m_mutex);
00852     if (ret != 0)
00853                 {
00854                   m_pc_status = PC_CTRL_ERR;
00855                   std::cout << "State: Error com with Module: " << i << " Time: " << ros::Time::now() << std::endl;     
00856                   return false;                 
00857                 }
00858                 
00859       // if module is in error state --> reset
00860     if (state & STATEID_MOD_ERROR)
00861                 {       
00862                   pthread_mutex_lock(&m_mutex);
00863                   ret = PCube_resetModule(m_DeviceHandle, m_params->GetModuleID(i));
00864                   pthread_mutex_unlock(&m_mutex);
00865                   if (ret != 0)
00866             {
00867               m_pc_status = PC_CTRL_ERR;
00868               std::cout << "State: Error com with Module: " << i << " Time: " << ros::Time::now() << std::endl;         
00869               return false;             
00870             }
00871                 }
00872   }
00873         
00874   // time for reboot
00875   usleep(500000); 
00876 
00877   // check is everything is ok now
00878   updateStates(); 
00879 
00880   if (m_pc_status == PC_CTRL_NOT_HOMED)
00881   {
00882     if (!doHoming())
00883                 {
00884                   return false;
00885                 }
00886   }
00887         
00888   usleep(500000);
00889 
00891   for (int i = 0; i < DOF; i++)
00892   {
00893     pthread_mutex_lock(&m_mutex);
00894     ret = PCube_setHomeOffset(m_DeviceHandle, ModulIDs[i], Offsets[i]);
00895     pthread_mutex_unlock(&m_mutex);
00896 
00897                 if (ret!=0) 
00898                 {               // 2. chance
00899                                 pthread_mutex_lock(&m_mutex);
00900                 ret = PCube_setHomeOffset(m_DeviceHandle, ModulIDs[i], Offsets[i]);
00901                 pthread_mutex_unlock(&m_mutex);
00902                                 if (ret!=0)
00903                                 {return false;}
00904                 }
00905   }
00906 
00908   setMaxVelocity(MaxVel);
00909         
00911         setMaxAcceleration(MaxAcc);
00912         
00914   setSyncMotion();
00915 
00916   // modules should be recovered now
00917   m_pc_status = PC_CTRL_OK;     
00918         
00919   updateStates(); 
00920   // check if modules are really back to normal state
00921   getStatus(status, errorMessages);
00922 
00923   if ((status != PC_CTRL_OK))
00924   {
00925           m_ErrorMessage.assign("");
00926 
00927     for (int i = 0; i < m_params->GetDOF(); i++)
00928                 {
00929                   m_ErrorMessage.append(errorMessages[i]);
00930                 }
00931     return false;
00932   }
00933 
00935   m_pc_status = PC_CTRL_OK;
00936   return true;
00937 }
00938 
00944 bool PowerCubeCtrl::setMaxVelocity(double maxVelocity)
00945 {
00946         std::vector<int> ModulIDs = m_params->GetModuleIDs();
00947 
00948   PCTRL_CHECK_INITIALIZED();
00949   for (int i = 0; i < m_params->GetDOF(); i++)
00950     {
00951       pthread_mutex_lock(&m_mutex);
00952       int ret = PCube_setMaxVel(m_DeviceHandle, m_params->GetModuleID(i), maxVelocity);
00953       pthread_mutex_unlock(&m_mutex);
00954                         if (ret!=0)
00955                         {       
00956                                 std::ostringstream errorMsg;
00957                                 errorMsg << "Could not set MaxVelocity in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
00958                                 m_ErrorMessage = errorMsg.str();
00959                                 return false;
00960                         }
00961 
00962       std::vector<double> maxVelocities(maxVelocity);
00963       m_params->SetMaxVel(maxVelocities);
00964     }
00965 
00966   return true;
00967 }
00968 
00972 bool PowerCubeCtrl::setMaxVelocity(const std::vector<double>& maxVelocities)
00973 {       
00974   PCTRL_CHECK_INITIALIZED();
00975         
00976         std::vector<int> ModulIDs = m_params->GetModuleIDs();
00977         
00978   for (int i = 0; i < m_params->GetDOF(); i++)
00979     {
00980       pthread_mutex_lock(&m_mutex);
00981       //std::cout << "------------------------------> PCube_setMaxVel()" << std::endl;
00982       int ret = PCube_setMaxVel(m_DeviceHandle, m_params->GetModuleID(i), maxVelocities[i]);
00983       pthread_mutex_unlock(&m_mutex);
00984                         if (ret!=0)
00985                         {       
00986                                 std::ostringstream errorMsg;
00987                                 errorMsg << "Could not set MaxVelocity in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
00988                                 m_ErrorMessage = errorMsg.str();
00989                                 return false;
00990                         }
00991 
00992       m_params->SetMaxVel(maxVelocities);
00993     }
00994 
00995   return true;
00996 }
00997 
01003 bool PowerCubeCtrl::setMaxAcceleration(double maxAcceleration)
01004 {
01005   PCTRL_CHECK_INITIALIZED();
01006         
01007         std::vector<int> ModulIDs = m_params->GetModuleIDs();
01008 
01009   for (int i = 0; i < m_params->GetDOF(); i++)
01010     {
01011       pthread_mutex_lock(&m_mutex);
01012       //std::cout << "------------------------------> PCube_setMaxAcc()" << std::endl;
01013       int ret = PCube_setMaxAcc(m_DeviceHandle, m_params->GetModuleID(i), maxAcceleration);
01014       pthread_mutex_unlock(&m_mutex);
01015                         if (ret!=0)
01016                         {       
01017                                 std::ostringstream errorMsg;
01018                                 errorMsg << "Could not set MaxAcceleration in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
01019                                 m_ErrorMessage = errorMsg.str();
01020                                 return false;
01021                         }
01022 
01023       std::vector<double> maxAccelerations(maxAcceleration);
01024       m_params->SetMaxAcc(maxAccelerations);
01025     }
01026 
01027   return true;
01028 }
01029 
01033 bool PowerCubeCtrl::setMaxAcceleration(const std::vector<double>& maxAccelerations)
01034 {
01035   PCTRL_CHECK_INITIALIZED();
01036         
01037         std::vector<int> ModulIDs = m_params->GetModuleIDs();
01038 
01039   for (int i = 0; i < m_params->GetDOF(); i++)
01040     {
01041       pthread_mutex_lock(&m_mutex);
01042       int ret = PCube_setMaxAcc(m_DeviceHandle, m_params->GetModuleID(i), maxAccelerations[i]);
01043       pthread_mutex_unlock(&m_mutex);
01044                         if (ret!=0)
01045                         {       
01046                                 std::ostringstream errorMsg;
01047                                 errorMsg << "Could not set MaxAcceleration in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
01048                                 m_ErrorMessage = errorMsg.str();
01049                                 return false;
01050                         }
01051 
01052       m_params->SetMaxAcc(maxAccelerations);
01053     }
01054 
01055   return true;
01056 }
01057 
01064 bool PowerCubeCtrl::setHorizon(double horizon)
01065 {
01066   m_horizon = horizon;
01067 
01068   return true;
01069 }
01070 
01077 double PowerCubeCtrl::getHorizon()
01078 {
01079   return m_horizon;
01080 }
01081 
01087 bool PowerCubeCtrl::setSyncMotion()
01088 {
01089         std::vector<int> ModulIDs = m_params->GetModuleIDs();
01090 
01091   if (m_CANDeviceOpened)
01092   {
01093                 for (int i = 0; i < m_params->GetDOF(); i++)
01094                 {
01095                 unsigned long confword;
01096 
01098                 pthread_mutex_lock(&m_mutex);
01099                 PCube_getConfig(m_DeviceHandle, m_params->GetModuleID(i), &confword);
01100                 pthread_mutex_unlock(&m_mutex);
01101 
01103                 pthread_mutex_lock(&m_mutex);
01104                 int ret = PCube_setConfig(m_DeviceHandle, m_params->GetModuleID(i), confword | CONFIGID_MOD_SYNC_MOTION);
01105                 pthread_mutex_unlock(&m_mutex);
01106                         if (ret!=0)
01107                         {       
01108                                 std::ostringstream errorMsg;
01109                                 errorMsg << "Could not set SyncMotion in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
01110                                 m_ErrorMessage = errorMsg.str();
01111                                 return false;
01112                         }
01113                 }
01114       return true;
01115     }
01116   else
01117     {
01118       return false;
01119     }
01120 }
01126 bool PowerCubeCtrl::setASyncMotion()
01127 {
01128   if (m_CANDeviceOpened)
01129     {
01130       for (int i = 0; i < m_params->GetDOF(); i++)
01131         {
01132           unsigned long confword;
01133 
01135           pthread_mutex_lock(&m_mutex);
01136           PCube_getConfig(m_DeviceHandle, m_params->GetModuleID(i), &confword);
01137           pthread_mutex_unlock(&m_mutex);
01138 
01140           pthread_mutex_lock(&m_mutex);
01141           PCube_setConfig(m_DeviceHandle, m_params->GetModuleID(i), confword & (~CONFIGID_MOD_SYNC_MOTION));
01142           pthread_mutex_unlock(&m_mutex);
01143         }
01144       return true;
01145     }
01146 
01147   else
01148     {
01149       return false;
01150     }
01151 }
01155 bool PowerCubeCtrl::updateStates()
01156 {       
01157   PCTRL_CHECK_INITIALIZED();
01158 
01159   unsigned int DOF = m_params->GetDOF();
01160   unsigned long state;
01161   PC_CTRL_STATUS pc_status = PC_CTRL_ERR; 
01162   std::vector<std::string> ErrorMessages;
01163   std::ostringstream errorMsg;
01164 
01165   unsigned char dio;
01166   float position;
01167   int ret = 0;
01168 
01169   for (unsigned int i = 0; i < DOF; i++)
01170     {   
01171       state = m_status[i]; 
01172       pthread_mutex_lock(&m_mutex);
01173       ret = PCube_getStateDioPos(m_DeviceHandle, m_params->GetModuleID(i), &state, &dio, &position);
01174       pthread_mutex_unlock(&m_mutex);
01175                 
01176       if (ret != 0)
01177         {
01178           //m_pc_status = PC_CTRL_ERR;
01179           ROS_DEBUG("Error on com in UpdateStates");
01180           return true;
01181           //errorMsg << "State: Error com with Module [" <<  i << "]";
01182           //ErrorMessages[i] = errorMsg.str();                  
01183         }
01184       else
01185         {       
01186           ROS_DEBUG("Module %i, State: %li, Time: %f",i, state, ros::Time::now().toSec());
01187           
01188           m_status[i] = state;          
01189           m_dios[i] = dio;
01190           m_positions[i] = position;
01191         }       
01192       
01193     }
01194 
01195         /*
01196   double delta_t = ros::Time::now().toSec() - m_last_time_pub.toSec();
01197   m_last_time_pub = ros::Time::now();  
01198 
01199   updateVelocities(m_positions, delta_t);
01200         */
01201 
01202   // evaluate state for translation for diagnostics msgs
01203   getStatus(pc_status, ErrorMessages);
01204 
01205   for (unsigned int i=0; i<ErrorMessages.size(); i++)
01206   {     
01207                 m_ErrorMessage.clear();
01208                 m_ErrorMessage.assign("");
01209     m_ErrorMessage.append(ErrorMessages[i]);
01210   }
01211 
01212   return true;
01213 }
01214 
01218 bool PowerCubeCtrl::getStatus(PC_CTRL_STATUS& status, std::vector<std::string>& errorMessages)
01219 {       
01220   unsigned int DOF = m_params->GetDOF();
01221   std::vector<int> ModuleIDs = m_params->GetModuleIDs();
01222         
01223         std::vector<PC_CTRL_STATUS> StatusArray;
01224         StatusArray.resize(DOF);        
01225 
01226   errorMessages.clear();
01227   errorMessages.resize(DOF);
01228 
01229   status = PC_CTRL_OK;
01230 
01231   for (unsigned int i = 0; i < DOF; i++)
01232   {
01233                 std::ostringstream errorMsg;
01234                 
01235                 if (m_status[i] & STATEID_MOD_POWERFAULT)
01236                 {       
01237                         if (m_status[i] & STATEID_MOD_POW_VOLT_ERR)
01238                         {
01239                                 errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
01240                                 errorMsg << "Motor voltage below minimum value! Check Emergency Stop!";
01241                                 errorMessages[i] = errorMsg.str();
01242                         }
01243                         else if (m_status[i] & STATEID_MOD_POW_FET_TEMP)
01244                         {
01245                                 errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
01246                                 errorMsg << "Overheated power transitors! Power must be switched of to reset this error.";
01247                                 errorMessages[i] = errorMsg.str();
01248                         }
01249                         else if (m_status[i] & STATEID_MOD_POW_INTEGRALERR)
01250                         {
01251                                 errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
01252                                 errorMsg << "The drive has been overloaded and the servo loop has been disabled. Power must be switched off to reset this error.";
01253                                 errorMessages[i] = errorMsg.str();
01254                         }
01255                         StatusArray[i] = PC_CTRL_POW_VOLT_ERR;
01256                 }
01257     else if (m_status[i] & STATEID_MOD_TOW_ERROR)
01258                 {
01259                         errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
01260                         errorMsg << "The servo loop was not able to follow the target position!";
01261                         errorMessages[i] = errorMsg.str();
01262                         StatusArray[i] = PC_CTRL_ERR;
01263                 }
01264     else if (m_status[i] & STATEID_MOD_ERROR)
01265                 {       
01266                         // STOP the motion for each module
01267                         pthread_mutex_lock(&m_mutex);
01268                         PCube_haltModule(m_DeviceHandle, m_params->GetModuleID(i));
01269                         pthread_mutex_unlock(&m_mutex);
01270                          
01271                         errorMsg << "Error in  Module " << ModuleIDs[i];
01272                         errorMsg << " : Status code: " << std::hex << m_status[i];
01273                         errorMessages[i] = errorMsg.str();
01274                         StatusArray[i] = PC_CTRL_ERR;
01275                 }
01276     else if (m_pc_status & PC_CTRL_ERR)
01277                 {       
01278                         Stop(); // stop all motion
01279                         errorMsg << "PowerCubeCtrl is in global error state";
01280                         errorMessages[i] = errorMsg.str();
01281                         StatusArray[i] =  PC_CTRL_ERR;
01282                 }
01283     else
01284                 {
01285                         errorMsg << "Module with Id " << ModuleIDs[i];
01286                         errorMsg << ": Status OK.";
01287                         errorMessages[i] = errorMsg.str();
01288                         StatusArray[i] = PC_CTRL_OK;
01289                 }
01290         }
01291         
01292         // search for worst status
01293         for (unsigned int i = 0; i < DOF; i++)
01294   {     
01295                 if ((int)StatusArray[i] <= (int)status)
01296                 {
01297                         status = StatusArray[i]; 
01298                 }       
01299         }
01300         
01301         m_pc_status = status;
01302 
01303   return true;
01304 }
01305 
01309 std::vector<unsigned long> PowerCubeCtrl::getVersion()
01310 {
01311   return m_version; 
01312 }
01316 bool PowerCubeCtrl::statusMoving()
01317 {
01318   PCTRL_CHECK_INITIALIZED();
01319 
01320   for (int i = 0; i < m_params->GetDOF(); i++)
01321     {
01322       if (m_status[i] & STATEID_MOD_MOTION)
01323         return true;
01324     }
01325   return false;
01326 }
01327 
01331 std::vector<double> PowerCubeCtrl::getPositions()
01332 {
01333   return m_positions;
01334 }
01335 
01339 std::vector<double> PowerCubeCtrl::getVelocities()
01340 {
01342   return m_velocities;
01343 }
01344 
01348 std::vector<double> PowerCubeCtrl::getAccelerations()
01349 {
01351   return m_accelerations;
01352 }
01353 
01359 bool PowerCubeCtrl::doHoming()
01360 {
01361         unsigned int DOF = m_params->GetDOF();
01362         std::vector<int> ModuleIDs = m_params->GetModuleIDs();
01363         std::vector<double> LowerLimits = m_params->GetLowerLimits();
01364         std::vector<double> UpperLimits = m_params->GetUpperLimits();
01365 
01367   double max_homing_time = 15.0; // seconds   
01368   double homing_time = 999.0;   // set to 0 if any module is homed
01369   double intervall = 0.1;
01370         
01371   unsigned long state = PC_CTRL_ERR;
01372   unsigned char dio;
01373   float position;
01374   int ret = 0;
01375         
01377   for (unsigned int i = 0; i < DOF; i++)
01378     {   
01379         pthread_mutex_lock(&m_mutex);
01380         ret = PCube_getStateDioPos(m_DeviceHandle, m_params->GetModuleID(i), &state, &dio, &position);
01381         pthread_mutex_unlock(&m_mutex);
01382                 
01383         // check and init m_position variable for trajectory controller
01384         if ((position > UpperLimits[i]) || (position < LowerLimits[i]))
01385         {       
01386                 std::ostringstream errorMsg;
01387                 errorMsg << "Module " << ModuleIDs[i] << " has position " << position << " that is outside limits (" << UpperLimits[i] << " <-> " << LowerLimits[i] << std::endl; 
01388                 if ((m_ModuleTypes.at(i)=="PW") || (m_ModuleTypes.at(i) == "other"))
01389                 {       std::cout << "Position error for PW-Module. Init is aborted. Try to reboot the robot." << std::endl;
01390                         m_ErrorMessage = errorMsg.str(); 
01391                         m_pc_status = PC_CTRL_ERR;
01392                         return false;
01393                 }
01394                 else if (m_ModuleTypes.at(i)=="PRL") 
01395                 {       
01396                         ROS_INFO("Position of Module %i is outside limits. Module can only be moved in opposite direction.",i );
01397                         ROS_INFO("Homing for Module: %i not necessary", m_params->GetModuleID(i));
01398                 }       
01399                 else 
01400                 {       
01401                         ROS_INFO("Module type incorrect. (in func. PowerCubeCtrl::doHoming();)");
01402                         return false;
01403                 }
01404         }
01405         else
01406         {
01407                 m_positions[i] = position; 
01408         }
01409 
01410         // check module type before homing (PRL-Modules need not to be homed by ROS)
01411         if ( (m_ModuleTypes.at(i) == "PW") || (m_ModuleTypes.at(i) == "other") )
01412         {       
01413                 pthread_mutex_lock(&m_mutex);
01414                 ret = PCube_getStateDioPos(m_DeviceHandle, m_params->GetModuleID(i), &state, &dio, &position);
01415                 pthread_mutex_unlock(&m_mutex);
01416         
01417                 if (ret != 0)
01418                 {       
01419                         ROS_INFO("Error on communication with Module: %i.", m_params->GetModuleID(i)); 
01420                         m_pc_status = PC_CTRL_ERR;
01421                         return false;
01422                 }
01423                         
01424                 // only do homing when necessary 
01425                 if (!(state & STATEID_MOD_HOME))
01426                 {
01427                         // homing timer
01428                         homing_time = 0.0;
01429 
01430                           pthread_mutex_lock(&m_mutex);
01431                           ret = PCube_homeModule(m_DeviceHandle, ModuleIDs[i]);
01432                           pthread_mutex_unlock(&m_mutex);
01433 
01434                           ROS_INFO("Homing started at: %f", ros::Time::now().toSec()); 
01435 
01436                           if (ret != 0)
01437                         {        
01438                           ROS_INFO("Error while sending homing command to Module: %i. I try to reset the module.", i); 
01439 
01440                           // reset module with the hope that homing works afterwards
01441                           pthread_mutex_lock(&m_mutex);
01442                           ret = PCube_resetModule(m_DeviceHandle, ModuleIDs[i]);
01443                           pthread_mutex_unlock(&m_mutex);
01444                           if (ret != 0)
01445                                 {       
01446                                   std::ostringstream errorMsg;
01447                                   errorMsg << "Can't reset module after homing error" << ModuleIDs[i] << ", m5api error code: " << ret;
01448                                   m_ErrorMessage = errorMsg.str();
01449                                 }
01450 
01451                           // little break for reboot
01452                           usleep(200000); 
01453 
01454                           pthread_mutex_lock(&m_mutex);
01455                           ret = PCube_homeModule(m_DeviceHandle, ModuleIDs[i]);
01456                           pthread_mutex_unlock(&m_mutex);
01457                           if (ret != 0)
01458                                 {       
01459                                   std::ostringstream errorMsg;
01460                                   errorMsg << "Can't start homing for module " << ModuleIDs[i] << ", tried reset with no success, m5api error code: " << ret;
01461                                   m_ErrorMessage = errorMsg.str();
01462                                   return false;                         
01463                                 }
01464 
01465                         }
01466             }else
01467             {
01468               ROS_INFO("Homing for Module: %i not necessary", m_params->GetModuleID(i));
01469             } 
01470         }else
01471         {
01472           ROS_INFO("Homing for PRL-Module %i not necessary", m_params->GetModuleID(i));
01473         } 
01474     }
01475 
01476   for (unsigned int i = 0; i < DOF; i++)
01477     {   
01478       unsigned long int help; 
01479       do
01480                         {
01481                                 pthread_mutex_lock(&m_mutex);
01482                                 PCube_getModuleState(m_DeviceHandle, ModuleIDs[i], &help);
01483                                 pthread_mutex_unlock(&m_mutex);
01484                                 ROS_DEBUG("Homing active for Module: %i State: %li", ModuleIDs.at(i), help);
01485 
01487                                 usleep(intervall * 1000000);    // convert sec to usec
01488                                 homing_time += intervall; 
01489                                 if (homing_time >= max_homing_time) {Stop(); break;} 
01490 
01491                         } while ((help & STATEID_MOD_HOME) == 0);
01492      
01493                         m_status[i] = help;
01494       ROS_DEBUG("State of Module %i : %li", ModuleIDs.at(i), help);
01495     }
01496 
01497   for (unsigned int i = 0; i < DOF; i++)
01498     {   
01500       if (!(m_status[i] & STATEID_MOD_HOME) || (m_status[i] & STATEID_MOD_ERROR) )
01501                         {
01502                                 std::cout << "Homing failed: Error in  Module " << ModuleIDs[i] << std::endl;
01503                                 m_pc_status = PC_CTRL_NOT_HOMED;
01504                                 return false;
01505                         }
01506                 
01507       ROS_INFO("Homing for Modul %i done.", ModuleIDs.at(i)); 
01508     }
01509 
01510   // modules successfully homed
01511   m_pc_status = PC_CTRL_OK;
01512   return true;
01513 }
01514 
01518 bool m_TranslateError2Diagnosics(std::ostringstream* errorMsg)
01519 {
01520   return true;
01521 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


schunk_powercube_chain
Author(s): Florian Weisshardt
autogenerated on Tue Mar 5 2013 14:44:47