Skip to content

Commit ac27d62

Browse files
authored
feat(trajectory): improve shift function and their documents (#337)
* feat(trajectory): add populate function Signed-off-by: Mamoru Sobue <[email protected]> * update curvature figure for approximation desc Signed-off-by: Mamoru Sobue <[email protected]> * update align_orientation_with_trajectory_direction fig Signed-off-by: Mamoru Sobue <[email protected]> * finished trajectory classes Signed-off-by: Mamoru Sobue <[email protected]> * refactored shift Signed-off-by: Mamoru Sobue <[email protected]> * add comment Signed-off-by: Mamoru Sobue <[email protected]> * update error message Signed-off-by: Mamoru Sobue <[email protected]> --------- Signed-off-by: Mamoru Sobue <[email protected]>
1 parent ceda7f4 commit ac27d62

File tree

18 files changed

+1198
-375
lines changed

18 files changed

+1198
-375
lines changed

common/autoware_trajectory/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@ ament_auto_add_library(autoware_trajectory SHARED
1212

1313
if(BUILD_TESTING)
1414
find_package(ament_cmake_ros REQUIRED)
15+
find_package(autoware_motion_utils REQUIRED)
16+
include_directories(${autoware_motion_utils_INCLUDE_DIRS})
1517

1618
file(GLOB_RECURSE test_files test/*.cpp)
1719

1820
ament_add_ros_isolated_gtest(test_autoware_trajectory ${test_files})
1921

2022
target_link_libraries(test_autoware_trajectory
2123
autoware_trajectory
24+
${autoware_motion_utils_LIBRARIES}
2225
)
2326

2427
# Examples
@@ -27,20 +30,27 @@ if(BUILD_TESTING)
2730
add_definitions("-Wno-attributes")
2831
find_package(ament_lint_auto REQUIRED)
2932
find_package(autoware_pyplot REQUIRED)
33+
find_package(autoware_utils_geometry REQUIRED)
3034
find_package(range-v3 REQUIRED)
35+
find_package(autoware_test_utils REQUIRED)
3136
ament_lint_auto_find_test_dependencies()
3237
find_package(pybind11 REQUIRED)
3338
include_directories(${autoware_pyplot_INCLUDE_DIRS})
39+
include_directories(${autoware_test_utils_INCLUDE_DIRS})
40+
include_directories(${autoware_utils_geometry_INCLUDE_DIRS})
3441
foreach(example_file ${example_files})
3542
get_filename_component(example_name ${example_file} NAME_WE)
3643
ament_auto_add_executable(${example_name}
3744
${example_file}
3845
)
3946
target_link_libraries(${example_name}
4047
autoware_trajectory
48+
${autoware_utils_geometry_LIBRARIES}
49+
${autoware_motion_utils_LIBRARIES}
4150
${autoware_pyplot_LIBRARIES}
4251
range-v3::range-v3
4352
pybind11::embed
53+
${autoware_test_utils_LIBRARIES}
4454
)
4555
endforeach()
4656
endif()

common/autoware_trajectory/README.md

Lines changed: 130 additions & 27 deletions
Large diffs are not rendered by default.

common/autoware_trajectory/examples/example_pose.cpp

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
// limitations under the License.
1414

1515
#include "autoware/trajectory/pose.hpp"
16+
#include "autoware_utils_geometry/geometry.hpp"
1617

1718
#include <autoware/pyplot/pyplot.hpp>
19+
#include <range/v3/all.hpp>
1820
#include <tf2/LinearMath/Quaternion.hpp>
1921
#include <tf2/LinearMath/Vector3.hpp>
2022

@@ -23,6 +25,8 @@
2325
#include <pybind11/embed.h>
2426
#include <pybind11/stl.h>
2527

28+
#include <algorithm>
29+
#include <string>
2630
#include <vector>
2731

2832
geometry_msgs::msg::Pose pose(double x, double y)
@@ -34,11 +38,37 @@ geometry_msgs::msg::Pose pose(double x, double y)
3438
return p;
3539
}
3640

41+
using autoware::trajectory::Trajectory;
42+
using ranges::to;
43+
using ranges::views::transform;
44+
45+
void plot_trajectory_base_with_orientation(
46+
const Trajectory<geometry_msgs::msg::Pose> & trajectory, const std::string & label,
47+
autoware::pyplot::Axes & ax)
48+
{
49+
const auto s = trajectory.get_underlying_bases();
50+
const auto c = trajectory.compute(s);
51+
const auto x =
52+
c | transform([](const auto & point) { return point.position.x; }) | to<std::vector>();
53+
const auto y =
54+
c | transform([](const auto & point) { return point.position.y; }) | to<std::vector>();
55+
const auto th =
56+
c | transform([](const auto & quat) { return autoware_utils_geometry::get_rpy(quat).z; }) |
57+
to<std::vector>();
58+
const auto cos_th = th | transform([](const auto v) { return std::cos(v); }) | to<std::vector>();
59+
const auto sin_th = th | transform([](const auto v) { return std::sin(v); }) | to<std::vector>();
60+
ax.scatter(Args(x, y), Kwargs("color"_a = "red", "marker"_a = "o", "label"_a = "underlying"));
61+
ax.quiver(Args(x, y, cos_th, sin_th), Kwargs("color"_a = "green", "label"_a = label));
62+
}
63+
3764
int main()
3865
{
3966
pybind11::scoped_interpreter guard{};
4067

4168
auto plt = autoware::pyplot::import();
69+
auto [fig, axes] = plt.subplots(1, 2);
70+
auto & ax1 = axes[0];
71+
auto & ax2 = axes[1];
4272

4373
std::vector<geometry_msgs::msg::Pose> poses = {
4474
pose(0.49, 0.59), pose(0.61, 1.22), pose(0.86, 1.93), pose(1.20, 2.56), pose(1.51, 3.17),
@@ -47,11 +77,12 @@ int main()
4777
pose(6.88, 3.54), pose(7.51, 4.25), pose(7.85, 4.93), pose(8.03, 5.73), pose(8.16, 6.52),
4878
pose(8.31, 7.28), pose(8.45, 7.93), pose(8.68, 8.45), pose(8.96, 8.96), pose(9.32, 9.36)};
4979

50-
using autoware::trajectory::Trajectory;
51-
5280
auto trajectory = Trajectory<geometry_msgs::msg::Pose>::Builder{}.build(poses);
5381

82+
plot_trajectory_base_with_orientation(*trajectory, "before", ax1);
5483
trajectory->align_orientation_with_trajectory_direction();
84+
plot_trajectory_base_with_orientation(
85+
*trajectory, "after align_orientation_with_trajectory_direction()", ax2);
5586

5687
{
5788
std::vector<double> x;
@@ -63,34 +94,15 @@ int main()
6394
y.push_back(p.position.y);
6495
}
6596

66-
plt.plot(Args(x, y), Kwargs("label"_a = "Trajectory", "color"_a = "blue"));
97+
ax1.plot(Args(x, y), Kwargs("label"_a = "Trajectory", "color"_a = "blue"));
98+
ax2.plot(Args(x, y), Kwargs("label"_a = "Trajectory", "color"_a = "blue"));
6799
}
68100

69-
{
70-
std::vector<double> x;
71-
std::vector<double> y;
72-
std::vector<double> dx;
73-
std::vector<double> dy;
74-
75-
for (double i = 0.0; i <= trajectory->length(); i += 1.0) {
76-
auto p = trajectory->compute(i);
77-
x.push_back(p.position.x);
78-
y.push_back(p.position.y);
79-
80-
tf2::Vector3 x_axis(1.0, 0.0, 0.0);
81-
tf2::Quaternion q(p.orientation.x, p.orientation.y, p.orientation.z, p.orientation.w);
82-
tf2::Vector3 direction = tf2::quatRotate(q, x_axis);
83-
dx.push_back(direction.x());
84-
dy.push_back(direction.y());
85-
// double azimuth = trajectory->azimuth(i);
86-
// dx.push_back(std::cos(azimuth));
87-
// dy.push_back(std::sin(azimuth));
88-
}
89-
plt.quiver(Args(x, y, dx, dy), Kwargs("label"_a = "Direction", "color"_a = "green"));
101+
fig.tight_layout();
102+
for (auto & ax : axes) {
103+
ax.set_aspect(Args("equal"));
104+
ax.grid();
105+
ax.legend();
90106
}
91-
92-
plt.axis(Args("equal"));
93-
plt.grid();
94-
plt.legend();
95107
plt.show();
96108
}

common/autoware_trajectory/examples/example_readme.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,21 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include "autoware/motion_utils/resample/resample.hpp"
16+
#include "autoware/motion_utils/trajectory/trajectory.hpp"
1517
#include "autoware/trajectory/interpolator/akima_spline.hpp"
1618
#include "autoware/trajectory/interpolator/cubic_spline.hpp"
1719
#include "autoware/trajectory/interpolator/linear.hpp"
1820
#include "autoware/trajectory/interpolator/stairstep.hpp"
1921
#include "autoware/trajectory/pose.hpp"
22+
#include "autoware_utils_geometry/geometry.hpp"
2023

2124
#include <autoware/pyplot/pyplot.hpp>
2225
#include <range/v3/all.hpp>
2326
#include <tf2/LinearMath/Quaternion.hpp>
2427
#include <tf2/LinearMath/Vector3.hpp>
2528

29+
#include <autoware_internal_planning_msgs/msg/path_point_with_lane_id.hpp>
2630
#include <autoware_planning_msgs/msg/path_point.hpp>
2731
#include <geometry_msgs/msg/point.hpp>
2832

@@ -509,7 +513,7 @@ int main_curvature()
509513

510514
ax1.plot(Args(s, cubic.curvature(s)), Kwargs("color"_a = "navy", "label"_a = "curvature"));
511515
ax.quiver(
512-
Args(points_x, points_y, cos_yaw, sin_yaw), Kwargs("color"_a = "green", "label"_a = "yaw"));
516+
Args(points_x, points_y, cos_yaw, sin_yaw), Kwargs("color"_a = "green", "label"_a = "azimuth"));
513517

514518
fig.tight_layout();
515519
for (auto & a : axes) {
@@ -525,7 +529,9 @@ int main_trajectory_overview()
525529
{
526530
using autoware::trajectory::Trajectory;
527531
using ranges::to;
532+
using ranges::views::drop;
528533
using ranges::views::stride;
534+
using ranges::views::take;
529535
using ranges::views::transform;
530536

531537
auto plt = autoware::pyplot::import();
@@ -551,7 +557,7 @@ int main_trajectory_overview()
551557
return 0;
552558
}
553559
auto & trajectory = result.value();
554-
const auto s = trajectory.base_arange(0.05); // like numpy.arange
560+
const auto s = trajectory.base_arange(0.05); // cppcheck-suppress shadowVariable
555561
const auto C = trajectory.compute(s);
556562
const auto Cx = C | transform([&](const auto & p) { return p.x; }) | to<std::vector>();
557563
const auto Cy = C | transform([&](const auto & p) { return p.y; }) | to<std::vector>();
@@ -569,6 +575,28 @@ int main_trajectory_overview()
569575

570576
ax1.plot(Args(s, trajectory.curvature(s)), Kwargs("color"_a = "purple", "label"_a = "curvature"));
571577

578+
// compare curvature with discrete version
579+
autoware_internal_planning_msgs::msg::PathWithLaneId discrete_path;
580+
for (unsigned i = 0; i < underlying_points.size(); ++i) {
581+
const auto & point = underlying_points.at(i);
582+
const auto s = trajectory.get_underlying_bases().at(i); // cppcheck-suppress shadowVariable
583+
autoware_internal_planning_msgs::msg::PathPointWithLaneId point_with_lane_id;
584+
point_with_lane_id.point.pose.position = point;
585+
point_with_lane_id.point.pose.orientation =
586+
autoware_utils_geometry::create_quaternion_from_yaw(trajectory.azimuth(s));
587+
discrete_path.points.push_back(point_with_lane_id);
588+
}
589+
const auto discrete_interpolated_path =
590+
autoware::motion_utils::resamplePath(discrete_path, s /* arc lengths for this interpolation */);
591+
const auto discrete_curvature =
592+
autoware::motion_utils::calcCurvature(discrete_interpolated_path.points);
593+
const auto discrete_curvature_bases = s | drop(1) | take(s.size() - 2) | to<std::vector>();
594+
ax1.plot(
595+
Args(s, discrete_curvature),
596+
Kwargs(
597+
"color"_a = "blue",
598+
"label"_a = "discrete approximation using menger curvature")); // # cspell: ignore menger
599+
572600
const auto points_x = underlying_points |
573601
ranges::views::transform([&](const auto & p) { return p.x; }) |
574602
ranges::to<std::vector>();

0 commit comments

Comments
 (0)