icub-client
guiUpdater.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 WYSIWYD Consortium, European Commission FP7 Project ICT-612139
3  * Authors: Stéphane Lallée
4  * email: stephane.lallee@gmail.com
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 <yarp/os/all.h>
19 #include <yarp/sig/all.h>
20 #include <yarp/dev/all.h>
21 #include <iostream>
22 #include <string>
23 #include <map>
24 #include <list>
25 
26 #include "guiUpdater.h"
27 
28 using namespace std;
29 using namespace yarp;
30 using namespace yarp::sig;
31 using namespace yarp::os;
32 using namespace yarp::dev;
33 
34 
35 bool GuiUpdater::configure(yarp::os::ResourceFinder &rf)
36 {
37  string moduleName = rf.check("name", Value("guiUpdater"), "module name (string)").asString().c_str();
38  string opcName = rf.check("OPCname", Value("OPC"), "OPC name (string)").asString().c_str();
39 
40  setName(moduleName.c_str());
41 
42  displaySkeleton = rf.check("displaySkeletons");
43  yInfo() << "Display skeleton status:" << displaySkeleton;
44 
45  opc = new OPCClient(getName().c_str());
46  opc->connect(opcName);
47  opc->isVerbose = false;
48  if(opc->isConnected()) {
49  iCub = opc->addOrRetrieveEntity<Agent>("icub");
50  } else {
51  yError() << "Could not connect to OPC, abort";
52  return false;
53  }
54 
55  //GUI Port
56  toGui.open("/" + getName() + "/gui:o");
57  resetGUI();
58 
59  //GUI Base Port
60  toGuiBase.open("/" + getName() + "/guiBase:o");
61 
62  //RPC
63  if (!handlerPort.open("/" + getName() + "/rpc")) {
64  yError() << getName() << ": Unable to open port " << handlerPort.getName();
65  return false;
66  }
67  attach(handlerPort);
68 
69  return true;
70 }
71 
73 {
74  handlerPort.interrupt();
75  opc->interrupt();
76  toGui.interrupt();
77  toGuiBase.interrupt();
78  return true;
79 }
80 
82 {
83  yDebug() << "close";
84  handlerPort.interrupt();
85  handlerPort.close();
86 
87  if(opc) {
88  opc->close();
89  delete opc;
90  }
91 
92  toGui.interrupt();
93  toGui.close();
94  toGuiBase.interrupt();
95  toGuiBase.close();
96 
97  yDebug() << "bye";
98 
99  return true;
100 }
101 
102 bool GuiUpdater::respond(const yarp::os::Bottle& command, yarp::os::Bottle& reply)
103 {
104  string helpMessage = string(getName().c_str()) +
105  " commands are: \n" +
106  "reset \n" +
107  "help \n" +
108  "quit \n" ;
109 
110  reply.clear();
111 
112  if (command.get(0).asString()=="quit") {
113  reply.addString("quitting");
114  return false;
115  }
116  else if (command.get(0).asString()=="help") {
117  yInfo() << helpMessage;
118  reply.addString("ok");
119  reply.addString(helpMessage);
120  }
121  else if (command.get(0).asString()=="reset") {
122  yInfo() << "Reset";
123  resetGUI();
124  reply.addString("ok");
125  }
126  return true;
127 }
128 
130 {
131  return 0.1;
132 }
133 
135 {
136  if (opc->isConnected())
137  {
138  opc->checkout(); //Retrieve all entities
139  iCub = opc->addOrRetrieveEntity<Agent>("icub");
140 
141  //Display the iCub specifics
142  addiCub(iCub);
143 
144  //Display the objects
145  list<shared_ptr<Entity>> entities = opc->EntitiesCacheCopy();
146  if (oldEntities.size() != entities.size()) {
147  resetGUI();
148  } else {
149  list<shared_ptr<Entity>>::iterator e_new, e_old;
150  for(e_new = entities.begin(), e_old = oldEntities.begin();
151  e_new != entities.end() && e_old != oldEntities.end();
152  e_new++, e_old++) {
153  if((*e_new)->name() != (*e_old)->name()) {
154  resetGUI(); // Entities are the same, but a name has changed, so reset
155  break;
156  }
157  }
158  }
159  oldEntities = entities;
160 
161  for(auto& entity : entities) {
162  if( isDisplayable(entity.get()) ) {
163  Object* o = dynamic_cast<Object*>(entity.get());
164  if(!o) {
165  yError() << "Could not cast " << entity->name();
166  continue;
167  }
168 
169  ostringstream guiTag;
170  guiTag << o->name() << "(" << o->opc_id() << ")";
171 
172  if (o->m_present==0.0) {
173  deleteObject(guiTag.str(), o);
174  } else {
175  if (o->name() != "icub") {
177  Agent* a = dynamic_cast<Agent*>(o);
178  if (a)
179  addAgent(a);
180  } else {
181  addObject(o);
182  }
183  }
184  }
185  }
186  }
187  }
188 
189  return true;
190 }
191 
193 {
194  return entity->isType(ICUBCLIENT_OPC_ENTITY_OBJECT);
195 }
196 
197 void GuiUpdater::deleteObject(const string &opcTag, Object* o)
198 {
199  Bottle cmd;
200  cmd.addString("delete");
201  cmd.addString(opcTag.c_str());
202  toGui.write(cmd);
203 
204  //Delete all the body parts
205  if (o != nullptr && o->entity_type() == ICUBCLIENT_OPC_ENTITY_AGENT && displaySkeleton)
206  {
207  unsigned int i = 0;
208  Agent* a = dynamic_cast<Agent*>(o);
209  if(a == nullptr) {
210  yError() << "Could not cast to agent";
211  return;
212  }
213  while (i < a->m_body.m_parts.size()) // remove all body parts of the agent
214  {
215  ostringstream opcTagPart;
216  opcTagPart << o->opc_id() << "_" << i;
217  cmd.clear();
218  cmd.addString("delete");
219  cmd.addString(opcTagPart.str().c_str());
220  toGui.write(cmd);
221  i++;
222  }
223  }
224 }
225 
227 {
228  if (displaySkeleton) // display all body parts
229  {
230  int i=0;
231  for(auto& part : o->m_body.m_parts)
232  {
233  //Get the position of the object in the current reference frame of the robot (not the initial one)
234  Vector inCurrentRootReference = iCub->getSelfRelativePosition(part.second);
235 
236  ostringstream opcTagPart;
237  opcTagPart<<o->opc_id() << "_" << i;
238  Bottle cmd;
239  cmd.addString("object");
240  cmd.addString(opcTagPart.str().c_str());
241 
242  //Body parts have fixed dimensions
243  cmd.addDouble(0.05 *1000.0); // dimX in [mm]
244  cmd.addDouble(0.05 *1000.0); // dimY in [mm]
245  cmd.addDouble(0.05 *1000.0); // dimZ in [mm]
246  cmd.addDouble(inCurrentRootReference[0] *1000.0); // posX in [mm]
247  cmd.addDouble(inCurrentRootReference[1] *1000.0); // posY in [mm]
248  cmd.addDouble(inCurrentRootReference[2] *1000.0); // posZ in [mm]
249  cmd.addDouble(0); // discard the orientation
250  cmd.addDouble(0); // "
251  cmd.addDouble(0); // "
252  cmd.addInt((int)o->m_color[0]); // color R
253  cmd.addInt((int)o->m_color[1]); // color G
254  cmd.addInt((int)o->m_color[2]); // color B
255  cmd.addDouble(1); // alpha coefficient [0,1]
256  toGui.write(cmd);
257  i++;
258  }
259  }
260  else // only display the head
261  {
262  Vector inCurrentRootReference = iCub->getSelfRelativePosition(o->m_ego_position);
263  ostringstream opcTagPart;
264  opcTagPart << o->name() << "(" << o->opc_id() << ")";
265  Bottle cmd;
266  cmd.addString("object");
267  cmd.addString(opcTagPart.str().c_str());
268 
269  //Body parts have fixed dimensions
270  cmd.addDouble(0.15 *1000.0); // dimX in [mm]
271  cmd.addDouble(0.15 *1000.0); // dimY in [mm]
272  cmd.addDouble(0.25 *1000.0); // dimZ in [mm]
273  cmd.addDouble(inCurrentRootReference[0] *1000.0); // posX in [mm]
274  cmd.addDouble(inCurrentRootReference[1] *1000.0); // posY in [mm]
275  cmd.addDouble(inCurrentRootReference[2] *1000.0); // posZ in [mm]
276  cmd.addDouble(0 - iCub->m_ego_orientation[0]); // discard the orientation
277  cmd.addDouble(0 - iCub->m_ego_orientation[1]); // "
278  cmd.addDouble(0 - iCub->m_ego_orientation[2]); // "
279  cmd.addInt((int)o->m_color[0]); // color R
280  cmd.addInt((int)o->m_color[1]); // color G
281  cmd.addInt((int)o->m_color[2]); // color B
282  cmd.addDouble(1); // alpha coefficient [0,1]
283  toGui.write(cmd);
284  }
285 }
286 
288 {
289  //Get the position of the object in the current reference frame of the robot (not the initial one)
290  Vector inCurrentRootReference = iCub->getSelfRelativePosition(o->m_ego_position);
291 
292  ostringstream guiTag;
293  guiTag << o->name() << "(" << o->opc_id() << ")";
294 
295  Bottle cmd;
296  cmd.addString("object");
297  cmd.addString(guiTag.str());
298 
299  cmd.addDouble(o->m_dimensions[0] *1000.0); // dimX in [mm]
300  cmd.addDouble(o->m_dimensions[1] *1000.0); // dimY in [mm]
301  cmd.addDouble(o->m_dimensions[2] *1000.0); // dimZ in [mm]
302  cmd.addDouble(inCurrentRootReference[0] *1000.0); // posX in [mm]
303  cmd.addDouble(inCurrentRootReference[1] *1000.0); // posY in [mm]
304  cmd.addDouble(inCurrentRootReference[2] *1000.0); // posZ in [mm]
305  cmd.addDouble(o->m_ego_orientation[0] - iCub->m_ego_orientation[0]); // Deal with the object orientation that is moving with the base
306  cmd.addDouble(o->m_ego_orientation[1] - iCub->m_ego_orientation[1]); // "
307  cmd.addDouble(o->m_ego_orientation[2] - iCub->m_ego_orientation[2]); // "
308  cmd.addInt((int)o->m_color[0]); // color R
309  cmd.addInt((int)o->m_color[1]); // color G
310  cmd.addInt((int)o->m_color[2]); // color B
311  cmd.addDouble(1); // alpha coefficient [0,1]
312  toGui.write(cmd);
313 }
314 
316 {
317  Bottle cmd;
318  cmd.addDouble(a->m_ego_orientation[0]); //in opc we store rotation around x,y,z, which seems different of the iCubGUI
319  cmd.addDouble(a->m_ego_orientation[1]);
320  cmd.addDouble(a->m_ego_orientation[2]);
321  cmd.addDouble(a->m_ego_position[0] * 1000.0);
322  cmd.addDouble(a->m_ego_position[1] * 1000.0);
323  cmd.addDouble(a->m_ego_position[2] * 1000.0);
324  toGuiBase.write(cmd);
325 }
326 
328 {
329  Bottle cmd,reply;
330  cmd.clear();
331  reply.clear();
332  cmd.addString("reset");
333  toGui.write(cmd);
334 }
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
yarp::sig::VectorOf< double > m_color
Mean color of the object (r,g,b) used mainly for debugging/displaying purposes in the iCubGUI...
Definition: object.h:61
Represent any entity that can be stored within the OPC.
Definition: entity.h:40
yarp::sig::VectorOf< double > m_ego_orientation
Orientation of the Object, in the initial ego-centered reference frame of the agent mainting the OPC ...
Definition: object.h:51
virtual bool isType(std::string _entityType) const
Test if an entity is inheriting a given type.
Definition: entity.h:67
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
void deleteObject(const string &opcTag, Object *o=nullptr)
Deletes an object with name opcTag from the OPC.
Definition: guiUpdater.cpp:197
bool isDisplayable(Entity *entity)
Checks whether an Entity can be displayed in the GUI.
Definition: guiUpdater.cpp:192
STL namespace.
void resetGUI()
Send a request to the iCubGUI to remove all items.
Definition: guiUpdater.cpp:327
Represent any physical entity (including objects and agents) that can be stored within the OPC...
Definition: object.h:35
yarp::sig::VectorOf< double > m_ego_position
Position of the Object, in the initial ego-centered reference frame of the agent mainting the OPC (in...
Definition: object.h:46
virtual bool isType(std::string _entityType) const
Test if an entity is inheriting a given type.
Definition: object.h:86
void addiCub(Agent *a)
Adds the iCub the the iCubGUI.
Definition: guiUpdater.cpp:315
Represent an agent.
Definition: agent.h:93
bool updateModule()
Definition: guiUpdater.cpp:134
yarp::sig::VectorOf< double > m_dimensions
Dimensions of the Object, in meters.
Definition: object.h:56
void addAgent(Agent *a)
Adds an agent to the iCubGUI.
Definition: guiUpdater.cpp:226
An OPC client using the datastructures defined within the icub-client library.
Definition: opcClient.h:35
bool interruptModule()
Definition: guiUpdater.cpp:72
bool close()
Definition: guiUpdater.cpp:81
void addObject(Object *o)
Adds an object to the iCubGUI.
Definition: guiUpdater.cpp:287
std::string name() const
Return the name of an entity (which has to be unique within the OPC)
Definition: entity.h:93
double getPeriod()
Definition: guiUpdater.cpp:129
#define ICUBCLIENT_OPC_ENTITY_OBJECT
Definition: tags.h:38
bool respond(const yarp::os::Bottle &command, yarp::os::Bottle &reply)
Definition: guiUpdater.cpp:102
#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
std::map< std::string, yarp::sig::VectorOf< double > > m_parts
Definition: agent.h:35
bool configure(yarp::os::ResourceFinder &rf)
Definition: guiUpdater.cpp:35