tibi_dabo_head_driver_node.cpp
Go to the documentation of this file.
00001 #include "tibi_dabo_head_driver_node.h"
00002 #include "eventserver.h"
00003 #include "XmlRpcValue.h"
00004 
00005 TibiDaboHeadDriverNode::TibiDaboHeadDriverNode(ros::NodeHandle &nh) : iri_base_driver::IriBaseNodeDriver<TibiDaboHeadDriver>(nh),
00006   motion_sequence_aserver_(this->public_node_handle_, "motion_sequence"),
00007   joint_motion_aserver_(this->public_node_handle_, "joint_motion")
00008 {
00009   XmlRpc::XmlRpcValue files_param_list;
00010   XmlRpc::XmlRpcValue param_list_item;
00011   unsigned int i=0;
00012 
00013   //init class attributes if necessary
00014   this->loop_rate_ = 100;//in [Hz]
00015 
00016   // [init publishers]
00017   this->joint_feedback_publisher_ = this->public_node_handle_.advertise<sensor_msgs::JointState>("joint_feedback", 100);
00018   
00019   // [init subscribers]
00020   this->joint_position_subscriber_ = this->public_node_handle_.subscribe("joint_position", 10, &TibiDaboHeadDriverNode::joint_position_callback, this);
00021   this->facial_expression_subscriber_ = this->public_node_handle_.subscribe("facial_expression", 100, &TibiDaboHeadDriverNode::facial_expression_callback, this);
00022 
00023   // [init services]
00024   
00025   // [init clients]
00026   
00027   // [init action servers]
00028   motion_sequence_aserver_.registerStartCallback(boost::bind(&TibiDaboHeadDriverNode::motion_sequence_startCallback, this, _1));
00029   motion_sequence_aserver_.registerStopCallback(boost::bind(&TibiDaboHeadDriverNode::motion_sequence_stopCallback, this));
00030   motion_sequence_aserver_.registerIsFinishedCallback(boost::bind(&TibiDaboHeadDriverNode::motion_sequence_isFinishedCallback, this));
00031   motion_sequence_aserver_.registerHasSucceedCallback(boost::bind(&TibiDaboHeadDriverNode::motion_sequence_hasSucceedCallback, this));
00032   motion_sequence_aserver_.registerGetResultCallback(boost::bind(&TibiDaboHeadDriverNode::motion_sequence_getResultCallback, this, _1));
00033   motion_sequence_aserver_.registerGetFeedbackCallback(boost::bind(&TibiDaboHeadDriverNode::motion_sequence_getFeedbackCallback, this, _1));
00034   
00035   joint_motion_aserver_.registerStartCallback(boost::bind(&TibiDaboHeadDriverNode::joint_motion_startCallback, this, _1));
00036   joint_motion_aserver_.registerStopCallback(boost::bind(&TibiDaboHeadDriverNode::joint_motion_stopCallback, this));
00037   joint_motion_aserver_.registerIsFinishedCallback(boost::bind(&TibiDaboHeadDriverNode::joint_motion_isFinishedCallback, this));
00038   joint_motion_aserver_.registerHasSucceedCallback(boost::bind(&TibiDaboHeadDriverNode::joint_motion_hasSucceedCallback, this));
00039   joint_motion_aserver_.registerGetResultCallback(boost::bind(&TibiDaboHeadDriverNode::joint_motion_getResultCallback, this, _1));
00040   joint_motion_aserver_.registerGetFeedbackCallback(boost::bind(&TibiDaboHeadDriverNode::joint_motion_getFeedbackCallback, this, _1));
00041   // [init action clients]
00042   // [init action clients]
00043   // publish parameters
00044   files_param_list.setSize(this->driver_.get_num_motion_seq_files());
00045   for(i=0;i<this->driver_.get_num_motion_seq_files();i++)
00046   {
00047     param_list_item=this->driver_.get_motion_seq_file(i);
00048     files_param_list[i]=param_list_item; 
00049   }
00050   this->public_node_handle_.setParam("motion_files",files_param_list);
00051   files_param_list.clear();
00052   files_param_list.setSize(this->driver_.get_num_config_files());
00053   for(i=0;i<this->driver_.get_num_config_files();i++)
00054   {
00055     param_list_item=this->driver_.get_config_file(i);
00056     files_param_list[i]=param_list_item; 
00057   }
00058   this->public_node_handle_.setParam("config_files",files_param_list);
00059   files_param_list.clear();
00060 }
00061 
00062 void TibiDaboHeadDriverNode::mainNodeThread(void)
00063 {
00064   std::vector<double> position(3);
00065   std::vector<double> velocity(3);
00066   unsigned int i=0;
00067 
00068   //lock access to driver if necessary
00069   this->driver_.lock();
00070 
00071   // update the loop rate
00072   this->loop_rate_ = this->driver_.get_feedback_rate();//in [Hz]
00073 
00074   // [fill msg Header if necessary]
00075   this->JointState_msg_.header.stamp = ros::Time::now();
00076   //<publisher_name>.header.frame_id = "<publisher_topic_name>";
00077 
00078   // [fill msg structures]
00079   this->driver_.get_position(position);
00080   this->driver_.get_velocity(velocity);
00081   this->JointState_msg_.position.clear();
00082   this->JointState_msg_.velocity.clear();
00083   this->JointState_msg_.name.clear();
00084   this->JointState_msg_.name.push_back("pan");
00085   this->JointState_msg_.name.push_back("tilt");
00086   this->JointState_msg_.name.push_back("roll");
00087   for(i=0;i<position.size();i++)
00088   {
00089     // convert from degrees to radians
00090     this->JointState_msg_.position.push_back(position[i]*3.14159/180.0);
00091     this->JointState_msg_.velocity.push_back(velocity[i]*3.14159/180.0);
00092   }
00093   // [fill srv structure and make request to the server]
00094   
00095   // [fill action structure and make request to the action server]
00096 
00097   // [publish messages]
00098   this->joint_feedback_publisher_.publish(this->JointState_msg_);
00099 
00100   //unlock access to driver if previously blocked
00101   this->driver_.unlock();
00102 }
00103 
00104 void TibiDaboHeadDriverNode::check_motion_sequence_status(diagnostic_updater::DiagnosticStatusWrapper &stat)
00105 {
00106   CEventServer *event_server=CEventServer::instance();
00107 
00108   if(driver_.isRunning())
00109   {
00110     if(this->driver_.get_motion_sequence_complete_event_id()!="")
00111     {
00112       if(event_server->event_is_set(this->driver_.get_motion_sequence_complete_event_id()))
00113       {
00114         if(event_server->event_is_set(this->driver_.get_motion_sequence_error_event_id()))
00115         {
00116           stat.summary(1,"Sequence has finished with errors");
00117           stat.add("Reported error",this->driver_.get_motion_sequence_error_message());
00118         }
00119         else
00120         {
00121           stat.summary(0,"Sequence has finished ok");
00122         }
00123       }
00124       else
00125         stat.summary(0,"Sequence is in progress");
00126     }
00127     else
00128       stat.summary(0,"No sequence has been executed");
00129   }
00130 }
00131 
00132 /*  [subscriber callbacks] */
00133 void TibiDaboHeadDriverNode::joint_position_callback(const trajectory_msgs::JointTrajectoryPoint::ConstPtr& msg) 
00134 { 
00135   std::vector<double> position(3,0.0),velocity(3,0.0);
00136   tibi_dabo_msgs::sequenceResult result;
00137   unsigned int i=0;
00138 
00139 //  ROS_INFO("TibiDaboHeadDriverNode::joint_position_callback: New Message Received"); 
00140 
00141   try{
00142     // get the current position of the head
00143     if(msg->positions.size()==3 && msg->velocities.size()==3)
00144     {
00145       for(i=0;i<3;i++)
00146       {
00147         position[i]=180.0*msg->positions[i]/3.14159;
00148         velocity[i]=180.0*msg->velocities[i]/3.14159;
00149       }
00150       this->driver_.lock(); 
00151       if(this->driver_.isRunning())
00152         this->driver_.move_absolute_angle(position,velocity);
00153       this->driver_.unlock(); 
00154     }
00155   }catch(CException &e){
00156     std::cout << e.what() << std::endl;
00157   }
00158 }
00159 
00160 void TibiDaboHeadDriverNode::facial_expression_callback(const std_msgs::String::ConstPtr& msg) 
00161 {
00162   tibi_dabo_msgs::sequenceResult result;
00163   std::string expression;
00164  
00165   ROS_DEBUG("TibiDaboHeadDriverNode::facial_expression_callback: New Message Received"); 
00166 
00167   //use appropiate mutex to shared variables if necessary 
00168   //this->driver_.lock(); 
00169   //this->facial_expression_mutex_.enter(); 
00170 
00171   this->driver_.lock();
00172   if( driver_.isRunning() )
00173   {
00174     expression=msg->data;
00175     this->driver_.set_brightness(80.0);
00176     this->driver_.set_face_expression(expression);
00177   }
00178   this->driver_.unlock();
00179   //unlock previously blocked shared variables 
00180   //this->driver_.unlock(); 
00181   //this->facial_expression_mutex_.exit(); 
00182 }
00183 
00184 /*  [service callbacks] */
00185 
00186 /*  [action callbacks] */
00187 void TibiDaboHeadDriverNode::motion_sequence_startCallback(const tibi_dabo_msgs::sequenceGoalConstPtr& goal)
00188 {
00189   std::string file;
00190   tibi_dabo_msgs::sequenceResult result;
00191 
00192   //lock access to driver if necessary
00193   this->driver_.lock();
00194 
00195   if( driver_.isRunning() )
00196   {
00197     if(this->joint_motion_aserver_.isActive())
00198     {
00199       result.successful.push_back(false);
00200       result.observations.push_back(std::string("A joint motion is in progress"));
00201       this->motion_sequence_aserver_.setAborted(result);
00202     }
00203     else
00204     {
00205       try{
00206         // add the full path to the incomming filename
00207         ROS_INFO("Head motion sequence file %s",goal->sequence_file[0].c_str());
00208         file=goal->sequence_file[0];
00209         this->driver_.start_motion_sequence(file);
00210       }catch(CException &e){
00211         result.successful.push_back(false);
00212         result.observations.push_back(e.what());
00213         this->motion_sequence_aserver_.setAborted(result);
00214       }
00215     }
00216   }
00217 
00218   //unlock access to driver if necessary
00219   this->driver_.unlock();
00220 }
00221 
00222 void TibiDaboHeadDriverNode::motion_sequence_stopCallback(void)
00223 {
00224   //lock access to driver if necessary
00225   this->driver_.lock();
00226 
00227   if( driver_.isRunning() )
00228   {
00229     try{
00230       this->driver_.stop_motion_sequence();
00231     }catch(CException &e){
00232       this->driver_.unlock();
00233       throw;
00234     }
00235   }
00236 
00237   //unlock access to driver if necessary
00238   this->driver_.unlock();
00239 }
00240 
00241 bool TibiDaboHeadDriverNode::motion_sequence_isFinishedCallback(void)
00242 {
00243   CEventServer *event_server=CEventServer::instance();
00244   bool finished=false;
00245 
00246   //lock access to driver if necessary
00247   this->driver_.lock();
00248 
00249   if( driver_.isRunning() )
00250   {
00251     finished=event_server->event_is_set(this->driver_.get_motion_sequence_complete_event_id());
00252   }
00253 
00254   //unlock access to driver if necessary
00255   this->driver_.unlock();
00256 
00257   return finished;
00258 }
00259 
00260 bool TibiDaboHeadDriverNode::motion_sequence_hasSucceedCallback(void)
00261 {
00262   CEventServer *event_server=CEventServer::instance();
00263   bool success=false;
00264 
00265   //lock access to driver if necessary
00266   this->driver_.lock();
00267 
00268   if( driver_.isRunning() )
00269   {
00270     success=!event_server->event_is_set(this->driver_.get_motion_sequence_error_event_id());
00271   }
00272 
00273   //unlock access to driver if necessary
00274   this->driver_.unlock();
00275 
00276   return success;
00277 }
00278 
00279 void TibiDaboHeadDriverNode::motion_sequence_getResultCallback(tibi_dabo_msgs::sequenceResultPtr& result)
00280 {
00281   CEventServer *event_server=CEventServer::instance();
00282 
00283   //lock access to driver if necessary
00284   this->driver_.lock();
00285 
00286   if( driver_.isRunning() )
00287   {
00288     result->successful.clear();
00289     result->observations.clear();
00290     result->successful.push_back(!event_server->event_is_set(this->driver_.get_motion_sequence_error_event_id()));
00291     result->observations.push_back(this->driver_.get_motion_sequence_error_message());
00292   }
00293 
00294   //unlock access to driver if necessary
00295   this->driver_.unlock();
00296 }
00297 
00298 void TibiDaboHeadDriverNode::motion_sequence_getFeedbackCallback(tibi_dabo_msgs::sequenceFeedbackPtr& feedback)
00299 {
00300   //lock access to driver if necessary
00301   this->driver_.lock();
00302 
00303   if( driver_.isRunning() )
00304   {
00305     try{
00306       feedback->percentage.clear();
00307       feedback->percentage.push_back(this->driver_.get_motion_sequence_completed_percentage());
00308     }catch(CException &e){
00309       this->driver_.unlock();
00310       throw;
00311     }
00312   }
00313 
00314   //unlock access to driver if necessary
00315   this->driver_.unlock();
00316 }
00317 
00318 void TibiDaboHeadDriverNode::joint_motion_startCallback(const control_msgs::FollowJointTrajectoryGoalConstPtr& goal)
00319 {
00320   control_msgs::FollowJointTrajectoryResult result;
00321   std::vector<double> current_position(3);
00322   std::vector<TDynamixelMotionStep> seq;
00323   unsigned int i=0,j=0;
00324   TDynamixelMotionStep step;
00325 
00326   //lock access to driver if necessary
00327   this->driver_.lock();
00328 
00329   if( driver_.isRunning() )
00330   {
00331     if(this->motion_sequence_aserver_.isActive())
00332       this->joint_motion_aserver_.setAborted(result,std::string("A motion sequence has been started"));
00333     else
00334     {
00335       try{
00336         this->driver_.get_position(current_position);
00337         // generate and execute the motion sequence
00338         for(i=0;i<goal->trajectory.points.size();i++)
00339         {
00340           step.position=current_position;
00341           step.velocity.resize(3,0.0);
00342           for(j=0;j<goal->trajectory.joint_names.size();j++)
00343           {
00344             if(goal->trajectory.joint_names[j]=="pan")
00345             {
00346               step.position[0]=goal->trajectory.points[i].positions[j]*180.0/3.14159;
00347               step.velocity[0]=goal->trajectory.points[i].velocities[j]*180.0/3.14159;
00348             }
00349             else if(goal->trajectory.joint_names[j]=="tilt")
00350             {
00351               step.position[1]=goal->trajectory.points[i].positions[j]*180.0/3.14159;
00352               step.velocity[1]=goal->trajectory.points[i].velocities[j]*180.0/3.14159;
00353             }
00354             else if(goal->trajectory.joint_names[j]=="roll")
00355             {
00356               step.position[2]=goal->trajectory.points[i].positions[j]*180.0/3.14159;
00357               step.velocity[2]=goal->trajectory.points[i].velocities[j]*180.0/3.14159;
00358             }
00359           }
00360           step.delay=goal->trajectory.points[i].time_from_start.toSec()*1000;
00361           seq.push_back(step);
00362           // set the next current position;
00363           current_position=step.position;
00364         }
00365         this->driver_.start_motion_sequence(seq);
00366       }catch(CException &e){
00367         this->joint_motion_aserver_.setAborted(result);
00368       }
00369     }
00370   }
00371 
00372   //unlock access to driver if necessary
00373   this->driver_.unlock();
00374 }
00375 
00376 void TibiDaboHeadDriverNode::joint_motion_stopCallback(void)
00377 {
00378   //lock access to driver if necessary
00379   this->driver_.lock();
00380 
00381   if( driver_.isRunning() )
00382   {
00383     try{
00384       this->driver_.stop();
00385     }catch(CException &e){
00386       this->driver_.unlock();
00387       throw;
00388     }
00389   }
00390 
00391   //unlock access to driver if necessary
00392   this->driver_.unlock();
00393 }
00394 
00395 bool TibiDaboHeadDriverNode::joint_motion_isFinishedCallback(void)
00396 {
00397   CEventServer *event_server=CEventServer::instance();
00398   bool finished=false;
00399 
00400   //lock access to driver if necessary
00401   this->driver_.lock();
00402 
00403   if( driver_.isRunning() )
00404   {
00405     finished=event_server->event_is_set(this->driver_.get_motion_sequence_complete_event_id());
00406   }
00407 
00408   //unlock access to driver if necessary
00409   this->driver_.unlock();
00410 
00411   return finished;
00412 }
00413 
00414 bool TibiDaboHeadDriverNode::joint_motion_hasSucceedCallback(void)
00415 {
00416   CEventServer *event_server=CEventServer::instance();
00417 
00418   //lock access to driver if necessary
00419   this->driver_.lock();
00420   bool success=false;
00421 
00422   if( driver_.isRunning() )
00423   {
00424     success=!event_server->event_is_set(this->driver_.get_motion_sequence_error_event_id());
00425   }
00426 
00427   //unlock access to driver if necessary
00428   this->driver_.unlock();
00429 
00430   return success;
00431 }
00432 
00433 void TibiDaboHeadDriverNode::joint_motion_getResultCallback(control_msgs::FollowJointTrajectoryResultPtr& result)
00434 {
00435   CEventServer *event_server=CEventServer::instance();
00436 
00437   //lock access to driver if necessary
00438   this->driver_.lock();
00439 
00440   if( driver_.isRunning() )
00441   {
00442     if(event_server->event_is_set(this->driver_.get_motion_sequence_error_event_id()))
00443       result->error_code=-1;
00444     else
00445       result->error_code=0;
00446   }
00447 
00448   //unlock access to driver if necessary
00449   this->driver_.unlock();
00450 }
00451 
00452 void TibiDaboHeadDriverNode::joint_motion_getFeedbackCallback(control_msgs::FollowJointTrajectoryFeedbackPtr& feedback)
00453 {
00454   std::vector<double> position,velocity;
00455   unsigned int i=0;
00456 
00457   //lock access to driver if necessary
00458   this->driver_.lock();
00459 
00460   if( driver_.isRunning() )
00461   {
00462     try{
00463       this->driver_.get_position(position);
00464       this->driver_.get_velocity(velocity); 
00465       for(i=0;i<position.size();i++)
00466       {
00467         feedback->actual.positions.push_back(position[i]);
00468         feedback->actual.velocities.push_back(velocity[i]);
00469       }
00470     }catch(CException &e){
00471       this->driver_.unlock();
00472       throw;
00473     }
00474   }
00475 
00476   //unlock access to driver if necessary
00477   this->driver_.unlock();
00478 }
00479 /*  [action requests] */
00480 
00481 void TibiDaboHeadDriverNode::postNodeOpenHook(void)
00482 {
00483   this->motion_sequence_aserver_.start();
00484   ROS_INFO("TibiDaboHeadDriverNode:: Motion sequence server started!");
00485   this->joint_motion_aserver_.start();
00486   ROS_INFO("TibiDaboHeadDriverNode:: Joint motion server started!");
00487 }
00488 
00489 void TibiDaboHeadDriverNode::preNodeCloseHook(void)
00490 {
00491   if(this->motion_sequence_aserver_.isStarted())
00492   {
00493     this->motion_sequence_aserver_.shutdown(); 
00494     ROS_INFO("TibiDaboHeadDriverNode:: Motion sequence server stopped!");
00495   }
00496   if(this->joint_motion_aserver_.isStarted())
00497   {
00498     this->joint_motion_aserver_.shutdown(); 
00499     ROS_INFO("TibiDaboHeadDriverNode:: Joint motion server stopped!");
00500   }
00501 //  ros::shutdown();
00502 }
00503 
00504 void TibiDaboHeadDriverNode::addNodeDiagnostics(void)
00505 {
00506   diagnostic_.add("Motion sequence status", this, &TibiDaboHeadDriverNode::check_motion_sequence_status);
00507 }
00508 
00509 void TibiDaboHeadDriverNode::addNodeOpenedTests(void)
00510 {
00511 }
00512 
00513 void TibiDaboHeadDriverNode::addNodeStoppedTests(void)
00514 {
00515 }
00516 
00517 void TibiDaboHeadDriverNode::addNodeRunningTests(void)
00518 {
00519 }
00520 
00521 void TibiDaboHeadDriverNode::reconfigureNodeHook(int level)
00522 {
00523 }
00524 
00525 TibiDaboHeadDriverNode::~TibiDaboHeadDriverNode()
00526 {
00527   this->driver_.lock();
00528   // [free dynamic memory]
00529   if(this->motion_sequence_aserver_.isActive())
00530   {
00531     this->motion_sequence_aserver_.setAborted();
00532     this->driver_.stop_motion_sequence();
00533   } 
00534   this->driver_.unlock();
00535 }
00536 
00537 /* main function */
00538 int main(int argc,char *argv[])
00539 {
00540   return driver_base::main<TibiDaboHeadDriverNode>(argc, argv, "tibi_dabo_head_driver_node");
00541 }


tibi_dabo_head_node
Author(s): Sergi Hernandez Juan
autogenerated on Fri Dec 6 2013 21:36:40