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
00014 this->loop_rate_ = 100;
00015
00016
00017 this->joint_feedback_publisher_ = this->public_node_handle_.advertise<sensor_msgs::JointState>("joint_feedback", 100);
00018
00019
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
00024
00025
00026
00027
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
00042
00043
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
00069 this->driver_.lock();
00070
00071
00072 this->loop_rate_ = this->driver_.get_feedback_rate();
00073
00074
00075 this->JointState_msg_.header.stamp = ros::Time::now();
00076
00077
00078
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
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
00094
00095
00096
00097
00098 this->joint_feedback_publisher_.publish(this->JointState_msg_);
00099
00100
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
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
00140
00141 try{
00142
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
00168
00169
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
00180
00181
00182 }
00183
00184
00185
00186
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
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
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
00219 this->driver_.unlock();
00220 }
00221
00222 void TibiDaboHeadDriverNode::motion_sequence_stopCallback(void)
00223 {
00224
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
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
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
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
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
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
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
00295 this->driver_.unlock();
00296 }
00297
00298 void TibiDaboHeadDriverNode::motion_sequence_getFeedbackCallback(tibi_dabo_msgs::sequenceFeedbackPtr& feedback)
00299 {
00300
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
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
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
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
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
00373 this->driver_.unlock();
00374 }
00375
00376 void TibiDaboHeadDriverNode::joint_motion_stopCallback(void)
00377 {
00378
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
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
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
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
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
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
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
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
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
00477 this->driver_.unlock();
00478 }
00479
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
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
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
00538 int main(int argc,char *argv[])
00539 {
00540 return driver_base::main<TibiDaboHeadDriverNode>(argc, argv, "tibi_dabo_head_driver_node");
00541 }