Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
demo_inspection.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 
22 """
23 Basic stock inspection demo. In this demonstration, the expectation
24 is that there are cameras or RFID sensors mounted on the robots
25 collecting information about stock quantity and location.
26 """
27 
28 
29 def main() -> None:
30  rclpy.init()
31 
32  navigator = BasicNavigator()
33 
34  # Inspection route, probably read in from a file for a real application
35  # from either a map or drive and repeat. (x, y, yaw)
36  inspection_route = [
37  [8.21, 1.3, 1.57],
38  [8.7, 4.0, 1.57],
39  [11.6, 4.0, -1.57],
40  [11.6, 1.3, -1.57],
41  [12.6, 1.3, 1.57],
42  [12.6, 4.0, -1.57],
43  [15.27, 1.3, -1.57],
44  [16.4, 1.3, 1.57],
45  [19.0, 1.3, 1.57],
46  [19.0, 4.0, 1.57],
47  ]
48 
49  # Set our demo's initial pose
50  initial_pose = PoseStamped()
51  initial_pose.header.frame_id = 'map'
52  initial_pose.header.stamp = navigator.get_clock().now().to_msg()
53  initial_pose.pose.position.x = 0.0
54  initial_pose.pose.position.y = 0.0
55  initial_pose.pose.orientation.z = 0.0
56  initial_pose.pose.orientation.w = 1.0
57  navigator.setInitialPose(initial_pose)
58 
59  # Wait for navigation to fully activate
60  navigator.waitUntilNav2Active()
61 
62  # Send our route
63  inspection_points = []
64  inspection_pose = PoseStamped()
65  inspection_pose.header.frame_id = 'map'
66  inspection_pose.header.stamp = navigator.get_clock().now().to_msg()
67  for pt in inspection_route:
68  inspection_pose.pose.position.x = pt[0]
69  inspection_pose.pose.position.y = pt[1]
70  # Simplification of angle handling for demonstration purposes
71  if pt[2] > 0:
72  inspection_pose.pose.orientation.z = 0.707
73  inspection_pose.pose.orientation.w = 0.707
74  else:
75  inspection_pose.pose.orientation.z = -0.707
76  inspection_pose.pose.orientation.w = 0.707
77  inspection_points.append(deepcopy(inspection_pose))
78 
79  wpf_task = navigator.followWaypoints(inspection_points)
80 
81  # Do something during our route (e.x. AI to analyze stock information or upload to the cloud)
82  # Simply the current waypoint ID for the demonstration
83  i = 0
84  while not navigator.isTaskComplete(task=wpf_task):
85  i += 1
86  feedback = navigator.getFeedback(task=wpf_task)
87  if feedback and i % 5 == 0:
88  print(
89  'Executing current waypoint: '
90  + str(feedback.current_waypoint + 1)
91  + '/'
92  + str(len(inspection_points))
93  )
94 
95  result = navigator.getResult()
96  if result == TaskResult.SUCCEEDED:
97  print('Inspection of shelves complete! Returning to start...')
98  elif result == TaskResult.CANCELED:
99  print('Inspection of shelving was canceled. Returning to start...')
100  elif result == TaskResult.FAILED:
101  (error_code, error_msg) = navigator.getTaskError()
102  print(f'Inspection of shelving failed!:{error_code}:{error_msg}')
103  print('Returning to start...')
104 
105  # go back to start
106  initial_pose.header.stamp = navigator.get_clock().now().to_msg()
107  go_to_pose_task = navigator.goToPose(initial_pose)
108  while not navigator.isTaskComplete(task=go_to_pose_task):
109  pass
110 
111  exit(0)
112 
113 
114 if __name__ == '__main__':
115  main()