00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef USE_YARP_COMM
00020 #ifndef YARP_COMM_H
00021 #define YARP_COMM_H
00022
00023 #include "RelPose.h"
00024 #include "VisFinder.h"
00025 #include "Signature.h"
00026 #include "Comm.h"
00027
00028
00029 #include <yarp/os/all.h>
00030 #include <map>
00031
00032 #ifdef BOOST_THREAD
00033 #ifdef BOOST_1_35
00034 #include <boost/thread/mutex.hpp>
00035 #else
00036 #include <boost/thread/detail/lock.hpp>
00037 typedef boost::detail::thread::lock_ops<boost::mutex> locker;
00038 #endif
00039 boost::mutex s_mutexAnswer;
00040 #define BOOST(A) A
00041 #else
00042 #define BOOST(A) ;
00043 #endif
00044
00045
00046 #define STD_COP_OUTPUT_PORT "/tracking/out"
00047
00048 #ifdef BOOST_THREAD
00049 #include <boost/thread.hpp>
00050 #include <boost/bind.hpp>
00051 using namespace boost;
00052 #endif
00053
00054
00055
00056
00057
00058
00059 std::pair<RelPose*, Probability_1D_t> CreatePoseFromBottle(yarp::os::Bottle* lo)
00060 {
00061 std::pair<RelPose*, Probability_1D_t> result;
00062
00063 result.first = NULL;
00064 if(!lo->get(0).isDouble())
00065 return result;
00066 result.second = lo->get(0).asDouble();
00067 if(!lo->get(1).isInt())
00068 return result;
00070 int id = lo->get(1).asInt();
00071 RelPose* pose = RelPoseFactory::FRelPose(id);
00073 result.first = pose;
00074 return result;
00075 }
00076
00077
00078
00079
00080
00081
00082 void AddMatrixToABottle(int width, yarp::os::Bottle& lo, Matrix m)
00083 {
00084 yarp::os::Bottle &mat_b = lo.addList();;
00085 for(int r = 0; r < width; r++)
00086 {
00087 for(int c = 0; c < width; c++)
00088 {
00089 mat_b.addDouble(m.element(r,c));
00090 }
00091 }
00092 }
00093
00094
00095
00096
00097
00098 void PutPoseIntoABottle(yarp::os::Bottle &lo, jlo::LocatedObject* pose)
00099 {
00100 lo.addInt(pose->m_uniqueID);
00101 if(pose->m_uniqueID != ID_WORLD)
00102 lo.addInt(pose->m_parentID);
00103 else
00104 lo.addInt(1);
00105 Matrix m = pose->GetMatrix();
00106
00107 int width = 4;
00108 AddMatrixToABottle(width, lo, m);
00109 width = 6;
00110 Matrix cov = pose->GetCovarianceMatrix();
00111 AddMatrixToABottle(width,lo,cov);
00112 }
00113
00114
00115
00116
00117
00118
00119 class YarpComm : public Comm
00120 {
00121 public:
00122
00123
00124
00125
00126
00127
00128 YarpComm(VisFinder& visFinder, PossibleLocations_t* pose, Signature& sig, int numOfObjects, yarp::os::BufferedPort<yarp::os::Bottle>* port, int actionType) :
00129 m_visFinder(visFinder),
00130 m_pose(pose),
00131 m_sig(sig),
00132 m_numOfObjects(numOfObjects),
00133 m_port(port),
00134 m_actionType(actionType)
00135 {
00136 }
00137
00138
00139
00140
00141
00142
00143
00144 ~YarpComm(void)
00145 {
00146 #ifdef BOOST_THREAD
00147
00148 #endif
00149 delete m_pose;
00150 m_visFinder.m_sigdb.FreeActiveSignature(&m_sig);
00151
00152 }
00153
00154
00155
00156
00157
00158
00159 void Start()
00160 {
00161 #ifdef BOOST_THREAD
00162 boost::thread( boost::bind(&YarpComm::threadfunc, this));
00163 #else
00164 YarpComm::threadfunc();
00165 #endif
00166
00167 }
00168
00169
00170
00171
00172
00173
00174
00175 virtual void NotifyPoseUpdate(RelPose* pose, bool sendObjectRelation = true)
00176 {
00177 #ifdef BOOST_1_35
00178 BOOST(s_mutexAnswer.lock());
00179 #else
00180 BOOST(locker::lock(s_mutexAnswer));
00181 #endif
00182
00183 yarp::os::Bottle& new_loc_bottle = m_port->prepare();
00184 new_loc_bottle.clear();
00185 yarp::os::Bottle& subelement = new_loc_bottle.addList();
00186 if(sendObjectRelation)
00187 {
00188 subelement.addInt(m_sig.m_ID);
00189 subelement.addDouble(pose->m_qualityMeasure);
00190 }
00191 subelement.add(pose->m_uniqueID);
00192
00193 m_port->write();
00194 #ifdef _DEBUG
00195 printf("Writing a bottle in Pose Update Notification: %s\n", new_loc_bottle.toString().c_str());
00196 #endif
00197 #ifdef BOOST_1_35
00198 BOOST(s_mutexAnswer.unlock());
00199 #else
00200 BOOST(locker::unlock(s_mutexAnswer));
00201 #endif
00202 };
00203
00204
00205
00206
00207
00208
00209 void threadfunc()
00210 {
00211 printf("Answer Thread started for object %d command %s\n", m_sig.m_ID, ((m_actionType == ALGORITHMTYPE_LOCATE) ? "Locate" : ((m_actionType == ALGORITHMTYPE_TRACK) ? "Track" : "StopTrack or unknown action")));
00212 bool bFinished = false;
00213 switch(m_actionType)
00214 {
00215 case ALGORITHMTYPE_TRACK:
00216 m_sig.SetCommCallBack(this);
00217 if(m_pose->size() > 0)
00218 {
00219 PossibleLocations_t::const_iterator it = m_pose->begin();
00220 m_visFinder.StartTrack(m_sig, (*it).first);
00221 }
00222 else
00223 m_visFinder.StartTrack(m_sig, NULL);
00224 break;
00225 case ALGORITHMTYPE_STOPTRACK:
00226 m_sig.SetCommCallBack(NULL);
00227 m_visFinder.StopTrack(m_sig);
00228 bFinished = true;
00229 break;
00230 case ALGORITHMTYPE_LOCATE:
00231 {
00232 Locate(m_pose);
00233 bFinished = true;
00234 }
00235 break;
00236 }
00237 printf("Finished with action of type \"%s\".\nReturning to listen loop.\n", ((m_actionType == ALGORITHMTYPE_LOCATE) ? "Locate" : ((m_actionType == ALGORITHMTYPE_TRACK) ? "Track" : "StopTrack or unknown action")) );
00238 if(bFinished)
00239 delete this;
00240 }
00241 void Locate(PossibleLocations_t* pose)
00242 {
00243 try
00244 {
00245 const SignatureLocations_t &new_location = m_visFinder.Locate(pose, m_sig, m_numOfObjects);
00246 #ifdef BOOST_1_35
00247 BOOST(s_mutexAnswer.lock());
00248 #else
00249 BOOST(locker::lock(s_mutexAnswer));
00250 #endif
00251 yarp::os::Bottle& main_bot = m_port->prepare();
00252 main_bot.clear();
00253 if(m_numOfObjects > 0 && new_location.size() > 0)
00254 {
00255 for(unsigned int i = 0; (signed)i < m_numOfObjects && i < new_location.size(); i++)
00256 {
00257 yarp::os::Bottle& new_loc_bottle = main_bot.addList();
00258 new_loc_bottle.addInt(new_location[i].second->m_ID);
00259 new_loc_bottle.addDouble(new_location[i].first->m_qualityMeasure);
00260
00261 new_loc_bottle.addInt(new_location[i].first->m_uniqueID);
00262 }
00263 }
00264 else
00265 {
00266 main_bot.addString("No Object Found!");
00267 }
00268 m_port->write();
00269 #ifdef BOOST_1_35
00270 BOOST(s_mutexAnswer.unlock());
00271 #else
00272 BOOST(locker::unlock(s_mutexAnswer));
00273 #endif
00274
00275 #ifdef WIN32
00276 #ifdef BOOST_1_35
00277 BOOST(boost::system_time t);
00278 #else
00279 BOOST(boost::xtime t);
00280 #endif
00281
00282 #ifdef BOOST_1_35
00283 BOOST(t = get_system_time());
00284 BOOST(t += boost::posix_time::seconds(1));
00285
00286 #else
00287 BOOST(boost::xtime_get(&t, boost::TIME_UTC));
00288 BOOST(t.sec += 1);
00289 #endif
00290
00291 BOOST(boost::thread::sleep(t));
00292 delete m_visFinder.m_imageSys.GetCamara(0)->m_win;
00293 m_visFinder.m_imageSys.GetCamara(0)->m_win = NULL;
00294 #endif
00295 }
00296 catch(char const* text)
00297 {
00298 printf("Locate called by yarp failed: %s\n", text);
00299 #ifdef BOOST_1_35
00300 BOOST(s_mutexAnswer.lock());
00301 #else
00302 BOOST(locker::lock(s_mutexAnswer));
00303 #endif
00304
00305 yarp::os::Bottle& main_bot = m_port->prepare();
00306 main_bot.addString("Locate failed: %s");
00307 m_port->write();
00308 #ifdef BOOST_1_35
00309 BOOST(s_mutexAnswer.unlock());
00310 #else
00311 BOOST(locker::unlock(s_mutexAnswer));
00312 #endif
00313
00314 return;
00315 }
00316 catch(...)
00317 {
00318 #ifdef BOOST_1_35
00319 BOOST(s_mutexAnswer.lock());
00320 #else
00321 BOOST(locker::lock(s_mutexAnswer));
00322 #endif
00323
00324 yarp::os::Bottle& main_bot = m_port->prepare();
00325 main_bot.addString("Locate failed.");
00326 m_port->write();
00327 #ifdef BOOST_1_35
00328 BOOST(s_mutexAnswer.unlock());
00329 #else
00330 BOOST(locker::unlock(s_mutexAnswer));
00331 #endif
00332
00333 return;
00334 }
00335 }
00336
00337 yarp::os::BufferedPort<yarp::os::Bottle>* m_port;
00338 VisFinder& m_visFinder;
00339 PossibleLocations_t* m_pose;
00340 Signature& m_sig;
00341 int m_numOfObjects;
00342 int m_actionType;
00343 private:
00344
00345 #ifdef BOOST_THREAD
00346
00347 #endif
00348 YarpComm& operator=(YarpComm&){}
00349 };
00350
00351
00352
00353
00354
00355
00356 class YarpPortManager
00357 {
00358 public:
00359 YarpPortManager()
00360 {
00361 }
00362
00363 ~YarpPortManager()
00364 {
00365 std::map<std::string, yarp::os::BufferedPort<yarp::os::Bottle>* > ::iterator it = m_PortMapping.begin();
00366 for(; it != m_PortMapping.end(); it++)
00367 {
00368 (*it).second->close();
00369 delete (*it).second;
00370 }
00371 }
00372
00373 void CloseYarpPort(std::string port_name)
00374 {
00375
00376 }
00377
00378 void Listen(yarp::os::BufferedPort<yarp::os::Bottle> & port, volatile bool &g_stopall, VisFinder* s_visFinder, SignatureDB *s_sigDb)
00379 {
00380 while(!g_stopall)
00381 {
00382 try
00383 {
00385 yarp::os::Bottle *input = port.read(true);
00386 if(g_stopall)
00387 return;
00388 #ifdef _DEBUG
00389 printf("Got something\n");
00390 #endif
00391 int num = input == NULL ? 0 : input->size();
00392 if(num == 0)
00393 {
00394 #ifdef _DEBUG
00395 printf("Got Empty Bottle\n");
00396 #endif
00397 continue;
00398 }
00399 std::string outputname;
00400 std::vector<int> class_id;
00401 int i = 0;
00402 if(input->get(i).isString())
00403 {
00404 outputname = input->get(i).asString();
00405 i++;
00406 }
00407 else
00408 {
00409 outputname = STD_COP_OUTPUT_PORT;
00410 printf("YarpComm: Incoming Request did not specify a portname.\n Using %s\n",STD_COP_OUTPUT_PORT);
00411 }
00412 try
00413 {
00414 if(i > num)
00415 {
00416 #ifdef _DEBUG
00417 printf("Got Bottle of a too short length\n");
00418 #endif
00419 continue;
00420 }
00421 Signature* sig = NULL;
00422 if(input->get(i).isList())
00423 {
00424 yarp::os::Bottle* bot = input->get(i).asList();
00425 int num_list = bot->size();
00426 #ifdef _DEBUG
00427 printf("Yarp Comm: Got %d describing entries\n", num_list);
00428 #endif
00429 try
00430 {
00431 for(int j = 0; j < num_list ; j++)
00432 {
00433 if(bot->get(j).isInt())
00434 {
00435 int index;
00436 int id = bot->get(j).asInt();
00437 if(s_sigDb->CheckClass(id).length() > 0)
00438 {
00439 class_id.push_back(id);
00440 }
00441 else if(s_sigDb->Check(id, index))
00442 {
00443 sig = s_sigDb->GetSignatureByID(id);
00444 }
00445 else
00446 {
00447 printf("Received unknown Element id: %d\n", id);
00448 }
00449 }
00450 else if(bot->get(j).isString())
00451 {
00452 int class_from_string = s_sigDb->CheckClass(std::string(bot->get(j).asString()));
00453 printf(" Class as string: %s\n", bot->get(j).asString().c_str());
00454 if(class_from_string != -1)
00455 class_id.push_back(class_from_string);
00456 else
00457 {
00458 Class cl;
00459 cl.SetName(std::string(bot->get(j).asString()));
00460 s_sigDb->AddClass(cl.GetName(), cl.m_ID);
00461 int class_from_string = s_sigDb->CheckClass(std::string(bot->get(j).asString()));
00462 if(class_from_string != -1)
00463 class_id.push_back(class_from_string);
00464 }
00465 }
00466 else if(bot->get(j).isList())
00467 {
00469 throw "Not yet implemented";
00470 }
00471 }
00472 }
00473 catch(...)
00474 {
00475 printf("YarpComm: Problems reading classes\n");
00476 continue;
00477 }
00478 }
00479 else
00480 {
00481 printf("Error parsing bottle: Element %d was not of expected type(expected Bottle of ints + strings)", i);
00482 continue;
00483 }
00484 if(sig == NULL)
00485 {
00486 try
00487 {
00488 sig = s_sigDb->GetSignature(class_id);
00489 if(sig == NULL)
00490 {
00491 printf("YarpComm: Could not generatesignature for the requested description (%s)\n", input->toString().c_str());
00492 continue;
00493 }
00494 }
00495 catch(char const* text)
00496 {
00497 printf("Error Creating signature: %s\n", text);
00498 break;
00499 }
00500 catch(...)
00501 {
00502 printf("Error Creating signature\n");
00503 break;
00504 }
00505 }
00506 #ifdef _DEBUG
00507 printf("Created Signature with all classes (%d)\n", sig->m_ID);
00508 #endif
00509 i++;
00510 if(!input->get(i).isInt())
00511 {
00512 printf("Error parsing bottle: Element %d was not of expected type (expected number of elements)", i);
00513 continue;
00514 }
00515 int numOfObjects = input->get(i).asInt();
00516 i++;
00517 if(!input->get(i).isInt())
00518 {
00519 printf("Error parsing bottle: Element %d was not of expected type (expected action type (Track or Locate))", i);
00520 continue;
00521 }
00522 int actionType = input->get(i).asInt();
00523 i++;
00524 PossibleLocations_t* poses = new PossibleLocations_t();
00525 if(input->get(i).isList())
00526 {
00527 yarp::os::Bottle* bot = input->get(i).asList();
00528 int num_list = bot->size();
00530 for(int j = 0; j < num_list ; j++)
00531 {
00532 if(!bot->get(j).isList())
00533 continue;
00535 yarp::os::Bottle* lo = bot->get(j).asList();
00536 std::pair<RelPose*, double> pose = CreatePoseFromBottle(lo);
00537 if(pose.first == NULL)
00538 {
00539 printf("YarpComm: Received Pose is NULL!\n");
00540 break;
00541 }
00542 poses->push_back(pose);
00543 printf("Start Locate with:\n", sig->m_ID);
00544 #ifdef _DEBUG
00545 pose.first->Print();
00546 #endif
00547 }
00548 #ifdef _DEBUG
00549 #endif
00550 }
00551 else
00552 {
00553 printf("No poses given, trying last known pose.\n");
00554 if(sig->m_relPose != NULL)
00555 poses->push_back(std::pair<RelPose*, double>(sig->m_relPose, 1.0));
00556 else
00557 printf("A Bottle was received that could not be used for finding the requested object\n.");
00558 }
00559 yarp::os::BufferedPort<yarp::os::Bottle>* port = OpenCommOnYarpPort(outputname);
00560 YarpComm* comm = new YarpComm(*s_visFinder, poses, *sig, numOfObjects, port, actionType);
00561 comm->Start();
00562 }
00563 catch(char const* text)
00564 {
00565 printf("Could not open outputport TOCHECK, wait? %s\n", text);
00566 continue;
00567 }
00568 }
00569 catch(char const* text)
00570 {
00571 printf("StartListeningYarpPort Exception: %s\n", text);
00572 }
00573 catch(...)
00574 {
00575 printf("StartListeningYarpPort Unknown Exception\n");
00576 }
00577 }
00578 }
00579
00580 yarp::os::BufferedPort<yarp::os::Bottle>* OpenCommOnYarpPort(std::string st)
00581 {
00582 if(m_PortMapping.find(st) == m_PortMapping.end())
00583 {
00584 m_PortMapping[st] = new yarp::os::BufferedPort<yarp::os::Bottle>();
00585 try
00586 {
00587 yarp::os::Contact contact = yarp::os::Network::queryName(st.c_str());
00588 if(!contact.isValid() && m_PortMapping[st]->open(st.c_str()))
00589 {
00590 return m_PortMapping[st];
00591 }
00592 else
00593 {
00594 system ("yarp clean");
00595 for(int i = 0; i < 1000; i++)
00596 {
00597 yarp::os::Contact contact = yarp::os::Network::queryName(st.c_str());
00598 if(!contact.isValid())
00599 break;
00600 }
00601 if(m_PortMapping[st]->open(st.c_str()))
00602 {
00603 return m_PortMapping[st];
00604 }
00605 else
00606 {
00607 printf("YarpManager::OpenCommOnYarpPort : Error (Try: yarp clean before starting again)\n");
00608 throw "Error opening port";
00609 }
00610 }
00611 }
00612 catch(char * text)
00613 {
00614 printf("YarpManager::OpenCommOnYarpPort : (%s) (Try: yarp clean before starting again)\n", text);
00615 throw "Error opening port";
00616 }
00617 catch(...)
00618 {
00619 printf("YarpManager::OpenCommOnYarpPort : Unknown Exception: Try Yarp Clean\n");
00620 throw "Error opening port";
00621 }
00622 }
00623 else
00624 return m_PortMapping[st];
00625 }
00626 private:
00627 std::map<std::string, yarp::os::BufferedPort<yarp::os::Bottle>* > m_PortMapping;
00628 };
00629
00630 #endif
00631 #endif
00632