00001 #include "dabo_intro_alg_node.h"
00002 #include <wiimote/State.h>
00003
00004 DaboIntroAlgNode::DaboIntroAlgNode(void) :
00005 algorithm_base::IriBaseAlgorithm<DaboIntroAlgorithm>(),
00006 hri_client_client_("hri_client", true)
00007 {
00008
00009
00010
00011
00012
00013
00014 this->joy_subscriber_ = this->public_node_handle_.subscribe("joy", 1, &DaboIntroAlgNode::joy_callback, this);
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 this->hriActive =false;
00026 this->trigger_forward =false;
00027 this->trigger_backward=false;
00028 this->current_language=0;
00029 this->robot=0;
00030 this->hri_client_goal_.sequence_file.resize(5);
00031
00032 std::locale::global(std::locale(""));
00033 this->loadSequences();
00034 }
00035
00036 DaboIntroAlgNode::~DaboIntroAlgNode(void)
00037 {
00038
00039 }
00040
00041 void DaboIntroAlgNode::mainNodeThread(void)
00042 {
00043 static int state=1;
00044
00045
00046
00047
00048
00049
00050
00051 alg_.lock();
00052 switch(state)
00053 {
00054
00055 case 0:
00056 if(this->trigger_forward)
00057 {
00058
00059 {
00060 this->trigger_forward=false;
00061 state++;
00062 }
00063 }
00064 else if(this->trigger_backward)
00065 {
00066 this->trigger_backward=false;
00067 state=5;
00068 }
00069 break;
00070
00071 case 1:
00072 if(this->trigger_forward)
00073 {
00074 if(this->doHri(state))
00075 {
00076 this->trigger_forward=false;
00077 state=2;
00078 }
00079 }
00080 else if(this->trigger_backward)
00081 {
00082 this->trigger_backward=false;
00083 state=6;
00084 }
00085 break;
00086
00087 case 2:
00088 if(this->trigger_forward)
00089 {
00090 if(this->doHri(state))
00091 {
00092 this->trigger_forward=false;
00093 state=4;
00094 }
00095 }
00096 else if(this->trigger_backward)
00097 {
00098 this->trigger_backward=false;
00099 state=1;
00100 }
00101 break;
00102
00103 case 3:
00104 if(this->trigger_forward)
00105 {
00106
00107 {
00108 this->trigger_forward=false;
00109 state++;
00110 }
00111 }
00112 else if(this->trigger_backward)
00113 {
00114 this->trigger_backward=false;
00115 state--;
00116 }
00117 break;
00118
00119 case 4:
00120 if(this->trigger_forward)
00121 {
00122 if(this->doHri(state))
00123 {
00124 this->trigger_forward=false;
00125 state=6;
00126 }
00127 }
00128 else if(this->trigger_backward)
00129 {
00130 this->trigger_backward=false;
00131 state=2;
00132 }
00133 break;
00134
00135 case 5:
00136 if(this->trigger_forward)
00137 {
00138
00139 {
00140 this->trigger_forward=false;
00141 state++;
00142 }
00143 }
00144 else if(this->trigger_backward)
00145 {
00146 this->trigger_backward=false;
00147 state--;
00148 }
00149 break;
00150
00151 case 6:
00152 if(this->trigger_forward)
00153 {
00154 if(this->doHri(state))
00155 {
00156 this->trigger_forward=false;
00157 state=1;
00158 }
00159 }
00160 else if(this->trigger_backward)
00161 {
00162 this->trigger_backward=false;
00163 state=4;
00164 }
00165 break;
00166
00167 case 7:
00168 if(this->trigger_forward)
00169 {
00170
00171 {
00172 this->trigger_forward=false;
00173 state=0;
00174 }
00175 }
00176 else if(this->trigger_backward)
00177 {
00178 this->trigger_backward=false;
00179 state--;
00180 }
00181 break;
00182 }
00183
00184 this->alg_.unlock();
00185
00186
00187
00188
00189
00190
00191
00192
00193 }
00194
00195 bool DaboIntroAlgNode::doHri(int state)
00196 {
00197 bool done=false;
00198 static int index = 0;
00199 int number = this->speech[state].size();
00200
00201 if(!hriActive)
00202 {
00203 if(index<number)
00204 {
00205 this->fillHriGoal(state,index);
00206 hri_clientMakeActionRequest();
00207 ROS_INFO("DaboIntroAlgNode:doHri: speech[%d][%d][%d]: %s", state, index, this->current_language, this->hri_client_goal_.sequence_file[0].c_str());
00208 index++;
00209 }
00210 else
00211 {
00212 done=true;
00213 index=0;
00214 }
00215 }
00216 return done;
00217 }
00218
00219 void DaboIntroAlgNode::fillHriGoal(int state, int index)
00220 {
00221 this->hri_client_goal_.sequence_file[0] = this->hri_prefix[this->robot][this->current_language] + this->speech[state][index][this->current_language];
00222 this->hri_client_goal_.sequence_file[1] = "";
00223 this->hri_client_goal_.sequence_file[2] = this->head_sequence[state][index][this->current_language];
00224 this->hri_client_goal_.sequence_file[4] = this->left_arm_sequence[state][index][this->current_language];
00225 this->hri_client_goal_.sequence_file[3] = this->right_arm_sequence[state][index][this->current_language];
00226 }
00227
00228
00229 void DaboIntroAlgNode::joy_callback(const sensor_msgs::Joy::ConstPtr& msg)
00230 {
00231
00232 static std::vector<int> prev_buttons(msg->buttons);
00233
00234 this->alg_.lock();
00235
00236 if(msg->buttons[wiimote::State::MSG_BTN_PLUS]==1 && prev_buttons[wiimote::State::MSG_BTN_PLUS]==0)
00237 {
00238 ROS_INFO("DaboIntroAlgNode::joy_callback: trigger forward");
00239 this->trigger_forward =true;
00240 this->trigger_backward=false;
00241 }
00242 else if(msg->buttons[wiimote::State::MSG_BTN_MINUS]==1 && prev_buttons[wiimote::State::MSG_BTN_MINUS]==0)
00243 {
00244 ROS_INFO("DaboIntroAlgNode::joy_callback: trigger backward");
00245 this->trigger_backward=true;
00246 this->trigger_forward =false;
00247 }
00248 else if(msg->buttons[wiimote::State::MSG_BTN_HOME]==1 && prev_buttons[wiimote::State::MSG_BTN_HOME]==0)
00249 {
00250 ROS_INFO("TibiDaboIntroAlgNode::joy_callback: cancel hri");
00251 this->hri_client_client_.cancelGoal();
00252 }
00253 prev_buttons=msg->buttons;
00254 this->alg_.unlock();
00255 }
00256
00257
00258
00259
00260 void DaboIntroAlgNode::hri_clientDone(const actionlib::SimpleClientGoalState& state, const tibi_dabo_msgs::sequenceResultConstPtr& result)
00261 {
00262 this->alg_.lock();
00263 if( state.toString().compare("SUCCEEDED") == 0 )
00264 ROS_INFO("DaboIntroAlgNode::hri_clientDone: Goal Achieved!");
00265 else
00266 ROS_INFO("DaboIntroAlgNode::hri_clientDone: %s", state.toString().c_str());
00267
00268
00269 this->hriActive=false;
00270 this->alg_.unlock();
00271 }
00272
00273 void DaboIntroAlgNode::hri_clientActive()
00274 {
00275 this->alg_.lock();
00276
00277 this->hriActive=true;
00278 this->alg_.unlock();
00279 }
00280
00281 void DaboIntroAlgNode::hri_clientFeedback(const tibi_dabo_msgs::sequenceFeedbackConstPtr& feedback)
00282 {
00283 this->alg_.lock();
00284
00285
00286 bool feedback_is_ok = true;
00287
00288
00289
00290
00291
00292 if( !feedback_is_ok )
00293 {
00294 hri_client_client_.cancelGoal();
00295
00296 }
00297 this->alg_.unlock();
00298 }
00299
00300
00301 void DaboIntroAlgNode::hri_clientMakeActionRequest()
00302 {
00303 ROS_INFO("DaboIntroAlgNode::hri_clientMakeActionRequest: Starting New Request!");
00304
00305
00306
00308 ROS_INFO("DaboIntroAlgNode::hri_clientMakeActionRequest: Server is Available!");
00309
00310
00311
00312 hri_client_client_.sendGoal(hri_client_goal_,
00313 boost::bind(&DaboIntroAlgNode::hri_clientDone, this, _1, _2),
00314 boost::bind(&DaboIntroAlgNode::hri_clientActive, this),
00315 boost::bind(&DaboIntroAlgNode::hri_clientFeedback, this, _1));
00316 ROS_INFO("DaboIntroAlgNode::hri_clientMakeActionRequest: Goal Sent. Wait for Result!");
00318 }
00319
00320 void DaboIntroAlgNode::loadSequences()
00321 {
00322 std::vector < std::vector < std::string > > sequence;
00323 std::vector < std::string > sentence;
00324
00325
00326 sentence.push_back("Hola, bienvenidos al laboratorio de robótica móvil.");
00327 sentence.push_back("Hola, benvinguts al laboratori de robòtica mòbil.");
00328 sentence.push_back("Hello, welcome to the mobile robotics laboratory.");
00329 sequence.push_back(sentence);
00330 sentence.clear();
00331 sentence.push_back("Ahora os presentaremos algunos de los robots que tenemos por aquí.");
00332 sentence.push_back("Ara us presentarem alguns dels robots que tenim per aquí.");
00333 sentence.push_back("Now we will present some of the robots we have here.");
00334 sequence.push_back(sentence);
00335 sentence.clear();
00336 this->speech.push_back(sequence);
00337 sequence.clear();
00338
00339
00340 sentence.push_back("Yo soy Dabo. Un robot de servicio, social, y urbano.");
00341 sentence.push_back("Jo sóc Dàbo. Un robot de servei, social, i urbà.");
00342 sentence.push_back("I am Dabo. A service, social, and urban robot.");
00343 sequence.push_back(sentence);
00344 sentence.clear();
00345 this->speech.push_back(sequence);
00346 sequence.clear();
00347
00348
00349 sentence.push_back("Continuemos. Por aquí tenemos a Teo. Es un robot todo terreno de cuatro ruedas, que puede hacer mapas 3 d.");
00350 sentence.push_back("Continuem. Per aquí tenim el Téóh. És un robot tot terreny de quatre rodes, que pot fer mapes 3 d.");
00351 sentence.push_back("Let's continue. Here we have Teo. It's an all terrain robot with four wheels.");
00352 sequence.push_back(sentence);
00353 sentence.clear();
00354 this->speech.push_back(sequence);
00355 sequence.clear();
00356
00357
00358 sentence.push_back("Ahora os enseñaremos los humanoides.");
00359 sentence.push_back("Ara us ensenyarem els humanoides.");
00360 sentence.push_back("Now we will show you the humanoids.");
00361 sequence.push_back(sentence);
00362 sentence.clear();
00363 sentence.push_back("Son unos pequeños robots con piernas y brazos que pueden caminar, subir escaleras, jugar a sumo, e incluso jugar a fútbol.");
00364 sentence.push_back("Són uns petits robots amb cames i braços que poden caminar, pujar escales, jugar a sumo, i fins i tot jugar a futbol.");
00365 sentence.push_back("They are little robots with legs and arms who can walk, climb stairs, play sumo, and even soccer.");
00366 sequence.push_back(sentence);
00367 sentence.clear();
00368 this->speech.push_back(sequence);
00369 sequence.clear();
00370
00371
00372 sentence.push_back("Y aquí veis a Kinton, nuestro robot volador. Es como un helicóptero con cuatro hélices.");
00373 sentence.push_back("I aquí veieu el kíntoun, el nostre robot volador. És com un helicòpter amb quatre hèlices.");
00374 sentence.push_back("And here you can see Kinton, our flying robot. Is like a helicopter with four helixs.");
00375 sequence.push_back(sentence);
00376 sentence.clear();
00377 sentence.push_back("Aunque no puede volar aquí, lo utilizamos en investigación de vehículos aéreos, y vuelo autònomo.");
00378 sentence.push_back("Encara que aquí no pot volar, el fem servir en investigació de vehicles aeris i, vol autònom.");
00379 sentence.push_back("Although it can not fly here, we use it for air vehicle research and autonomous flight.");
00380 sequence.push_back(sentence);
00381 sentence.clear();
00382 this->speech.push_back(sequence);
00383 sequence.clear();
00384
00385
00386 sentence.push_back("Si teneis preguntas, ahora es el momento. No dudeis en preguntar, intentaremos responderlas todas.");
00387 sentence.push_back("Si teniu preguntes, ara és el moment. No dubteu en demanar-les, intentarem resoldre-les totes.");
00388 sentence.push_back("If you have questions, now is the moment. Don't doubt to ask them to us, we will try to solve them all.");
00389 sequence.push_back(sentence);
00390 sentence.clear();
00391 this->speech.push_back(sequence);
00392 sequence.clear();
00393
00394
00395 sentence.push_back("Muchas gracias por haber venido. Esperamos que os haya gustado esta visita virtual.");
00396 sentence.push_back("Moltes gràcies per haver vingut. Esperem que us hagi agradat aquesta visita virtual.");
00397 sentence.push_back("Thank you for coming, We hope you have enjoyed this virtual visit.");
00398 sequence.push_back(sentence);
00399 sentence.clear();
00400 this->speech.push_back(sequence);
00401 sequence.clear();
00402
00403
00404 sentence.push_back("Ha sido un placer. Hasta la próxima. Adiós!");
00405 sentence.push_back("Ha estat un plaer. Fins la propera. Adéu!");
00406 sentence.push_back("It's been a pleasure. See you next time. Bye!");
00407 sequence.push_back(sentence);
00408 sentence.clear();
00409 speech.push_back(sequence);
00410 sequence.clear();
00411
00412 int max_sentences = 2;
00413
00414 sentence.resize(3,"head_home.xml");
00415 sequence.resize(max_sentences,sentence);
00416 sentence.clear();
00417 this->head_sequence.resize(8,sequence);
00418 sequence.clear();
00419
00420
00421 sentence.resize(3,"left_arm_home.xml");
00422 sequence.resize(max_sentences,sentence);
00423 sentence.clear();
00424 this->left_arm_sequence.resize(8,sequence);
00425 sequence.clear();
00426
00427
00428 sentence.resize(3,"right_arm_home.xml");
00429 sequence.resize(max_sentences,sentence);
00430 sentence.clear();
00431 this->right_arm_sequence.resize(8,sequence);
00432 sequence.clear();
00433
00434
00435
00436 this->head_sequence[0][0][0] ="head_hi.xml";
00437 this->left_arm_sequence[0][0][0] ="left_arm_home.xml";
00438 this->right_arm_sequence[0][0][0]="right_arm_home.xml";
00439
00440 this->head_sequence[0][1][0] ="head_home.xml";
00441 this->left_arm_sequence[0][1][0] ="left_arm_home.xml";
00442 this->right_arm_sequence[0][1][0]="right_arm_home.xml";
00443
00444 this->head_sequence[1][0][0] ="head_talk_circle_6s.xml";
00445 this->left_arm_sequence[1][0][0] ="left_arm_talk.xml";
00446 this->right_arm_sequence[1][0][0]="right_arm_talk.xml";
00447
00448 this->head_sequence[1][1][0] ="head_talk_l_4s.xml";
00449
00450
00451
00452 this->head_sequence[2][0][0] = "head_down.xml";
00453
00454 this->head_sequence[3][0][0] ="head_talk_right_6s.xml";
00455 this->left_arm_sequence[3][0][0] ="left_arm_right.xml";
00456 this->right_arm_sequence[3][0][0]="right_arm_right.xml";
00457
00458 this->head_sequence[4][0][0] = "head_talk_l_4s.xml";
00459
00460 this->head_sequence[5][0][0] = "head_yes_4s.xml";
00461
00462 this->head_sequence[6][0][0] = "head_roll.xml";
00463
00464 this->head_sequence[7][0][0] = "head_side.xml";
00465
00466
00467 sentence.resize(3,"left_arm_home.xml");
00468 sequence.resize(max_sentences,sentence);
00469 sentence.clear();
00470 this->left_arm_sequence.resize(8,sequence);
00471 sequence.clear();
00472
00473
00474 sentence.resize(3,"right_arm_home.xml");
00475 sequence.resize(max_sentences,sentence);
00476 sentence.clear();
00477 this->right_arm_sequence.resize(8,sequence);
00478 sequence.clear();
00479
00480 std::vector < std::string > prefix;
00481 prefix.push_back("\\language=Spanish \\voice=Leonor ");
00482 prefix.push_back("\\language=Catalan \\voice=Montserrat ");
00483 prefix.push_back("\\language=English \\voice=Kate ");
00484 this->hri_prefix.push_back(prefix);
00485 prefix.clear();
00486 prefix.push_back("\\language=Spanish \\voice=Jorge ");
00487 prefix.push_back("\\language=Catalan \\voice=Jordi ");
00488 prefix.push_back("\\language=English \\voice=Simon ");
00489 this->hri_prefix.push_back(prefix);
00490 prefix.clear();
00491 }
00492
00493 void DaboIntroAlgNode::node_config_update(Config &config, uint32_t level)
00494 {
00495 this->alg_.lock();
00496 if(config.trigger_forward)
00497 {
00498 this->trigger_forward=config.trigger_forward;
00499 config.trigger_forward=false;
00500 }
00501 else if(config.trigger_backward)
00502 {
00503 this->trigger_backward=config.trigger_backward;
00504 config.trigger_backward=false;
00505 }
00506 this->current_language=config.language;
00507 if(config.robot=="tibi")
00508 {
00509 this->robot=0;
00510 }
00511 else if(config.robot=="dabo")
00512 {
00513 this->robot=1;
00514 }
00515 else
00516 {
00517 ROS_ERROR("TibiDaboIntroAlgNode::node_config_update: wrong parameter robot, must be tibi or dabo");
00518 config.robot="tibi";
00519 }
00520 if(config.stop_hri)
00521 {
00522 this->hri_client_client_.cancelGoal();
00523 config.stop_hri=false;
00524 }
00525 this->alg_.unlock();
00526 }
00527
00528 void DaboIntroAlgNode::addNodeDiagnostics(void)
00529 {
00530 }
00531
00532
00533 int main(int argc,char *argv[])
00534 {
00535 return algorithm_base::main<DaboIntroAlgNode>(argc, argv, "dabo_intro_alg_node");
00536 }