00001 00027 #include <boost/function.hpp> 00028 #include <boost/foreach.hpp> 00029 #define foreach BOOST_FOREACH 00030 00031 #include <geometry_msgs/PoseStamped.h> 00032 00033 #include <topological_tools/topological_action_manager.h> 00034 #include <predicate_manager/predicate_manager.h> 00035 00036 00037 00038 using namespace std; 00039 using namespace ros; 00040 using namespace topological_tools; 00041 using namespace predicate_manager; 00042 00043 00044 00045 TopologicalActionManager:: 00046 TopologicalActionManager ( TopologicalMap& tm, CallbackQueueInterface* queue ) : 00047 pred_updates_sub_ (), 00048 pred_map_sub_ (), 00049 tm_ ( tm ), 00050 pred_id_node_map_(), 00051 pm_id_ ( 0 ), 00052 current_node_name_(), 00053 requested_update_() 00054 { 00055 SubscribeOptions update_opts = SubscribeOptions::create<PredicateUpdate> 00056 ( "/predicate_updates", 1, boost::bind ( &TopologicalActionManager::predicateUpdatesCallback, this,_1 ),VoidPtr(), queue ); 00057 SubscribeOptions map_opts = SubscribeOptions::create<PredicateInfoMap> 00058 ( "/predicate_maps", 1, boost::bind ( &TopologicalActionManager::predicateMapCallback, this,_1 ),VoidPtr(), queue ); 00059 00060 pred_updates_sub_ = nh_.subscribe ( update_opts ); 00061 pred_map_sub_ = nh_.subscribe ( map_opts ); 00062 nh_.getParam ( "pm_id", pm_id_ ); 00063 } 00064 00065 00066 00067 TopologicalActionManager:: 00068 TopologicalActionManager ( const std::string& map_file, CallbackQueueInterface* queue ) : 00069 pred_updates_sub_ (), 00070 pred_map_sub_ (), 00071 tm_ ( map_file ), 00072 pred_id_node_map_(), 00073 pm_id_ ( 0 ), 00074 current_node_name_(), 00075 requested_update_() 00076 { 00077 SubscribeOptions update_opts = SubscribeOptions::create<PredicateUpdate> 00078 ( "/predicate_updates", 1, boost::bind ( &TopologicalActionManager::predicateUpdatesCallback, this,_1 ),VoidPtr(), queue ); 00079 SubscribeOptions map_opts = SubscribeOptions::create<PredicateInfoMap> 00080 ( "/predicate_maps", 1, boost::bind ( &TopologicalActionManager::predicateMapCallback, this,_1 ),VoidPtr(), queue ); 00081 00082 pred_updates_sub_ = nh_.subscribe ( update_opts ); 00083 pred_map_sub_ = nh_.subscribe ( map_opts ); 00084 nh_.getParam ( "pm_id", pm_id_ ); 00085 } 00086 00087 00088 00089 geometry_msgs::Pose 00090 TopologicalActionManager:: 00091 getGoalPoseForLabel ( const std::string& connection_label ) 00092 { 00093 if ( !isInitialized() ) 00094 { 00095 ROS_ERROR ( "TopologicalActionManager:: Not yet initialized. Current node unknown." ); 00096 return geometry_msgs::Pose(); 00097 } 00098 00099 return getGoalPoseForLabel ( connection_label, current_node_name_ ); 00100 } 00101 00102 00103 00104 geometry_msgs::Pose 00105 TopologicalActionManager:: 00106 getGoalPoseForLabel ( const std::string& connection_label, const std::string& origin_name ) 00107 { 00108 geometry_msgs::Pose goal_pose; 00109 boost::shared_ptr<TopologicalNode> goal_node = getGoalNodeForLabel ( connection_label, origin_name ); 00110 if ( goal_node ) 00111 { 00112 goal_pose = goal_node->getGoalPose(); 00113 } 00114 else 00115 { 00116 ROS_ERROR_STREAM ( "TopologicalActionManager:: Could not get the goal node for the label pair < " << origin_name << ", " << connection_label << " >" ); 00117 } 00118 return goal_pose; 00119 } 00120 00121 00122 00123 boost::shared_ptr<TopologicalNode> 00124 TopologicalActionManager:: 00125 getGoalNodeForLabel ( const std::string& connection_label ) 00126 { 00127 if ( !isInitialized() ) 00128 { 00129 ROS_ERROR ( "TopologicalActionManager:: Not yet initialized. Current node unknown." ); 00130 return boost::shared_ptr<TopologicalNode>(); 00131 } 00132 00133 return getGoalNodeForLabel ( connection_label, current_node_name_ ); 00134 } 00135 00136 00137 00138 boost::shared_ptr<TopologicalNode> 00139 TopologicalActionManager:: 00140 getGoalNodeForLabel ( const std::string& connection_label, const std::string& origin_name ) 00141 { 00142 boost::shared_ptr<TopologicalNode> node = tm_.getNodeByName ( origin_name ); 00143 if ( !node ) 00144 return node; 00145 if ( !node->hasConnection ( connection_label ) ) 00146 { 00147 ROS_WARN_STREAM ( "TopologicalActionManager:: Node '" << node->getName() << "' has no connection '" << connection_label << "'. Idling" ); 00148 return node; 00149 } 00150 else 00151 { 00152 return node->getConnection ( connection_label ); 00153 } 00154 } 00155 00156 00157 00158 boost::shared_ptr<TopologicalNode> 00159 TopologicalActionManager:: 00160 getCurrentNode() 00161 { 00162 if ( !isInitialized() ) 00163 { 00164 ROS_ERROR ( "TopologicalActionManager:: Not yet initialized. Current node unknown." ); 00165 return boost::shared_ptr<TopologicalNode>(); 00166 } 00167 00168 return tm_.getNodeByName ( current_node_name_ ); 00169 } 00170 00171 00172 00173 bool 00174 TopologicalActionManager:: 00175 isInitialized() 00176 { 00177 return !current_node_name_.empty(); 00178 } 00179 00180 00181 00182 void 00183 TopologicalActionManager:: 00184 predicateMapCallback ( const PredicateInfoMapConstPtr& msg ) 00185 { 00186 if ( msg->pm_id != ( uint32_t ) pm_id_ ) 00187 { 00188 return; 00189 } 00190 00191 foreach ( PredicateInfoMap::_map_type::value_type pred_info, msg->map ) 00192 if ( tm_.hasNode ( pred_info.name ) ) 00193 { 00194 pred_id_node_map_[pred_info.nr] = pred_info.name; 00195 } 00196 00197 if ( !requested_update_.true_predicates.empty() ) 00198 { 00199 predicateUpdatesInternal ( requested_update_ ); 00200 } 00201 } 00202 00203 00204 00205 void 00206 TopologicalActionManager:: 00207 predicateUpdatesCallback ( const PredicateUpdateConstPtr& msg ) 00208 { 00209 if ( msg->pm_id != ( uint32_t ) pm_id_ ) 00210 { 00211 return; 00212 } 00213 00214 if ( pred_id_node_map_.empty() ) 00215 { 00217 requested_update_ = *msg; 00218 return; 00219 } 00220 else 00221 { 00222 requested_update_.true_predicates.clear(); 00223 } 00224 00225 predicateUpdatesInternal ( *msg ); 00226 } 00227 00228 00229 00230 void 00231 TopologicalActionManager:: 00232 predicateUpdatesInternal ( const PredicateUpdate& msg ) 00233 { 00234 foreach ( PredicateUpdate::_true_predicates_type::value_type pred, msg.true_predicates ) 00235 if ( pred_id_node_map_.count ( pred ) ) 00236 { 00237 current_node_name_ = pred_id_node_map_[pred]; 00238 ROS_INFO_STREAM ( "TopologicalActionManager:: Current node is now " << current_node_name_ ); 00239 } 00240 }