Nav2 Navigation Stack - jazzy  jazzy
ROS 2 Navigation Stack
trajectory.py
1 # Copyright (c) 2021, Matthew Booker
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License. Reserved.
14 
15 from dataclasses import dataclass
16 
17 from helper import angle_difference, normalize_angle
18 
19 import numpy as np
20 
21 
22 @dataclass(frozen=True)
24  """
25  A dataclass that holds the data needed to create the path for a trajectory.
26 
27  turning_radius: The radius of the circle used to generate
28  the arc of the path
29  x_offset: The x coordinate of the circle used to generate
30  the arc of the path
31  y_offset: They y coordinate of the circle used to generate
32  the arc of the path
33  end_point: The end coordinate of the path
34  start_angle: The starting angle of the path
35  - given in radians from -pi to pi where 0 radians is along
36  the positive x axis
37  end_angle: The end angle of the path
38  - given in radians from -pi to pi where 0 radians is along
39  the positive x axis
40  left_turn: Whether the arc in the path turns to the left
41  arc_start_point: Coordinates of the starting position of the arc
42  arc_end_point: Coordinates of the ending position of the arc
43  """
44 
45  turning_radius: float
46  x_offset: float
47  y_offset: float
48  end_point: np.array
49  start_angle: float
50  end_angle: float
51  left_turn: bool
52 
53  arc_start_point: float
54  arc_end_point: float
55 
56  @property
57  def arc_length(self):
58  """Arc length of the trajectory."""
59  return self.turning_radius * angle_difference(
60  self.start_angle, self.end_angle, self.left_turn
61  )
62 
63  @property
65  """Length of the straight line from start to arc."""
66  return np.linalg.norm(self.arc_start_point)
67 
68  @property
70  """Length of the straight line from arc to end."""
71  return np.linalg.norm(self.end_point - self.arc_end_point)
72 
73  @property
74  def total_length(self):
75  """Total length of trajectory."""
76  return self.arc_lengtharc_length + self.start_straight_lengthstart_straight_length + self.end_straight_lengthend_straight_length
77 
78  @staticmethod
79  def no_arc(end_point, start_angle, end_angle):
80  """Create the parameters for a trajectory with no arc."""
81  return TrajectoryParameters(
82  turning_radius=0.0,
83  x_offset=0.0,
84  y_offset=0.0,
85  end_point=end_point,
86  start_angle=start_angle,
87  end_angle=end_angle,
88  left_turn=True,
89  arc_start_point=end_point,
90  arc_end_point=end_point,
91  )
92 
93 
94 @dataclass(frozen=True)
95 class Path:
96  """
97  A dataclass that holds the generated poses for a given trajectory.
98 
99  xs: X coordinates of poses along trajectory
100  ys: Y coordinates of poses along trajectory
101  yaws: Yaws of poses along trajectory
102  """
103 
104  xs: np.array
105  ys: np.array
106  yaws: np.array
107 
108  def __add__(self, rhs):
109  """Add two paths together by concatenating them."""
110  if self.xs is None:
111  return rhs
112 
113  xs = np.concatenate((self.xs, rhs.xs))
114  ys = np.concatenate((self.ys, rhs.ys))
115  yaws = np.concatenate((self.yaws, rhs.yaws))
116 
117  return Path(xs, ys, yaws)
118 
119  def to_output_format(self):
120  """Return the path data in a format suitable for outputting."""
121  output_xs = self.xs.round(5)
122  output_ys = self.ys.round(5)
123 
124  # A bit of a hack but it removes any -0.0
125  output_xs = output_xs + 0.0
126  output_ys = output_ys + 0.0
127  output_yaws = self.yaws + 0.0
128 
129  vectorized_normalize_angle = np.vectorize(normalize_angle)
130  output_yaws = vectorized_normalize_angle(output_yaws)
131 
132  stacked = np.vstack([output_xs, output_ys, output_yaws]).transpose()
133 
134  return stacked.tolist()
135 
136 
137 @dataclass(frozen=True)
139  """
140  A dataclass that holds the path and parameters for a trajectory.
141 
142  path: The Path that represents the trajectory
143  parameters: The TrajectoryParameters that represent the trajectory
144  """
145 
146  path: Path
147  parameters: TrajectoryParameters
def __add__(self, rhs)
Definition: trajectory.py:108
def to_output_format(self)
Definition: trajectory.py:119
def no_arc(end_point, start_angle, end_angle)
Definition: trajectory.py:79