moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
test_utils.cpp
Go to the documentation of this file.
1// Copyright 2024 Intrinsic Innovation LLC.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
19#include <gtest/gtest.h>
20#include <rclcpp/version.h>
21
22#include <geometry_msgs/msg/point.hpp>
24#include <moveit_msgs/msg/joint_constraint.hpp>
25#include <moveit_msgs/msg/orientation_constraint.hpp>
26#include <moveit_msgs/msg/position_constraint.hpp>
27
28// For Rolling, Kilted, and newer
29#if RCLCPP_VERSION_GTE(29, 6, 0)
30#include <tf2_ros/buffer.hpp>
31// For Jazzy and older
32#else
33#include <tf2_ros/buffer.h>
34#endif
35
36#include "../fixtures/warehouse_fixture.hpp"
37
38namespace
39{
40
41using ::testing::TestParamInfo;
42using ::testing::ValuesIn;
43
44using ::warehouse_ros::MessageCollection;
45using ::warehouse_ros::Metadata;
46using ::warehouse_ros::Query;
47
48// This test throws an exception on Humble. It is not clear why. Excluding it for now.
49#if RCLCPP_VERSION_GTE(28, 3, 3)
50TEST_F(WarehouseFixture, QueryAppendCenterWithToleranceWorks)
51{
52 MessageCollection<geometry_msgs::msg::Point> coll =
53 db_->openCollection<geometry_msgs::msg::Point>("test_db", "test_collection");
54
55 Metadata::Ptr metadata = coll.createMetadata();
56 metadata->append("test_metadata", 5.0);
57 coll.insert(geometry_msgs::msg::Point(), metadata);
58
59 Query::Ptr unrelated_query = coll.createQuery();
60 moveit_ros::trajectory_cache::queryAppendCenterWithTolerance(*unrelated_query, "unrelated_metadata", 1.0, 10.0);
61 EXPECT_TRUE(coll.queryList(unrelated_query).empty());
62
63 Query::Ptr related_query_too_low = coll.createQuery();
64 moveit_ros::trajectory_cache::queryAppendCenterWithTolerance(*related_query_too_low, "test_metadata", 4.45, 1.0);
65 EXPECT_TRUE(coll.queryList(related_query_too_low).empty());
66
67 Query::Ptr related_query_too_high = coll.createQuery();
68 moveit_ros::trajectory_cache::queryAppendCenterWithTolerance(*related_query_too_high, "test_metadata", 5.55, 1.0);
69 EXPECT_TRUE(coll.queryList(related_query_too_high).empty());
70
71 Query::Ptr related_query_in_range = coll.createQuery();
72 moveit_ros::trajectory_cache::queryAppendCenterWithTolerance(*related_query_in_range, "test_metadata", 5.0, 1.0);
73 EXPECT_EQ(coll.queryList(related_query_in_range).size(), 1);
74}
75#endif
76
77// restateInNewFrame.
78
79TEST(RestateInNewFrameTest, NoopOnNullTranslationAndRotation)
80{
81 auto tf_buffer = std::make_shared<tf2_ros::Buffer>(std::make_shared<rclcpp::Clock>(RCL_ROS_TIME));
82
84 tf_buffer, "frame_a", "frame_b", nullptr, nullptr, tf2::TimePointZero);
85
86 EXPECT_EQ(result, moveit::core::MoveItErrorCode::SUCCESS);
87}
88
89TEST(RestateInNewFrameTest, NoopOnSameFrame)
90{
91 auto tf_buffer = std::make_shared<tf2_ros::Buffer>(std::make_shared<rclcpp::Clock>(RCL_ROS_TIME));
92 geometry_msgs::msg::Point translation;
93 translation.x = 1;
94 translation.y = 2;
95 translation.z = 3;
96 geometry_msgs::msg::Quaternion rotation;
97 rotation.x = 0;
98 rotation.y = 0;
99 rotation.z = 0;
100 rotation.w = 1;
101
103 tf_buffer, "frame_a", "frame_a", &translation, &rotation, tf2::TimePointZero);
104
105 EXPECT_EQ(result, moveit::core::MoveItErrorCode::SUCCESS);
106 EXPECT_EQ(translation.x, 1);
107 EXPECT_EQ(translation.y, 2);
108 EXPECT_EQ(translation.z, 3);
109 EXPECT_EQ(rotation.x, 0);
110 EXPECT_EQ(rotation.y, 0);
111 EXPECT_EQ(rotation.z, 0);
112 EXPECT_EQ(rotation.w, 1);
113}
114
115TEST(RestateInNewFrameTest, FailsOnMissingTransform)
116{
117 auto tf_buffer = std::make_shared<tf2_ros::Buffer>(std::make_shared<rclcpp::Clock>(RCL_ROS_TIME));
118 geometry_msgs::msg::Point translation;
119 geometry_msgs::msg::Quaternion rotation;
120
122 tf_buffer, "frame_a", "frame_c", &translation, &rotation, tf2::TimePointZero);
123
124 EXPECT_NE(result, moveit::core::MoveItErrorCode::SUCCESS);
125}
126
127struct RestateInNewFrameTestCase
128{
129 std::string test_name;
130 bool translate;
131 bool rotate;
132 double expected_translation_x;
133 double expected_translation_y;
134 double expected_translation_z;
135 double expected_rotation_x;
136 double expected_rotation_y;
137 double expected_rotation_z;
138 double expected_rotation_w;
139};
140
141class RestateInNewFrameParameterizedTest : public testing::WithParamInterface<RestateInNewFrameTestCase>,
142 public testing::Test
143{
144};
145
146INSTANTIATE_TEST_SUITE_P(RestateInNewFrameParameterizedTests, RestateInNewFrameParameterizedTest,
147 ValuesIn<RestateInNewFrameTestCase>({ {
148 .test_name = "TranslateAndRotate",
149 .translate = true,
150 .rotate = true,
151 .expected_translation_x = 2,
152 .expected_translation_y = 4,
153 .expected_translation_z = 6,
154 .expected_rotation_x = 0,
155 .expected_rotation_y = 0,
156 .expected_rotation_z = 0.707,
157 .expected_rotation_w = 0.707,
158 },
159 {
160 .test_name = "NullTranslationIgnoresTranslation",
161 .translate = false,
162 .rotate = true,
163 .expected_translation_x = 1,
164 .expected_translation_y = 2,
165 .expected_translation_z = 3,
166 .expected_rotation_x = 0,
167 .expected_rotation_y = 0,
168 .expected_rotation_z = 0.707,
169 .expected_rotation_w = 0.707,
170 },
171 {
172 .test_name = "NullRotationIgnoresRotation",
173 .translate = true,
174 .rotate = false,
175 .expected_translation_x = 2,
176 .expected_translation_y = 4,
177 .expected_translation_z = 6,
178 .expected_rotation_x = 0,
179 .expected_rotation_y = 0,
180 .expected_rotation_z = 0,
181 .expected_rotation_w = 1,
182 } }),
183 [](const TestParamInfo<RestateInNewFrameParameterizedTest::ParamType>& info) {
184 return info.param.test_name;
185 });
186
187TEST_P(RestateInNewFrameParameterizedTest, RestateInNewFrame)
188{
189 auto tf_buffer = std::make_shared<tf2_ros::Buffer>(std::make_shared<rclcpp::Clock>(RCL_ROS_TIME));
190 geometry_msgs::msg::TransformStamped transform;
191 transform.header.frame_id = "frame_a";
192 transform.child_frame_id = "frame_b";
193 transform.transform.translation.x = 1;
194 transform.transform.translation.y = 2;
195 transform.transform.translation.z = 3;
196 transform.transform.rotation.x = 0;
197 transform.transform.rotation.y = 0;
198 transform.transform.rotation.z = 0.707; // 90 degree rotation about the z-axis.
199 transform.transform.rotation.w = 0.707;
200 tf_buffer->setTransform(transform, "test");
201
202 geometry_msgs::msg::Point translation;
203 translation.x = 1;
204 translation.y = 2;
205 translation.z = 3;
206
207 geometry_msgs::msg::Quaternion rotation;
208 rotation.x = 0;
209 rotation.y = 0;
210 rotation.z = 0;
211 rotation.w = 1;
212
213 RestateInNewFrameTestCase params = GetParam();
214
216 moveit_ros::trajectory_cache::restateInNewFrame(tf_buffer, /*target_frame=*/"frame_a", /*source_frame=*/"frame_b",
217 params.translate ? &translation : nullptr,
218 params.rotate ? &rotation : nullptr, tf2::TimePointZero);
219
220 EXPECT_EQ(result, moveit::core::MoveItErrorCode::SUCCESS);
221
222 if (params.translate)
223 {
224 EXPECT_EQ(translation.x, params.expected_translation_x);
225 EXPECT_EQ(translation.y, params.expected_translation_y);
226 EXPECT_EQ(translation.z, params.expected_translation_z);
227 }
228 else
229 {
230 EXPECT_EQ(translation.x, 1);
231 EXPECT_EQ(translation.y, 2);
232 EXPECT_EQ(translation.z, 3);
233 }
234
235 if (params.rotate)
236 {
237 EXPECT_NEAR(rotation.x, params.expected_rotation_x, 1e-3);
238 EXPECT_NEAR(rotation.y, params.expected_rotation_y, 1e-3);
239 EXPECT_NEAR(rotation.z, params.expected_rotation_z, 1e-3);
240 EXPECT_NEAR(rotation.w, params.expected_rotation_w, 1e-3);
241 }
242 else
243 {
244 EXPECT_EQ(rotation.x, 0);
245 EXPECT_EQ(rotation.y, 0);
246 EXPECT_EQ(rotation.z, 0);
247 EXPECT_EQ(rotation.w, 1);
248 }
249}
250
251// Other utils.
252
253TEST(TestUtils, GetExecutionTimeWorks)
254{
255 moveit_msgs::msg::RobotTrajectory trajectory;
256 trajectory.joint_trajectory.points.resize(2);
257 trajectory.joint_trajectory.points[0].time_from_start = rclcpp::Duration::from_seconds(1.0);
258 trajectory.joint_trajectory.points[1].time_from_start = rclcpp::Duration::from_seconds(2.0);
259
260 EXPECT_EQ(moveit_ros::trajectory_cache::getExecutionTime(trajectory), 2.0);
261}
262
263TEST(TestUtils, ConstraintSortingWorks)
264{
265 // Joint constraints.
266 {
267 moveit_msgs::msg::JointConstraint jc1;
268 jc1.joint_name = "joint2";
269 moveit_msgs::msg::JointConstraint jc2;
270 jc2.joint_name = "joint1";
271 std::vector<moveit_msgs::msg::JointConstraint> joint_constraints = { jc1, jc2 };
273
274 EXPECT_EQ(joint_constraints[0].joint_name, "joint1");
275 EXPECT_EQ(joint_constraints[1].joint_name, "joint2");
276 }
277
278 // Position constraints.
279 {
280 moveit_msgs::msg::PositionConstraint pc1;
281 pc1.link_name = "link2";
282 moveit_msgs::msg::PositionConstraint pc2;
283 pc2.link_name = "link1";
284 std::vector<moveit_msgs::msg::PositionConstraint> position_constraints = { pc1, pc2 };
286 EXPECT_EQ(position_constraints[0].link_name, "link1");
287 EXPECT_EQ(position_constraints[1].link_name, "link2");
288 }
289
290 // Orientation constraints.
291 {
292 moveit_msgs::msg::OrientationConstraint oc1;
293 oc1.link_name = "link2";
294 moveit_msgs::msg::OrientationConstraint oc2;
295 oc2.link_name = "link1";
296 std::vector<moveit_msgs::msg::OrientationConstraint> orientation_constraints = { oc1, oc2 };
298 EXPECT_EQ(orientation_constraints[0].link_name, "link1");
299 EXPECT_EQ(orientation_constraints[1].link_name, "link2");
300 }
301}
302
303} // namespace
304
305int main(int argc, char** argv)
306{
307 rclcpp::init(argc, argv);
308 ::testing::InitGoogleTest(&argc, argv);
309 int result = RUN_ALL_TESTS();
310 rclcpp::shutdown();
311 return result;
312}
Test fixture to spin up a node to start a warehouse_ros connection with.
a wrapper around moveit_msgs::MoveItErrorCodes to make it easier to return an error code message from...
int main(int argc, char **argv)
Utilities used by the trajectory_cache package.
void sortJointConstraints(std::vector< moveit_msgs::msg::JointConstraint > &joint_constraints)
Sorts a vector of joint constraints in-place by joint name.
Definition utils.cpp:195
double getExecutionTime(const moveit_msgs::msg::RobotTrajectory &trajectory)
Returns the execution time of the trajectory in double seconds.
Definition utils.cpp:154
moveit::core::MoveItErrorCode restateInNewFrame(const std::shared_ptr< tf2_ros::Buffer > &tf, const std::string &target_frame, const std::string &source_frame, geometry_msgs::msg::Point *translation, geometry_msgs::msg::Quaternion *rotation, const tf2::TimePoint &lookup_time=tf2::TimePointZero)
Restates a translation and rotation in a new frame.
Definition utils.cpp:96
void sortOrientationConstraints(std::vector< moveit_msgs::msg::OrientationConstraint > &orientation_constraints)
Sorts a vector of orientation constraints in-place by link name.
Definition utils.cpp:211
void sortPositionConstraints(std::vector< moveit_msgs::msg::PositionConstraint > &position_constraints)
Sorts a vector of position constraints in-place by link name.
Definition utils.cpp:203
void queryAppendCenterWithTolerance(warehouse_ros::Query &query, const std::string &name, double center, double tolerance)
Appends a range inclusive query with some tolerance about some center value.
TEST(AllValid, Instantiate)
TEST_F(BulletCollisionDetectionTester, DISABLED_ContinuousCollisionSelf)
Continuous self collision checks are not supported yet by the bullet integration.
#define INSTANTIATE_TEST_SUITE_P(...)
TEST_P(CollisionDetectorTests, Threaded)
Tests the collision detector in multiple threads.