39 #include <gtest/gtest.h> 
   47 TEST(time_optimal_trajectory_generation, test1)
 
   49   Eigen::VectorXd waypoint(4);
 
   52   waypoint << 1424.0, 984.999694824219, 2126.0, 0.0;
 
   54   waypoint << 1423.0, 985.000244140625, 2126.0, 0.0;
 
   57   Eigen::VectorXd max_velocities(4);
 
   58   max_velocities << 1.3, 0.67, 0.67, 0.5;
 
   59   Eigen::VectorXd max_accelerations(4);
 
   60   max_accelerations << 0.00249, 0.00249, 0.00249, 0.00249;
 
   63   EXPECT_TRUE(trajectory.
isValid());
 
   64   EXPECT_DOUBLE_EQ(40.080256821829849, trajectory.
getDuration());
 
   67   EXPECT_DOUBLE_EQ(1424.0, trajectory.
getPosition(0.0)[0]);
 
   68   EXPECT_DOUBLE_EQ(984.999694824219, trajectory.
getPosition(0.0)[1]);
 
   69   EXPECT_DOUBLE_EQ(2126.0, trajectory.
getPosition(0.0)[2]);
 
   70   EXPECT_DOUBLE_EQ(0.0, trajectory.
getPosition(0.0)[3]);
 
   79 TEST(time_optimal_trajectory_generation, test2)
 
   81   Eigen::VectorXd waypoint(4);
 
   84   waypoint << 1427.0, 368.0, 690.0, 90.0;
 
   86   waypoint << 1427.0, 368.0, 790.0, 90.0;
 
   88   waypoint << 952.499938964844, 433.0, 1051.0, 90.0;
 
   90   waypoint << 452.5, 533.0, 1051.0, 90.0;
 
   92   waypoint << 452.5, 533.0, 951.0, 90.0;
 
   95   Eigen::VectorXd max_velocities(4);
 
   96   max_velocities << 1.3, 0.67, 0.67, 0.5;
 
   97   Eigen::VectorXd max_accelerations(4);
 
   98   max_accelerations << 0.002, 0.002, 0.002, 0.002;
 
  101   EXPECT_TRUE(trajectory.
isValid());
 
  102   EXPECT_DOUBLE_EQ(1922.1418427445944, trajectory.
getDuration());
 
  105   EXPECT_DOUBLE_EQ(1427.0, trajectory.
getPosition(0.0)[0]);
 
  106   EXPECT_DOUBLE_EQ(368.0, trajectory.
getPosition(0.0)[1]);
 
  107   EXPECT_DOUBLE_EQ(690.0, trajectory.
getPosition(0.0)[2]);
 
  108   EXPECT_DOUBLE_EQ(90.0, trajectory.
getPosition(0.0)[3]);
 
  117 TEST(time_optimal_trajectory_generation, test3)
 
  119   Eigen::VectorXd waypoint(4);
 
  122   waypoint << 1427.0, 368.0, 690.0, 90.0;
 
  124   waypoint << 1427.0, 368.0, 790.0, 90.0;
 
  126   waypoint << 952.499938964844, 433.0, 1051.0, 90.0;
 
  128   waypoint << 452.5, 533.0, 1051.0, 90.0;
 
  130   waypoint << 452.5, 533.0, 951.0, 90.0;
 
  133   Eigen::VectorXd max_velocities(4);
 
  134   max_velocities << 1.3, 0.67, 0.67, 0.5;
 
  135   Eigen::VectorXd max_accelerations(4);
 
  136   max_accelerations << 0.002, 0.002, 0.002, 0.002;
 
  139   EXPECT_TRUE(trajectory.
isValid());
 
  140   EXPECT_DOUBLE_EQ(1919.5597888812974, trajectory.
getDuration());
 
  143   EXPECT_DOUBLE_EQ(1427.0, trajectory.
getPosition(0.0)[0]);
 
  144   EXPECT_DOUBLE_EQ(368.0, trajectory.
getPosition(0.0)[1]);
 
  145   EXPECT_DOUBLE_EQ(690.0, trajectory.
getPosition(0.0)[2]);
 
  146   EXPECT_DOUBLE_EQ(90.0, trajectory.
getPosition(0.0)[3]);
 
  156 TEST(time_optimal_trajectory_generation, test_custom_limits)
 
  158   constexpr 
auto robot_name{ 
"panda" };
 
  159   constexpr 
