icub-client
proactiveTagging.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2015 WYSIWYD Consortium, European Commission FP7 Project ICT-612139
3 * Authors: GrĂ©goire Pointeau, Tobias Fischer, Maxime Petit
4 * email: greg.pointeau@gmail.com, t.fischer@imperial.ac.uk, m.petit@imperial.ac.uk
5 * Permission is granted to copy, distribute, and/or modify this program
6 * under the terms of the GNU General Public License, version 2 or any
7 * later version published by the Free Software Foundation.
8 *
9 * A copy of the license can be found at
10 * icub-client/license/gpl.txt
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 * Public License for more details
16 */
17 
18 #include "proactiveTagging.h"
19 
25 
26 using namespace yarp::os;
27 using namespace icubclient;
28 using namespace std;
29 
30 bool proactiveTagging::configure(yarp::os::ResourceFinder &rf) {
31  string moduleName = rf.check("name", Value("proactiveTagging")).asString().c_str();
32  setName(moduleName.c_str());
33 
34  GrammarAskNameObject = rf.findFileByName(rf.check("GrammarAskNameObject", Value("GrammarAskNameObject.xml")).toString());
35  GrammarAskNameAgent = rf.findFileByName(rf.check("GrammarAskNameAgent", Value("GrammarAskNameAgent.xml")).toString());
36  GrammarAskNameBodypart = rf.findFileByName(rf.check("GrammarAskNameBodypart", Value("GrammarAskNameBodypart.xml")).toString());
37 
38  babblingArm = rf.check("babblingArm", Value("left")).toString();
39 
40  thresholdDistinguishObjectsRatio = rf.check("thresholdDistinguishObjectsRatio", Value(3.0)).asDouble();
41  thresholdSalienceDetection = rf.check("thresholdSalienceDetection", Value(1.5)).asDouble();
42 
43  yDebug() << "------------> babblingArm: " << babblingArm;
44 
45  period = rf.check("period", Value(0.1)).asDouble();
46 
47  //Create an iCub Client and check that all dependencies are here before starting
48  bool isRFVerbose = true;
49  iCub = new ICubClient(moduleName, "proactiveTagging", "client.ini", isRFVerbose);
50  iCub->opc->isVerbose &= true;
51 
52  while (!iCub->connect()) {
53  yWarning() << "iCubClient : Some dependencies are not running...";
54  Time::delay(1.0);
55  }
56  iCub->opc->checkout();
57 
58  configureOPC(rf);
59 
60  std::string ttsOptions = rf.check("ttsOptions", yarp::os::Value("iCub")).toString();
61  if (ttsOptions != "iCub") {
62  if (iCub->getSpeechClient())
63  iCub->getSpeechClient()->SetOptions(ttsOptions);
64  }
65 
66  //--------------------------------------------- output ports
67  // out to pasar
68  portToPasar.open(("/" + moduleName + "/pasar:o").c_str());
69  if (!Network::connect(portToPasar.getName().c_str(), "/pasar/rpc")) {
70  yWarning() << "PASAR NOT CONNECTED: will not engage pointing";
71  iCub->say("PASAR NOT CONNECTED");
72  }
73 
74  //in from TouchDetector
75  portFromTouchDetector.open(("/" + moduleName + "/fromTouch:i").c_str());
76  touchDetectorRpc = rf.check("touchDetectorOut", Value("/touchDetector/touchClean:o")).asString().c_str();
77 
78  if (!Network::connect(touchDetectorRpc.c_str(), portFromTouchDetector.getName().c_str())) {
79  yWarning() << "TOUCH DETECTOR NOT CONNECTED: selfTagging will not work";
80  iCub->say("TOUCH DETECTOR NOT CONNECTED");
81  }
82 
83  if (!iCub->getRecogClient()) {
84  iCub->say("speech recognizer not connected");
85  yWarning() << "SPEECH RECOGNIZER NOT CONNECTED";
86  }
87 
88  //rpc port
89  rpcPort.open(("/" + moduleName + "/rpc").c_str());
90  attach(rpcPort);
91 
92  iCub->say("pro active tagging is ready", false);
93  yInfo() << "\n \n" << "----------------------------------------------" << "\n \n" << moduleName << " ready ! \n \n ";
94 
95  iCub->home();
96 
97  return true;
98 }
99 
100 
102  portFromTouchDetector.interrupt();
103  portToPasar.interrupt();
104  rpcPort.interrupt();
105 
106  return true;
107 }
108 
110  if(iCub) {
111  iCub->close();
112  delete iCub;
113  }
114 
115  portFromTouchDetector.interrupt();
116  portFromTouchDetector.close();
117 
118  portToPasar.interrupt();
119  portToPasar.close();
120 
121  rpcPort.interrupt();
122  rpcPort.close();
123 
124  return true;
125 }
126 
127 
128 bool proactiveTagging::respond(const Bottle& command, Bottle& reply) {
129  string helpMessage = string(getName().c_str()) +
130  " commands are: \n" +
131  "help \n" +
132  "quit \n" +
133  "change_name oldname newname \n" +
134  "exploreUnknownEntity entity_type entity_name \n" +
135  "searchingEntity entity_type entity_name \n";
136  reply.clear();
137 
138  if (command.get(0).asString() == "quit") {
139  reply.addString("quitting");
140 
141  rpcPort.reply(reply);
142  return false;
143  }
144  else if(command.get(0).asString() == "change_name") {
145  string oldname = command.get(1).toString();
146  string newname = command.get(2).toString();
147  yInfo() << "change_name from" << oldname << "to" << newname;
148  Entity *e = iCub->opc->getEntity(oldname);
149  if(!e) {
150  iCub->say("No entity with name " + oldname);
151  yError() << "No entity with name " << oldname;
152  reply.addString("nack");
153  } else {
154  iCub->changeName(e, newname);
155  reply.addString("ack");
156  }
157  }
158  else if (command.get(0).asString() == "exploreUnknownEntity") {
159  // disable EARS early on
160  iCub->getRecogClient()->enableEars(false);
161 
162  yInfo() << " exploreUnknownEntity";
163  string type = command.get(1).toString();
164  string name = command.get(2).toString();
165  yDebug() << "exploreUnknownEntity with name = " << name;
166 
167  if ((type == ICUBCLIENT_OPC_ENTITY_BODYPART) && (name.find("unknown") == std::string::npos)) { //type is bodypart and it already has a name
168  iCub->opc->checkout();
169  Bodypart* bp = dynamic_cast<Bodypart*>(iCub->opc->getEntity(name));
170  if(!bp) {
171  yError() << "Could not cast" << name << "to bodypart";
172  iCub->say("Could not cast " + name + " to bodypart");
173  } else {
174  if (bp->m_tactile_number == -1) {
175  yInfo() << "Going to tag skin part";
176  reply = exploreTactileEntityWithName(command);
177  } else {
178  yWarning("Not sure what to do, name and tactile information already known");
179  }
180  }
181  } else if (type == ICUBCLIENT_OPC_ENTITY_BODYPART) {
182  yInfo() << "Going to tag bodypart (include babbling)";
183  reply = exploreUnknownEntity(command);
184  }
185  else if (type == ICUBCLIENT_OPC_ENTITY_OBJECT) {
186  yInfo() << "Going to tag object (include a pointing)";
187  reply = exploreUnknownEntity(command);
188  } else if (type == ICUBCLIENT_OPC_ENTITY_AGENT) {
189  yInfo() << "Going to tag an agent (face recog)";
190  reply = exploreUnknownEntity(command);
191  } else {
192  yWarning() << "Type = " << type << " is NON valid for exploreUnknownEntity -> doing nothing";
193  reply.addString("error");
194  reply.addString("Type is NON valid for exploreUnknownEntity");
195  }
196 
197  // enable EARS again
198  iCub->getRecogClient()->enableEars(true);
199  }
200  else if (command.get(0).asString() == "searchingEntity") {
201  yInfo() << " searchingEntity";
202  reply = searchingEntity(command);
203  }
204  else {
205  yInfo() << helpMessage;
206  reply.addString(helpMessage);
207  }
208 
209  rpcPort.reply(reply);
210 
211  return true;
212 }
213 
214 /* Called periodically every getPeriod() seconds */
216  return true;
217 }
218 
219 Bottle proactiveTagging::getNameFromSAM(string sNameTarget, string currentEntityType) {
220  iCub->say("Have we met before?", false);
221  Bottle bOutput;
222  if (iCub->getSAMClient())
223  {
224  Bottle SAMreply = iCub->getSAMClient()->askXLabel("face");
225  if(SAMreply.get(0).asString() == "true")
226  {
227  string sNameSAM = SAMreply.get(1).asString();
228 
229  if(sNameSAM != "unknown" && sNameSAM != "" && sNameSAM != "None")
230  {
231  Entity* e = iCub->opc->getEntity(sNameTarget);
232  if(e) {
233  Agent* TARGET = dynamic_cast<Agent*>(e);
234  if(TARGET) {
235  yDebug() << "Changing name from " << TARGET->name() << " to " << sNameSAM;
236  iCub->changeName(TARGET,sNameSAM);
237  iCub->opc->commit(TARGET);
238 
239  iCub->say("Yes, I remember. Nice to see you, " + sNameSAM);
240  yarp::os::Time::delay(0.2);
241  iCub->home();
242 
243  bOutput.addString("success");
244  bOutput.addString(currentEntityType);
245  } else {
246  bOutput.addString("nack");
247  yError() << "Could not cast" << e->name() << "to Agent";
248  }
249  } else {
250  yError() << sNameTarget << "is not an entity";
251  bOutput.addString("nack");
252  }
253  } else {
254  yError() << "Classification not recognised";
255  bOutput.addString("nack");
256  }
257  } else {
258  yError() << "askXlabel failed";
259  bOutput.addString("nack");
260  }
261  } else {
262  yError() << "getSAMClient returned false";
263  bOutput.addString("nack");
264  }
265  return bOutput;
266 }
267 
268 yarp::os::Bottle proactiveTagging::exploreTactileEntityWithName(Bottle bInput) {
269  Bottle bOutput;
270 
271  if (bInput.size() != 3)
272  {
273  yError() << " proactiveTagging::exploreTactileEntityWithName | Problem in input size.";
274  bOutput.addString("nack");
275  bOutput.addString("Problem in input size");
276  iCub->say("Error in input size explore tactile with name");
277  return bOutput;
278  }
279 
280  string sName = bInput.get(2).toString();
281 
282  //1. search through opc for the bodypart entity
283  iCub->opc->checkout();
284  Bodypart* BPentity = dynamic_cast<Bodypart*>(iCub->opc->getEntity(sName, true));
285  if(!BPentity) {
286  iCub->say("Could not cast to bodypart in exploreTactileEntityWithName");
287  yError() << "Could not cast to bodypart in exploreTactileEntityWithName";
288  bOutput.addString("nack");
289  return bOutput;
290  }
291 
292  if (!Network::isConnected(touchDetectorRpc.c_str(), portFromTouchDetector.getName().c_str())) {
293  if (!Network::connect(touchDetectorRpc.c_str(), portFromTouchDetector.getName().c_str())) {
294  yError() << " proactiveTagging::exploreTactileEntityWithName | touch detector not connected.";
295  bOutput.addString("nack");
296  bOutput.addString("touch detector not connected");
297  iCub->say("I cannot feel my skin, sorry!");
298  return bOutput;
299  }
300  }
301 
302  //2.Ask human to touch
303  string sAsking = "I know how to move my " + getBodyPartNameForSpeech(sName) + ", but how does it feel when I touch something? Can you touch my " + getBodyPartNameForSpeech(sName) + " when I move it, please?";
304  iCub->lookAtPartner();
305  iCub->say(sAsking, false);
306  portFromTouchDetector.read(false); // clear buffer from previous readings
307 
308  yarp::os::Time::delay(1.0);
309 
310  // Move the bodypart to show it has been learnt
311  yInfo() << "Cast okay : name BP = " << BPentity->name();
312  int joint = BPentity->m_joint_number;
313  //send rpc command to babbling to move the corresponding part
314  yInfo() << "Start babbling";
315  double babbling_duration = 3.0;
316  iCub->babbling(joint, babblingArm, babbling_duration);
317 
318  //3. Read until some tactile value are detected
319  bool gotTouch = false;
320  Bottle *bTactile;
321  int timeout = 0;
322  while(!gotTouch && timeout<10) {
323  bTactile = portFromTouchDetector.read(false);
324  if(bTactile != nullptr) {
325  gotTouch = true;
326  break;
327  } else {
328  yarp::os::Time::delay(0.5);
329  timeout++;
330  }
331  }
332 
333  if(!gotTouch) {
334  yError() << " error in proactiveTagging::exploreTactileEntityWithName | for " << sName << " | Touch not detected!" ;
335  bOutput.addString("nack");
336  bOutput.addString("I did not feel any touch.");
337  iCub->say("I did not feel any touch.", false);
338  iCub->home();
339 
340  return bOutput;
341  }
342 
343  //4. Assign m_tactile_number
344  BPentity->m_tactile_number = bTactile->get(0).asInt();
345  bOutput.addString("ack");
346  bOutput.addInt(bTactile->get(0).asInt());
347  yDebug() << "Assigned" << BPentity->name() << "(id)" << BPentity->opc_id() << "tactile_number to" << bTactile->get(0).asInt();
348  iCub->opc->commit(BPentity);
349 
350  //4.Ask human to touch
351  string sThank = " Thank you, now I know when I am touching object with my " + getBodyPartNameForSpeech(sName);
352  iCub->lookAtPartner();
353  iCub->say(sThank);
354  iCub->home();
355 
356  return bOutput;
357 }
358 
359 
360 Bottle proactiveTagging::exploreUnknownEntity(const Bottle& bInput) {
361  Bottle bOutput;
362  if (bInput.size() != 3)
363  {
364  yInfo() << " proactiveTagging::exploreEntity | Problem in input size.";
365  bOutput.addString("Problem in input size");
366  return bOutput;
367  }
368 
369  iCub->opc->checkout();
370 
371  string currentEntityType = bInput.get(1).toString();
372  string sNameTarget = bInput.get(2).toString();
373 
374  yInfo() << " EntityType : " << currentEntityType;
375 
376  //Ask question for the human, or ask to pay attention (if action to focus attention after)
377  string sQuestion;
378  if (currentEntityType == ICUBCLIENT_OPC_ENTITY_AGENT) {
379  iCub->lookAtPartner();
380 
381  // try to do face recognition with SAM
382  if(iCub->getSAMClient()) {
383  Bottle recogFromSAM = getNameFromSAM(sNameTarget, currentEntityType);
384 
385  if (recogFromSAM.get(0).toString() == "nack" ){ // SAM responded but could not recognize face
386  sQuestion = " No, I don't know you. What is your name?";
387  }
388  else{ // SAM responded, directly return the Bottle from SAM
389  return recogFromSAM;
390  }
391  }
392  else // SAM not connected
393  {
394  sQuestion = " Hello, I don't know you. Who are you?";
395  }
396  }
397  else if (currentEntityType == ICUBCLIENT_OPC_ENTITY_OBJECT) {
398  iCub->look(sNameTarget);
399  sQuestion = " Hum, what is this object?";
400  }
401  else if (currentEntityType == ICUBCLIENT_OPC_ENTITY_BODYPART) {
402  iCub->lookAtPartner();
403  sQuestion = " Watch please, I will move a part of my body";
404  }
405  else {
406  yError() << " error in proactiveTagging::exploreUnknownEntity | for " << currentEntityType << " | Entity Type not managed";
407  bOutput.addString("nack");
408  bOutput.addString("Entity Type not managed");
409  return bOutput;
410  }
411 
412  yInfo() << sQuestion;
413  iCub->say(sQuestion, false);
414 
415  //Act to determine the entity to be named, according to entityType (e.g. bodypart is sending a command to move the joint, ...)
416  if (currentEntityType == "bodypart") {
417  Bodypart* BPtemp = dynamic_cast<Bodypart*>(iCub->opc->getEntity(sNameTarget));
418  if(!BPtemp) {
419  bOutput.addString("nack");
420  bOutput.addString("Could not cast to Bodypart");
421  iCub->say(bOutput.toString());
422  return bOutput;
423  }
424  int joint = BPtemp->m_joint_number;
425  //send rpc command to babbling to move the corresponding part
426  yInfo() << "Start babbling";
427  double babbling_duration=3.0;
428  iCub->babbling(joint, babblingArm, babbling_duration);
429 
430  iCub->lookAtPartner();
431  sQuestion = " How do you call this part of my body?";
432 
433  yInfo() << sQuestion;
434  iCub->say(sQuestion, false);
435  }
436  else if (currentEntityType == ICUBCLIENT_OPC_ENTITY_OBJECT) {
437  yDebug() << "Going to point to " << sNameTarget;
438  iCub->point(sNameTarget);
439  }
440 
441  // now detect name via speech recognizer
442  Bottle bName = recogName(currentEntityType);
443  string sName;
444 
445  if (bName.get(0).asString() == "error") {
446  return bName; //if error, bName = (error errorDescription) -> return it
447  }
448  else {
449  sName = bName.get(0).asString();
450  }
451 
452  string sReply;
453  // change name of the entity with name provided by human
454  Entity* e = iCub->opc->getEntity(sNameTarget);
455  iCub->changeName(e, sName);
456 
457  iCub->lookAtPartner();
458  if (currentEntityType == ICUBCLIENT_OPC_ENTITY_AGENT) {
459  sReply = " Nice to meet you " + sName;
460  }
461  else if (currentEntityType == ICUBCLIENT_OPC_ENTITY_OBJECT) {
462  sReply = " I get it, this is a " + sName;
463  }
464  else if (currentEntityType == ICUBCLIENT_OPC_ENTITY_BODYPART) {
465  sReply = " Nice, I know that I have a " + getBodyPartNameForSpeech(sName);
466  } else {
467  iCub->say("I do not know this entity type");
468  }
469 
470  iCub->say(sReply, false);
471  yarp::os::Time::delay(1.5);
472 
473  iCub->home();
474 
475  bOutput.addString("success");
476  bOutput.addString(currentEntityType);
477 
478  yInfo() << "End of exploreUnknownEntity";
479 
480  return bOutput;
481 }
482 
483 
484 Bottle proactiveTagging::searchingEntity(const Bottle &bInput) {
485  Bottle bOutput;
486 
487  if (bInput.size() < 3) {
488  yInfo() << " proactiveTagging::searchingEntity | Problem in input size.";
489  bOutput.addString("error");
490  bOutput.addString("Problem in input size");
491  return bOutput;
492  }
493 
494  string sTypeTarget = bInput.get(1).toString();
495  string sNameTarget = bInput.get(2).toString();
496  bool verboseSearch = true;
497  if(bInput.size() == 4) {
498  verboseSearch = bInput.get(3).asInt() > 0;
499  }
500  yInfo() << " Entity to find: " << sNameTarget << "(Type: " << sTypeTarget << ", verbosity: " << verboseSearch << ")";
501 
502  int unknownEntitiesPresent = 0; // # of unknown entities
503 
504  // check if the entity is already present in the OPC
505  if (iCub->opc->isConnected()) {
506  iCub->opc->checkout();
507  list<shared_ptr<Entity>> lEntities = iCub->opc->EntitiesCacheCopy();
508 
509  for (auto& entity : lEntities) {
510  if (entity->name() == sNameTarget && entity->entity_type() == sTypeTarget) {
511  yInfo() << " Entity " << sNameTarget << " is already known.";
512  bOutput.addString("warning");
513  bOutput.addString("entity already exists");
514  return bOutput;
515  }
516  Object *o = dynamic_cast<Object*>(entity.get());
517  if(o && o->name().find("unknown") != string::npos && o->entity_type() == sTypeTarget && o->m_present == 1.0) {
518  unknownEntitiesPresent++;
519  }
520  }
521 
522  if(unknownEntitiesPresent == 0) {
523  yInfo() << "No unknown entity is present.";
524  bOutput.addString("nack");
525  bOutput.addString("No unknown entity is present.");
526  return bOutput;
527  } else if(unknownEntitiesPresent == 1) {
528  yInfo() << "There is only one unknown entity";
529  for (auto& entity : lEntities) {
530  Object *o = dynamic_cast<Object*>(entity.get());
531  if(o && o->name().find("unknown") != string::npos && o->entity_type() == sTypeTarget && o->m_present == 1.0) {
532  iCub->lookAtPartner();
533  iCub->say("There was only one object which I didn't know");
534  iCub->changeName(o, sNameTarget);
535  yDebug() << "Changed name for" << sNameTarget;
536  iCub->say("Now I know the " + sNameTarget, false);
537  iCub->home();
538 
539  bOutput.addString("name changed");
540  return bOutput;
541  }
542  }
543  }
544  } else {
545  yWarning() << " in proactiveTagging::searchingEntity | OPC not Connected";
546  bOutput.addString("error");
547  bOutput.addString("OPC not connected");
548 
549  return bOutput;
550  }
551 
552  // if there are several objects unknown
553  string sSentence;
554  if(verboseSearch) {
555  if(sTypeTarget == ICUBCLIENT_OPC_ENTITY_OBJECT) {
556  sSentence = "I don't known which of these objects is a " + sNameTarget + ". Can you show me the " + sNameTarget;
557  } else if (sTypeTarget == ICUBCLIENT_OPC_ENTITY_BODYPART) {
558  sSentence = "I don't known my " + sNameTarget + ". Can you please touch my " + sNameTarget;
559  }
560 
561  iCub->lookAtPartner();
562  iCub->say(sSentence);
563  }
564 
565  if(sTypeTarget == ICUBCLIENT_OPC_ENTITY_OBJECT) { // activate pointing detection in pasar if it's an object
566  iCub->home();
567 
568  bool success = setPasarPointing(true);
569  if(!success) {
570  yError() << "Problem with pasar when setPasarPointing(true)";
571  bOutput.addString("error");
572  bOutput.addString("Problem with pasar");
573  return bOutput;
574  }
575  }
576 
577  string sNameBestEntity = getBestEntity(sTypeTarget);
578  if(sNameBestEntity=="none") {
579  iCub->say("you did not point at any object");
580  yError() << "you did not point at any object";
581  bOutput.addString("error");
582  bOutput.addString("no pointing received");
583  return bOutput;
584  }
585 
586  // change name
587  Object* TARGET = dynamic_cast<Object*>(iCub->opc->getEntity(sNameBestEntity));
588  if(sTypeTarget == ICUBCLIENT_OPC_ENTITY_OBJECT) {
589  iCub->look(TARGET->name());
590  }
591 
592  iCub->changeName(TARGET,sNameTarget);
593 
594  yInfo() << " name changed: " << sNameBestEntity << " is now " << sNameTarget;
595  bOutput.addString("name changed");
596  iCub->say("Now I know the " + sNameTarget, false);
597 
598  // de-activate pointing detection in pasar
599  if(sTypeTarget == ICUBCLIENT_OPC_ENTITY_OBJECT) {
600  bool success = setPasarPointing(false);
601  if(!success) {
602  yError() << "Problem with pasar when setPasarPointing(false)";
603  bOutput.addString("error");
604  bOutput.addString("Problem with pasar");
605  return bOutput;
606  }
607  }
608 
609  iCub->home();
610 
611  return bOutput;
612 }
int opc_id() const
Return the id of an entity (which has to be unique within the OPC) Typically, modules should employ t...
Definition: entity.h:101
Represent any entity that can be stored within the OPC.
Definition: entity.h:40
Grants access to high level motor commands (grasp, touch, look, goto, etc) of the robot as well as it...
Definition: icubClient.h:66
double m_present
Is the object present in the scene A value of 1.0 means that the object currently is in the scene A v...
Definition: object.h:69
bool configure(yarp::os::ResourceFinder &rf)
yarp::os::Bottle searchingEntity(const yarp::os::Bottle &bInput)
Search for the entity corresponding to a certain name in all the unknown entities.
int m_tactile_number
Tactile number of the represented body part.
Definition: bodypart.h:43
STL namespace.
Represent any physical entity (including objects and agents) that can be stored within the OPC...
Definition: object.h:35
void changeName(std::string sName)
Definition: entity.cpp:149
Represent an agent.
Definition: agent.h:93
#define ICUBCLIENT_OPC_ENTITY_BODYPART
Definition: tags.h:39
int m_joint_number
Joint number of the represented body part.
Definition: bodypart.h:38
Represents a body part of the robot.
Definition: bodypart.h:29
yarp::os::Bottle exploreUnknownEntity(const yarp::os::Bottle &bInput)
Explore an unknown entity by asking for the name (response via speech recognition) ...
std::string name() const
Return the name of an entity (which has to be unique within the OPC)
Definition: entity.h:93
yarp::os::Bottle getNameFromSAM(std::string sNameTarget, std::string currentEntityType)
Send request to SAM to use its face recognition to recognise partner.
#define ICUBCLIENT_OPC_ENTITY_OBJECT
Definition: tags.h:38
bool respond(const yarp::os::Bottle &cmd, yarp::os::Bottle &reply)
yarp::os::Bottle exploreTactileEntityWithName(yarp::os::Bottle bInput)
Explore an unknown tactile entity (e.g.
#define ICUBCLIENT_OPC_ENTITY_AGENT
Definition: tags.h:40
std::string entity_type() const
Return the specific type of an entity.
Definition: entity.h:121