moveit2
The MoveIt Motion Planning Framework for ROS 2.
integrationtest_sequence_action_preemption.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2018 Pilz GmbH & Co. KG
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 Pilz GmbH & Co. KG 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 #include <chrono>
36 #include <condition_variable>
37 #include <gmock/gmock.h>
38 #include <gtest/gtest.h>
39 #include <iostream>
40 #include <memory>
41 #include <mutex>
42 #include <stdexcept>
43 #include <thread>
44 
45 #include <actionlib/client/simple_action_client.h>
50 #include <moveit_msgs/Constraints.h>
51 #include <moveit_msgs/GetMotionPlan.h>
52 #include <moveit_msgs/JointConstraint.h>
53 #include <ros/ros.h>
54 #include <sensor_msgs/JointState.h>
55 
57 
61 
62 #include <moveit_msgs/MoveGroupSequenceAction.h>
63 
64 static constexpr double WAIT_FOR_RESULT_TIME_OUT{ 5. }; // seconds
65 static constexpr double TIME_BEFORE_CANCEL_GOAL{ 1.0 }; // seconds
66 static constexpr double WAIT_FOR_ACTION_SERVER_TIME_OUT{ 10. }; // seconds
67 
68 const std::string SEQUENCE_ACTION_NAME("/sequence_move_group");
69 
70 // Parameters from the node
71 const std::string JOINT_POSITION_TOLERANCE("joint_position_tolerance");
72 
73 // events for callback tests
74 const std::string GOAL_SUCCEEDED_EVENT = "GOAL_SUCCEEDED";
75 const std::string SERVER_IDLE_EVENT = "SERVER_IDLE";
76 
77 const std::string TEST_DATA_FILE_NAME("testdata_file_name");
78 const std::string GROUP_NAME("group_name");
79 
81 
82 class IntegrationTestSequenceAction : public testing::Test, public testing::AsyncTest
83 {
84 protected:
85  void SetUp() override;
86 
87 public:
88  MOCK_METHOD0(active_callback, void());
89  MOCK_METHOD1(feedback_callback, void(const moveit_msgs::msg::MoveGroupSequenceFeedbackConstPtr& feedback));
90  MOCK_METHOD2(done_callback, void(const actionlib::SimpleClientGoalState& state,
91  const moveit_msgs::msg::MoveGroupSequenceResultConstPtr& result));
92 
93 protected:
94  ros::NodeHandle ph_{ "~" };
95  actionlib::SimpleActionClient<moveit_msgs::msg::MoveGroupSequenceAction> ac_{ ph_, SEQUENCE_ACTION_NAME, true };
96  std::shared_ptr<moveit::planning_interface::MoveGroupInterface> move_group_;
97 
99  robot_model::RobotModelPtr robot_model_;
100  double joint_position_tolerance_;
101 
102  std::string test_data_file_name_;
103  std::string group_name_;
104  TestdataLoaderUPtr data_loader_;
105 
107  JointConfiguration start_config;
108 };
109 
111 {
112  // get necessary parameters
113  ASSERT_TRUE(ph_.getParam(JOINT_POSITION_TOLERANCE, joint_position_tolerance_));
114  ASSERT_TRUE(ph_.getParam(TEST_DATA_FILE_NAME, test_data_file_name_));
115  ph_.param<std::string>(GROUP_NAME, group_name_, "manipulator");
116 
117  robot_model_ = model_loader_.getModel();
118 
119  data_loader_ = std::make_unique<XmlTestdataLoader>(test_data_file_name_, robot_model_);
120  ASSERT_NE(nullptr, data_loader_) << "Failed to load test data by provider.";
121 
122  // wait for action server
123  ASSERT_TRUE(ac_.waitForServer(ros::Duration(WAIT_FOR_ACTION_SERVER_TIME_OUT))) << "Action server is not active.";
124 
125  // move to default position
126  start_config = data_loader_->getJoints("ZeroPose", group_name_);
127  robot_state::RobotState robot_state{ start_config.toRobotState() };
128 
129  move_group_ = std::make_shared<moveit::planning_interface::MoveGroupInterface>(start_config.getGroupName());
130  move_group_->setPlannerId("PTP");
131  move_group_->setGoalTolerance(joint_position_tolerance_);
132  move_group_->setJointValueTarget(robot_state);
133  move_group_->setMaxVelocityScalingFactor(1.0);
134  move_group_->setMaxAccelerationScalingFactor(1.0);
135  move_group_->move();
136 
137  ASSERT_TRUE(isAtExpectedPosition(robot_state, *(move_group_->getCurrentState()), joint_position_tolerance_));
138 }
139 
151 TEST_F(IntegrationTestSequenceAction, TestCancellingOfGoal)
152 {
153  Sequence seq{ data_loader_->getSequence("ComplexSequence") };
154 
155  moveit_msgs::msg::MoveGroupSequenceGoal seq_goal;
156  seq_goal.request = seq.toRequest();
157 
158  ac_.sendGoal(seq_goal);
159  // wait for 1 second
160  ros::Duration(TIME_BEFORE_CANCEL_GOAL).sleep();
161 
162  ac_.cancelGoal();
163  ac_.waitForResult(ros::Duration(WAIT_FOR_RESULT_TIME_OUT));
164 
165  moveit_msgs::msg::MoveGroupSequenceResultConstPtr res = ac_.getResult();
166  EXPECT_EQ(res->response.error_code.val, moveit_msgs::msg::MoveItErrorCodes::PREEMPTED)
167  << "Error code should be preempted.";
168 }
169 
170 int main(int argc, char** argv)
171 {
172  ros::init(argc, argv, "integrationtest_sequence_action_preemption");
173  ros::NodeHandle nh;
174 
175  ros::AsyncSpinner spinner{ 1 };
176  spinner.start();
177 
178  testing::InitGoogleTest(&argc, argv);
179  return RUN_ALL_TESTS();
180 }
MOCK_METHOD1(feedback_callback, void(const moveit_msgs::msg::MoveGroupSequenceFeedbackConstPtr &feedback))
MOCK_METHOD0(active_callback, void())
MOCK_METHOD2(done_callback, void(const actionlib::SimpleClientGoalState &state, const moveit_msgs::msg::MoveGroupSequenceResultConstPtr &result))
Class to define a robot configuration in space with the help of joint values.
Data class storing all information regarding a Sequence command.
Definition: sequence.h:54
moveit_msgs::msg::MotionSequenceRequest toRequest() const
Definition: sequence.cpp:67
Test class that allows the handling of asynchronous test objects.
Definition: async_test.h:70
const std::string JOINT_POSITION_TOLERANCE("joint_position_tolerance")
int main(int argc, char **argv)
const std::string GROUP_NAME("group_name")
const std::string SERVER_IDLE_EVENT
const std::string GOAL_SUCCEEDED_EVENT
const std::string TEST_DATA_FILE_NAME("testdata_file_name")
TEST_F(IntegrationTestSequenceAction, TestCancellingOfGoal)
Tests that goal can be cancelled.
const std::string SEQUENCE_ACTION_NAME("/sequence_move_group")
::testing::AssertionResult isAtExpectedPosition(const moveit::core::RobotState &expected, const moveit::core::RobotState &actual, const double epsilon, const std::string &group_name="")
Definition: checks.h:42
std::unique_ptr< TestdataLoader > TestdataLoaderUPtr