Skip to content

Commit e17e537

Browse files
committed
workshop 9
1 parent fe3f241 commit e17e537

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
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+
import math
17+
import rclpy
18+
from rclpy.node import Node
19+
from rclpy import qos
20+
from geometry_msgs.msg import PoseStamped
21+
from nav2_simple_commander.robot_navigator import BasicNavigator, TaskResult
22+
from tf_transformations import quaternion_from_euler
23+
24+
"""
25+
A simple waypoint navigation demo where the robot visits a sequence of waypoints placed on the map.
26+
"""
27+
28+
# The waypoint route, probably read in from a file for a real application
29+
# from either a map or drive and repeat. x, y and theta (in radians)
30+
waypoint_route = [
31+
[0.0, -1.75, math.pi],
32+
[-4.0, -1.75, math.pi/2],
33+
[-4.0, 0.0, 0.0],
34+
[-2.0, 0.0, -math.pi/2],
35+
[-2.0, -1.75, 0.0],
36+
[0.0, -1.75, math.pi/2],
37+
[0.0, 0.0, 0.0],
38+
]
39+
40+
# the same route but expressed as x, y and angle as partial quarterion (z, w)
41+
waypoint_route_quat = [
42+
[0.0, -1.75, -1.0, 0.0],
43+
[-4.0, -1.75, 0.7, 0.7],
44+
[-4.0, 0.0, 0.0, 1.0],
45+
[-2.0, 0.0, -0.7, 0.7],
46+
[-2.0, -1.75, 0.0, 1.0],
47+
[0.0, -1.75, 0.7, 0.7],
48+
[0.0, 0.0, 0.0, 1.0],
49+
]
50+
51+
def pose_from_xyquat(timestamp, x=0.0, y=0.0, pz=0.0, pw=1.0):
52+
pose = PoseStamped()
53+
pose.header.frame_id = 'map'
54+
pose.header.stamp = timestamp
55+
pose.pose.position.x = x
56+
pose.pose.position.y = y
57+
pose.pose.orientation.z = pz
58+
pose.pose.orientation.w = pw
59+
return pose
60+
61+
def pose_from_xytheta(timestamp, x=0.0, y=0.0, theta=0.0):
62+
# negative theta: turn clockwise
63+
q = quaternion_from_euler(0, 0, theta)
64+
return pose_from_xyquat(timestamp, x, y, q[2], q[3])
65+
66+
67+
def main():
68+
69+
rclpy.init()
70+
71+
# publish the current waypoint location (for visualisation in rviz)
72+
publisher = Node("waypoint_publisher").create_publisher(PoseStamped, "/current_waypoint", qos_profile=qos.qos_profile_parameters)
73+
74+
navigator = BasicNavigator()
75+
76+
# Set the initial pose
77+
initial_pose = pose_from_xyquat(navigator.get_clock().now().to_msg())
78+
79+
navigator.setInitialPose(initial_pose)
80+
81+
# Wait for navigation to fully activate
82+
navigator.waitUntilNav2Active()
83+
84+
# Prepare a set of waypoints
85+
waypoints = []
86+
for wp in waypoint_route:
87+
waypoints.append(pose_from_xytheta(navigator.get_clock().now().to_msg(), *wp))
88+
89+
# # if you would rather specify the orientation as quaternion use the following line instead
90+
# for wp in waypoint_route_quat:
91+
# waypoints.append(pose_from_xyquat(navigator.get_clock().now().to_msg(), *wp))
92+
93+
# follow the specified waypoints
94+
navigator.followWaypoints(waypoints)
95+
96+
# Some feedback on the progress
97+
i = 0
98+
while not navigator.isTaskComplete():
99+
i += 1
100+
feedback = navigator.getFeedback()
101+
# publish currrent waypoint
102+
publisher.publish(waypoints[feedback.current_waypoint])
103+
if feedback and i % 5 == 0:
104+
print(
105+
'Executing current waypoint: '
106+
+ str(feedback.current_waypoint + 1)
107+
+ '/'
108+
+ str(len(waypoints))
109+
)
110+
111+
result = navigator.getResult()
112+
if result == TaskResult.SUCCEEDED:
113+
print('Task complete!')
114+
elif result == TaskResult.CANCELED:
115+
print('Task was canceled.')
116+
elif result == TaskResult.FAILED:
117+
print('Task failed!')
118+
119+
120+
if __name__ == '__main__':
121+
main()

0 commit comments

Comments
 (0)