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 }