Nav2 Navigation Stack - humble  humble
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 + \
77  self.end_straight_lengthend_straight_length
78 
79  @staticmethod
80  def no_arc(end_point, start_angle, end_angle):
81  """Create the parameters for a trajectory with no arc."""
82  return TrajectoryParameters(
83  turning_radius=0.0,
84  x_offset=0.0,
85  y_offset=0.0,
86  end_point=end_point,
87  start_angle=start_angle,
88  end_angle=end_angle,
89  left_turn=True,
90  arc_start_point=end_point,
91  arc_end_point=end_point,
92  )
93 
94 
95 @dataclass(frozen=True)
96 class Path:
97  """
98  A dataclass that holds the generated poses for a given trajectory.
99 
100  xs: X coordinates of poses along trajectory
101  ys: Y coordinates of poses along trajectory
102  yaws: Yaws of poses along trajectory
103  """
104 
105  xs: np.array
106  ys: np.array
107  yaws: np.array
108 
109  def __add__(self, rhs):
110  """Add two paths together by concatenating them."""
111  if self.xs is None:
112  return rhs
113 
114  xs = np.concatenate((self.xs, rhs.xs))
115  ys = np.concatenate((self.ys, rhs.ys))
116  yaws = np.concatenate((self.yaws, rhs.yaws))
117 
118  return Path(xs, ys, yaws)
119 
120  def to_output_format(self):
121  """Return the path data in a format suitable for outputting."""
122  output_xs = self.xs.round(5)
123  output_ys = self.ys.round(5)
124 
125  # A bit of a hack but it removes any -0.0
126  output_xs = output_xs + 0.0
127  output_ys = output_ys + 0.0
128  output_yaws = self.yaws + 0.0
129 
130  vectorized_normalize_angle = np.vectorize(normalize_angle)
131  output_yaws = vectorized_normalize_angle(output_yaws)
132 
133  stacked = np.vstack([output_xs, output_ys, output_yaws]).transpose()
134 
135  return stacked.tolist()
136 
137 
138 @dataclass(frozen=True)
140  """
141  A dataclass that holds the path and parameters for a trajectory.
142 
143  path: The Path that represents the trajectory
144  parameters: The TrajectoryParameters that represent the trajectory
145  """
146 
147  path: Path
148  parameters: TrajectoryParameters
def __add__(self, rhs)
Definition: trajectory.py:109
def to_output_format(self)
Definition: trajectory.py:120
def no_arc(end_point, start_angle, end_angle)
Definition: trajectory.py:80