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
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 }