auto group_name{ 
"panda_arm" };
 
  162   ASSERT_TRUE((
bool)robot_model) << 
"Failed to load robot model" << robot_name;
 
  163   auto group = robot_model->getJointModelGroup(group_name);
 
  164   ASSERT_TRUE((
bool)
group) << 
"Failed to load joint model group " << group_name;
 
  168   const double delta_t = 0.1;
 
  177   std::unordered_map<std::string, double> vel_limits{ { 
"panda_joint1", 1.3 } };
 
  178   std::unordered_map<std::string, double> accel_limits{ { 
"panda_joint2", 2.3 }, { 
"panda_joint3", 3.3 } };
 
  179   ASSERT_TRUE(totg.
computeTimeStamps(trajectory, vel_limits, accel_limits)) << 
"Failed to compute time stamps";
 
  183 TEST(time_optimal_trajectory_generation, testLargeAccel)
 
  185   double path_tolerance = 0.1;
 
  186   double resample_dt = 0.1;
 
  187   Eigen::VectorXd waypoint(6);
 
  189   Eigen::VectorXd max_velocities(6);
 
  190   Eigen::VectorXd max_accelerations(6);
 
  194   waypoint << 1.6113056281076339,
 
  195              -0.21400163389235427,
 
  197               9.9653618690354051e-12,
 
  202   waypoint << 1.6088016187976597,
 
  203              -0.21792862470933924,
 
  205               0.00010424017303217738,
 
  210   waypoint << 1.5887695443178671,
 
  211              -0.24934455124521923,
 
  213               0.00093816147756670078,
 
  218   waypoint << 1.1647412393815282,
 
  219              -0.91434018564402375,
 
  221               0.018590164397622583,
 
  227   max_velocities << 0.89535390627300004,
 
  234   max_accelerations << 0.82673490883799994,
 
  244   ASSERT_TRUE(parameterized.
isValid());
 
  246   size_t sample_count = std::ceil(parameterized.
getDuration() / resample_dt);
 
  247   for (
size_t sample = 0; sample <= sample_count; ++sample)
 
  250     double t = std::min(parameterized.
getDuration(), sample * resample_dt);
 
  253     ASSERT_EQ(acceleration.size(), 6);
 
  254     for (std::size_t i = 0; i < 6; ++i)
 
  255       EXPECT_NEAR(acceleration(i), 0.0, 100.0) << 
"Invalid acceleration at position " << sample_count << 
"\n";
 
  260 TEST(time_optimal_trajectory_generation, testLastWaypoint)
 
  262   constexpr 
auto robot_name{ 
"panda" };
 
  263   constexpr 
