NavigationState.cpp
Go to the documentation of this file.
2 
3 namespace rsm {
4 
6 }
7 
9 }
10 
12  //initialize services, publisher and subscriber
13  ros::NodeHandle nh("rsm");
15  nh.serviceClient<rsm_msgs::GetNavigationGoal>("getNavigationGoal");
17  rsm_msgs::GoalCompleted>("navigationGoalCompleted");
18  _get_robot_pose_service = nh.serviceClient<rsm_msgs::GetRobotPose>(
19  "getRobotPose");
20  _get_reverse_mode_service = nh.serviceClient<std_srvs::Trigger>(
21  "getReverseMode");
22  _reverse_mode_subscriber = nh.subscribe<std_msgs::Bool>("reverseMode", 10,
24  _get_exploration_mode_service = nh.serviceClient<std_srvs::Trigger>(
25  "getExplorationMode");
27  &NavigationState::timerCallback, this, true, false);
28  //initialize variables
29  _name = "Navigation";
30  _navigation_mode = -1;
31  _goal_active = false;
32  _reverse_mode = false;
33  _exploration_mode = -1;
34  _operation_mode = rsm_msgs::OperationMode::STOPPED;
35  _navigation_completed_status = rsm_msgs::GoalStatus::ACTIVE;
36 }
37 
39  //Request navigation goal from Service Provider
40  rsm_msgs::GetNavigationGoal srv;
42  _nav_goal = srv.response.goal;
43  _navigation_mode = srv.response.navigationMode;
44  _routine = srv.response.routine;
45  switch (_navigation_mode) {
46  case EXPLORATION:
47  _name = "E: Navigation";
48  break;
49  case WAYPOINT_FOLLOWING:
50  _name = "W: Navigation";
51  break;
52  case SIMPLE_GOAL:
53  _name = "G: Navigation";
54  break;
55  default:
56  _name = "Navigation";
57  break;
58  }
59  } else {
60  ROS_ERROR("Failed to call Get Navigation Goal service");
62  }
63  //Check if reverse mode is active with Service Provider
64  std_srvs::Trigger srv2;
65  if (_get_reverse_mode_service.call(srv2)) {
66  _reverse_mode = srv2.response.success;
67  if (_reverse_mode) {
68  _move_base_client.reset(
69  new MoveBaseClient("move_base_reverse", true));
70  } else {
71  _move_base_client.reset(new MoveBaseClient("move_base", true));
72  }
73  } else {
74  ROS_ERROR("Failed to call Get Reverse Mode service");
75  _move_base_client.reset(new MoveBaseClient("move_base", true));
76  }
77  //Get exploration mode from Service Provider if exploration is active
79  std_srvs::Trigger srv2;
81  _exploration_mode = srv2.response.success;
82  if (_exploration_mode) {
83  ros::NodeHandle nh("rsm");
84  _get_goal_obsolete_subscriber = nh.subscribe("goalObsolete", 1,
86  }
87  } else {
88  ROS_ERROR("Failed to call Get Exploration Mode service");
90  }
91  }
92  //Start timer for checking navigation being stuck for too long (15 secs) without proper message from Move Base
94 }
95 
97  if (_move_base_client->isServerConnected()) {
98  if (_goal_active) {
99  if (_move_base_client->getState().isDone()) {
100  if (_move_base_client->getState().state_
102  if (!_interrupt_occured) {
103  switch (_navigation_mode) {
104  case EXPLORATION: {
107  MAPPING_STATE));
108  break;
109  }
110  case WAYPOINT_FOLLOWING: {
111  if (_routine.empty()) {
113  rsm_msgs::GoalStatus::REACHED;
115  boost::make_shared<
117  } else {
121  }
122  break;
123  }
124  default: {
125  abortNavigation();
126  break;
127  }
128  }
129  }
130  } else {
131  if (!_interrupt_occured) {
133  rsm_msgs::GoalStatus::FAILED;
134  switch (_navigation_mode) {
135  case EXPLORATION: {
139  break;
140  }
141  case WAYPOINT_FOLLOWING: {
143  boost::make_shared<WaypointFollowingState>());
144  break;
145  }
146  default: {
147  abortNavigation();
148  break;
149  }
150  }
151  }
152  }
153  } else {
154  //Check if robot moved for navigation failure check
155  comparePose();
156  }
157  } else {
158  //Initialize goal
159  move_base_msgs::MoveBaseGoal goal;
160  goal.target_pose.header.frame_id = "map";
161  goal.target_pose.header.stamp = ros::Time::now();
162  goal.target_pose.pose = _nav_goal;
163  _move_base_client->sendGoal(goal);
164  _goal_active = true;
165  }
166  }
167 }
168 
170  if (_goal_active) {
171  _move_base_client->cancelGoal();
172  }
173  if (_navigation_completed_status != rsm_msgs::GoalStatus::ACTIVE) {
174  rsm_msgs::GoalCompleted srv;
175  srv.request.status.goal_status = _navigation_completed_status;
177  ROS_ERROR("Failed to call Complete Navigation Goal service");
178  }
179  }
180 }
181 
182 void NavigationState::onExplorationStart(bool &success, std::string &message) {
183  switch (_navigation_mode) {
184  case EXPLORATION:
185  success = false;
186  message = "Exploration running";
187  break;
188  case WAYPOINT_FOLLOWING:
189  success = false;
190  message = "Waypoint following running";
191  break;
192  case SIMPLE_GOAL:
193  success = false;
194  message = "Simple Goal running";
195  break;
196  default:
197  success = false;
198  message = "Nothing running";
199  break;
200  }
201 }
202 
203 void NavigationState::onExplorationStop(bool &success, std::string &message) {
204  switch (_navigation_mode) {
205  case EXPLORATION:
206  success = true;
207  message = "Exploration stopped";
208  abortNavigation();
209  break;
210  case WAYPOINT_FOLLOWING:
211  success = false;
212  message = "Waypoint following running";
213  break;
214  case SIMPLE_GOAL:
215  success = false;
216  message = "Simple Goal running";
217  break;
218  default:
219  success = false;
220  message = "Nothing running";
221  break;
222  }
223 }
224 
226  std::string &message) {
227  success = false;
228  switch (_navigation_mode) {
229  case EXPLORATION:
230  message = "Exploration running";
231  break;
232  case WAYPOINT_FOLLOWING:
233  message = "Waypoint following running";
234  break;
235  case SIMPLE_GOAL:
236  message = "Simple Goal running";
237  break;
238  default:
239  message = "Nothing running";
240  break;
241  }
242 }
243 
245  std::string &message) {
246  switch (_navigation_mode) {
247  case EXPLORATION:
248  success = false;
249  message = "Exploration running";
250  break;
251  case WAYPOINT_FOLLOWING:
252  success = true;
253  message = "Waypoint following stopped";
254  abortNavigation();
255  break;
256  case SIMPLE_GOAL:
257  success = false;
258  message = "Simple Goal running";
259  break;
260  default:
261  success = false;
262  message = "Nothing running";
263  break;
264  }
265 }
266 
267 void NavigationState::onInterrupt(int interrupt) {
268  _navigation_completed_status = rsm_msgs::GoalStatus::ABORTED;
269  switch (interrupt) {
272  boost::make_shared<EmergencyStopState>());
273  _interrupt_occured = true;
274  break;
277  boost::make_shared<TeleoperationState>());
278  _interrupt_occured = true;
279  break;
283  _interrupt_occured = true;
284  break;
286  if (_navigation_mode == SIMPLE_GOAL) {
288  boost::make_shared<IdleState>());
289  }
290  break;
291  }
292 }
293 
295  ROS_ERROR("Navigation aborted because robot appears to be stuck");
296  abortNavigation();
297 }
298 
300  if (_operation_mode == rsm_msgs::OperationMode::AUTONOMOUS) {
301  if (_comparison_counter++ >= 5) { //only compare poses every 5th call to reduce load
302  tf::Pose current_pose;
303  rsm_msgs::GetRobotPose srv;
304  if (_get_robot_pose_service.call(srv)) {
305  tf::poseMsgToTF(srv.response.pose, current_pose);
306  tf::Pose pose_difference = current_pose.inverseTimes(
307  _last_pose);
308  if (pose_difference.getOrigin().x() < POSE_TOLERANCE
309  && pose_difference.getOrigin().y() < POSE_TOLERANCE
310  && pose_difference.getOrigin().z() < POSE_TOLERANCE
311  && pose_difference.getRotation().x() == 0.0
312  && pose_difference.getRotation().y() == 0.0
313  && pose_difference.getRotation().z() == 0.0
314  && pose_difference.getRotation().w() == 1.0) {
315  _idle_timer.start();
316  } else {
317  _idle_timer.stop();
318  }
319  _last_pose = current_pose;
321  } else {
322  ROS_ERROR("Failed to call Get Robot Pose service");
323  }
324  }
325  } else {
326  _idle_timer.stop();
327  }
328 }
329 
331  const std_msgs::Bool::ConstPtr& msg) {
332  if (msg->data && !_interrupt_occured) {
333  _navigation_completed_status = rsm_msgs::GoalStatus::ABORTED;
336  MAPPING_STATE));
337  }
338 }
339 
341  const std_msgs::Bool::ConstPtr& reverse_mode) {
342  if (_reverse_mode != reverse_mode->data) {
343  if (_goal_active) {
344  _move_base_client->cancelGoal();
345  }
346  _goal_active = false;
347  _reverse_mode = reverse_mode->data;
348  if (_reverse_mode) {
349  _move_base_client.reset(
350  new MoveBaseClient("move_base_reverse", true));
351  } else {
352  _move_base_client.reset(new MoveBaseClient("move_base", true));
353  }
354  }
355 }
356 
358  const rsm_msgs::OperationMode::ConstPtr& operation_mode) {
359  _operation_mode = operation_mode->mode;
360 }
361 
363  if (!_interrupt_occured) {
364  _navigation_completed_status = rsm_msgs::GoalStatus::ABORTED;
366  boost::make_shared<IdleState>());
367  }
368 }
369 
370 }
371 
void onWaypointFollowingStart(bool &success, std::string &message)
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
static void poseMsgToTF(const geometry_msgs::Pose &msg, Pose &bt)
void goalObsoleteCallback(const std_msgs::Bool::ConstPtr &msg)
ros::Subscriber _get_goal_obsolete_subscriber
void onExplorationStart(bool &success, std::string &message)
boost::shared_ptr< rsm::BaseState > getPluginState(int plugin_type, std::string routine="")
#define MAPPING_STATE
ros::ServiceClient _get_reverse_mode_service
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ros::ServiceClient _get_navigation_goal_service
#define NAVIGATION_STATE
#define SIMPLE_GOAL_STOP_INTERRUPT
State being active when the robot should move to a previously set goal. First obtains the goal and th...
void stop()
bool call(MReq &req, MRes &res)
void start()
#define ROUTINE_STATE
void onWaypointFollowingStop(bool &success, std::string &message)
geometry_msgs::Pose _nav_goal
void transitionToVolatileState(boost::shared_ptr< rsm::BaseState > next_state)
bool _interrupt_occured
#define WAYPOINT_FOLLOWING
#define TELEOPERATION_INTERRUPT
TFSIMD_FORCE_INLINE const tfScalar & x() const
void onInterrupt(int interrupt)
Called when an operation mode interrupt was received.
TFSIMD_FORCE_INLINE const tfScalar & z() const
ros::ServiceClient _get_robot_pose_service
#define CALCULATEGOAL_STATE
std::string _name
TFSIMD_FORCE_INLINE const tfScalar & y() const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
StateInterface * _stateinterface
#define EMERGENCY_STOP_INTERRUPT
#define EXPLORATION
void onExplorationStop(bool &success, std::string &message)
void timerCallback(const ros::TimerEvent &event)
Callback for idle timer.
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
ros::ServiceClient _get_exploration_mode_service
void operationModeCallback(const rsm_msgs::OperationMode::ConstPtr &operation_mode)
ros::ServiceClient _navigation_goal_completed_service
ros::NodeHandle _nh
actionlib::SimpleActionClient< move_base_msgs::MoveBaseAction > MoveBaseClient
Quaternion getRotation() const
static Time now()
void reverseModeCallback(const std_msgs::Bool::ConstPtr &reverse_mode)
#define SIMPLE_GOAL_INTERRUPT
#define SIMPLE_GOAL
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
boost::shared_ptr< MoveBaseClient > _move_base_client
#define ROS_ERROR(...)
Transform inverseTimes(const Transform &t) const
ros::Subscriber _reverse_mode_subscriber


rsm_additions
Author(s): Marco Steinbrink
autogenerated on Tue Mar 16 2021 02:44:35