Nav2 Navigation Stack - rolling  main
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 import rclpy
21 from rclpy.duration import Duration
22 
23 """
24 Basic security route patrol demo. In this demonstration, the expectation
25 is that there are security cameras mounted on the robots recording or being
26 watched live by security staff.
27 """
28 
29 
30 def main() -> None:
31  rclpy.init()
32 
33  navigator = BasicNavigator()
34 
35  # Security route, probably read in from a file for a real application
36  # from either a map or drive and repeat.
37  security_route = [
38  [10.15, -0.77],
39  [17.86, -0.77],
40  [21.58, -3.5],
41  [19.4, -6.4],
42  [-6.0, 5.0],
43  ]
44 
45  # Set our demo's initial pose
46  initial_pose = PoseStamped()
47  initial_pose.header.frame_id = 'map'
48  initial_pose.header.stamp = navigator.get_clock().now().to_msg()
49  initial_pose.pose.position.x = 0.0
50  initial_pose.pose.position.y = 0.0
51  initial_pose.pose.orientation.z = 0.0
52  initial_pose.pose.orientation.w = 1.0
53  navigator.setInitialPose(initial_pose)
54 
55  # Wait for navigation to fully activate
56  navigator.waitUntilNav2Active()
57 
58  # Do security route until dead
59  while rclpy.ok():
60  # Send our route
61  route_poses = []
62  pose = PoseStamped()
63  pose.header.frame_id = 'map'
64  pose.header.stamp = navigator.get_clock().now().to_msg()
65  pose.pose.orientation.w = 1.0
66  for pt in security_route:
67  pose.pose.position.x = pt[0]
68  pose.pose.position.y = pt[1]
69  route_poses.append(deepcopy(pose))
70  go_through_poses_task = navigator.goThroughPoses(route_poses)
71 
72  # Do something during our route (e.x. AI detection on camera images for anomalies)
73  # Simply print ETA for the demonstration
74  i = 0
75  while not navigator.isTaskComplete(task=go_through_poses_task):
76  i += 1
77  feedback = navigator.getFeedback(task=go_through_poses_task)
78  if feedback and i % 5 == 0:
79  print(
80  'Estimated time to complete current route: '
81  + '{:.0f}'.format(
82  Duration.from_msg(feedback.estimated_time_remaining).nanoseconds
83  / 1e9
84  )
85  + ' seconds.'
86  )
87 
88  # Some failure mode, must stop since the robot is clearly stuck
89  if Duration.from_msg(feedback.navigation_time) > Duration(
90  seconds=180.0
91  ):
92  print('Navigation has exceeded timeout of 180s, canceling request.')
93  navigator.cancelTask()
94 
95  # If at end of route, reverse the route to restart
96  security_route.reverse()
97 
98  result = navigator.getResult()
99  if result == TaskResult.SUCCEEDED:
100  print('Route complete! Restarting...')
101  elif result == TaskResult.CANCELED:
102  print('Security route was canceled, exiting.')
103  exit(1)
104  elif result == TaskResult.FAILED:
105  (error_code, error_msg) = navigator.getTaskError()
106  print(f'Security route failed!:{error_code}:{error_msg}')
107  print('Restarting from other side...')
108 
109  exit(0)
110 
111 
112 if __name__ == '__main__':
113  main()