auto group_name{ 
"hand" };
 
  266   ASSERT_TRUE((
bool)robot_model) << 
"Failed to load robot model" << robot_name;
 
  267   auto group = robot_model->getJointModelGroup(group_name);
 
  268   ASSERT_TRUE((
bool)
group) << 
"Failed to load joint model group " << group_name;
 
  273   auto add_waypoint = [&](
const std::vector<double>& waypoint) {
 
  277   add_waypoint({ 0.000000000, 0.000000000 });
 
  278   add_waypoint({ 0.000396742, 0.000396742 });
 
  279   add_waypoint({ 0.000793484, 0.000793484 });
 
  280   add_waypoint({ 0.001190226, 0.001190226 });
 
  281   add_waypoint({ 0.001586968, 0.001586968 });
 
  282   add_waypoint({ 0.001983710, 0.001983710 });
 
  283   add_waypoint({ 0.002380452, 0.002380452 });
 
  284   add_waypoint({ 0.002777194, 0.002777194 });
 
  285   add_waypoint({ 0.003173936, 0.003173936 });
 
  286   add_waypoint({ 0.003570678, 0.003570678 });
 
  287   add_waypoint({ 0.003967420, 0.003967420 });
 
  288   add_waypoint({ 0.004364162, 0.004364162 });
 
  289   add_waypoint({ 0.004760904, 0.004760904 });
 
  290   add_waypoint({ 0.005157646, 0.005157646 });
 
  291   add_waypoint({ 0.005554388, 0.005554388 });
 
  292   add_waypoint({ 0.005951130, 0.005951130 });
 
  293   add_waypoint({ 0.006347872, 0.006347872 });
 
  294   add_waypoint({ 0.006744614, 0.006744614 });
 
  295   add_waypoint({ 0.007141356, 0.007141356 });
 
  296   add_waypoint({ 0.007538098, 0.007538098 });
 
  297   add_waypoint({ 0.007934840, 0.007934840 });
 
  298   add_waypoint({ 0.008331582, 0.008331582 });
 
  299   add_waypoint({ 0.008728324, 0.008728324 });
 
  300   add_waypoint({ 0.009125066, 0.009125066 });
 
  301   add_waypoint({ 0.009521808, 0.009521808 });
 
  302   add_waypoint({ 0.009918550, 0.009918550 });
 
  303   add_waypoint({ 0.010315292, 0.010315292 });
 
  304   add_waypoint({ 0.010712034, 0.010712034 });
 
  305   add_waypoint({ 0.011108776, 0.011108776 });
 
  306   add_waypoint({ 0.011505518, 0.011505518 });
 
  307   add_waypoint({ 0.011902261, 0.011902261 });
 
  308   add_waypoint({ 0.012299003, 0.012299003 });
 
  309   add_waypoint({ 0.012695745, 0.012695745 });
 
  310   add_waypoint({ 0.013092487, 0.013092487 });
 
  311   add_waypoint({ 0.013489229, 0.013489229 });
 
  312   add_waypoint({ 0.013885971, 0.013885971 });
 
  313   add_waypoint({ 0.014282713, 0.014282713 });
 
  314   add_waypoint({ 0.014679455, 0.014679455 });
 
  315   add_waypoint({ 0.015076197, 0.015076197 });
 
  316   add_waypoint({ 0.015472939, 0.015472939 });
 
  317   add_waypoint({ 0.015869681, 0.015869681 });
 
  318   add_waypoint({ 0.016266423, 0.016266423 });
 
  319   add_waypoint({ 0.016663165, 0.016663165 });
 
  320   add_waypoint({ 0.017059907, 0.017059907 });
 
  321   add_waypoint({ 0.017456649, 0.017456649 });
 
  322   add_waypoint({ 0.017853391, 0.017853391 });
 
  323   add_waypoint({ 0.018250133, 0.018250133 });
 
  324   add_waypoint({ 0.018646875, 0.018646875 });
 
  325   add_waypoint({ 0.019043617, 0.019043617 });
 
  326   add_waypoint({ 0.019440359, 0.019440359 });
 
  327   add_waypoint({ 0.019837101, 0.019837101 });
 
  328   add_waypoint({ 0.020233843, 0.020233843 });
 
  329   add_waypoint({ 0.020630585, 0.020630585 });
 
  330   add_waypoint({ 0.021027327, 0.021027327 });
 
  331   add_waypoint({ 0.021424069, 0.021424069 });
 
  332   add_waypoint({ 0.021820811, 0.021820811 });
 
  333   add_waypoint({ 0.022217553, 0.022217553 });
 
  334   add_waypoint({ 0.022614295, 0.022614295 });
 
  335   add_waypoint({ 0.023011037, 0.023011037 });
 
  336   add_waypoint({ 0.023407779, 0.023407779 });
 
  337   add_waypoint({ 0.023804521, 0.023804521 });
 
  338   add_waypoint({ 0.024201263, 0.024201263 });
 
  339   add_waypoint({ 0.024598005, 0.024598005 });
 
  340   add_waypoint({ 0.024994747, 0.024994747 });
 
  341   add_waypoint({ 0.025391489, 0.025391489 });
 
  342   add_waypoint({ 0.025788231, 0.025788231 });
 
  343   add_waypoint({ 0.026184973, 0.026184973 });
 
  344   add_waypoint({ 0.026581715, 0.026581715 });
 
  345   add_waypoint({ 0.026978457, 0.026978457 });
 
  346   add_waypoint({ 0.027375199, 0.027375199 });
 
  347   add_waypoint({ 0.027771941, 0.027771941 });
 
  348   add_waypoint({ 0.028168683, 0.028168683 });
 
  349   add_waypoint({ 0.028565425, 0.028565425 });
 
  350   add_waypoint({ 0.028962167, 0.028962167 });
 
  351   add_waypoint({ 0.029358909, 0.029358909 });
 
  352   add_waypoint({ 0.029755651, 0.029755651 });
 
  353   add_waypoint({ 0.030152393, 0.030152393 });
 
  354   add_waypoint({ 0.030549135, 0.030549135 });
 
  355   add_waypoint({ 0.030945877, 0.030945877 });
 
  356   add_waypoint({ 0.031342619, 0.031342619 });
 
  357   add_waypoint({ 0.031739361, 0.031739361 });
 
  358   add_waypoint({ 0.032136103, 0.032136103 });
 
  359   add_waypoint({ 0.032532845, 0.032532845 });
 
  360   add_waypoint({ 0.032929587, 0.032929587 });
 
  361   add_waypoint({ 0.033326329, 0.033326329 });
 
  362   add_waypoint({ 0.033723071, 0.033723071 });
 
  363   add_waypoint({ 0.034119813, 0.034119813 });
 
  364   add_waypoint({ 0.034516555, 0.034516555 });
 
  366   const std::vector<double> expected_last_waypoint = { 0.034913297, 0.034913297 };
 
  367   add_waypoint(expected_last_waypoint);
 
  370   ASSERT_TRUE(totg.
computeTimeStamps(trajectory)) << 
"Failed to compute time stamps";
 
  372   std::vector<double> actual_last_waypoint;
 
  374   EXPECT_TRUE(std::equal(actual_last_waypoint.cbegin(), actual_last_waypoint.cend(), expected_last_waypoint.cbegin(),
 
  375                          expected_last_waypoint.cend(), [](
const double rhs, 
const double lhs) {
 
  376                            return std::abs(rhs - lhs) < std::numeric_limits<double>::epsilon();
 
  380 TEST(time_optimal_trajectory_generation, testPluginAPI)
 
  382   constexpr 
auto robot_name{ 
"panda" };
 
  383   constexpr 
auto group_name{ 
"panda_arm" };
 
  386   ASSERT_TRUE((
bool)robot_model) << 
"Failed to load robot model" << robot_name;
 
  387   auto group = robot_model->getJointModelGroup(group_name);
 
  388   ASSERT_TRUE((
bool)
group) << 
"Failed to load joint model group " << group_name;
 
  407   constexpr 
size_t totg_iterations = 10;
 
  410   moveit_msgs::msg::RobotTrajectory first_trajectory_msg_start, first_trajectory_msg_end;
 
  418     ASSERT_EQ(test_bounds.size(), original_bounds.size());
 
  419     for (
size_t bound_idx = 0; bound_idx < test_bounds.at(0)->size(); ++bound_idx)
 
  421       ASSERT_EQ(test_bounds.at(0)->at(bound_idx).max_velocity_, original_bounds.at(0)->at(bound_idx).max_velocity_);
 
  422       ASSERT_EQ(test_bounds.at(0)->at(bound_idx).min_velocity_, original_bounds.at(0)->at(bound_idx).min_velocity_);
 
  423       ASSERT_EQ(test_bounds.at(0)->at(bound_idx).velocity_bounded_,
 
  424                 original_bounds.at(0)->at(bound_idx).velocity_bounded_);
 
  426       ASSERT_EQ(test_bounds.at(0)->at(bound_idx).max_acceleration_,
 
  427                 original_bounds.at(0)->at(bound_idx).max_acceleration_);
 
  428       ASSERT_EQ(test_bounds.at(0)->at(bound_idx).min_acceleration_,
 
  429                 original_bounds.at(0)->at(bound_idx).min_acceleration_);
 
  430       ASSERT_EQ(test_bounds.at(0)->at(bound_idx).acceleration_bounded_,
 
  431                 original_bounds.at(0)->at(bound_idx).acceleration_bounded_);
 
  436     ASSERT_TRUE(totg.
computeTimeStamps(test_trajectory)) << 
"Failed to compute time stamps";
 
  441     for (
size_t i = 0; i < totg_iterations; ++i)
 
  444       EXPECT_TRUE(totg_success) << 
"Failed to compute time stamps with a same TOTG instance in iteration " << i;
 
  451   moveit_msgs::msg::RobotTrajectory second_trajectory_msg_start, second_trajectory_msg_end;
 
  457       ASSERT_TRUE(totg.
computeTimeStamps(test_trajectory)) << 
"Failed to compute time stamps";
 
  463     for (
size_t i = 0; i < totg_iterations; ++i)
 
  467       EXPECT_TRUE(totg_success) << 
"Failed to compute time stamps with a new TOTG instance in iteration " << i;
 
  474   ASSERT_EQ(first_trajectory_msg_start, second_trajectory_msg_start);
 
  475   ASSERT_EQ(first_trajectory_msg_end, second_trajectory_msg_end);
 
  478   moveit_msgs::msg::RobotTrajectory third_trajectory_msg_end;
 
  482     ASSERT_TRUE(totg.
computeTimeStamps(trajectory)) << 
"Failed to compute time stamps";
 
  485   for (
size_t i = 0; i < totg_iterations; ++i)
 
  489     ASSERT_TRUE(totg_success) << 
"Failed to compute timestamps on a new TOTG instance in iteration " << i;
 
  496   ASSERT_EQ(first_trajectory_msg_end, third_trajectory_msg_end);
 
  499 TEST(time_optimal_trajectory_generation, testRelevantZeroMaxAccelerationsInvalidateTrajectory)
 
  501   const Eigen::Vector2d max_velocity(1, 1);
 
  502   const Path path(std::list<Eigen::VectorXd>{ Eigen::Vector2d(0, 0), Eigen::Vector2d(1, 1) });
 
  504   EXPECT_FALSE(
Trajectory(path, max_velocity, Eigen::Vector2d(0, 1)).isValid());
 
  505   EXPECT_FALSE(
Trajectory(path, max_velocity, Eigen::Vector2d(1, 0)).isValid());
 
  506   EXPECT_FALSE(
Trajectory(path, max_velocity, Eigen::Vector2d(0, 0)).isValid());
 
  509 TEST(time_optimal_trajectory_generation, testIrrelevantZeroMaxAccelerationsDontInvalidateTrajectory)
 
  511   const Eigen::Vector2d max_velocity(1, 1);
 
  513   EXPECT_TRUE(
Trajectory(
Path(std::list<Eigen::VectorXd>{ Eigen::Vector2d(0, 0), Eigen::Vector2d(0, 1) }), max_velocity,
 
  514                          Eigen::Vector2d(0, 1))
 
  516   EXPECT_TRUE(
Trajectory(
Path(std::list<Eigen::VectorXd>{ Eigen::Vector2d(0, 0), Eigen::Vector2d(1, 0) }), max_velocity,
 
  517                          Eigen::Vector2d(1, 0))
 
  521 TEST(time_optimal_trajectory_generation, testTimeStepZeroMakesTrajectoryInvalid)
 
  523   EXPECT_FALSE(
Trajectory(
Path(std::list<Eigen::VectorXd>{ Eigen::Vector2d(0, 0), Eigen::Vector2d(1, 1) }),
 
  524                           Eigen::Vector2d(1, 1), Eigen::Vector2d(1, 1),
 
  529 int main(
int argc, 
char** argv)
 
  531   testing::InitGoogleTest(&argc, argv);
 
  532   return RUN_ALL_TESTS();
 
Representation of a robot's state. This includes position, velocity, acceleration and effort.
 
void setJointGroupPositions(const std::string &joint_group_name, const double *gstate)
Given positions for the variables that make up a group, in the order found in the group (including va...
 
void copyJointGroupPositions(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the position values of the variables that make up the group into another loca...
 
void setToDefaultValues()
Set all joints to their default positions. The default position is 0, or if that is not within bounds...
 
Maintain a sequence of waypoints and the time durations between these waypoints.
 
const moveit::core::RobotModelConstPtr & getRobotModel() const
 
void getRobotTrajectoryMsg(moveit_msgs::msg::RobotTrajectory &trajectory, const std::vector< std::string > &joint_filter=std::vector< std::string >()) const
 
RobotTrajectory & addSuffixWayPoint(const moveit::core::RobotState &state, double dt)
Add a point to the trajectory.
 
double getWayPointDurationFromPrevious(std::size_t index) const
 
double getDuration() const
 
const moveit::core::RobotState & getLastWayPoint() const
 
bool computeTimeStamps(robot_trajectory::RobotTrajectory &trajectory, const double max_velocity_scaling_factor=1.0, const double max_acceleration_scaling_factor=1.0) const override
 
Eigen::VectorXd getAcceleration(double time) const
Return the acceleration vector for a given point in time.
 
bool isValid() const
Call this method after constructing the object to make sure the trajectory generation succeeded witho...
 
Eigen::VectorXd getPosition(double time) const
Return the position/configuration vector for a given point in time.
 
double getDuration() const
Returns the optimal duration of the trajectory.
 
moveit::core::RobotModelPtr loadTestingRobotModel(const std::string &robot_name)
Loads a robot from moveit_resources.
 
std::vector< const JointModel::Bounds * > JointBoundsVector
 
int main(int argc, char **argv)
 
TEST(time_optimal_trajectory_generation, test1)