Skip to content

Commit a6cf5fc

Browse files
authored
feat(motion_utils): add new resmaple path (autowarefoundation#2015)
* feat(motion_utils): add new resmaple path Signed-off-by: Takayuki Murooka <takayuki5168@gmail.com> * add test Signed-off-by: Takayuki Murooka <takayuki5168@gmail.com> Signed-off-by: Takayuki Murooka <takayuki5168@gmail.com>
1 parent ee4f381 commit a6cf5fc

File tree

3 files changed

+541
-1
lines changed

3 files changed

+541
-1
lines changed

common/motion_utils/include/motion_utils/resample/resample.hpp

+23
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,29 @@ autoware_auto_planning_msgs::msg::Path resamplePath(
126126
const std::vector<double> & resampled_arclength, const bool use_lerp_for_xy = false,
127127
const bool use_lerp_for_z = true, const bool use_zero_order_hold_for_v = true);
128128

129+
/**
130+
* @brief A resampling function for a path. Note that in a default setting, position xy
131+
* are resampled by spline interpolation, position z are resampled by linear interpolation,
132+
* longitudinal and lateral velocity are resampled by zero_order_hold, and heading rate is resampled
133+
* by linear interpolation. Orientation of the resampled path are calculated by a forward difference
134+
* method based on the interpolated position x and y.
135+
* @param input_path input path to resample
136+
* @param resampled_interval resampling interval
137+
* point
138+
* @param use_lerp_for_xy If true, it uses linear interpolation to resample position x and
139+
* y. Otherwise, it uses spline interpolation
140+
* @param use_lerp_for_z If true, it uses linear interpolation to resample position z.
141+
* Otherwise, it uses spline interpolation
142+
* @param use_zero_order_hold_for_v If true, it uses zero_order_hold to resample
143+
* longitudinal and lateral velocity. Otherwise, it uses linear interpolation
144+
* @param resample_input_path_stop_point If true, resample closest stop point in input path
145+
* @return resampled path
146+
*/
147+
autoware_auto_planning_msgs::msg::Path resamplePath(
148+
const autoware_auto_planning_msgs::msg::Path & input_path, const double resample_interval,
149+
const bool use_lerp_for_xy = false, const bool use_lerp_for_z = true,
150+
const bool use_zero_order_hold_for_v = true, const bool resample_input_path_stop_point = true);
151+
129152
/**
130153
* @brief A resampling function for a trajectory. Note that in a default setting, position xy are
131154
* resampled by spline interpolation, position z are resampled by linear interpolation, twist

common/motion_utils/src/resample/resample.cpp

+59
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,65 @@ autoware_auto_planning_msgs::msg::Path resamplePath(
335335
return resampled_path;
336336
}
337337

338+
autoware_auto_planning_msgs::msg::Path resamplePath(
339+
const autoware_auto_planning_msgs::msg::Path & input_path, const double resample_interval,
340+
const bool use_lerp_for_xy, const bool use_lerp_for_z, const bool use_zero_order_hold_for_twist,
341+
const bool resample_input_path_stop_point)
342+
{
343+
// validate arguments
344+
if (!resample_utils::validate_arguments(input_path.points, resample_interval)) {
345+
return input_path;
346+
}
347+
348+
const double input_path_len = motion_utils::calcArcLength(input_path.points);
349+
350+
std::vector<double> resampling_arclength;
351+
for (double s = 0.0; s < input_path_len; s += resample_interval) {
352+
resampling_arclength.push_back(s);
353+
}
354+
if (resampling_arclength.empty()) {
355+
std::cerr << "[motion_utils]: resampling arclength is empty" << std::endl;
356+
return input_path;
357+
}
358+
359+
// Insert terminal point
360+
if (input_path_len - resampling_arclength.back() < motion_utils::overlap_threshold) {
361+
resampling_arclength.back() = input_path_len;
362+
} else {
363+
resampling_arclength.push_back(input_path_len);
364+
}
365+
366+
// Insert stop point
367+
if (resample_input_path_stop_point) {
368+
const auto distance_to_stop_point =
369+
motion_utils::calcDistanceToForwardStopPoint(input_path.points, 0);
370+
if (distance_to_stop_point && !resampling_arclength.empty()) {
371+
for (size_t i = 1; i < resampling_arclength.size(); ++i) {
372+
if (
373+
resampling_arclength.at(i - 1) <= *distance_to_stop_point &&
374+
*distance_to_stop_point < resampling_arclength.at(i)) {
375+
const double dist_to_prev_point =
376+
std::fabs(*distance_to_stop_point - resampling_arclength.at(i - 1));
377+
const double dist_to_following_point =
378+
std::fabs(resampling_arclength.at(i) - *distance_to_stop_point);
379+
if (dist_to_prev_point < motion_utils::overlap_threshold) {
380+
resampling_arclength.at(i - 1) = *distance_to_stop_point;
381+
} else if (dist_to_following_point < motion_utils::overlap_threshold) {
382+
resampling_arclength.at(i) = *distance_to_stop_point;
383+
} else {
384+
resampling_arclength.insert(resampling_arclength.begin() + i, *distance_to_stop_point);
385+
}
386+
break;
387+
}
388+
}
389+
}
390+
}
391+
392+
return resamplePath(
393+
input_path, resampling_arclength, use_lerp_for_xy, use_lerp_for_z,
394+
use_zero_order_hold_for_twist);
395+
}
396+
338397
autoware_auto_planning_msgs::msg::Trajectory resampleTrajectory(
339398
const autoware_auto_planning_msgs::msg::Trajectory & input_trajectory,
340399
const std::vector<double> & resampled_arclength, const bool use_lerp_for_xy,

0 commit comments

Comments
 (0)