moveit2
The MoveIt Motion Planning Framework for ROS 2.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
test_ros_integration.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2023, PickNik Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of PickNik Inc. nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
35/* Author : V Mohammed Ibrahim
36 Desc : ROS API integration tests
37 Title : test_ros_integration.cpp
38 Project : moveit_servo
39 Created : 07/23/2023
40*/
41
42#include "servo_ros_fixture.hpp"
43#include <control_msgs/msg/joint_jog.hpp>
44#include <geometry_msgs/msg/pose_stamped.hpp>
45#include <geometry_msgs/msg/twist_stamped.hpp>
46
61namespace
62{
63const int NUM_COMMANDS = 10;
64}
65
66namespace
67{
68TEST_F(ServoRosFixture, testJointJog)
69{
70 waitForJointStates();
71
72 auto joint_jog_publisher = servo_test_node_->create_publisher<control_msgs::msg::JointJog>(
73 "/servo_node/delta_joint_cmds", rclcpp::SystemDefaultsQoS());
74
75 // Call input type service
76 auto request = std::make_shared<moveit_msgs::srv::ServoCommandType::Request>();
77 request->command_type = moveit_msgs::srv::ServoCommandType::Request::JOINT_JOG;
78 auto response = switch_input_client_->async_send_request(request);
79 ASSERT_EQ(response.get()->success, true);
80
81 ASSERT_NE(state_count_, 0);
82
83 control_msgs::msg::JointJog jog_cmd;
84
85 jog_cmd.header.frame_id = "panda_link0";
86 jog_cmd.joint_names.resize(7);
87 jog_cmd.velocities.resize(7);
88 jog_cmd.joint_names = { "panda_joint1", "panda_joint2", "panda_joint3", "panda_joint4",
89 "panda_joint5", "panda_joint6", "panda_joint7" };
90
91 std::fill(jog_cmd.velocities.begin(), jog_cmd.velocities.end(), 0.0);
92
93 jog_cmd.velocities[6] = 0.5;
94
95 size_t count = 0;
96 while (rclcpp::ok() && count < NUM_COMMANDS)
97 {
98 jog_cmd.header.stamp = servo_test_node_->now();
99 joint_jog_publisher->publish(jog_cmd);
100 count++;
101 rclcpp::sleep_for(std::chrono::milliseconds(100));
102 }
103
104 ASSERT_GE(traj_count_, NUM_COMMANDS);
105
106 moveit_servo::StatusCode status = status_;
107 RCLCPP_INFO_STREAM(servo_test_node_->get_logger(), "Status after jointjog: " << static_cast<size_t>(status));
108 ASSERT_EQ(status_, moveit_servo::StatusCode::NO_WARNING);
109
110 // Ensure error when number of commands doesn't match number of joints
111 int traj_count_before = traj_count_;
112 jog_cmd.velocities.pop_back();
113 jog_cmd.header.stamp = servo_test_node_->now();
114 joint_jog_publisher->publish(jog_cmd);
115 rclcpp::sleep_for(std::chrono::milliseconds(100));
116 ASSERT_EQ(status_, moveit_servo::StatusCode::INVALID);
117 jog_cmd.velocities.push_back(1.0);
118 jog_cmd.velocities.push_back(1.0);
119 jog_cmd.header.stamp = servo_test_node_->now();
120 joint_jog_publisher->publish(jog_cmd);
121 rclcpp::sleep_for(std::chrono::milliseconds(100));
122 ASSERT_EQ(status_, moveit_servo::StatusCode::INVALID);
123
124 // No additional trajectories were generated with the invalid commands
125 ASSERT_EQ(traj_count_, traj_count_before);
126 status = status_;
127 RCLCPP_INFO_STREAM(servo_test_node_->get_logger(), "Status after invalid jointjog: " << static_cast<size_t>(status));
128}
129
130TEST_F(ServoRosFixture, testTwist)
131{
132 waitForJointStates();
133
134 auto twist_publisher = servo_test_node_->create_publisher<geometry_msgs::msg::TwistStamped>(
135 "/servo_node/delta_twist_cmds", rclcpp::SystemDefaultsQoS());
136
137 auto request = std::make_shared<moveit_msgs::srv::ServoCommandType::Request>();
138 request->command_type = moveit_msgs::srv::ServoCommandType::Request::TWIST;
139 auto response = switch_input_client_->async_send_request(request);
140 ASSERT_EQ(response.get()->success, true);
141
142 ASSERT_NE(state_count_, 0);
143
144 geometry_msgs::msg::TwistStamped twist_cmd;
145 twist_cmd.header.frame_id = "panda_link0"; // Planning frame
146 twist_cmd.twist.linear.x = 0.0;
147 twist_cmd.twist.linear.y = 0.0;
148 twist_cmd.twist.linear.z = 0.0;
149 twist_cmd.twist.angular.x = 0.0;
150 twist_cmd.twist.angular.y = 0.0;
151 twist_cmd.twist.angular.z = 0.5;
152
153 size_t count = 0;
154 while (rclcpp::ok() && count < NUM_COMMANDS)
155 {
156 twist_cmd.header.stamp = servo_test_node_->now();
157 twist_publisher->publish(twist_cmd);
158 count++;
159 rclcpp::sleep_for(std::chrono::milliseconds(100));
160 }
161
162 ASSERT_GE(traj_count_, NUM_COMMANDS);
163
164 moveit_servo::StatusCode status = status_;
165 RCLCPP_INFO_STREAM(servo_test_node_->get_logger(), "Status after twist: " << static_cast<size_t>(status));
166 ASSERT_EQ(status_, moveit_servo::StatusCode::NO_WARNING);
167}
168
169TEST_F(ServoRosFixture, testPose)
170{
171 waitForJointStates();
172
173 auto pose_publisher = servo_test_node_->create_publisher<geometry_msgs::msg::PoseStamped>(
174 "/servo_node/pose_target_cmds", rclcpp::SystemDefaultsQoS());
175
176 auto request = std::make_shared<moveit_msgs::srv::ServoCommandType::Request>();
177 request->command_type = moveit_msgs::srv::ServoCommandType::Request::POSE;
178 auto response = switch_input_client_->async_send_request(request);
179 ASSERT_EQ(response.get()->success, true);
180
181 geometry_msgs::msg::PoseStamped pose_cmd;
182 pose_cmd.header.frame_id = "panda_link0"; // Planning frame
183
184 pose_cmd.pose.position.x = 0.2;
185 pose_cmd.pose.position.y = -0.2;
186 pose_cmd.pose.position.z = 0.6;
187 pose_cmd.pose.orientation.x = 0.7071;
188 pose_cmd.pose.orientation.y = -0.7071;
189 pose_cmd.pose.orientation.z = 0.0;
190 pose_cmd.pose.orientation.w = 0.0;
191
192 ASSERT_NE(state_count_, 0);
193
194 size_t count = 0;
195 while (rclcpp::ok() && count < NUM_COMMANDS)
196 {
197 pose_cmd.header.stamp = servo_test_node_->now();
198 pose_publisher->publish(pose_cmd);
199 count++;
200 rclcpp::sleep_for(std::chrono::milliseconds(100));
201 }
202
203 ASSERT_GE(traj_count_, NUM_COMMANDS);
204
205 moveit_servo::StatusCode status = status_;
206 RCLCPP_INFO_STREAM(servo_test_node_->get_logger(), "Status after pose: " << static_cast<size_t>(status));
207 ASSERT_EQ(status_, moveit_servo::StatusCode::NO_WARNING);
208}
209
210} // namespace
211
212int main(int argc, char** argv)
213{
214 rclcpp::init(argc, argv);
215 ::testing::InitGoogleTest(&argc, argv);
216 int result = RUN_ALL_TESTS();
217 rclcpp::shutdown();
218 return result;
219}
TEST_F(BulletCollisionDetectionTester, DISABLED_ContinuousCollisionSelf)
Continuous self collision checks are not supported yet by the bullet integration.
int main(int argc, char **argv)