demonstrator_control.cpp
Go to the documentation of this file.
00001 // ROS includes
00002 #include <ros/ros.h>
00003 
00004 // standard includes
00005 #include <boost/thread.hpp>
00006 #include <string>
00007 #include <cstring>
00008 #include <stdlib.h>
00009 #include <math.h>
00010 
00011 // own includes
00012 #include <cob_3d_mapping_demonstrator/demonstrator_control.h>
00013 
00014 MapDemonCtrl::MapDemonCtrl(DemonstratorParams * params)
00015 {
00016   serial_device_opened_ = false;
00017   initialized_ = false;
00018   last_time_pub_ = ros::Time::now();
00019   params_ = params;
00020   sd_ = new SerialDevice();//sd;
00021 }
00022 
00024 MapDemonCtrl::~MapDemonCtrl()
00025 {
00026   sd_->PutString("R0\n");      
00027   sd_->FlushInBuffer();
00028   sd_->FlushOutBuffer();
00029 
00030   sd_->closePort();
00031   delete sd_;
00032 }
00033 
00037 bool MapDemonCtrl::init(DemonstratorParams * params)
00038 {
00040   std::string SerialDeviceName = params_->getSerialDevice();
00041   int SerialBaudrate = params_->getBaudRate();
00042   std::ostringstream errorMsg;
00043 
00044   int DOF = params_->getDOF();
00045   std::vector<std::string> JointNames = params_->getJointNames();
00046   std::vector<double> MaxVel = params_->getMaxVel();
00047   std::vector<double> FixedVel = params_->getVels();
00048   std::vector<double> Offsets = params_->getOffsets();
00049   std::vector<double> LowerLimits = params_->getLowerLimits();
00050   std::vector<double> UpperLimits = params_->getUpperLimits();
00051 
00052 
00053   positions_.resize(DOF);
00054   positions_[0] = 0;
00055   positions_[1] = 0;
00056   old_positions_.resize(DOF);
00057   old_positions_[0] = 0;
00058   old_positions_[1] = 0;
00059   velocities_.resize(DOF);
00060   velocities_[0] = 0;
00061   velocities_[1] = 0;
00062 
00063   std::cout << "============================================================================== " << std::endl;
00064   std::cout << "Mapping Demonstrator Init: Trying to initialize with the following parameters: " << std::endl;
00065 
00066   std::cout << std::endl << "Joint Names:\t\t";
00067   for (int i = 0; i < DOF; i++)
00068   {
00069     std::cout << JointNames[i] << "\t";
00070   }
00071 
00072   std::cout << std::endl << "maxVel     :\t\t";
00073   for (int i = 0; i < DOF; i++)
00074   {
00075     std::cout << MaxVel[i] << "\t";
00076   }
00077 
00078   std::cout << std::endl << "fixedVel   :\t\t";
00079   for (int i = 0; i < DOF; i++)
00080   {
00081     std::cout << FixedVel[i] << "\t";
00082   }
00083 
00084   std::cout << std::endl << "upperLimits:\t\t";
00085   for (int i = 0; i < DOF; i++)
00086   {
00087     std::cout << UpperLimits[i] << "\t";
00088   }
00089 
00090   std::cout << std::endl << "lowerLimits:\t\t";
00091   for (int i = 0; i < DOF; i++)
00092   {
00093     std::cout << LowerLimits[i] << "\t";
00094   }
00095 
00096   std::cout << std::endl << "offsets    :\t\t";
00097   for (int i = 0; i < DOF; i++)
00098   {
00099     std::cout << Offsets[i] << "\t";
00100   }
00101 
00102   std::cout << std::endl << "============================================================================== " << std::endl;
00103 
00105   int spres = sd_->openPort(SerialDeviceName.c_str(), SerialBaudrate, 2, 0);
00106   if(spres == -1)
00107   {
00108     errorMsg << "Could not open device " << SerialDeviceName;
00109     error_message_ = errorMsg.str();
00110     return false;
00111   }
00112 
00114   sd_->PutString("R0\n");
00115   usleep(200000);
00116   if( !sd_->FlushInBuffer() )
00117     return false;       
00118   usleep(200000);
00119 
00120   std::cout << "Detecting the robot..." << std::endl;
00121   //m_sd->PutString("N\n");
00122   //usleep(200000);
00123   std::string str("");
00124   //m_sd->GetString(str);
00125   sd_->PutString("N\n");
00126 
00127   unsigned int ctr=0;
00128   while(str.find("COB3DMD") == std::string::npos)
00129   {
00130     str.clear();
00131     sd_->GetString(str);
00132     std::cout << "return 1: " << str.c_str() << std::endl;
00133     //str.resize(30);   // Resize just in case weird name is too long
00134     ctr++;
00135     if(ctr>=100)
00136     {
00137       errorMsg << "Unknown robot. ID: """ << str.c_str() << std::endl ;
00138       error_message_ = errorMsg.str();
00139       return false;
00140     }
00141   }
00142 
00143   std::cout << "Robot successfuly detected. ID: """ << str.c_str() << """" << std::endl;
00144 
00145 
00146   serial_device_opened_ = true;
00147 
00148   std::cout << "Now running calibration" << std::endl;
00150   if(!runCalibration())
00151   {
00152     errorMsg << "Calibration failed.";
00153     error_message_ = errorMsg.str();
00154     return false;
00155   }
00156 
00157   sd_->PutString("R1\n");
00158   initialized_ = true;
00159 
00160   return true;
00161 }
00162 
00163 /*
00164  * \brief Run Calibration
00165  *
00166  *
00167  */
00168 bool MapDemonCtrl::runCalibration()
00169 {
00170   std::ostringstream errorMsg;
00171   std::vector<std::string> JointNames = params_->getJointNames();
00172   std::vector<double> MaxVel = params_->getMaxVel();
00173 
00175   usleep(200000);
00176   if( !sd_->FlushInBuffer() )
00177     return false;       
00178   usleep(200000);
00179 
00181   sd_->PutString("L\n");
00182 
00183   size_t found = std::string::npos;
00184   char retry = 0;       //
00185 
00187   while( found == std::string::npos )
00188   {
00189     std::string str;
00190     sd_->GetString(str);        // read another message
00191     found = str.find_first_of("L", 0);  // find L
00192     retry++;
00193     std::cout << "calib cb: " << str << std::endl;
00194     if(retry == 4)      // experimental value, normally one or two messages are received btw flushinbuffer and getstring.
00195       return false;     
00196   }
00197 
00198   //char *cstr = new char (str.size()+1);
00199   //strcpy(cstr, str.c_str());
00200 
00201   //if(strchr(cstr, 'L') == NULL)
00202   //    return false;
00203 
00205   std::vector<double> tmppos( 2, 0.0f );
00206   movePos(tmppos);
00207 
00208   return true;
00209 }
00210 
00211 /*
00212  * \brief Move both joints to designed position, constant velocity
00213  *
00214  * This will use the velocity defined in parameter server as Velocity
00215  * \param JointNames Vector target_positions Vector
00216  */
00217 bool MapDemonCtrl::movePos( const std::vector<double>& target_positions )
00218 {
00219   std::vector<double> Offsets = params_->getOffsets();
00220   std::vector<double> velo = params_->getVels();
00221   int target_step[2];
00222   int time_to_target[2];
00223   int lat[2];
00224 
00225   std::stringstream ss;
00226 
00228   target_step[0] = (int)round( (target_positions[0] + Offsets[0]) * 63.66197724f );     
00229   target_step[1] = (int)round( (target_positions[1] + Offsets[1]) * 81.4873308631f );   
00230 
00231   time_to_target[0] = (int)round(1000 * (target_positions[0] - positions_[0]) / velo[0] );      // "Interstep latency = delta_position / vel"
00232   time_to_target[1] = (int)round(1000 * (target_positions[1] - positions_[1]) / velo[1] );      // "Interstep latency = delta_position / vel"
00233 
00234   lat[0] = time_to_target[0] / ((target_positions[0] - positions_[0]) * 63.66197724f) ;
00235   lat[1] = time_to_target[1] / ((target_positions[1] - positions_[1]) * 81.4873308631f) ;
00236 
00237   printf("TARGET POS: %f\n", target_positions[0]);
00238   printf("TARGET STEP: %d\n", target_step[0]);
00239   printf("Lat: %d\n", lat[0]);
00240 
00241   ss << "P" << target_step[0] << "," << lat[0] << std::endl;
00242   ss << "T" << target_step[1] << "," << lat[1] << std::endl << std::ends;
00243 
00244   sd_->PutString(ss.str());
00245 
00246   return true;
00247 }
00248 
00249 /*
00250  * \brief Move joints with calculated velocities
00251  *
00252  * Calculating positions and times by desired value of the cob_trajectory_controller
00253  * \param velocities Vector
00254  */
00255 /*bool MapDemonCtrl::MoveVel(const std::vector<double>& target_velocities)
00256 {
00257   m_velocities[0] = target_velocities[0];
00258   m_velocities[1] = target_velocities[1];
00259 
00260   unsigned int DOF = m_params_->GetDOF();
00261 
00262   std::vector<std::string> JointNames = m_params_->GetJointNames();
00263   std::vector<double> lowerLimits = m_params_->GetLowerLimits();
00264   std::vector<double> upperLimits = m_params_->GetUpperLimits();
00265   std::vector<double> Offsets = m_params_->GetOffsets();
00266 
00267   std::ostringstream ss;
00268   std::ostringstream errorMsg;
00269   bool errSet = false;
00270 
00271   double delta_t;
00272   double target_pos[2];
00273   int target_step[2];
00274   int latencies[2];
00275 
00276   //if ( !UpdatePositions() )
00277   //    return false;
00278 
00280   delta_t = ros::Time::now().toSec() - m_last_time_pub.toSec();
00281 
00283   m_last_time_pub = ros::Time::now();
00284   delta_t = 0.05;//delta_t > 0.1 ? 0.1 : delta_t;       // Limit delta_t to avoid insane velocities in case of long delta_t
00285 
00287   target_pos[0] = target_velocities[0] * delta_t + m_positions[0] + Offsets[0];
00288   target_pos[1] = target_velocities[1] * delta_t + m_positions[1] + Offsets[1];
00289 
00291   for(unsigned int i=0; i<DOF; i++)
00292   {
00293     if(target_pos[i] < lowerLimits[i])
00294     {
00295       errorMsg << "Computed final position for joint """ << JointNames[i] << """ exceeds limit " << lowerLimits[i] << std::endl;
00296       m_ErrorMessage = errorMsg.str();
00297       target_pos[i] = lowerLimits[i];
00298       m_velocities[0] = 0.0f;
00299       errSet = true;
00300     }
00301     if(target_pos[i] > upperLimits[i])
00302     {
00303       errorMsg << "Computed final position for joint """ << JointNames[i] << """ exceeds limit " << upperLimits[i] << std::endl;
00304       m_ErrorMessage = errorMsg.str();
00305       target_pos[i] = upperLimits[i];
00306       m_velocities[0] = 0.0f;
00307       errSet = true;
00308     }
00309     else
00310       errSet = false;
00311   }
00312 
00314   target_step[0] = (int)round( target_pos[0] * 63.66197724f );
00315   target_step[1] = (int)round( target_pos[1] * 81.4873308631f );
00316   std::cout << "t_step: " << target_step[1] << std::endl;
00317 
00319   //double stepper_delta_step = fabs(target_velocities[0]) * delta_t / 0.015707963f ;
00320   //double servo_delta_step = fabs(target_velocities[1]) * delta_t / 0.0122718463f;
00321   //int stepper_delta_step = (int)round( fabs(target_velocities[0]) * delta_t * 63.66197724f );
00322   //int servo_delta_step = (int)round( fabs(target_velocities[1]) * delta_t * 81.4873308631f );
00323 
00324 
00325   double stepper_delta_step = fabs((target_pos[0] - m_positions[0]) * 63.66197724f) ;
00326   double servo_delta_step =  fabs((target_pos[1] - m_positions[1]) * 81.4873308631f) ;
00327 
00328   if(stepper_delta_step>=1)
00329   {
00330     latencies[0] = ( (int)round(delta_t * 1000 / stepper_delta_step ) );
00331     latencies[0] = (latencies[0] > 4) ? latencies[0] : 4; // security for encoder
00332     ss << "P" << target_step[0] << "," << latencies[0] << std::endl;
00333   }
00334 
00336   //latencies[0] = (int)round( 0.015707963 * 1000 / stepper_delta_step ) ;
00337   //latencies[1] = (int)round( 0.0122718463 * 1000 / servo_delta_step ) ;
00338 
00339   std::cout << servo_delta_step << std::endl;
00340   if(servo_delta_step>=1)
00341   {
00342     latencies[1] = ( (int)round(delta_t * 1000 / servo_delta_step ) );
00343     //latencies[1] = (latencies[1] > 1) ? latencies[
00344     ss << "T" << target_step[1] << "," << latencies[1] << std::endl;
00345     std::cout << ss.str() << std::endl;
00346   }
00347 
00348   ss << std::ends;      /// end string with null for the uart driver
00349 
00350   m_sd->PutString(ss.str());
00351 
00352   if(errSet)
00353     return false;
00354 
00355   return true;
00356 }*/
00357 
00358 /*
00359  * \brief Queries the robot its real position
00360  *
00361  * The robot answers p, e, t
00362  * \param
00363  */
00364 bool MapDemonCtrl::updatePositions()
00365 {
00366   std::vector<double> Offsets = params_->getOffsets();
00367 
00368   std::ostringstream errorMsg;
00369   std::string str;
00370   char *p_pos;
00371   char *e_pos;
00372   char *t_pos;
00373 
00374   //if( !m_sd->FlushInBuffer() )
00375   //    return false;   /// ...and flush serial port input buffer
00376 
00377   //m_sd->PutString("r\n");
00378   sd_->GetString(str);  
00379 
00380   str.resize(40, NULL); // max Positions string size is 20 (5x3 ints, 2 commas, 'R' and ':'), resize for security to the double ensuring at least one can be read if present
00381 
00382   char* cstr = new char (str.size()+1);
00383   strcpy(cstr, str.c_str());    // cstr point to found position
00384 
00386   p_pos = strchr(cstr,'R')+2;   
00387   if(p_pos == NULL)
00388     return false;
00389 
00390   e_pos = strchr(p_pos, ',');   // lookup first ','
00391   if(e_pos == NULL)
00392     return false;
00393   *e_pos = '\0';                // replace comma by null to mark end of first token
00394   e_pos++;                              // advance ptr2 to begining of next token
00395 
00396   t_pos = strchr(e_pos, ',');   // lookup second ','
00397   if(t_pos == NULL)
00398     return false;
00399   *t_pos = '\0';                // replace comma by null to mark end of first token
00400   t_pos++;                              // advance ptr2 to begining of next token
00401 
00402   old_positions_[0] = positions_[0];
00403   old_positions_[1] = positions_[1];
00404   positions_[0] = (double)atoi(p_pos) * 0.015707963f - Offsets[0];      // convert step number to angle
00405   encoder_ = (double)atoi(e_pos) * 0.003141593f - Offsets[0];
00406   positions_[1] = (double)atoi(t_pos) * 0.0122718463f - Offsets[1];     // convert servo pos to angle
00407 
00409   if(fabs(positions_[0] - encoder_) > 0.05f)
00410   {
00411     errorMsg << "Pan reported incongruent position. Run recover";
00412     error_message_ = errorMsg.str();
00413     return false;
00414   }
00415   else
00416     error_message_ = "";
00417 
00418   return true;
00419 }
00420 
00421 bool MapDemonCtrl::stop()
00422 {
00423   std::ostringstream errorMsg;
00424   std::string str("");
00425 
00426   sd_->PutString("E\n");
00427   unsigned int ctr=0;
00428   while(str.find("E") == std::string::npos)
00429   {
00430     str.clear();
00431     sd_->GetString(str);
00432     if(ctr>50)
00433     {
00434       errorMsg << "COB3DMD did not confirm halt";
00435       error_message_ = errorMsg.str();
00436       return false;
00437     }
00438     ctr++;
00439   }
00440   /*if ( str.find("E\n") == std::string::npos )
00441   {
00442     errorMsg << "COB3DMD did not confirm halt";
00443     m_ErrorMessage = errorMsg.str();
00444     return false;
00445   }*/
00446 
00447   return true;
00448 }
00452 bool MapDemonCtrl::close()
00453 {
00454   sd_->PutString("E\n");        // stop movement
00455   initialized_ = false;
00456   sd_->closePort();
00457   serial_device_opened_ = false;
00458   return true;
00459 }
00460 
00464 bool MapDemonCtrl::recover()
00465 {
00466   std::ostringstream errorMsg;
00467 
00468   sd_->PutString("R0\n");       
00469 
00470   if( !sd_->checkIfStillThere() )
00471   {
00472     errorMsg << "COB3DMD not detected anymore.";
00473     sd_->closePort();
00474     error_message_ = errorMsg.str();
00475     return false;
00476   }
00477   else if( !runCalibration() )
00478   {
00479     errorMsg << "COB3DMD recalibration failed.";
00480     error_message_ = errorMsg.str();
00481     return false;
00482   }
00483   else
00484   {
00485     sd_->PutString("R1\n");
00486     return true;
00487   }
00488 }


cob_3d_mapping_demonstrator
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:03:46