YarpComm.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009 by Ulrich Friedrich Klank <klank@in.tum.de>
00003  * 
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 3 of the License, or
00007  * (at your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
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 *     CreatePoseFromBottle                                         */
00056 /********************************************************************
00057 *   @brief Creates a lo from a bottle
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 *     AddMatrixToABottle                                         */
00079 /********************************************************************
00080 *   @brief Adds a bottle containing a matrix
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 *     PutPoseIntoABottle                                         */
00095 /********************************************************************
00096 *   @brief Creates a lo from a bottle
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   /* Bottle per matrix*/
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 *  class YarpComm                                                                             */
00116 /*****************************************************************************************
00117 *  Class organizing the answer system to a specifie yarp port
00118 ******************************************************************************************/
00119 class YarpComm : public Comm
00120 {
00121 public:
00122 
00123   /*****************************************************************************************
00124   *  YarpComm                                                                             */
00125   /*****************************************************************************************
00126   *  Constructor
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   *  ~YarpComm                                                                             */
00141   /*****************************************************************************************
00142   *  Destructor
00143   ******************************************************************************************/
00144   ~YarpComm(void)
00145   {
00146 #ifdef BOOST_THREAD
00147     /*delete m_YarpAnswerThread;*/
00148 #endif /*BOOST_THREAD*/
00149     delete m_pose;
00150     m_visFinder.m_sigdb.FreeActiveSignature(&m_sig);
00151     /*delete &m_sig;*/
00152   }
00153 
00154   /*****************************************************************************************
00155   *  Start                                                                                */
00156   /*****************************************************************************************
00157   *  Calls the yarp threadfunc, with a new thread if this is possible
00158   ******************************************************************************************/
00159   void Start()
00160   {
00161 #ifdef BOOST_THREAD
00162     /*m_YarpAnswerThread = new */boost::thread( boost::bind(&YarpComm::threadfunc, this));
00163 #else
00164     YarpComm::threadfunc();
00165 #endif /*BOOST_THREAD*/
00166 
00167   }
00168 
00169   /*****************************************************************************************
00170   *  NotifyPoseUpdate                                                                        */
00171   /*****************************************************************************************
00172   *  Call back that is called whenever a new pose is set for a certain model
00173   *  This callback must be told the signature that is tracked
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 /*        PutPoseIntoABottle(new_loc_bottle, pose);*/
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 /*_DEBUG*/
00197 #ifdef BOOST_1_35
00198   BOOST(s_mutexAnswer.unlock());
00199 #else
00200   BOOST(locker::unlock(s_mutexAnswer));
00201 #endif
00202   };
00203 
00204   /*****************************************************************************************
00205   *  threadfunc                                                                           */
00206   /*****************************************************************************************
00207   *  Yarp action: calls visual finder, and writes the results on a yarp port
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     /*          PutPoseIntoABottle(new_loc_bottle, new_location[i].first);*/
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));  //TODO Check
00285 
00286 #else
00287           BOOST(boost::xtime_get(&t, boost::TIME_UTC));
00288           BOOST(t.sec +=  1);  //TODO Check
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   /*boost::thread* m_YarpAnswerThread;*/
00347 #endif
00348   YarpComm& operator=(YarpComm&){}
00349 };
00350 
00351 /*****************************************************************************************
00352 *  class YarpPortManager                                                                */
00353 /*****************************************************************************************
00354 *  Class organizing opened yarp ports
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 /*_DEBUG*/
00391             int num = input == NULL ? 0 : input->size();
00392             if(num == 0)
00393             {
00394 #ifdef _DEBUG
00395               printf("Got Empty Bottle\n");
00396   #endif /*_DEBUG*/
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 /*_DEBUG*/
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 /*_DEBUG*/
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 /*YARP_COMM_H*/
00631 #endif /*USE_YARP_COMM*/
00632 


cognitive_perception
Author(s): Ulrich F Klank
autogenerated on Mon Oct 6 2014 10:48:45