Skip to content

Commit 4287c80

Browse files
XingxinHEnbbrooksEzraBrooks
authored
Fix findWayPointIndicesForDurationAfterStart method when out of bounds (#3626)
* Fix findWayPointIndicesForDurationAfterStart method when out of bounds and add unit tests * Use .at() to index deque; Add 2 more edge test cases * Revise function comments --------- Co-authored-by: Nathan Brooks <[email protected]> Co-authored-by: Ezra Brooks <[email protected]>
1 parent 9fba743 commit 4287c80

File tree

3 files changed

+119
-4
lines changed

3 files changed

+119
-4
lines changed

moveit_core/robot_trajectory/include/moveit/robot_trajectory/robot_trajectory.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,16 @@ class RobotTrajectory
310310
* @param The waypoint index before the supplied duration.
311311
* @param The waypoint index after (or equal to) the supplied duration.
312312
* @param The progress (0 to 1) between the two waypoints, based on time (not based on joint distances).
313+
*
314+
* General Case:
315+
* - Usually after == before + 1, except in the edge cases listed below.
316+
* - blend 0.0 implies being exactly at the before waypoint.
317+
* - blend 1.0 implies being exactly at the after waypoint.
318+
* Edge Cases:
319+
* - Empty Trajectory: before == 0, after == 0, blend == 0.0
320+
* - Negative Duration: before == 0, after == 0, blend == 0.0
321+
* - Duration > Total Duration: before == size() - 1, after == size() - 1, blend == 1.0
322+
* - Single Waypoint Trajectory: before == 0, after == 0, blend == 1.0
313323
*/
314324
void findWayPointIndicesForDurationAfterStart(double duration, int& before, int& after, double& blend) const;
315325

moveit_core/robot_trajectory/src/robot_trajectory.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ RobotTrajectory& RobotTrajectory::setRobotTrajectoryMsg(const moveit::core::Robo
568568
void RobotTrajectory::findWayPointIndicesForDurationAfterStart(double duration, int& before, int& after,
569569
double& blend) const
570570
{
571-
if (duration < 0.0)
571+
if (duration < 0.0 || waypoints_.empty())
572572
{
573573
before = 0;
574574
after = 0;
@@ -581,22 +581,22 @@ void RobotTrajectory::findWayPointIndicesForDurationAfterStart(double duration,
581581
double running_duration = 0.0;
582582
for (; index < num_points; ++index)
583583
{
584-
running_duration += duration_from_previous_[index];
584+
running_duration += duration_from_previous_.at(index);
585585
if (running_duration >= duration)
586586
break;
587587
}
588588
before = std::max<int>(index - 1, 0);
589589
after = std::min<int>(index, num_points - 1);
590590

591591
// Compute duration blend
592-
double before_time = running_duration - duration_from_previous_[index];
593592
if (after == before)
594593
{
595594
blend = 1.0;
596595
}
597596
else
598597
{
599-
blend = (duration - before_time) / duration_from_previous_[index];
598+
double before_time = running_duration - duration_from_previous_.at(index);
599+
blend = (duration - before_time) / duration_from_previous_.at(index);
600600
}
601601
}
602602

moveit_core/robot_trajectory/test/test_robot_trajectory.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,111 @@ TEST_F(RobotTrajectoryTestFixture, RobotTrajectoryDensity)
599599
EXPECT_FALSE(density.has_value());
600600
}
601601

602+
TEST_F(RobotTrajectoryTestFixture, RobotTrajectoryFindWayPointIndicesBetweenWaypoints)
603+
{
604+
robot_trajectory::RobotTrajectoryPtr trajectory;
605+
initTestTrajectory(trajectory);
606+
EXPECT_EQ(trajectory->size(), 5);
607+
EXPECT_EQ(trajectory->getDuration(), 0.5);
608+
609+
int before = -1;
610+
int after = -1;
611+
double blend = -1.0;
612+
613+
EXPECT_NO_THROW(trajectory->findWayPointIndicesForDurationAfterStart(0.15, before, after, blend));
614+
EXPECT_EQ(before, 0);
615+
EXPECT_EQ(after, 1);
616+
EXPECT_NEAR(blend, /*between 0 and 1*/ 0.5, 1e-6);
617+
618+
EXPECT_NO_THROW(trajectory->findWayPointIndicesForDurationAfterStart(0.3, before, after, blend));
619+
EXPECT_EQ(before, 1);
620+
EXPECT_EQ(after, 2);
621+
EXPECT_NEAR(blend, /*exactly at 2*/ 1.0, 1e-6);
622+
}
623+
624+
TEST_F(RobotTrajectoryTestFixture, RobotTrajectoryFindWayPointIndicesAtLastOfManyWaypoints)
625+
{
626+
robot_trajectory::RobotTrajectoryPtr trajectory;
627+
initTestTrajectory(trajectory);
628+
629+
int before = -1;
630+
int after = -1;
631+
double blend = -1.0;
632+
633+
const double total_duration = trajectory->getDuration();
634+
EXPECT_NO_THROW(trajectory->findWayPointIndicesForDurationAfterStart(total_duration, before, after, blend));
635+
EXPECT_EQ(before, 3);
636+
EXPECT_EQ(after, 4);
637+
EXPECT_DOUBLE_EQ(blend, 1.0);
638+
}
639+
640+
TEST_F(RobotTrajectoryTestFixture, RobotTrajectoryFindWayPointIndicesAfterLastWaypoint)
641+
{
642+
robot_trajectory::RobotTrajectoryPtr trajectory;
643+
initTestTrajectory(trajectory);
644+
645+
const double total_duration = trajectory->getDuration();
646+
const double outbound_duration = total_duration + 100.0;
647+
EXPECT_GT(outbound_duration, total_duration);
648+
649+
int before = -1;
650+
int after = -1;
651+
double blend = -1.0;
652+
EXPECT_NO_THROW(trajectory->findWayPointIndicesForDurationAfterStart(outbound_duration, before, after, blend));
653+
EXPECT_EQ(before, 4);
654+
EXPECT_EQ(after, 4);
655+
EXPECT_DOUBLE_EQ(blend, 1.0);
656+
}
657+
658+
TEST_F(RobotTrajectoryTestFixture, RobotTrajectoryFindWayPointIndicesEmptyWaypoints)
659+
{
660+
robot_trajectory::RobotTrajectory empty_traj(robot_model_, arm_jmg_name_);
661+
const double total_duration = empty_traj.getDuration();
662+
EXPECT_DOUBLE_EQ(total_duration, 0.0);
663+
664+
const double outbound_duration = 1.0;
665+
EXPECT_GT(outbound_duration, total_duration);
666+
667+
int before = -1;
668+
int after = -1;
669+
double blend = -1.0;
670+
EXPECT_NO_THROW(empty_traj.findWayPointIndicesForDurationAfterStart(outbound_duration, before, after, blend));
671+
EXPECT_EQ(before, 0);
672+
EXPECT_EQ(after, 0);
673+
EXPECT_DOUBLE_EQ(blend, 0.0);
674+
}
675+
676+
TEST_F(RobotTrajectoryTestFixture, RobotTrajectoryFindWayPointIndicesBeforeFirstWaypoint)
677+
{
678+
robot_trajectory::RobotTrajectoryPtr trajectory;
679+
initTestTrajectory(trajectory);
680+
681+
int before = -1;
682+
int after = -1;
683+
double blend = -1.0;
684+
685+
EXPECT_NO_THROW(trajectory->findWayPointIndicesForDurationAfterStart(-0.1, before, after, blend));
686+
EXPECT_EQ(before, 0);
687+
EXPECT_EQ(after, 0);
688+
EXPECT_DOUBLE_EQ(blend, 0.0);
689+
}
690+
691+
TEST_F(RobotTrajectoryTestFixture, RobotTrajectoryFindWayPointIndicesAtLastOfSingleWaypoint)
692+
{
693+
robot_trajectory::RobotTrajectory trajectory(robot_model_, arm_jmg_name_);
694+
trajectory.addSuffixWayPoint(robot_state_, 0.0);
695+
696+
int before = -1;
697+
int after = -1;
698+
double blend = -1.0;
699+
700+
const double total_duration = trajectory.getDuration();
701+
EXPECT_NO_THROW(trajectory.findWayPointIndicesForDurationAfterStart(total_duration, before, after, blend));
702+
EXPECT_EQ(before, 0);
703+
EXPECT_EQ(after, 0);
704+
EXPECT_DOUBLE_EQ(blend, 1.0);
705+
}
706+
602707
TEST_F(OneRobot, Unwind)
603708
{
604709
const double epsilon = 1e-4;

0 commit comments

Comments
 (0)