moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
servo_ros_fixture.hpp
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 : Resources used by servo ROS integration tests
37 Title : servo_ros_fixture.hpp
38 Project : moveit_servo
39 Created : 07/23/2023
40*/
41
42#pragma once
43
44#include <gtest/gtest.h>
45#include <moveit_msgs/msg/servo_status.hpp>
46#include <moveit_msgs/srv/servo_command_type.hpp>
48#include <rclcpp/client.hpp>
49#include <rclcpp/executors.hpp>
50#include <rclcpp/node.hpp>
51#include <rclcpp/publisher.hpp>
52#include <rclcpp/qos.hpp>
53#include <sensor_msgs/msg/joint_state.hpp>
54#include <trajectory_msgs/msg/joint_trajectory.hpp>
55
56class ServoRosFixture : public testing::Test
57{
58protected:
59 void statusCallback(const moveit_msgs::msg::ServoStatus::ConstSharedPtr& msg)
60 {
61 status_ = static_cast<moveit_servo::StatusCode>(msg->code);
63 }
64
65 void jointStateCallback(const sensor_msgs::msg::JointState::ConstSharedPtr& msg)
66 {
67 joint_states_ = *msg;
69 }
70
71 void trajectoryCallback(const trajectory_msgs::msg::JointTrajectory::ConstSharedPtr& msg)
72 {
75 }
76
77 void SetUp() override
78 {
79 // Create a node to be given to Servo.
80 servo_test_node_ = std::make_shared<rclcpp::Node>("moveit_servo_test");
81
83
84 status_subscriber_ = servo_test_node_->create_subscription<moveit_msgs::msg::ServoStatus>(
85 "/servo_node/status", rclcpp::SystemDefaultsQoS(),
86 [this](const moveit_msgs::msg::ServoStatus::ConstSharedPtr& msg) { return statusCallback(msg); });
87
88 joint_state_subscriber_ = servo_test_node_->create_subscription<sensor_msgs::msg::JointState>(
89 "/joint_states", rclcpp::SystemDefaultsQoS(),
90 [this](const sensor_msgs::msg::JointState::ConstSharedPtr& msg) { return jointStateCallback(msg); });
91
92 trajectory_subscriber_ = servo_test_node_->create_subscription<trajectory_msgs::msg::JointTrajectory>(
93 "/panda_arm_controller/joint_trajectory", rclcpp::SystemDefaultsQoS(),
94 [this](const trajectory_msgs::msg::JointTrajectory::ConstSharedPtr& msg) { return trajectoryCallback(msg); });
95
97 servo_test_node_->create_client<moveit_msgs::srv::ServoCommandType>("/servo_node/switch_command_type");
98
100
101 executor_.add_node(servo_test_node_);
102 executor_thread_ = std::thread([this]() { executor_.spin(); });
103 }
104
105 void TearDown() override
106 {
107 executor_.remove_node(servo_test_node_);
108 executor_.cancel();
109 if (executor_thread_.joinable())
110 {
111 executor_thread_.join();
112 }
113 }
114
116 {
117 auto logger = servo_test_node_->get_logger();
118 while (!switch_input_client_->service_is_ready())
119 {
120 if (!rclcpp::ok())
121 {
122 RCLCPP_ERROR(logger, "Interrupted while waiting for the service. Exiting.");
123 std::exit(EXIT_FAILURE);
124 }
125
126 rclcpp::sleep_for(std::chrono::milliseconds(500));
127 }
128 RCLCPP_INFO(logger, "MoveIt Servo input switching service ready!");
129 }
130
132 {
133 auto logger = servo_test_node_->get_logger();
134 auto wait_timeout = rclcpp::Duration::from_seconds(5);
135 auto start_time = servo_test_node_->now();
136
137 while (rclcpp::ok() && state_count_ == 0)
138 {
139 rclcpp::sleep_for(std::chrono::milliseconds(500));
140 auto elapsed_time = servo_test_node_->now() - start_time;
141 if (elapsed_time >= wait_timeout)
142 {
143 RCLCPP_ERROR(logger, "Timed out waiting for joint states");
144 FAIL();
145 }
146 }
147 }
148
150 {
151 }
152
153 std::shared_ptr<rclcpp::Node> servo_test_node_;
154
155 // Executor and a thread to run the executor.
156 rclcpp::executors::SingleThreadedExecutor executor_;
157 std::thread executor_thread_;
158
159 rclcpp::Subscription<moveit_msgs::msg::ServoStatus>::SharedPtr status_subscriber_;
160 rclcpp::Subscription<sensor_msgs::msg::JointState>::SharedPtr joint_state_subscriber_;
161 rclcpp::Subscription<trajectory_msgs::msg::JointTrajectory>::SharedPtr trajectory_subscriber_;
162 rclcpp::Client<moveit_msgs::srv::ServoCommandType>::SharedPtr switch_input_client_;
163
164 sensor_msgs::msg::JointState joint_states_;
165 trajectory_msgs::msg::JointTrajectory published_trajectory_;
166
167 std::atomic<int> status_count_;
168 std::atomic<moveit_servo::StatusCode> status_;
169
170 std::atomic<int> state_count_;
171 std::atomic<int> traj_count_;
172};
trajectory_msgs::msg::JointTrajectory published_trajectory_
std::atomic< int > traj_count_
std::atomic< moveit_servo::StatusCode > status_
rclcpp::executors::SingleThreadedExecutor executor_
sensor_msgs::msg::JointState joint_states_
std::thread executor_thread_
void SetUp() override
std::atomic< int > status_count_
std::atomic< int > state_count_
rclcpp::Subscription< sensor_msgs::msg::JointState >::SharedPtr joint_state_subscriber_
void jointStateCallback(const sensor_msgs::msg::JointState::ConstSharedPtr &msg)
std::shared_ptr< rclcpp::Node > servo_test_node_
rclcpp::Subscription< moveit_msgs::msg::ServoStatus >::SharedPtr status_subscriber_
rclcpp::Client< moveit_msgs::srv::ServoCommandType >::SharedPtr switch_input_client_
void trajectoryCallback(const trajectory_msgs::msg::JointTrajectory::ConstSharedPtr &msg)
void TearDown() override
void statusCallback(const moveit_msgs::msg::ServoStatus::ConstSharedPtr &msg)
rclcpp::Subscription< trajectory_msgs::msg::JointTrajectory >::SharedPtr trajectory_subscriber_