square.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # coding: UTF-8
3 # The MIT License (MIT)
4 #
5 # Copyright (c) 2018 Bluewhale Robot
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be included in all
15 # copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 # SOFTWARE.
24 
25 from math import pi, radians
26 
27 import actionlib
28 import roslib
29 import rospy
30 from actionlib_msgs.msg import GoalStatus
31 from geometry_msgs.msg import Point, Pose, Quaternion, Twist
32 from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal
33 from tf.transformations import quaternion_from_euler
34 from visualization_msgs.msg import Marker
35 
36 
38 
39  def __init__(self):
40  rospy.init_node('xiaoqiang_navigation', anonymous=False)
41 
42  rospy.on_shutdown(self.shutdown)
43 
44  # How big is the square we want the robot to navigate?
45  # 设定正方形的尺寸,默认是一米
46  square_size = rospy.get_param("~square_size", 1.0) # meters
47 
48  # Create a list to hold the target quaternions (orientations)
49  # 创建一个列表,保存目标的角度数据
50  quaternions = list()
51 
52  # First define the corner orientations as Euler angles
53  # 定义四个顶角处机器人的方向角度(Euler angles:http://zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89%E8%A7%92)
54  euler_angles = (pi/2, pi, 3*pi/2, 0)
55 
56  # Then convert the angles to quaternions
57  # 将上面的Euler angles转换成Quaternion的格式
58  for angle in euler_angles:
59  q_angle = quaternion_from_euler(0, 0, angle, axes='sxyz')
60  q = Quaternion(*q_angle)
61  quaternions.append(q)
62 
63  # Create a list to hold the waypoint poses
64  # 创建一个列表存储导航点的位置
65  waypoints = list()
66 
67  # Append each of the four waypoints to the list. Each waypoint
68  # is a pose consisting of a position and orientation in the map frame.
69  # 创建四个导航点的位置(角度和坐标位置)
70  waypoints.append(Pose(Point(square_size, 0.0, 0.0), quaternions[0]))
71  waypoints.append(
72  Pose(Point(square_size, square_size, 0.0), quaternions[1]))
73  waypoints.append(Pose(Point(0.0, square_size, 0.0), quaternions[2]))
74  waypoints.append(Pose(Point(0.0, 0.0, 0.0), quaternions[3]))
75 
76  # Initialize the visualization markers for RViz
77  # 初始化可视化标记
78  self.init_markers()
79 
80  # Set a visualization marker at each waypoint
81  # 给每个定点的导航点一个可视化标记(就是rviz中看到的粉色圆盘标记)
82  for waypoint in waypoints:
83  p = Point()
84  p = waypoint.position
85  self.markers.points.append(p)
86 
87  # Publisher to manually control the robot (e.g. to stop it)
88  # 发布TWist消息控制机器人
89  self.cmd_vel_pub = rospy.Publisher('cmd_vel', Twist, queue_size=0)
90 
91  # Subscribe to the move_base action server
92  # 订阅move_base服务器的消息
94  "move_base", MoveBaseAction)
95 
96  rospy.loginfo("Waiting for move_base action server...")
97 
98  # Wait 60 seconds for the action server to become available
99  # 等待move_base服务器建立
100  self.move_base.wait_for_server(rospy.Duration(60))
101 
102  rospy.loginfo("Connected to move base server")
103  rospy.loginfo("Starting navigation test")
104 
105  # Initialize a counter to track waypoints
106  # 初始化一个计数器,记录到达的顶点号
107  i = 0
108 
109  # Cycle through the four waypoints
110  # 主循环,环绕通过四个定点
111  while i < 4 and not rospy.is_shutdown():
112  # Update the marker display
113  # 发布标记指示四个目标的位置,每个周期发布一起,确保标记可见
114  self.marker_pub.publish(self.markers)
115 
116  # Intialize the waypoint goal
117  # 初始化goal为MoveBaseGoal类型
118  goal = MoveBaseGoal()
119 
120  # Use the map frame to define goal poses
121  # 使用map的frame定义goal的frame id
122  goal.target_pose.header.frame_id = 'map'
123 
124  # Set the time stamp to "now"
125  # 设置时间戳
126  goal.target_pose.header.stamp = rospy.Time.now()
127 
128  # Set the goal pose to the i-th waypoint
129  # 设置目标位置是当前第几个导航点
130  goal.target_pose.pose = waypoints[i]
131 
132  # Start the robot moving toward the goal
133  # 机器人移动
134  self.move(goal)
135 
136  i += 1
137 
138  def move(self, goal):
139  # Send the goal pose to the MoveBaseAction server
140  # 把目标位置发送给MoveBaseAction的服务器
141  self.move_base.send_goal(goal)
142 
143  # Allow 1 minute to get there
144  # 设定1分钟的时间限制
145  finished_within_time = self.move_base.wait_for_result(
146  rospy.Duration(60))
147 
148  # If we don't get there in time, abort the goal
149  # 如果一分钟之内没有到达,放弃目标
150  if not finished_within_time:
151  self.move_base.cancel_goal()
152  rospy.loginfo("Timed out achieving goal")
153  else:
154  # We made it!
155  state = self.move_base.get_state()
156  if state == GoalStatus.SUCCEEDED:
157  rospy.loginfo("Goal succeeded!")
158 
159  def init_markers(self):
160  # Set up our waypoint markers
161  # 设置标记的尺寸
162  marker_scale = 0.2
163  marker_lifetime = 0 # 0 is forever
164  marker_ns = 'waypoints'
165  marker_id = 0
166  marker_color = {'r': 1.0, 'g': 0.7, 'b': 1.0, 'a': 1.0}
167 
168  # Define a marker publisher.
169  # 定义一个标记的发布者
170  self.marker_pub = rospy.Publisher(
171  'waypoint_markers', Marker, queue_size=0)
172 
173  # Initialize the marker points list.
174  # 初始化标记点的列表
175  self.markers = Marker()
176  self.markers.ns = marker_ns
177  self.markers.id = marker_id
178  self.markers.type = Marker.CUBE_LIST
179  self.markers.action = Marker.ADD
180  self.markers.lifetime = rospy.Duration(marker_lifetime)
181  self.markers.scale.x = marker_scale
182  self.markers.scale.y = marker_scale
183  self.markers.color.r = marker_color['r']
184  self.markers.color.g = marker_color['g']
185  self.markers.color.b = marker_color['b']
186  self.markers.color.a = marker_color['a']
187 
188  self.markers.header.frame_id = 'map'
189  self.markers.header.stamp = rospy.Time.now()
190  self.markers.points = list()
191 
192  def shutdown(self):
193  rospy.loginfo("Stopping the robot...")
194  # Cancel any active goals
195  self.move_base.cancel_goal()
196  rospy.sleep(2)
197  # Stop the robot
198  self.cmd_vel_pub.publish(Twist())
199  rospy.sleep(1)
200 
201 
202 if __name__ == '__main__':
203  try:
205  except rospy.ROSInterruptException:
206  rospy.loginfo("Navigation test finished.")
def move(self, goal)
Definition: square.py:138
def __init__(self)
Definition: square.py:39
def init_markers(self)
Definition: square.py:159
def shutdown(self)
Definition: square.py:192


xiaoqiang_navigation_example
Author(s):
autogenerated on Mon Jun 10 2019 15:53:36