Skip to content

Commit 7ce2fa9

Browse files
uavstersjahr
andauthored
[TOTG] Exit loop when position can't change (backport #2307) (#2646)
Co-authored-by: Sebastian Jahr <sebastian.jahr@picknik.ai>
1 parent b4e9c86 commit 7ce2fa9

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

moveit_core/trajectory_processing/src/time_optimal_trajectory_generation.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,12 @@ Trajectory::Trajectory(const Path& path, const Eigen::VectorXd& max_velocity, co
324324
, time_step_(time_step)
325325
, cached_time_(std::numeric_limits<double>::max())
326326
{
327+
if (time_step_ == 0)
328+
{
329+
valid_ = false;
330+
RCLCPP_ERROR(LOGGER, "The trajectory is invalid because the time step is 0.");
331+
return;
332+
}
327333
trajectory_.push_back(TrajectoryStep(0.0, 0.0));
328334
double after_acceleration = getMinMaxPathAcceleration(0.0, 0.0, true);
329335
while (valid_ && !integrateForward(trajectory_, after_acceleration) && valid_)
@@ -565,6 +571,16 @@ bool Trajectory::integrateForward(std::list<TrajectoryStep>& trajectory, double
565571
trajectory.push_back(TrajectoryStep(path_pos, path_vel));
566572
acceleration = getMinMaxPathAcceleration(path_pos, path_vel, true);
567573

574+
if (path_vel == 0 && acceleration == 0)
575+
{
576+
// The position will never change if velocity and acceleration are zero.
577+
// The loop will spin indefinitely as no exit condition is met.
578+
valid_ = false;
579+
RCLCPP_ERROR(LOGGER, "Error while integrating forward: zero acceleration and velocity. Are any relevant "
580+
"acceleration components limited to zero?");
581+
return true;
582+
}
583+
568584
if (path_vel > getAccelerationMaxPathVelocity(path_pos) || path_vel > getVelocityMaxPathVelocity(path_pos))
569585
{
570586
// Find more accurate intersection with max-velocity curve using bisection

moveit_core/trajectory_processing/test/test_time_optimal_trajectory_generation.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,36 @@ TEST(time_optimal_trajectory_generation, testPluginAPI)
496496
ASSERT_EQ(first_trajectory_msg_end, third_trajectory_msg_end);
497497
}
498498

499+
TEST(time_optimal_trajectory_generation, testRelevantZeroMaxAccelerationsInvalidateTrajectory)
500+
{
501+
const Eigen::Vector2d max_velocity(1, 1);
502+
const Path path(std::list<Eigen::VectorXd>{ Eigen::Vector2d(0, 0), Eigen::Vector2d(1, 1) });
503+
504+
EXPECT_FALSE(Trajectory(path, max_velocity, /*max_acceleration=*/Eigen::Vector2d(0, 1)).isValid());
505+
EXPECT_FALSE(Trajectory(path, max_velocity, /*max_acceleration=*/Eigen::Vector2d(1, 0)).isValid());
506+
EXPECT_FALSE(Trajectory(path, max_velocity, /*max_acceleration=*/Eigen::Vector2d(0, 0)).isValid());
507+
}
508+
509+
TEST(time_optimal_trajectory_generation, testIrrelevantZeroMaxAccelerationsDontInvalidateTrajectory)
510+
{
511+
const Eigen::Vector2d max_velocity(1, 1);
512+
513+
EXPECT_TRUE(Trajectory(Path(std::list<Eigen::VectorXd>{ Eigen::Vector2d(0, 0), Eigen::Vector2d(0, 1) }), max_velocity,
514+
/*max_acceleration=*/Eigen::Vector2d(0, 1))
515+
.isValid());
516+
EXPECT_TRUE(Trajectory(Path(std::list<Eigen::VectorXd>{ Eigen::Vector2d(0, 0), Eigen::Vector2d(1, 0) }), max_velocity,
517+
/*max_acceleration=*/Eigen::Vector2d(1, 0))
518+
.isValid());
519+
}
520+
521+
TEST(time_optimal_trajectory_generation, testTimeStepZeroMakesTrajectoryInvalid)
522+
{
523+
EXPECT_FALSE(Trajectory(Path(std::list<Eigen::VectorXd>{ Eigen::Vector2d(0, 0), Eigen::Vector2d(1, 1) }),
524+
/*max_velocity=*/Eigen::Vector2d(1, 1), /*max_acceleration=*/Eigen::Vector2d(1, 1),
525+
/*time_step=*/0)
526+
.isValid());
527+
}
528+
499529
int main(int argc, char** argv)
500530
{
501531
testing::InitGoogleTest(&argc, argv);

0 commit comments

Comments
 (0)