Nav2 Navigation Stack - humble  humble
ROS 2 Navigation Stack
demo_security.py
1 #! /usr/bin/env python3
2 # Copyright 2021 Samsung Research America
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from copy import deepcopy
17 
18 from geometry_msgs.msg import PoseStamped
19 from nav2_simple_commander.robot_navigator import BasicNavigator, TaskResult
20 
21 import rclpy
22 from rclpy.duration import Duration
23 
24 
25 """
26 Basic security route patrol demo. In this demonstration, the expectation
27 is that there are security cameras mounted on the robots recording or being
28 watched live by security staff.
29 """
30 
31 
32 def main():
33  rclpy.init()
34 
35  navigator = BasicNavigator()
36 
37  # Security route, probably read in from a file for a real application
38  # from either a map or drive and repeat.
39  security_route = [
40  [1.792, 2.144],
41  [1.792, -5.44],
42  [1.792, -9.427],
43  [-3.665, -9.427],
44  [-3.665, -4.303],
45  [-3.665, 2.330],
46  [-3.665, 9.283]]
47 
48  # Set our demo's initial pose
49  initial_pose = PoseStamped()
50  initial_pose.header.frame_id = 'map'
51  initial_pose.header.stamp = navigator.get_clock().now().to_msg()
52  initial_pose.pose.position.x = 3.45
53  initial_pose.pose.position.y = 2.15
54  initial_pose.pose.orientation.z = 1.0
55  initial_pose.pose.orientation.w = 0.0
56  navigator.setInitialPose(initial_pose)
57 
58  # Wait for navigation to fully activate
59  navigator.waitUntilNav2Active()
60 
61  # Do security route until dead
62  while rclpy.ok():
63  # Send our route
64  route_poses = []
65  pose = PoseStamped()
66  pose.header.frame_id = 'map'
67  pose.header.stamp = navigator.get_clock().now().to_msg()
68  pose.pose.orientation.w = 1.0
69  for pt in security_route:
70  pose.pose.position.x = pt[0]
71  pose.pose.position.y = pt[1]
72  route_poses.append(deepcopy(pose))
73  navigator.goThroughPoses(route_poses)
74 
75  # Do something during our route (e.x. AI detection on camera images for anomalies)
76  # Simply print ETA for the demonstation
77  i = 0
78  while not navigator.isTaskComplete():
79  i += 1
80  feedback = navigator.getFeedback()
81  if feedback and i % 5 == 0:
82  print('Estimated time to complete current route: ' + '{0:.0f}'.format(
83  Duration.from_msg(feedback.estimated_time_remaining).nanoseconds / 1e9)
84  + ' seconds.')
85 
86  # Some failure mode, must stop since the robot is clearly stuck
87  if Duration.from_msg(feedback.navigation_time) > Duration(seconds=180.0):
88  print('Navigation has exceeded timeout of 180s, canceling request.')
89  navigator.cancelTask()
90 
91  # If at end of route, reverse the route to restart
92  security_route.reverse()
93 
94  result = navigator.getResult()
95  if result == TaskResult.SUCCEEDED:
96  print('Route complete! Restarting...')
97  elif result == TaskResult.CANCELED:
98  print('Security route was canceled, exiting.')
99  exit(1)
100  elif result == TaskResult.FAILED:
101  print('Security route failed! Restarting from other side...')
102 
103  exit(0)
104 
105 
106 if __name__ == '__main__':
107  main()