15 from copy
import deepcopy
16 from scipy.interpolate
import splrep, splev, interp1d
18 from uuv_waypoints
import Waypoint, WaypointSet
19 from visualization_msgs.msg
import MarkerArray
23 from ..trajectory_point
import TrajectoryPoint
24 from .line_segment
import LineSegment
25 from .bezier_curve
import BezierCurve
26 from .path_generator
import PathGenerator
31 Linear interpolator with polynomial blends. 35 Biagiotti, Luigi, and Claudio Melchiorri. Trajectory planning for 36 automatic machines and robots. Springer Science & Business Media, 2008. 41 super(LIPBInterpolator, self).
__init__(self)
52 """Initialize the interpolator. To have the path segments generated, 53 `init_waypoints()` must be called beforehand by providing a set of 54 waypoints as `uuv_waypoints.WaypointSet` type. 58 `True` if the path segments were successfully generated. 60 if self._waypoints
is None:
69 if self._waypoints.num_waypoints == 2:
71 LineSegment(self._waypoints.get_waypoint(0).pos,
72 self._waypoints.get_waypoint(1).pos))
73 self._segment_to_wp_map.append(1)
75 heading = [self._waypoints.get_waypoint(k).heading_offset
for k
in range(self._waypoints.num_waypoints)]
77 elif self._waypoints.num_waypoints > 2:
78 q_seg = self._waypoints.get_waypoint(0).pos
80 heading = [self._waypoints.get_waypoint(0).heading_offset]
81 for i
in range(1, self._waypoints.num_waypoints):
82 first_line = LineSegment(q_start_line, self._waypoints.get_waypoint(i).pos)
83 radius = min(self.
_radius, first_line.get_length() / 2)
84 if i + 1 < self._waypoints.num_waypoints:
85 second_line = LineSegment(self._waypoints.get_waypoint(i).pos,
86 self._waypoints.get_waypoint(i + 1).pos)
87 radius = min(radius, second_line.get_length() / 2)
88 if i < self._waypoints.num_waypoints - 1:
90 (q_seg, first_line.interpolate((first_line.get_length() - radius) / first_line.get_length())))
91 self.
_interp_fcns[
'pos'].append(LineSegment(q_start_line, q_seg[-1, :]))
92 heading.append(self._waypoints.get_waypoint(i).heading_offset)
93 self._segment_to_wp_map.append(i)
94 if i == self._waypoints.num_waypoints - 1:
95 q_seg = np.vstack((q_seg, self._waypoints.get_waypoint(i).pos))
96 self.
_interp_fcns[
'pos'].append(LineSegment(q_seg[-2, :], q_seg[-1, :]))
97 heading.append(self._waypoints.get_waypoint(i).heading_offset)
98 self._segment_to_wp_map.append(i)
99 elif i + 1 < self._waypoints.num_waypoints:
100 q_seg = np.vstack((q_seg, second_line.interpolate(radius / second_line.get_length())))
102 BezierCurve([q_seg[-2, :], self._waypoints.get_waypoint(i).pos, q_seg[-1, :]], 5))
103 heading.append(self._waypoints.get_waypoint(i).heading_offset)
104 self._segment_to_wp_map.append(i)
105 q_start_line = deepcopy(q_seg[-1, :])
110 lengths = [seg.get_length()
for seg
in self.
_interp_fcns[
'pos']]
111 lengths = [0] + lengths
112 self.
_s = np.cumsum(lengths) / np.sum(lengths)
115 [self._waypoints.get_waypoint(k).max_forward_speed
for k
in range(self._waypoints.num_waypoints)])
121 if self._waypoints.num_waypoints == 2:
122 head_offset_line = deepcopy(self._waypoints.get_waypoint(1).heading_offset)
123 self.
_interp_fcns[
'heading'] =
lambda x: head_offset_line
131 """Set interpolator's parameters. All the options 132 for the `params` input can be seen below: 140 * `radius` (*type:* `float`): Radius of the corners modeled 141 as fifth-order Bezier curves. 145 * `params` (*type:* `dict`): `dict` containing interpolator's 146 configurable elements. 148 if 'radius' in params:
149 assert params[
'radius'] > 0,
'Radius must be greater than zero' 150 self.
_radius = params[
'radius']
154 """Sample the full path for position and quaternion vectors. 155 `step` is represented in the path's parametric space. 159 * `step` (*type:* `float`, *default:* `0.001`): Parameter description 163 List of `uuv_trajectory_generator.TrajectoryPoint`. 165 if self._waypoints
is None:
169 s = np.arange(0, 1 + step, step)
173 pnt = TrajectoryPoint()
180 """Generate a position vector for the path sampled point 181 interpolated on the position related to `s`, `s` being 182 represented in the curve's parametric space. 186 * `s` (*type:* `float`): Curve's parametric input expressed in the 191 3D position vector as a `numpy.array`. 195 idx = self.get_segment_idx(s)
200 u_k = (s - self.
_s[idx - 1]) / (self.
_s[idx] - self.
_s[idx - 1])
201 pos = self.
_interp_fcns[
'pos'][idx - 1].interpolate(u_k)
205 """Compute a point that belongs to the path on the 206 interpolated space related to `s`, `s` being represented 207 in the curve's parametric space. 211 * `s` (*type:* `float`): Curve's parametric input expressed in the 213 * `t` (*type:* `float`): Trajectory point's timestamp 217 `uuv_trajectory_generator.TrajectoryPoint` including position 218 and quaternion vectors. 220 pnt = TrajectoryPoint()
230 """Compute the quaternion of the path reference for a interpolated 231 point related to `s`, `s` being represented in the curve's parametric 233 The quaternion is computed assuming the heading follows the direction 234 of the path towards the target. Roll and pitch can also be computed 235 in case the `full_dof` is set to `True`. 239 * `s` (*type:* `float`): Curve's parametric input expressed in the 244 Rotation quaternion as a `numpy.array` as `(x, y, z, w)` 249 last_s = s - self._s_step
255 return self._init_rot
259 dx = this_pos[0] - last_pos[0]
260 dy = this_pos[1] - last_pos[1]
261 dz = this_pos[2] - last_pos[2]
263 rotq = self._compute_rot_quat(dx, dy, dz)
267 q_step = quaternion_about_axis(
271 rotq = quaternion_multiply(rotq, q_step)
def init_interpolator(self)
def set_parameters(self, params)
def generate_pnt(self, s, t=0.0, args)
def generate_quat(self, s)
def get_samples(self, max_time, step=0.001)
def generate_pos(self, s, args)