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)