action_layer.cpp
Go to the documentation of this file.
00001 
00026 #include <mdm_library/common_defs.h>
00027 #include <mdm_library/action_layer.h>
00028 
00029 
00030 using namespace ros;
00031 using namespace std;
00032 using namespace mdm_library;
00033 
00034 
00035 
00036 ActionLayer::
00037 ActionLayer() :
00038     action_sub_ ( nh_.subscribe ( "action", 1, &ActionLayer::actionSymbolCallback, this ) ),
00039     action_metadata_sub_ ( nh_.subscribe ( "action_metadata", 1, &ActionLayer::actionMetadataCallback, this ) ),
00040     action_callbacks_ (),
00041     local_action_names_ (),
00042     action_sizes_ (),
00043     cached_sizes_prod_ ( 0 ),
00044     pending_action_ (),
00045     mdm_agent_index_ ( 0 ),
00046     using_named_actions_ ( false )
00047 {
00048     NodeHandle private_nh ( "~" );
00049     if ( ! ( private_nh.getParam ( "mdm_agent_index", mdm_agent_index_ ) ) )
00050     {
00051         ROS_WARN ( "ActionLayer:: MDM Agent Index not specified. Proceeding as agent 0." );
00052     }
00053 }
00054 
00055 
00056 
00057 ActionLayer::
00058 ActionLayer ( const FactoredSymbolMetadataConstPtr& action_metadata ) :
00059     action_sub_ ( nh_.subscribe ( "action", 1, &ActionLayer::actionSymbolCallback, this ) ),
00060     action_metadata_sub_ (),
00061     action_callbacks_ (),
00062     local_action_names_ (),
00063     action_sizes_ (),
00064     cached_sizes_prod_ ( 0 ),
00065     pending_action_ (),
00066     mdm_agent_index_ ( 0 ),
00067     using_named_actions_ ( false )
00068 {
00069     NodeHandle private_nh ( "~" );
00070     if ( ! ( private_nh.getParam ( "mdm_agent_index", mdm_agent_index_ ) ) )
00071     {
00072         ROS_WARN ( "ActionLayer:: MDM Agent Index not specified. Proceeding as agent 0." );
00073     }
00074     actionMetadataCallback ( action_metadata );
00075 }
00076 
00077 
00078 
00079 ActionLayer::
00080 ActionLayer ( CallbackQueueInterface* queue ) :
00081     action_sub_ (),
00082     action_metadata_sub_ (),
00083     action_callbacks_ (),
00084     local_action_names_ (),
00085     action_sizes_ (),
00086     cached_sizes_prod_ ( 0 ),
00087     pending_action_ (),
00088     mdm_agent_index_ ( 0 ),
00089     using_named_actions_ ( false )
00090 {
00091     NodeHandle private_nh ( "~" );
00092     if ( ! ( private_nh.getParam ( "mdm_agent_index", mdm_agent_index_ ) ) )
00093     {
00094         ROS_WARN ( "ActionLayer:: MDM Agent Index not specified. Proceeding as agent 0." );
00095     }
00096     SubscribeOptions opts = SubscribeOptions::create<ActionSymbol>
00097                             ( "action", 1, boost::bind ( &ActionLayer::actionSymbolCallback, this,_1 ),VoidPtr(), queue );
00098     action_sub_ = nh_.subscribe ( opts );
00099 }
00100 
00101 
00102 void
00103 ActionLayer::
00104 addAction ( boost::function<void () > callback )
00105 {
00106     addAction ( callback, "" );
00107 }
00108 
00109 
00110 void
00111 ActionLayer::
00112 addAction ( boost::function<void () > callback, const string& action_name )
00113 {
00114     if ( ( action_name.empty() && using_named_actions_ )
00115             || ( !action_name.empty() && action_callbacks_.size() > 0 && !using_named_actions_ ) )
00116     {
00117         ROS_FATAL ( "ActionLayer:: Can't use both named and nameless actions." );
00118         ROS_FATAL ( "ActionLayer:: Please label every action (or none) when adding them to the Action Layer" );
00119         shutdown();
00120         return;
00121     }
00122 
00123     if ( !action_name.empty() )
00124     {
00125         using_named_actions_ = true;
00126         local_action_names_.push_back ( action_name );
00127     }
00128 
00129     if ( using_named_actions_ )
00130     {
00131         named_action_ids_[action_name] = action_callbacks_.size();
00132     }
00133 
00134     action_callbacks_.push_back ( callback );
00135 }
00136 
00137 
00138 
00139 void
00140 ActionLayer::
00141 actionSymbolCallback ( const ActionSymbolConstPtr& msg )
00142 {
00143     try
00144     {
00145         if ( action_sizes_.empty() )
00146         {
00147             ROS_WARN ( "ActionLayer:: Action received, but no metadata is known yet." );
00148             ROS_WARN ( "ActionLayer:: Proceeding as a single, unverified agent." );
00149             action_sizes_.push_back ( action_callbacks_.size() );
00150             action_ids_.clear();
00151             for ( size_t i = 0; i < action_callbacks_.size(); i++ )
00152                 action_ids_.push_back ( i );
00153             pending_action_ = boost::shared_ptr<const ActionSymbol> ( new ActionSymbol ( *msg ) );
00154         }
00155 
00156         uint32_t local_action;
00157         if ( action_sizes_.size() > 1 )
00158         {
00159             local_action = jointToIndividualAction ( msg->action_symbol );
00160         }
00161         else
00162         {
00163             local_action = msg->action_symbol;
00164         }
00165         if ( local_action_names_.empty() )
00166         {
00167             ROS_INFO_STREAM ( "ActionLayer:: Agent " << mdm_agent_index_ << " executing action " << local_action );
00168         }
00169         else
00170         {
00171             ROS_INFO_STREAM ( "ActionLayer:: Agent " << mdm_agent_index_ << " executing action " << local_action << " (" << local_action_names_[local_action] << ")" );
00172         }
00173         if ( action_ids_.size() > local_action && action_callbacks_.size() > action_ids_[local_action] )
00174         {
00175             size_t id = action_ids_[local_action];
00176             action_callbacks_[id] ();
00177         }
00178         else
00179         {
00180             ROS_FATAL_STREAM ( "ActionLayer:: Callback for action " << local_action << " is unknown" );
00181             shutdown();
00182         }
00183     }
00184     catch ( exception & e )
00185     {
00186         ROS_FATAL_STREAM ( e.what() );
00187         shutdown();
00188     }
00189 }
00190 
00191 
00192 
00193 void
00194 ActionLayer::
00195 actionMetadataCallback ( const FactoredSymbolMetadataConstPtr& msg )
00196 {
00197     if ( action_ids_.size() < action_callbacks_.size() )
00198     {
00199         action_ids_.reserve ( action_callbacks_.size() );
00200     }
00201 
00202     uint32_t declared_values = action_callbacks_.size();
00203 
00204     if ( msg->factors.size() < ( size_t ) mdm_agent_index_ )
00205     {
00206         ROS_FATAL_STREAM ( "ActionLayer:: Action Metadata for agent " << mdm_agent_index_ << " is not present" );
00207         shutdown();
00208         return;
00209     }
00210 
00211     uint32_t expected_values = msg->factors[mdm_agent_index_].number_of_symbols;
00212 
00213     if ( declared_values != expected_values )
00214     {
00215         ROS_FATAL_STREAM ( "ActionLayer:: Number of declared actions for agent " << mdm_agent_index_ << " (" << declared_values
00216                            << ") is different than the number of expected actions (" << expected_values << ")" );
00217         shutdown();
00218         return;
00219     }
00220 
00221     action_sizes_.clear();
00222     for ( size_t i = 0; i < msg->factors.size(); i++ )
00223     {
00224         action_sizes_.push_back ( msg->factors[i].number_of_symbols );
00225         if ( ! using_named_actions_ && i == mdm_agent_index_ )
00226         {
00227             for ( size_t j = 0; j < msg->factors[j].symbol_names.size(); j++ )
00228             {
00229                 local_action_names_.push_back ( msg->factors[i].symbol_names[j] );
00230                 action_ids_[j] = j; 
00231             }
00232         }
00233     }
00234 
00235     if ( using_named_actions_ )
00236     {
00237         for ( size_t i = 0; i < msg->factors[mdm_agent_index_].symbol_names.size(); i++ )
00238         {
00239             string name = msg->factors[mdm_agent_index_].symbol_names[i];
00240             if ( named_action_ids_.count ( name ) )
00241             {
00242                 action_ids_[i] = named_action_ids_[name];
00244             }
00245             else
00246             {
00247                 ROS_FATAL_STREAM ( "ActionLayer:: Action " << name << " is specified in the model metadata"
00248                                    << " but it isn't present in the Action Layer. Please define this action." );
00249                 shutdown();
00250                 return;
00251             }
00252         }
00253     }
00254 
00255     if ( pending_action_ != 0 )
00256     {
00257         actionSymbolCallback ( pending_action_ );
00258         pending_action_.reset();
00259     }
00260 }
00261 
00262 
00263 
00264 uint32_t
00265 ActionLayer::
00266 jointToIndividualAction ( const uint32_t joint_action )
00267 {
00268     if ( action_sizes_.empty() )
00269     {
00270         ROS_FATAL ( "ActionLayer:: Attempted to convert a joint action to an individual action, but the number of actions per agent is not known." );
00271         shutdown();
00272         return ( 0 );
00273     }
00274 
00275     if ( cached_sizes_prod_ == 0 )
00276     {
00277         cached_sizes_prod_ = 1;
00278         for ( ActionSizesVector::iterator it = action_sizes_.begin() +mdm_agent_index_+1;
00279                 it != action_sizes_.end();
00280                 it ++ )
00281         {
00282             cached_sizes_prod_ *= ( uint32_t ) ( *it );
00283         }
00284     }
00285 
00286     uint32_t local_action = floor ( ( joint_action % ( cached_sizes_prod_ * action_sizes_[mdm_agent_index_] ) ) / cached_sizes_prod_ );
00287 
00288     return local_action;
00289 }


mdm_library
Author(s): Joao Messias
autogenerated on Wed Aug 26 2015 12:28:41