predicate_manager.cpp
Go to the documentation of this file.
00001 
00025 #include <time.h> 
00026 
00027 #include <boost/bind.hpp>
00028 
00029 #include <predicate_manager/predicate_manager.h>
00030 
00031 using namespace std;
00032 using namespace ros;
00033 using namespace predicate_manager;
00034 
00039 PredicateManager::
00040 PredicateManager() :
00041     nh_ (),
00042     started_ ( false ),
00043     any_changed_ ( false ),
00044     pm_id_ ( 0 ),
00045     nr_of_predicates_(),
00046     initialized_pms_(),
00047     update_period_ ( 0.1 ),
00048     predicate_maps_pub_ (),
00049     predicate_updates_pub_ (),
00050     predicate_maps_sub_ ( nh_.subscribe ( "/predicate_maps", 10, &PredicateManager::consumePredicateMap, this ) ),
00051     predicate_updates_sub_ ( nh_.subscribe ( "/predicate_updates", 10, &PredicateManager::consumePredicateUpdate, this ) ),
00052     pred_update_counters_(),
00053     local_pred_refs_ (),
00054     value_map_ (),
00055     last_value_map_ (),
00056     registered_predicates_ (),
00057     pred_name_observer_ (),
00058     pred_nr_observer_ (),
00059     event_maps_pub_ (),
00060     event_updates_pub_ (),
00061     ev_update_counter_ ( 0 ),
00062     local_ev_refs_ (),
00063     registered_events_ (),
00064     ev_name_observer_ (),
00065     ev_nr_observer_ (),
00066     events_to_publish_ ()
00067 {
00068     nh_.getParam ( "pm_id", ( int& ) pm_id_ );
00069     double update_rate;
00070     if ( nh_.getParam ( "pm_update_rate", update_rate ) )
00071     {
00072         update_period_ = 1.0/update_rate;
00073     }
00074 }
00075 
00076 
00077 
00078 void
00079 PredicateManager::
00080 spin()
00081 {
00082     started_ = true;
00083 
00084     prepareLocalDependencies();
00085 
00086     if( local_pred_refs_.size() > 0 )
00087     {
00088       predicate_maps_pub_ = nh_.advertise<PredicateInfoMap> ( "/predicate_maps", 1, true );
00089       predicate_updates_pub_ = nh_.advertise<PredicateUpdate> ( "/predicate_updates", 1, true );
00090       publishPredicateMap();
00091     }
00092 
00093     if( local_ev_refs_.size() > 0 )
00094     {
00095       event_maps_pub_ = nh_.advertise<EventInfoMap> ( "/event_maps", 1, true );
00096       event_updates_pub_ = nh_.advertise<EventUpdate> ( "/event_updates", 1, true );
00097       publishEventMap();
00098     }
00099 
00100     spinOnce();
00101 
00102     foreach ( PredRefVector::value_type pred_ref, local_pred_refs_ )
00103     {
00104         pred_ref->update();
00105     }
00106     publishPredicateUpdate();
00107 
00108     while ( ok() )
00109     {
00110         struct timeval pre_update;
00111         gettimeofday ( &pre_update, NULL );
00112 
00113         PMUpdate();
00114 
00115         struct timeval post_update;
00116         gettimeofday ( &post_update, NULL );
00117 
00118         double update_duration = post_update.tv_sec-pre_update.tv_sec +
00119                                  ( post_update.tv_usec-pre_update.tv_usec ) /1000000.0;
00120 
00121         Duration rem ( update_period_- update_duration );
00122         if ( update_duration > update_period_ )
00123             ROS_WARN_STREAM ( "PredicateManager:: Update took longer than the desired update period! Update time: " << update_duration
00124                               << "; Desired update period: " << update_period_ );
00125         else
00126         {
00127             rem.sleep();
00128         }
00129     }
00130 }
00131 
00132 
00133 void
00134 PredicateManager::
00135 PMUpdate()
00136 {
00137     any_changed_ = false;
00138     spinOnce();
00139     if ( any_changed_ )
00140     {
00141         publishPredicateUpdate();
00142     }
00143     if ( events_to_publish_.size() > 0 )
00144     {
00145         publishEventUpdate();
00146     }
00147 }
00148 
00149 
00150 void
00151 PredicateManager::
00152 predicateUpdateTrigger ( const NrID pred_nr_id, bool value )
00153 {
00154     any_changed_ = true;
00155 
00156     value_map_[pred_nr_id] = value;
00157 
00158     updateDependants ( pred_nr_id );
00159 }
00160 
00161 void
00162 PredicateManager::
00163 eventTrigger ( const uint32_t ev_nr )
00164 {
00165     events_to_publish_.push_back ( ev_nr );
00166 }
00167 
00168 void
00169 PredicateManager::
00170 addPredicate ( Predicate& p )
00171 {
00172     if ( started_ )
00173     {
00174         ROS_FATAL ( "Trying to add predicates after starting." );
00175         ros::shutdown();
00176     }
00177 
00178     string pred_name = p.getName();
00179     NameID pred_name_id ( pm_id_, pred_name );
00180 
00181     if ( registered_predicates_.count ( pred_name_id ) != 0 )
00182     {
00183         ROS_FATAL_STREAM ( "Trying to add a predicate that already exists. Predicate: " << pred_name );
00184         ros::shutdown();
00185     }
00186 
00187     uint32_t pred_nr = local_pred_refs_.size();
00188     registered_predicates_.insert ( pred_name_id );
00189     local_pred_refs_.push_back ( boost::shared_ptr<Predicate> ( &p ) );
00190 
00191     NrID pred_nr_id ( pm_id_, pred_nr );
00192 
00193     if ( ! ( pred_name_observer_[pred_name_id] ) ) 
00194     {
00195         pred_name_observer_[pred_name_id] = boost::shared_ptr<set<uint32_t> > ( new set<uint32_t>() );
00196     }
00197 
00198     pred_nr_observer_[pred_nr_id] = pred_name_observer_[pred_name_id];
00199     ev_nr_observer_[pred_nr_id] = ev_name_observer_[pred_name_id];
00200 
00201     NameIDSet dep_set = p.getDependencies();
00202 
00203     foreach ( NameID id, dep_set )
00204     {
00205         if ( ! ( pred_name_observer_[id] ) )
00206         {
00207             pred_name_observer_[id] = boost::shared_ptr<set<uint32_t> > ( new set<uint32_t>() );
00208         }
00209         pred_name_observer_[id]->insert ( pred_nr );
00210     }
00211 
00212     p.setTrigger ( boost::bind ( &PredicateManager::predicateUpdateTrigger, this, pred_nr_id,_1 ) );
00213 }
00214 
00215 void
00216 PredicateManager::
00217 addEvent ( Event& e )
00218 {
00219     if ( started_ )
00220     {
00221         ROS_FATAL ( "Trying to add events after starting." );
00222         ros::shutdown();
00223     }
00224 
00225     string ev_name = e.getName();
00226     NameID ev_name_id ( pm_id_, ev_name );
00227 
00228     if ( registered_events_.count ( ev_name_id ) != 0 )
00229     {
00230         ROS_FATAL_STREAM ( "Trying to add an event that already exists. Event: " << ev_name );
00231         ros::shutdown();
00232     }
00233 
00234     uint32_t ev_nr = local_ev_refs_.size();
00235     registered_events_.insert ( ev_name_id );
00236     local_ev_refs_.push_back ( boost::shared_ptr<Event> ( &e ) );
00237 
00238     NameIDSet dep_set = e.getDependencies();
00239 
00240     foreach ( NameID id, dep_set )
00241     {
00242         if ( ! ( ev_name_observer_[id] ) )
00243         {
00244             ev_name_observer_[id] = boost::shared_ptr<set<uint32_t> > ( new set<uint32_t>() );
00245         }
00246         ev_name_observer_[id]->insert ( ev_nr );
00247     }
00248 
00249     e.setTrigger ( boost::bind ( &PredicateManager::eventTrigger, this, ev_nr ) );
00250 }
00251 
00252 void
00253 PredicateManager::
00254 publishPredicateMap()
00255 {
00256     PredicateInfoMap info_map;
00257 
00258     for ( uint32_t i = 0; i < local_pred_refs_.size(); i++ )
00259     {
00260         PredicateInfo info;
00261         info.name = local_pred_refs_[i]->getName();
00262         info.nr = i;
00263         info_map.map.push_back ( info );
00264     }
00265 
00266     info_map.pm_id = pm_id_;
00267 
00268     predicate_maps_pub_.publish ( info_map );
00269 }
00270 
00271 void
00272 PredicateManager::
00273 publishEventMap()
00274 {
00275     EventInfoMap info_map;
00276 
00277     for ( uint32_t i = 0; i < local_ev_refs_.size(); i++ )
00278     {
00279         EventInfo info;
00280         info.name = local_ev_refs_[i]->getName();
00281         info.nr = i;
00282         info_map.map.push_back ( info );
00283     }
00284 
00285     info_map.pm_id = pm_id_;
00286 
00287     event_maps_pub_.publish ( info_map );
00288 }
00289 
00290 void
00291 PredicateManager::
00292 consumePredicateMap ( const PredicateInfoMapConstPtr& msg )
00293 {
00294     if ( msg->pm_id != pm_id_ )
00295     {
00296         foreach ( PredicateInfo p_info, msg->map )
00297         {
00298             NameID pred_name_id ( msg->pm_id, p_info.name );
00299             if ( !registered_predicates_.count ( pred_name_id ) )
00300             {
00301                 ROS_DEBUG_STREAM ( "Registering predicate " << p_info.name
00302                                    << " from PM " << msg->pm_id );
00303                 NrID pred_nr_id ( msg->pm_id, p_info.nr );
00304 
00305                 setDependencyReferences ( pred_nr_id, pred_name_id );
00306 
00307                 value_map_[pred_nr_id] = false;
00308                 last_value_map_[pred_nr_id] = false;
00309                 registered_predicates_.insert ( pred_name_id );
00310             }
00311         }
00312         setNrOfPredicates ( msg->pm_id, msg->map.size() );
00313     }
00314 }
00315 
00316 
00317 void
00318 PredicateManager::
00319 publishPredicateUpdate()
00320 {
00321     PredicateUpdate update;
00322 
00323     update.pm_id = pm_id_;
00324 
00325     for ( size_t pred_nr = 0; pred_nr < local_pred_refs_.size(); pred_nr++ )
00326     {
00327         NrID pred_nr_id ( pm_id_, pred_nr );
00328         string pred_name = local_pred_refs_[pred_nr]->getName();
00329         if ( value_map_[pred_nr_id] )
00330         {
00331             update.true_predicates.push_back ( pred_nr );
00332             ROS_DEBUG_STREAM ( "Predicate Manager:: Predicate " << pred_name << " is TRUE" );
00333         }
00334         else
00335         {
00336             ROS_DEBUG_STREAM ( "Predicate Manager:: Predicate " << pred_name << " is FALSE" );
00337         }
00338         if ( last_value_map_.count ( pred_nr_id ) )
00339         {
00340             if ( last_value_map_[pred_nr_id] != value_map_[pred_nr_id] )
00341             {
00342                 if ( last_value_map_[pred_nr_id] )
00343                 {
00344                     update.falling_predicates.push_back ( pred_nr );
00345                 }
00346                 else
00347                 {
00348                     update.rising_predicates.push_back ( pred_nr );
00349                 }
00350             }
00351         }
00352         last_value_map_[pred_nr_id] = value_map_[pred_nr_id];
00353     }
00354 
00355     update.update_counter = pred_update_counters_[pm_id_];
00356 
00357     if ( pred_update_counters_[pm_id_] == MAX_UPDATE_COUNTER )
00358         pred_update_counters_[pm_id_] = 0;
00359     else
00360         pred_update_counters_[pm_id_]++;
00361 
00362     predicate_updates_pub_.publish ( update );
00363 }
00364 
00365 void
00366 PredicateManager::
00367 publishEventUpdate()
00368 {
00369     EventUpdate update;
00370 
00371     update.pm_id = pm_id_;
00372 
00373     foreach ( uint32_t ev, events_to_publish_ )
00374     {
00375         update.events.push_back ( ev );
00376         //ROS_DEBUG_STREAM("Predicate Manager:: Event " << pred_name << " is TRUE");
00377     }
00378 
00379     update.update_counter = ev_update_counter_;
00380 
00381     if ( ev_update_counter_ == MAX_UPDATE_COUNTER )
00382         ev_update_counter_ = 0;
00383     else
00384         ev_update_counter_++;
00385 
00386     event_updates_pub_.publish ( update );
00387 
00388     events_to_publish_.clear();
00389 }
00390 
00391 void
00392 PredicateManager::
00393 consumePredicateUpdate ( const PredicateUpdateConstPtr& msg )
00394 {
00395     if ( msg->pm_id != pm_id_ )
00396     {
00397         if ( initialized_pms_.size() <= msg->pm_id )
00398         {
00399             initialized_pms_.resize ( msg->pm_id + 1, false );
00400         }
00401         if ( pred_update_counters_.size() <= msg->pm_id )
00402         {
00403             pred_update_counters_.resize ( msg->pm_id + 1, 0 );
00404         }
00405         if ( !initialized_pms_[msg->pm_id] || pred_update_counters_[msg->pm_id] != msg->update_counter )
00406         {
00408             for ( size_t i = 0; i < nr_of_predicates_[msg->pm_id]; i++ )
00409             {
00410                 NrID pred_nr_id ( msg->pm_id, i );
00411                 value_map_[pred_nr_id] = false;
00412             }
00413 
00414             foreach ( uint32_t pred_nr, msg->true_predicates )
00415             {
00416                 NrID pred_nr_id ( msg->pm_id, pred_nr );
00417                 value_map_[pred_nr_id] = true;
00418             }
00419 
00420             for ( size_t i = 0; i < nr_of_predicates_[msg->pm_id]; i++ )
00421             {
00422                 NrID pred_nr_id ( msg->pm_id, i );
00423                 updateDependants ( pred_nr_id );
00424             }
00425 
00426             pred_update_counters_[msg->pm_id] = msg->update_counter;
00427         }
00428         else
00429         {
00431             foreach ( uint32_t pred_nr, msg->falling_predicates )
00432             {
00433                 NrID pred_nr_id ( msg->pm_id, pred_nr );
00434                 value_map_[pred_nr_id] = false;
00435                 updateDependants ( pred_nr_id );
00436             }
00437             foreach ( uint32_t pred_nr, msg->rising_predicates )
00438             {
00439                 NrID pred_nr_id ( msg->pm_id, pred_nr );
00440                 value_map_[pred_nr_id] = true;
00441                 updateDependants ( pred_nr_id );
00442             }
00443 
00444             if ( pred_update_counters_[msg->pm_id] == MAX_UPDATE_COUNTER )
00445                 pred_update_counters_[msg->pm_id] = 0;
00446             else
00447                 pred_update_counters_[msg->pm_id]++;
00448         }
00449     }
00450 }
00451 
00452 
00453 void
00454 PredicateManager::
00455 updateDependants ( const NrID pred_nr_id )
00456 {
00458     if ( pred_nr_observer_.count ( pred_nr_id ) )
00459     {
00460         ObserverPtr obs_ptr = pred_nr_observer_[pred_nr_id];
00461         if ( obs_ptr != boost::shared_ptr<std::set<uint32_t> >() )
00462         {
00463             foreach ( uint32_t dep_nr, *obs_ptr )
00464             {
00465                 local_pred_refs_[dep_nr]->update();
00466                 ROS_DEBUG_STREAM ( "Updating predicate '" << local_pred_refs_[dep_nr]->getName()
00467                                    << "' due to an updated dependency." );
00468             }
00469         }
00470     }
00472     if ( ev_nr_observer_.count ( pred_nr_id ) )
00473     {
00474         ObserverPtr obs_ptr = ev_nr_observer_[pred_nr_id];
00475         if ( obs_ptr != boost::shared_ptr<std::set<uint32_t> >() )
00476         {
00477             foreach ( uint32_t dep_nr, *obs_ptr )
00478             {
00479                 local_ev_refs_[dep_nr]->update();
00480                 ROS_DEBUG_STREAM ( "Updating event '" << local_ev_refs_[dep_nr]->getName()
00481                                    << "' due to an updated dependency." );
00482             }
00483         }
00484     }
00485 }
00486 
00487 void
00488 PredicateManager::
00489 prepareLocalDependencies()
00490 {
00491     for ( uint32_t i = 0; i < local_pred_refs_.size(); i++ )
00492     {
00493         PredicateInfo info;
00494         string pred_name = local_pred_refs_[i]->getName();
00495         NrID pred_nr_id ( pm_id_, i );
00496         NameID pred_name_id ( pm_id_, pred_name );
00497 
00498         setDependencyReferences ( pred_nr_id, pred_name_id );
00499     }
00500     setNrOfPredicates ( pm_id_, local_pred_refs_.size() );
00501 
00502     if ( pred_update_counters_.size() <= pm_id_ )
00503     {
00504         pred_update_counters_.resize ( pm_id_ + 1, 0 );
00505     }
00506 }
00507 
00508 void
00509 PredicateManager::
00510 setDependencyReferences ( const NrID pred_nr_id, const NameID pred_name_id )
00511 {
00512     if ( pred_name_observer_[pred_name_id] )
00513     {
00514         pred_nr_observer_[pred_nr_id] = pred_name_observer_[pred_name_id];
00515         ObserverPtr obs_ptr = pred_nr_observer_[pred_nr_id];
00516 
00517         foreach ( uint32_t pred_nr, *obs_ptr )
00518         {
00519             local_pred_refs_[pred_nr]->bindDependency ( pred_name_id, & ( value_map_[pred_nr_id] ) );
00520         }
00521     }
00522 
00523     if ( ev_name_observer_[pred_name_id] )
00524     {
00525         ev_nr_observer_[pred_nr_id] = ev_name_observer_[pred_name_id];
00526         ObserverPtr obs_ptr = ev_nr_observer_[pred_nr_id];
00527 
00528         foreach ( uint32_t ev_nr, *obs_ptr )
00529         {
00530             local_ev_refs_[ev_nr]->bindDependency ( pred_name_id, & ( value_map_[pred_nr_id] ) );
00531         }
00532     }
00533 }
00534 
00535 
00536 void
00537 PredicateManager::
00538 setNrOfPredicates ( const int pm_id, const size_t size )
00539 {
00540     if ( nr_of_predicates_.size() <= pm_id )
00541     {
00542         nr_of_predicates_.resize ( pm_id + 1 );
00543     }
00544     nr_of_predicates_[pm_id] = size;
00545 }


predicate_manager
Author(s): Joao Reis and Joao Messias
autogenerated on Wed Aug 26 2015 12:28:34