7 #include <geometry_msgs/PolygonStamped.h> 9 #include <frontier_exploration/ExploreTaskAction.h> 10 #include <frontier_exploration/GetNextFrontier.h> 11 #include <frontier_exploration/UpdateBoundaryPolygon.h> 15 #include <move_base_msgs/MoveBaseAction.h> 63 frontier_exploration::ExploreTaskFeedback
feedback_;
72 void executeCb(
const frontier_exploration::ExploreTaskGoalConstPtr &goal)
78 explore_costmap_ros_->resetLayers();
81 ros::ServiceClient updateBoundaryPolygon = private_nh_.
serviceClient<frontier_exploration::UpdateBoundaryPolygon>(
"explore_costmap/explore_boundary/update_boundary_polygon");
82 ros::ServiceClient getNextFrontier = private_nh_.
serviceClient<frontier_exploration::GetNextFrontier>(
"explore_costmap/explore_boundary/get_next_frontier");
92 frontier_exploration::UpdateBoundaryPolygon srv;
93 srv.request.explore_boundary = goal->explore_boundary;
94 if(updateBoundaryPolygon.
call(srv)){
97 ROS_ERROR(
"Failed to set region boundary");
107 frontier_exploration::GetNextFrontier srv;
110 geometry_msgs::PoseStamped goal_pose;
114 explore_costmap_ros_->getRobotPose(robot_pose);
120 geometry_msgs::PoseStamped eval_pose = srv.request.start_pose;
121 if(eval_pose.header.frame_id != goal->explore_boundary.header.frame_id){
122 tf_listener_.
transformPose(goal->explore_boundary.header.frame_id, srv.request.start_pose, eval_pose);
126 if(goal->explore_boundary.polygon.points.size() > 0 && !
pointInPolygon(eval_pose.pose.position,goal->explore_boundary.polygon)){
130 ROS_WARN(
"Robot left exploration boundary, returning to center");
132 ROS_DEBUG(
"Robot not initially in exploration boundary, traveling to center");
135 geometry_msgs::PointStamped eval_point;
136 eval_point.header = eval_pose.header;
137 eval_point.point = eval_pose.pose.position;
138 if(eval_point.header.frame_id != goal->explore_center.header.frame_id){
139 geometry_msgs::PointStamped temp = eval_point;
140 tf_listener_.
transformPoint(goal->explore_center.header.frame_id, temp, eval_point);
144 goal_pose.header = goal->explore_center.header;
145 goal_pose.pose.position = goal->explore_center.point;
148 }
else if(getNextFrontier.call(srv)){
152 goal_pose = feedback_.next_frontier = srv.response.next_frontier;
159 if(retry_ == 0 && success_){
160 ROS_WARN(
"Finished exploring room");
162 boost::unique_lock<boost::mutex> lock(move_client_lock_);
166 }
else if(retry_ == 0 || !
ros::ok()){
181 if(!moving_ || !
pointsNearby(move_client_goal_.target_pose.pose.position,goal_pose.pose.position,goal_aliasing_*0.5)){
183 move_client_goal_.target_pose = goal_pose;
184 boost::unique_lock<boost::mutex> lock(move_client_lock_);
215 boost::unique_lock<boost::mutex> lock(move_client_lock_);
217 ROS_WARN(
"Current exploration task cancelled");
231 feedback_.base_position = feedback->base_position;
256 int main(
int argc,
char** argv)
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
boost::shared_ptr< costmap_2d::Costmap2DROS > explore_costmap_ros_
void publishFeedback(const FeedbackConstPtr &feedback)
actionlib::SimpleActionServer< frontier_exploration::ExploreTaskAction > as_
bool waitForServer(const ros::Duration &timeout=ros::Duration(0, 0)) const
boost::mutex move_client_lock_
tf::TransformListener tf_listener_
void preemptCb()
Preempt callback for the server, cancels the current running goal and all associated movement actions...
static void poseStampedTFToMsg(const Stamped< Pose > &bt, geometry_msgs::PoseStamped &msg)
FrontierExplorationServer(std::string name)
Constructor for the server, sets up this node's ActionServer for exploration and ActionClient to move...
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool call(MReq &req, MRes &res)
bool pointsNearby(const T &one, const S &two, const double &proximity)
Evaluate whether two points are approximately adjacent, within a specified proximity distance...
ROSCPP_DECL const std::string & getName()
void doneMovingCb(const actionlib::SimpleClientGoalState &state, const move_base_msgs::MoveBaseResultConstPtr &result)
Done callback for the move_base client, checks for errors and aborts exploration task if necessary...
move_base_msgs::MoveBaseGoal move_client_goal_
void setSucceeded(const Result &result=Result(), const std::string &text=std::string(""))
void feedbackMovingCb(const move_base_msgs::MoveBaseFeedbackConstPtr &feedback)
Feedback callback for the move_base client, republishes as feedback for the exploration server...
ROSCPP_DECL void spin(Spinner &spinner)
Server for frontier exploration action, runs the state machine associated with a structured frontier ...
void executeCb(const frontier_exploration::ExploreTaskGoalConstPtr &goal)
Execute callback for actionserver, run after accepting a new goal.
void setPreempted(const Result &result=Result(), const std::string &text=std::string(""))
ros::NodeHandle private_nh_
actionlib::SimpleActionClient< move_base_msgs::MoveBaseAction > move_client_
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
void registerPreemptCallback(boost::function< void()> cb)
void cancelGoalsAtAndBeforeTime(const ros::Time &time)
frontier_exploration::ExploreTaskFeedback feedback_
void setAborted(const Result &result=Result(), const std::string &text=std::string(""))
void sendGoal(const Goal &goal, SimpleDoneCallback done_cb=SimpleDoneCallback(), SimpleActiveCallback active_cb=SimpleActiveCallback(), SimpleFeedbackCallback feedback_cb=SimpleFeedbackCallback())
static geometry_msgs::Quaternion createQuaternionMsgFromYaw(double yaw)
double yawOfVector(const T &origin, const S &end)
Calculate the yaw of vector defined by origin and end points.
bool pointInPolygon(const T &point, const geometry_msgs::Polygon &polygon)
Evaluate if point is inside area defined by polygon. Undefined behaviour for points on line...
int main(int argc, char **argv)