sr_self_test.cpp
Go to the documentation of this file.
00001 
00027 #include "sr_self_test/sr_self_test.hpp"
00028 #include <sr_utilities/sr_math_utils.hpp>
00029 #include <boost/filesystem.hpp>
00030 
00031 namespace shadow_robot
00032 {
00033   const double SrSelfTest::MAX_MSE_CONST_ = 0.18;
00034 
00035   SrSelfTest::SrSelfTest(bool simulated, const std::string& ns)
00036     : nh_()
00037     , nh_tilde_("~")
00038   {
00039     simulated_ = simulated;
00040     if (ns != "")
00041     {
00042       // Private handle for params but normal handle for the HandCommander
00043       nh_ = NodeHandle(ns);
00044       nh_tilde_ = NodeHandle(nh_, this_node::getName());
00045     }
00046 
00047     //rename existing folder if it exists
00048     if( boost::filesystem::exists("/tmp/self_tests") )
00049     {
00050       //delete the last backup if it exists
00051       if( boost::filesystem::exists("/tmp/self_tests.bk") )
00052         boost::filesystem::remove_all("/tmp/self_tests.bk");
00053 
00054       //backup last test plots
00055       boost::filesystem::rename("/tmp/self_tests", "/tmp/self_tests.bk");
00056     }
00057     //create folder in /tmp for storing the plots
00058     path_to_plots_ = "/tmp/self_tests/"+ros::this_node::getName() + "/";
00059     boost::filesystem::create_directories(path_to_plots_);
00060 
00061     test_runner_.setID("12345");
00062 
00063     //add the different tests
00064     test_services_();
00065 
00066     //some tests can only be run on the real hand
00067     if(!simulated_)
00068     {
00069       //parses the diagnostics to find common problems
00070       test_runner_.add_diagnostic_parser();
00071 
00072       //manual tests come after diagnostic parsing
00073       // as we notify the user that the hand
00074       // connection seems to be fine if the previous
00075       // tests passed
00076       //add manual tests (tactile, calibration)
00077       test_runner_.addManualTests();
00078       //test the noise of the sensors
00079       test_runner_.addSensorNoiseTest();
00080     }
00081 
00082     //calling this from a oneshot timer because we're using the
00083     // hand commander which needs the hand to be fully initialised
00084     // before we can instantiate it.
00085     // Using 30s sleep here is a pain... not sure how to best get
00086     // rid of that... testing for availability of some services may
00087     // be not enough.
00088     test_movement_timer_ = nh_tilde_.createTimer( ros::Duration(30.0),
00089                                                   &SrSelfTest::add_all_movements_tests_, this,
00090                                                   true );
00091   }
00092 
00093   void SrSelfTest::test_services_()
00094   {
00095     std::vector<std::string> services_to_test;
00096     services_to_test.push_back("pr2_controller_manager/list_controller_types");
00097     services_to_test.push_back("pr2_controller_manager/list_controllers");
00098     services_to_test.push_back("pr2_controller_manager/load_controller");
00099     services_to_test.push_back("pr2_controller_manager/reload_controller_libraries");
00100     services_to_test.push_back("pr2_controller_manager/switch_controller");
00101     services_to_test.push_back("pr2_controller_manager/unload_controller");
00102 
00103     test_runner_.addServicesTest(services_to_test);
00104   }
00105 
00107   // TESTING MOVEMENTS
00108 
00109   void SrSelfTest::add_all_movements_tests_(const ros::TimerEvent& event)
00110   {
00111     if(simulated_)
00112     {
00113       if( hand_commander_ == NULL )
00114         hand_commander_.reset(new shadowrobot::HandCommander(nh_.getNamespace()));
00115 
00116       joints_to_test_ = hand_commander_->get_all_joints();
00117     }
00118     else
00119     {
00120       joints_to_test_.clear();
00121       //we're adding all the possible joints here. They're checked against
00122       // controlled joints from hand commander later in the movement test.
00123       joints_to_test_.push_back("FFJ0");
00124       joints_to_test_.push_back("FFJ3");
00125       joints_to_test_.push_back("FFJ4");
00126 
00127       joints_to_test_.push_back("MFJ0");
00128       joints_to_test_.push_back("MFJ3");
00129       joints_to_test_.push_back("MFJ4");
00130 
00131       joints_to_test_.push_back("RFJ0");
00132       joints_to_test_.push_back("RFJ3");
00133       joints_to_test_.push_back("RFJ4");
00134 
00135       joints_to_test_.push_back("LFJ0");
00136       joints_to_test_.push_back("LFJ3");
00137       joints_to_test_.push_back("LFJ4");
00138       joints_to_test_.push_back("LFJ5");
00139 
00140       joints_to_test_.push_back("THJ1");
00141       joints_to_test_.push_back("THJ2");
00142       joints_to_test_.push_back("THJ3");
00143       joints_to_test_.push_back("THJ4");
00144       joints_to_test_.push_back("THJ5");
00145 
00146       joints_to_test_.push_back("WRJ1");
00147       joints_to_test_.push_back("WRJ2");
00148     }
00149 
00150     motor_tests_.clear();
00151 
00152     index_joints_to_test_ = 0;
00153     for(size_t i=0; i < joints_to_test_.size(); ++i)
00154     {
00155       //checking the movement of the finger
00156       test_runner_.add("Check movements ["+joints_to_test_[i]+"]", this, &SrSelfTest::test_movement_);
00157 
00158       if(!simulated_)
00159       {
00160         //running some tests on the motor (PWM mode, strain gauge response, etc...)
00161         motor_tests_.push_back(new MotorTest(&test_runner_, joints_to_test_[i], hand_commander_.get() ) );
00162       }
00163     }
00164   }
00165 
00166   void SrSelfTest::test_movement_(diagnostic_updater::DiagnosticStatusWrapper& status)
00167   {
00168     if( hand_commander_ == NULL )
00169       hand_commander_.reset(new shadowrobot::HandCommander(nh_.getNamespace()));
00170 
00171     if(index_joints_to_test_ == 0)
00172     {
00173       //send all the joints to their safe positions:
00174       for( size_t i=0; i<joints_to_test_.size(); ++i)
00175       {
00176         send_safe_target_(joints_to_test_[i]);
00177         ros::Duration(0.4).sleep();
00178       }
00179     }
00180 
00181     std::string joint_name = joints_to_test_[index_joints_to_test_];
00182 
00183     if(!simulated_)
00184     {
00185       //only test the joint that are controlled from the hand commander
00186       bool test_joint = false;
00187       for(size_t i=0; i < hand_commander_->get_all_joints().size(); ++i)
00188       {
00189         if(joint_name.compare(hand_commander_->get_all_joints()[i]) == 0)
00190         {
00191           test_joint = true;
00192           break;
00193         }
00194       }
00195       if(!test_joint)
00196         status.summary(diagnostic_msgs::DiagnosticStatus::OK, "Not testing the joint.");
00197     }
00198 
00199     //sends the joint to a collision safe position
00200     send_safe_target_(joint_name);
00201     ros::Duration(0.5).sleep();
00202 
00203     std::string img_path;
00204     if( !nh_tilde_.getParam("image_path", img_path) )
00205     {
00206       status.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Parameter image_path not set, can't analyse movements.");
00207       return;
00208     }
00209     test_mvts_[joint_name].reset( new TestJointMovement(joint_name, hand_commander_.get()) );
00210 
00211     //wait a bit for mse to be received
00212     ros::Duration(1.0).sleep();
00213 
00214     //plot the data
00215     test_runner_.plot(test_mvts_[joint_name]->values, path_to_plots_+joint_name+".png");
00216 
00217     //check they are correct
00218     std::stringstream diag_msg;
00219     diag_msg << "Movement for " << joint_name << " (mse = " << test_mvts_[joint_name]->mse <<")";
00220     if(test_mvts_[joint_name]->mse < MAX_MSE_CONST_)
00221       status.summary(diagnostic_msgs::DiagnosticStatus::OK, diag_msg.str());
00222     else
00223       status.summary(diagnostic_msgs::DiagnosticStatus::ERROR, diag_msg.str());
00224 
00225     if( index_joints_to_test_ + 1 < joints_to_test_.size() )
00226       ++index_joints_to_test_;
00227     else
00228       index_joints_to_test_ = 0;
00229   }
00230 
00231   void SrSelfTest::send_safe_target_(std::string joint_name)
00232   {
00233     if( safe_targets_ == NULL )
00234       init_safe_targets_();
00235 
00236     update_safe_targets_(joint_name);
00237 
00238     std::vector<sr_robot_msgs::joint> joint_vector;
00239     joint_vector.resize( joints_to_test_.size() );
00240 
00241     for( size_t i=0; i<joints_to_test_.size(); ++i)
00242     {
00243       std::map<std::string, sr_robot_msgs::joint>::iterator safe_target;
00244       safe_target = safe_targets_->find( joints_to_test_[i] );
00245       if( safe_target == safe_targets_->end() )
00246       {
00247         //joint not found in the map -> use the min
00248         joint_vector[i].joint_name = joints_to_test_[i];
00249         joint_vector[i].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max( joints_to_test_[i] ).first );
00250       }
00251       else
00252       {
00253         joint_vector[i].joint_name = joints_to_test_[i];
00254         joint_vector[i].joint_target = safe_target->second.joint_target;
00255       }
00256     }
00257 
00258     hand_commander_->sendCommands(joint_vector);
00259     ros::spinOnce();
00260   }
00261 
00262   void SrSelfTest::update_safe_targets_(std::string joint_name)
00263   {
00264     //This is very hugly.... not sure how to make it prettier easily - haven't much time...
00265     if( joint_name.compare("FFJ4") == 0 )
00266     {
00267       (*safe_targets_.get())["FFJ3"].joint_target = 45.0;
00268       (*safe_targets_.get())["FFJ4"].joint_target = 0.0;
00269       (*safe_targets_.get())["MFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("MFJ4").second );
00270       (*safe_targets_.get())["RFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("RFJ4").first );
00271       (*safe_targets_.get())["LFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("LFJ4").first );
00272     }
00273     else
00274     {
00275       if( joint_name.compare("MFJ4") == 0 )
00276       {
00277         (*safe_targets_.get())["FFJ3"].joint_target = 0.0;
00278         (*safe_targets_.get())["MFJ3"].joint_target = 45.0;
00279         (*safe_targets_.get())["FFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("FFJ4").first );
00280         (*safe_targets_.get())["MFJ4"].joint_target = 0.0;
00281         (*safe_targets_.get())["RFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("RFJ4").first );
00282         (*safe_targets_.get())["LFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("LFJ4").first );
00283       }
00284       else
00285       {
00286         if( joint_name.compare("RFJ4") == 0 )
00287         {
00288           (*safe_targets_.get())["MFJ3"].joint_target = 0.0;
00289           (*safe_targets_.get())["RFJ3"].joint_target = 45.0;
00290           (*safe_targets_.get())["FFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("FFJ4").first );
00291           (*safe_targets_.get())["MFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("MFJ4").first );
00292           (*safe_targets_.get())["RFJ4"].joint_target = 0.0;
00293           (*safe_targets_.get())["LFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("LFJ4").first );
00294         }
00295         else
00296         {
00297           if( joint_name.compare("LFJ4") == 0 )
00298           {
00299             (*safe_targets_.get())["RFJ3"].joint_target = 0.0;
00300             (*safe_targets_.get())["LFJ3"].joint_target = 45.0;
00301             (*safe_targets_.get())["FFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("FFJ4").first );
00302             (*safe_targets_.get())["MFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("MFJ4").first );
00303             (*safe_targets_.get())["RFJ4"].joint_target = sr_math_utils::to_degrees( hand_commander_->get_min_max("RFJ4").second );
00304             (*safe_targets_.get())["LFJ4"].joint_target = 0.0;
00305           }
00306           else
00307           {
00308             (*safe_targets_.get())["FFJ3"].joint_target = 0.0;
00309             (*safe_targets_.get())["MFJ3"].joint_target = 0.0;
00310             (*safe_targets_.get())["RFJ3"].joint_target = 0.0;
00311             (*safe_targets_.get())["LFJ3"].joint_target = 0.0;
00312 
00313             (*safe_targets_.get())["FFJ4"].joint_target = 0.0;
00314             (*safe_targets_.get())["MFJ4"].joint_target = 0.0;
00315             (*safe_targets_.get())["RFJ4"].joint_target = 0.0;
00316             (*safe_targets_.get())["LFJ4"].joint_target = 0.0;
00317           }
00318         }
00319       }
00320     }
00321     //we ignore the other joints
00322   }
00323 
00324   void SrSelfTest::init_safe_targets_()
00325   {
00326     safe_targets_.reset( new std::map<std::string, sr_robot_msgs::joint>());
00327     sr_robot_msgs::joint safe_target;
00328 
00329     //??J4 -> min or max or 0... need to find a way to do that
00330     safe_target.joint_name = "FFJ4";
00331     safe_target.joint_target = 0.0;
00332     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00333     safe_target.joint_name = "MFJ4";
00334     safe_target.joint_target = 0.0;
00335     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00336     safe_target.joint_name = "RFJ4";
00337     safe_target.joint_target = 0.0;
00338     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00339     safe_target.joint_name = "LFJ4";
00340     safe_target.joint_target = 0.0;
00341     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00342 
00343     //wrist -> 0
00344     safe_target.joint_name = "WRJ1";
00345     safe_target.joint_target = 0.0;
00346     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00347     safe_target.joint_name = "WRJ2";
00348     safe_target.joint_target = 0.0;
00349     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00350 
00351     //thumb -> 0
00352     safe_target.joint_name = "THJ2";
00353     safe_target.joint_target = 0.0;
00354     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00355     safe_target.joint_name = "THJ3";
00356     safe_target.joint_target = 0.0;
00357     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00358     safe_target.joint_name = "THJ4";
00359     safe_target.joint_target = 0.0;
00360     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00361     safe_target.joint_name = "THJ5";
00362     safe_target.joint_target = 0.0;
00363     safe_targets_->insert( std::pair<std::string, sr_robot_msgs::joint>(safe_target.joint_name, safe_target) );
00364   }
00365 
00366 }  // namespace shadow_robot
00367 
00368 
00369 /* For the emacs weenies in the crowd.
00370    Local Variables:
00371    c-basic-offset: 2
00372    End:
00373 */
00374 
00375 


sr_self_test
Author(s): Ugo Cupcic
autogenerated on Fri Aug 28 2015 13:09:38