Skip to content

Commit

Permalink
feat(motion_utils): add new calcSignedArcLength (autowarefoundation#1701
Browse files Browse the repository at this point in the history
)

Signed-off-by: Takayuki Murooka <[email protected]>

Signed-off-by: Takayuki Murooka <[email protected]>
  • Loading branch information
takayuki5168 authored and boyali committed Sep 28, 2022
1 parent 94952fc commit 383618a
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 0 deletions.
28 changes: 28 additions & 0 deletions common/motion_utils/include/motion_utils/trajectory/trajectory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,34 @@ double calcSignedArcLength(
return signed_length_on_traj - signed_length_src_offset + signed_length_dst_offset;
}

template <class T>
double calcSignedArcLength(
const T & points, const geometry_msgs::msg::Point & src_point, const size_t src_seg_idx,
const size_t dst_idx)
{
validateNonEmpty(points);

const double signed_length_on_traj = calcSignedArcLength(points, src_seg_idx, dst_idx);
const double signed_length_src_offset =
calcLongitudinalOffsetToSegment(points, src_seg_idx, src_point);

return signed_length_on_traj - signed_length_src_offset;
}

template <class T>
double calcSignedArcLength(
const T & points, const size_t src_idx, const geometry_msgs::msg::Point & dst_point,
const size_t dst_seg_idx)
{
validateNonEmpty(points);

const double signed_length_on_traj = calcSignedArcLength(points, src_idx, dst_seg_idx);
const double signed_length_dst_offset =
calcLongitudinalOffsetToSegment(points, dst_seg_idx, dst_point);

return signed_length_on_traj + signed_length_dst_offset;
}

template <class T>
size_t findFirstNearestIndexWithSoftConstraints(
const T & points, const geometry_msgs::msg::Pose & pose,
Expand Down
149 changes: 149 additions & 0 deletions common/motion_utils/test/src/trajectory/test_trajectory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4185,3 +4185,152 @@ TEST(trajectory, findFirstNearestIndexWithSoftConstraints)
}
}
}

TEST(trajectory, calcSignedArcLengthFromPointAndSegmentIndexToPointAndSegmentIndex)
{
using motion_utils::calcSignedArcLength;

const auto traj = generateTestTrajectory<Trajectory>(10, 1.0);

// Empty
EXPECT_DOUBLE_EQ(calcSignedArcLength(Trajectory{}.points, {}, {}), 0.0);

// Same point
{
const auto p = createPoint(3.0, 0.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p, 2, p, 2), 0, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, p, 3, p, 3), 0, epsilon);
}

// Forward
{
const auto p1 = createPoint(0.0, 0.0, 0.0);
const auto p2 = createPoint(3.0, 1.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, p2, 2), 3, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, p2, 3), 3, epsilon);
}

// Backward
{
const auto p1 = createPoint(9.0, 0.0, 0.0);
const auto p2 = createPoint(8.0, 0.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 8, p2, 7), -1, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 8, p2, 8), -1, epsilon);
}

// Point before start point
{
const auto p1 = createPoint(-3.9, 3.0, 0.0);
const auto p2 = createPoint(6.0, -10.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, p2, 5), 9.9, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, p2, 6), 9.9, epsilon);
}

// Point after end point
{
const auto p1 = createPoint(7.0, -5.0, 0.0);
const auto p2 = createPoint(13.3, -10.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 6, p2, 8), 6.3, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 7, p2, 8), 6.3, epsilon);
}

// Point before start point and after end point
{
const auto p1 = createPoint(-4.3, 10.0, 0.0);
const auto p2 = createPoint(13.8, -1.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, p2, 8), 18.1, epsilon);
}

// Random cases
{
const auto p1 = createPoint(1.0, 3.0, 0.0);
const auto p2 = createPoint(9.0, -1.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, p2, 8), 8, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 1, p2, 8), 8, epsilon);
}
{
const auto p1 = createPoint(4.3, 7.0, 0.0);
const auto p2 = createPoint(2.0, 3.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 4, p2, 2), -2.3, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 4, p2, 1), -2.3, epsilon);
}
}

TEST(trajectory, calcSignedArcLengthFromPointAndSegmentIndexToPointIndex)
{
using motion_utils::calcSignedArcLength;

const auto traj = generateTestTrajectory<Trajectory>(10, 1.0);

// Empty
EXPECT_DOUBLE_EQ(calcSignedArcLength(Trajectory{}.points, {}, {}), 0.0);

// Same point
{
const auto p = createPoint(3.0, 0.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p, 2, 3), 0, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 3, p, 3), 0, epsilon);
}

// Forward
{
const auto p1 = createPoint(0.0, 0.0, 0.0);
const auto p2 = createPoint(3.0, 1.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, 3), 3, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 0, p2, 2), 3, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 0, p2, 3), 3, epsilon);
}

// Backward
{
const auto p1 = createPoint(9.0, 0.0, 0.0);
const auto p2 = createPoint(8.0, 0.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 8, 8), -1, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 8, p2, 7), 0, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 8, p2, 8), 0, epsilon);
}

// Point before start point
{
const auto p1 = createPoint(-3.9, 3.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, 6), 9.9, epsilon);
}

// Point after end point
{
const auto p2 = createPoint(13.3, -10.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, 7, p2, 8), 6.3, epsilon);
}

// Start point
{
const auto p1 = createPoint(0.0, 3.0, 0.0);
const auto p2 = createPoint(5.3, -10.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, 5), 5, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 0, p2, 5), 5.3, epsilon);
}

// Point after end point
{
const auto p1 = createPoint(7.3, -5.0, 0.0);
const auto p2 = createPoint(9.0, -10.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 7, 9), 1.7, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 7, p2, 8), 2.0, epsilon);
}

// Random cases
{
const auto p1 = createPoint(1.0, 3.0, 0.0);
const auto p2 = createPoint(9.0, -1.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 0, 9), 8, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 1, 9), 8, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 1, p2, 8), 8, epsilon);
}
{
const auto p1 = createPoint(4.3, 7.0, 0.0);
const auto p2 = createPoint(2.3, 3.0, 0.0);
EXPECT_NEAR(calcSignedArcLength(traj.points, p1, 4, 2), -2.3, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 4, p2, 2), -1.7, epsilon);
EXPECT_NEAR(calcSignedArcLength(traj.points, 4, p2, 1), -1.7, epsilon);
}
}

0 comments on commit 383618a

Please sign in to comment.