waypoint.py
Go to the documentation of this file.
1 # Copyright (c) 2016-2019 The UUV Simulator Authors.
2 # All rights reserved.
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 import numpy as np
16 from uuv_control_msgs.msg import Waypoint as WaypointMessage
17 
18 
19 class Waypoint(object):
20  """Waypoint data structure
21 
22  > *Attributes*
23 
24  * `FINAL_WAYPOINT_COLOR` (*type:* list of `float`, *value:* `[1.0, 0.5737, 0.0]`): RGB color for marker of the final waypoint in RViz
25  * `OK_WAYPOINT` (*type:* list of `float`, *value:* `[0.1216, 0.4157, 0.8863]`): RGB color for marker of a successful waypoint in RViz
26  * `FAILED_WAYPOINT` (*type:* list of `float`, *value:* `[1.0, 0.0, 0.0]`): RGB color for marker of a failed waypoint in RViz
27 
28  > *Input arguments*
29 
30  * `x` (*type:* `float`, *default:* `0`): X coordinate in meters
31  * `y` (*type:* `float`, *default:* `0`): Y coordinate in meters
32  * `z` (*type:* `float`, *default:* `0`): Z coordinate in meters
33  * `max_forward_speed` (*type:* `float`, *default:* `0`): Reference maximum forward speed in m/s
34  * `heading_offset` (*type:* `float`, *default:* `0`): Heading offset to be added to the computed heading reference in radians
35  * `use_fixed_heading` (*type:* `float`, *default:* `False`): Use the heading offset as a fixed heading reference in radians
36  * `inertial_frame_id` (*type:* `str`, *default:* `'world'`): Name of the inertial reference frame, options are `world` or `world_ned`
37  * `radius_acceptance` (*type:* `float`, *default:* `0`): Radius around the waypoint where the vehicle can be considered to have reached the waypoint
38 
39  """
40  FINAL_WAYPOINT_COLOR = [1.0, 131.0 / 255, 0.0]
41  OK_WAYPOINT = [31. / 255, 106. / 255, 226. / 255]
42  FAILED_WAYPOINT = [1.0, 0.0, 0.0]
43 
44  def __init__(self, x=0, y=0, z=0, max_forward_speed=0, heading_offset=0,
45  use_fixed_heading=False, inertial_frame_id='world', radius_acceptance=0.0):
46  assert inertial_frame_id in ['world', 'world_ned'], \
47  'Invalid inertial reference frame, options' \
48  ' are world or world_ned, provided={}'.format(inertial_frame_id)
49  self._x = x
50  self._y = y
51  self._z = z
52  self._inertial_frame_id = inertial_frame_id
53  self._max_forward_speed = max_forward_speed
54  self._heading_offset = heading_offset
55  self._violates_constraint = False
56  self._use_fixed_heading = use_fixed_heading
57  self._radius_acceptance = radius_acceptance
58 
59  def __eq__(self, other):
60  return self._x == other.x and self._y == other.y and self._z == other.z
61 
62  def __ne__(self, other):
63  return self._x != other.x or self._y != other.y or self._z != other.z
64 
65  def __str__(self):
66  msg = '(x, y, z)= (%.2f, %.2f, %.2f) m\n' % (self._x, self._y, self._z)
67  msg += 'Max. forward speed = %.2f\n' % self._max_forward_speed
68  if self._use_fixed_heading:
69  msg += 'Heading offset = %.2f degrees\n' % (self._heading_offset * 180 / np.pi)
70  return msg
71 
72  @property
73  def inertial_frame_id(self):
74  """`str`: Name of the inertial reference frame"""
75  return self._inertial_frame_id
76 
77  @inertial_frame_id.setter
78  def inertial_frame_id(self, frame_id):
79  assert frame_id in ['world', 'world_ned']
80  self._inertial_frame_id = frame_id
81 
82  @property
83  def x(self):
84  """`float`: X coordinate of the waypoint in meters"""
85  return self._x
86 
87  @property
88  def y(self):
89  """`float`: Y coordinate of the waypoint in meters"""
90  return self._y
91 
92  @property
93  def z(self):
94  """`float`: Z coordinate of the waypoint in meters"""
95  return self._z
96 
97  @property
98  def pos(self):
99  """`numpy.ndarray`: Position 3D vector"""
100  return np.array([self._x, self._y, self._z])
101 
102  @pos.setter
103  def pos(self, new_pos):
104  if isinstance(new_pos, list):
105  assert len(new_pos) == 3, 'New position must have three elements'
106  elif isinstance(new_pos, np.ndarray):
107  assert new_pos.shape == (3,), 'New position must have three elements'
108  else:
109  raise Exception('Invalid position vector size')
110  self._x = new_pos[0]
111  self._y = new_pos[1]
112  self._z = new_pos[2]
113 
114  @property
116  """`bool`: Flag on constraint violation for this waypoint"""
117  return self._violates_constraint
118 
119  @violates_constraint.setter
120  def violates_constraint(self, flag):
121  self._violates_constraint = flag
122 
123  @property
124  def max_forward_speed(self):
125  """`float`: Maximum reference forward speed"""
126  return self._max_forward_speed
127 
128  @max_forward_speed.setter
129  def max_forward_speed(self, vel):
130  self._max_forward_speed = vel
131 
132  @property
133  def heading_offset(self):
134  """`float`: Heading offset in radians"""
135  return self._heading_offset
136 
137  @property
138  def heading(self):
139  """`float`: Heading reference stored for this waypoint in radians"""
140  return self._heading
141 
142  @heading.setter
143  def heading(self, angle):
144  self._heading = angle
145 
146  @property
148  """`float`: Radius of acceptance in meters"""
149  return self._radius_acceptance
150 
151  @radius_of_acceptance.setter
152  def radius_of_acceptance(self, radius):
153  assert radius >= 0, 'Radius must be greater or equal to zero'
154  self._radius_acceptance = radius
155 
156  @property
158  """`float`: Flag to use the heading offset"""
159  return self._use_fixed_heading
160 
161  def get_color(self):
162  """Return the waypoint marker's color
163 
164  > *Returns*
165 
166  RGB color as a `list`
167  """
168  return (self.FAILED_WAYPOINT if self._violates_constraint else self.OK_WAYPOINT)
169 
170  def get_final_color(self):
171  """Return the RGB color for the final waypoint
172 
173  > *Returns*
174 
175  RGB color as a `list`
176  """
177  return self.FINAL_WAYPOINT_COLOR
178 
179  def from_message(self, msg):
180  """Set waypoint parameters from `uuv_control_msgs/Waypoint`
181  message
182 
183  > *Input arguments*
184 
185  * `msg` (*type:* `uuv_control_msgs/Waypoint`): Waypoint message
186  """
187  self._inertial_frame_id = msg.header.frame_id
188  if len(self._inertial_frame_id) == 0:
189  self._inertial_frame_id = 'world'
190  self._x = msg.point.x
191  self._y = msg.point.y
192  self._z = msg.point.z
193  self._max_forward_speed = msg.max_forward_speed
194  self._use_fixed_heading = msg.use_fixed_heading
195  self._heading_offset = msg.heading_offset
196  self._radius_acceptance = msg.radius_of_acceptance
197 
198  def to_message(self):
199  """Convert waypoint to `uuv_control_msgs/Waypoint` message
200 
201  > *Returns*
202 
203  `uuv_control_msgs/Waypoint` message
204  """
205  wp = WaypointMessage()
206  wp.point.x = self._x
207  wp.point.y = self._y
208  wp.point.z = self._z
209  wp.max_forward_speed = self._max_forward_speed
210  wp.use_fixed_heading = self._use_fixed_heading
211  wp.heading_offset = self._heading_offset
212  wp.header.frame_id = self._inertial_frame_id
213  wp.radius_of_acceptance = self._radius_acceptance
214  return wp
215 
216  def dist(self, pos):
217  """Compute distance of waypoint to a point
218 
219  > *Input arguments*
220 
221  * `pos` (*type:* list of `float`): 3D position vector
222 
223  > *Returns*
224 
225  Distance to point in meters
226  """
227  return np.sqrt((self._x - pos[0])**2 +
228  (self._y - pos[1])**2 +
229  (self._z - pos[2])**2)
230 
231  def calculate_heading(self, target):
232  """Compute heading to target waypoint
233 
234  > *Input arguments*
235 
236  * `target` (*type:* `uuv_waypoints/Waypoint`): Target waypoint
237 
238  > *Returns*
239 
240  Heading angle in radians
241  """
242  dy = target.y - self.y
243  dx = target.x - self.x
244  return np.arctan2(dy, dx)
def __ne__(self, other)
Definition: waypoint.py:62
def calculate_heading(self, target)
Definition: waypoint.py:231
def __init__(self, x=0, y=0, z=0, max_forward_speed=0, heading_offset=0, use_fixed_heading=False, inertial_frame_id='world', radius_acceptance=0.0)
Definition: waypoint.py:45
def __eq__(self, other)
Definition: waypoint.py:59


uuv_trajectory_control
Author(s):
autogenerated on Thu Jun 18 2020 03:28:42