86 #include <condition_variable>
88 #include <yarp/os/all.h>
91 using namespace yarp::os;
95 class FakeClassifierService:
public PortReader
98 bool read(ConnectionReader& connection)
101 cmd.read(connection);
102 reply.addVocab32(
"ack");
106 if (cmd.get(0).asVocab32()==Vocab32::encode(
"classify"))
108 Bottle *payLoad=cmd.get(1).asList();
111 for (
int i=0; i<payLoad->size(); i++)
113 Bottle *item=payLoad->get(i).asList();
114 string tag=item->get(0).asString();
115 Bottle *blob=item->get(1).asList();
116 int tl_x=(int)blob->get(0).asFloat64();
117 int tl_y=(int)blob->get(1).asFloat64();
118 int br_x=(int)blob->get(2).asFloat64();
119 int br_y=(int)blob->get(3).asFloat64();
121 int area=(br_x-tl_x)*(br_y-tl_y);
125 Bottle &l1=reply.addList();
127 Bottle &l2=l1.addList().addList();
136 if (ConnectionWriter *client=connection.getWriter())
137 reply.write(*client);
145 class iolHelperModule:
public RFModule
150 Port extClassOutPort;
151 BufferedPort<Bottle> extClassInPort;
153 FakeClassifierService fakeService;
157 mutex mtx_replyEvent;
158 condition_variable cv_replyEvent;
161 deque<pair<int,string> > objects;
165 bool configure(ResourceFinder &rf)
167 string name=rf.find(
"name").asString();
168 opcPort.open(
"/"+name+
"/opc");
170 rpcPort.open(
"/"+name+
"/rpc");
173 fakePort.open(
"/"+name+
"/fake");
174 fakePort.setReader(fakeService);
176 extClassOutPort.open(
"/"+name+
"/extclass:o");
177 extClassInPort.open(
"/"+name+
"/extclass:i");
179 string context_extclass=rf.find(
"context_extclass").asString();
180 string memory_extclass=rf.find(
"memory_extclass").asString();
182 ResourceFinder memory_rf;
183 memory_rf.setDefaultContext(context_extclass);
184 memory_rf.setDefaultConfigFile(memory_extclass.c_str());
185 memory_rf.configure(0,NULL);
187 string dataFile=memory_rf.findFile(
"from");
188 Property dataProp; dataProp.fromConfigFile(dataFile);
189 Bottle dataBottle; dataBottle.read(dataProp);
190 for (
int i=0; i<dataBottle.size(); i++)
192 if (Bottle *payLoad=dataBottle.get(i).asList()->get(2).asList())
194 if (payLoad->check(
"extclass_id") && payLoad->check(
"name"))
196 int id=payLoad->find(
"extclass_id").asInt32();
197 string name=payLoad->find(
"name").asString();
198 objects.push_back(pair<int,string>(
id,name));
203 yInfo(
"Available objects:");
204 for (
size_t i=0; i<objects.size(); i++)
205 yInfo(
"#%d: %s",objects[i].first,objects[i].second.c_str());
212 bool interruptModule()
214 yInfo(
"interrupting...");
216 cv_replyEvent.notify_all();
226 extClassOutPort.close();
227 extClassInPort.close();
232 bool getNames(Bottle &names)
235 if (opcPort.getOutputCount()>0)
237 Bottle opcCmd,opcReply,opcReplyProp;
238 opcCmd.addVocab32(
"ask");
239 Bottle &content=opcCmd.addList().addList();
240 content.addString(
"entity");
241 content.addString(
"==");
242 content.addString(
"object");
243 opcPort.write(opcCmd,opcReply);
245 if (opcReply.size()>1)
247 if (opcReply.get(0).asVocab32()==Vocab32::encode(
"ack"))
249 if (Bottle *idField=opcReply.get(1).asList())
251 if (Bottle *idValues=idField->get(1).asList())
254 for (
int i=0; i<idValues->size(); i++)
256 int id=idValues->get(i).asInt32();
261 opcCmd.addVocab32(
"get");
262 Bottle &content=opcCmd.addList();
263 Bottle &list_bid=content.addList();
264 list_bid.addString(
"id");
265 list_bid.addInt32(
id);
266 Bottle &list_propSet=content.addList();
267 list_propSet.addString(
"propSet");
268 list_propSet.addList().addString(
"name");
269 opcPort.write(opcCmd,opcReplyProp);
272 if (opcReplyProp.get(0).asVocab32()==Vocab32::encode(
"ack"))
273 if (Bottle *propField=opcReplyProp.get(1).asList())
274 if (propField->check(
"name"))
275 names.addString(propField->find(
"name").asString());
289 int getLocation(
const Bottle &body, Bottle &location)
293 if ((opcPort.getOutputCount()>0) && (body.size()>0))
295 Bottle opcCmd,opcReply,opcReplyProp;
296 opcCmd.addVocab32(
"ask");
297 Bottle &content=opcCmd.addList();
298 Bottle &cond1=content.addList();
299 cond1.addString(
"entity");
300 cond1.addString(
"==");
301 cond1.addString(
"navloc");
302 content.addString(
"&&");
303 Bottle &cond2=content.addList();
304 cond2.addString(
"name");
305 cond2.addString(
"==");
306 cond2.addString(body.get(0).asString());
307 opcPort.write(opcCmd,opcReply);
309 if (opcReply.size()>1)
311 if (opcReply.get(0).asVocab32()==Vocab32::encode(
"ack"))
313 if (Bottle *idField=opcReply.get(1).asList())
315 if (Bottle *idValues=idField->get(1).asList())
317 if (idValues->size()>0)
320 id=idValues->get(0).asInt32();
325 opcCmd.addVocab32(
"get");
326 Bottle &content=opcCmd.addList();
327 Bottle &list_bid=content.addList();
328 list_bid.addString(
"id");
329 list_bid.addInt32(
id);
330 Bottle &list_propSet=content.addList();
331 list_propSet.addString(
"propSet");
332 list_propSet.addList().addString(
"location");
333 opcPort.write(opcCmd,opcReplyProp);
336 if (opcReplyProp.get(0).asVocab32()==Vocab32::encode(
"ack"))
337 if (Bottle *propField=opcReplyProp.get(1).asList())
338 if (propField->check(
"location"))
339 if (Bottle *loc=propField->find(
"location").asList())
340 for (
int i=0; i<loc->size(); i++)
341 location.addFloat64(loc->get(i).asFloat64());
353 bool setLocation(
const int id,
const Bottle &body)
355 if ((opcPort.getOutputCount()>0) && (body.size()>3))
357 Bottle opcCmd,opcReply;
358 Bottle *pContent=NULL;
361 opcCmd.addVocab32(
"add");
362 Bottle &content=opcCmd.addList();
363 Bottle &list_ent=content.addList();
364 list_ent.addString(
"entity");
365 list_ent.addString(
"navloc");
366 Bottle &list_name=content.addList();
367 list_name.addString(
"name");
368 list_name.addString(body.get(0).asString());
373 opcCmd.addVocab32(
"set");
374 Bottle &content=opcCmd.addList();
375 Bottle &list_id=content.addList();
376 list_id.addString(
"id");
377 list_id.addInt32(
id);
381 Bottle &list_loc=pContent->addList();
382 list_loc.addString(
"location");
383 Bottle &list_data=list_loc.addList();
384 list_data.addFloat64(body.get(1).asFloat64());
385 list_data.addFloat64(body.get(2).asFloat64());
386 list_data.addFloat64(body.get(3).asFloat64());
387 opcPort.write(opcCmd,opcReply);
389 return (opcReply.get(0).asVocab32()==Vocab32::encode(
"ack"));
396 Bottle mergeList(
const Bottle &b1,
const Bottle &b2)
399 for (
int i=0; i<b2.size(); i++)
401 string name=b2.get(i).asString();
402 bool toBeAppended=
true;
404 for (
int j=0; j<ret.size(); j++)
406 if (name==ret.get(j).asString())
421 bool respond(
const Bottle &cmd, Bottle &reply)
423 yInfo(
"Received request: %s",cmd.toString().c_str());
424 switch (cmd.get(0).asVocab32())
427 case createVocab32(
'n',
'a',
'm',
'e'):
432 reply.addString(
"ack");
433 reply.append(mergeList(cmd.tail(),names));
436 reply.addString(
"nack");
442 case createVocab32(
'n',
'a',
'v',
'g'):
445 if (getLocation(cmd.tail(),location)>=0)
447 reply.addString(
"ack");
448 reply.append(location);
451 reply.addString(
"nack");
457 case createVocab32(
'n',
'a',
'v',
's'):
460 Bottle body=cmd.tail();
461 int id=getLocation(body,location);
462 if (setLocation(
id,body))
463 reply.addString(
"ack");
465 reply.addString(
"nack");
471 case createVocab32(
'c',
'l',
'a',
's'):
473 if (extClassOutPort.getOutputCount()==0)
475 yWarning(
"external classifier is not connected => request skipped!");
476 reply.addString(
"failed");
482 msg.addString(
"classify");
484 Bottle *payLoad=cmd.get(1).asList();
485 for (
int i=0; i<payLoad->size(); i++)
487 Bottle *item=payLoad->get(i).asList();
488 string tag=item->get(0).asString();
489 Bottle *blob=item->get(1).asList();
490 int tl_x=(int)blob->get(0).asFloat64();
491 int tl_y=(int)blob->get(1).asFloat64();
492 int br_x=(int)blob->get(2).asFloat64();
493 int br_y=(int)blob->get(3).asFloat64();
495 blobTags.addString(tag);
502 if (blobTags.size()>0)
504 yInfo(
"Forwarding request: %s",msg.toString().c_str());
505 yInfo(
"waiting reply...");
506 extClassOutPort.write(msg);
507 unique_lock<mutex> lck(mtx_replyEvent);
508 cv_replyEvent.wait(lck);
511 yInfo(
"...sending reply");
516 yWarning(
"reply skipped!");
517 reply.addString(
"failed");
522 yWarning(
"empty request!");
523 reply.addString(
"failed");
531 return RFModule::respond(cmd,reply);
534 reply.addString(
"nack");
541 if (Bottle *msg=extClassInPort.read(
false))
543 yInfo(
"Received reply: %s",msg->toString().c_str());
546 for (
int i=0; i<msg->size(); i++)
548 Bottle &blob=reply.addList();
549 blob.addString(blobTags.get(i).asString());
550 Bottle &items=blob.addList();
551 for (
size_t j=0; j<objects.size(); j++)
553 Bottle &item=items.addList();
554 item.addString(objects[j].second);
555 item.addFloat64(objects[j].first==msg->get(i).asInt32()?1.0:0.0);
559 yInfo(
"Reply to be transmitted: %s",reply.toString().c_str());
560 cv_replyEvent.notify_all();
575 int main(
int argc,
char *argv[])
578 rf.setDefault(
"name",
"iolHelper");
579 rf.setDefault(
"context_extclass",
"iolStateMachineHandler");
580 rf.setDefault(
"memory_extclass",
"memory_extclass.ini");
581 rf.configure(argc,argv);
584 if (!yarp.checkNetwork())
587 iolHelperModule module;
588 return module.runModule(rf);