test_kinematics_as_plugin.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2008, Willow Garage, 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 Willow Garage 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: Sachin Chitta */
36 
37 #include <ros/ros.h>
38 #include <gtest/gtest.h>
40 
41 // MoveIt!
46 #include <urdf/model.h>
47 #include <srdfdom/model.h>
48 
49 #define IK_NEAR 1e-4
50 #define IK_NEAR_TRANSLATE 1e-5
51 
52 class ArmIKPlugin : public ::testing::Test
53 {
54 public:
55  void SetUp() override
56  {
57  double search_discretization;
58  ros::NodeHandle nh("~");
59  kinematics_loader_.reset(
60  new pluginlib::ClassLoader<kinematics::KinematicsBase>("moveit_core", "kinematics::KinematicsBase"));
61  std::string plugin_name;
62  if (!nh.getParam("plugin_name", plugin_name))
63  throw std::runtime_error("No plugin name found on parameter server");
64  ROS_INFO("Plugin name: %s", plugin_name.c_str());
65 
66  kinematics_solver_ = kinematics_loader_->createInstance(plugin_name);
67 
68  std::string root_name, tip_name;
69  if (!nh.getParam("root_name", root_name))
70  throw std::runtime_error("No root name found on parameter server");
71 
72  if (!nh.getParam("tip_name", tip_name))
73  throw std::runtime_error("No tip name found on parameter server");
74 
75  if (!nh.getParam("search_discretization", search_discretization))
76  throw std::runtime_error("No search discretization found on parameter server");
77 
78  ASSERT_TRUE(
79  kinematics_solver_->initialize("robot_description", "right_arm", root_name, tip_name, search_discretization));
80  }
81 
82  void joint_state_callback(const geometry_msgs::Pose& ik_pose, const std::vector<double>& joint_state,
83  moveit_msgs::MoveItErrorCodes& error_code)
84  {
85  std::vector<std::string> link_names;
86  link_names.push_back("r_elbow_flex_link");
87  std::vector<geometry_msgs::Pose> solutions;
88  solutions.resize(1);
89  if (!kinematics_solver_->getPositionFK(link_names, joint_state, solutions))
90  error_code.val = error_code.PLANNING_FAILED;
91  if (solutions[0].position.z > 0.0)
92  error_code.val = error_code.SUCCESS;
93  else
94  error_code.val = error_code.PLANNING_FAILED;
95  }
96 
98  std::shared_ptr<pluginlib::ClassLoader<kinematics::KinematicsBase> > kinematics_loader_;
99 };
100 
101 TEST_F(ArmIKPlugin, initialize)
102 {
103  // Test getting chain information
104  std::string root_name = kinematics_solver_->getBaseFrame();
105  EXPECT_TRUE(root_name == std::string("torso_lift_link"));
106  std::string tool_name = kinematics_solver_->getTipFrame();
107  EXPECT_TRUE(tool_name == std::string("r_wrist_roll_link"));
108  std::vector<std::string> joint_names = kinematics_solver_->getJointNames();
109  EXPECT_EQ((int)joint_names.size(), 7);
110 
111  EXPECT_EQ(joint_names[0], "r_shoulder_pan_joint");
112  EXPECT_EQ(joint_names[1], "r_shoulder_lift_joint");
113  EXPECT_EQ(joint_names[2], "r_upper_arm_roll_joint");
114  EXPECT_EQ(joint_names[3], "r_elbow_flex_joint");
115  EXPECT_EQ(joint_names[4], "r_forearm_roll_joint");
116  EXPECT_EQ(joint_names[5], "r_wrist_flex_joint");
117  EXPECT_EQ(joint_names[6], "r_wrist_roll_joint");
118 }
119 
121 {
122  rdf_loader::RDFLoader rdf_loader_;
123  robot_model::RobotModelPtr kinematic_model;
124  const srdf::ModelSharedPtr& srdf = rdf_loader_.getSRDF();
125  const urdf::ModelInterfaceSharedPtr& urdf_model = rdf_loader_.getURDF();
126  kinematic_model.reset(new robot_model::RobotModel(urdf_model, srdf));
127  robot_model::JointModelGroup* joint_model_group =
128  kinematic_model->getJointModelGroup(kinematics_solver_->getGroupName());
129 
130  std::vector<double> seed, fk_values, solution;
131  moveit_msgs::MoveItErrorCodes error_code;
132  solution.resize(kinematics_solver_->getJointNames().size(), 0.0);
133 
134  std::vector<std::string> fk_names;
135  fk_names.push_back(kinematics_solver_->getTipFrame());
136 
137  robot_state::RobotState kinematic_state(kinematic_model);
138 
139  ros::NodeHandle nh("~");
140  int number_fk_tests;
141  nh.param("number_fk_tests", number_fk_tests, 100);
142 
143  for (unsigned int i = 0; i < (unsigned int)number_fk_tests; ++i)
144  {
145  seed.resize(kinematics_solver_->getJointNames().size(), 0.0);
146  fk_values.resize(kinematics_solver_->getJointNames().size(), 0.0);
147 
148  kinematic_state.setToRandomPositions(joint_model_group);
149  kinematic_state.copyJointGroupPositions(joint_model_group, fk_values);
150 
151  std::vector<geometry_msgs::Pose> poses;
152  poses.resize(1);
153  bool result_fk = kinematics_solver_->getPositionFK(fk_names, fk_values, poses);
154  ASSERT_TRUE(result_fk);
155  }
156 }
157 
158 TEST_F(ArmIKPlugin, searchIK)
159 {
160  rdf_loader::RDFLoader rdf_loader_;
161  robot_model::RobotModelPtr kinematic_model;
162  const srdf::ModelSharedPtr& srdf_model = rdf_loader_.getSRDF();
163  const urdf::ModelInterfaceSharedPtr& urdf_model = rdf_loader_.getURDF();
164  kinematic_model.reset(new robot_model::RobotModel(urdf_model, srdf_model));
165  robot_model::JointModelGroup* joint_model_group =
166  kinematic_model->getJointModelGroup(kinematics_solver_->getGroupName());
167 
168  // Test inverse kinematics
169  std::vector<double> seed, fk_values, solution;
170  double timeout = 5.0;
171  moveit_msgs::MoveItErrorCodes error_code;
172  solution.resize(kinematics_solver_->getJointNames().size(), 0.0);
173 
174  std::vector<std::string> fk_names;
175  fk_names.push_back(kinematics_solver_->getTipFrame());
176 
177  robot_state::RobotState kinematic_state(kinematic_model);
178  // robot_state::JointStateGroup* joint_state_group =
179  // kinematic_state.getJointStateGroup(kinematics_solver_->getGroupName());
180 
181  ros::NodeHandle nh("~");
182  int number_ik_tests;
183  nh.param("number_ik_tests", number_ik_tests, 10);
184  unsigned int success = 0;
185 
186  ros::WallTime start_time = ros::WallTime::now();
187  for (unsigned int i = 0; i < (unsigned int)number_ik_tests; ++i)
188  {
189  seed.resize(kinematics_solver_->getJointNames().size(), 0.0);
190  fk_values.resize(kinematics_solver_->getJointNames().size(), 0.0);
191 
192  kinematic_state.setToRandomPositions(joint_model_group);
193  kinematic_state.copyJointGroupPositions(joint_model_group, fk_values);
194 
195  std::vector<geometry_msgs::Pose> poses;
196  poses.resize(1);
197  bool result_fk = kinematics_solver_->getPositionFK(fk_names, fk_values, poses);
198  ASSERT_TRUE(result_fk);
199 
200  bool result = kinematics_solver_->searchPositionIK(poses[0], seed, timeout, solution, error_code);
201  ROS_DEBUG("Pose: %f %f %f", poses[0].position.x, poses[0].position.y, poses[0].position.z);
202  ROS_DEBUG("Orient: %f %f %f %f", poses[0].orientation.x, poses[0].orientation.y, poses[0].orientation.z,
203  poses[0].orientation.w);
204  if (result)
205  {
206  success++;
207  result = kinematics_solver_->getPositionIK(poses[0], solution, solution, error_code);
208  EXPECT_TRUE(result);
209  }
210 
211  std::vector<geometry_msgs::Pose> new_poses;
212  new_poses.resize(1);
213  result_fk = kinematics_solver_->getPositionFK(fk_names, solution, new_poses);
214 
215  EXPECT_NEAR(poses[0].position.x, new_poses[0].position.x, IK_NEAR);
216  EXPECT_NEAR(poses[0].position.y, new_poses[0].position.y, IK_NEAR);
217  EXPECT_NEAR(poses[0].position.z, new_poses[0].position.z, IK_NEAR);
218 
219  EXPECT_NEAR(poses[0].orientation.x, new_poses[0].orientation.x, IK_NEAR);
220  EXPECT_NEAR(poses[0].orientation.y, new_poses[0].orientation.y, IK_NEAR);
221  EXPECT_NEAR(poses[0].orientation.z, new_poses[0].orientation.z, IK_NEAR);
222  EXPECT_NEAR(poses[0].orientation.w, new_poses[0].orientation.w, IK_NEAR);
223  }
224  ROS_INFO("Success Rate: %f", (double)success / number_ik_tests);
225  bool success_count = (success > 0.99 * number_ik_tests);
226  EXPECT_TRUE(success_count);
227  ROS_INFO("Elapsed time: %f", (ros::WallTime::now() - start_time).toSec());
228 }
229 
230 TEST_F(ArmIKPlugin, searchIKWithCallbacks)
231 {
232  rdf_loader::RDFLoader rdf_loader_;
233  robot_model::RobotModelPtr kinematic_model;
234  const srdf::ModelSharedPtr& srdf = rdf_loader_.getSRDF();
235  const urdf::ModelInterfaceSharedPtr& urdf_model = rdf_loader_.getURDF();
236  kinematic_model.reset(new robot_model::RobotModel(urdf_model, srdf));
237  robot_model::JointModelGroup* joint_model_group =
238  kinematic_model->getJointModelGroup(kinematics_solver_->getGroupName());
239 
240  // Test inverse kinematics
241  std::vector<double> seed, fk_values, solution;
242  double timeout = 5.0;
243  moveit_msgs::MoveItErrorCodes error_code;
244  solution.resize(kinematics_solver_->getJointNames().size(), 0.0);
245 
246  std::vector<std::string> fk_names;
247  fk_names.push_back(kinematics_solver_->getTipFrame());
248 
249  robot_state::RobotState kinematic_state(kinematic_model);
250 
251  ros::NodeHandle nh("~");
252  int number_ik_tests;
253  nh.param("number_ik_tests_with_callbacks", number_ik_tests, 10);
254  unsigned int success = 0;
255  unsigned int num_actual_tests = 0;
256 
257  for (unsigned int i = 0; i < (unsigned int)number_ik_tests; ++i)
258  {
259  seed.resize(kinematics_solver_->getJointNames().size(), 0.0);
260  fk_values.resize(kinematics_solver_->getJointNames().size(), 0.0);
261 
262  kinematic_state.setToRandomPositions(joint_model_group);
263  kinematic_state.copyJointGroupPositions(joint_model_group, fk_values);
264 
265  std::vector<geometry_msgs::Pose> poses;
266  poses.resize(1);
267  bool result_fk = kinematics_solver_->getPositionFK(fk_names, fk_values, poses);
268  ASSERT_TRUE(result_fk);
269  if (poses[0].position.z < 0.0)
270  continue;
271 
272  num_actual_tests++;
273  bool result = kinematics_solver_->searchPositionIK(
274  poses[0], seed, timeout, solution, boost::bind(&ArmIKPlugin::joint_state_callback, this, _1, _2, _3),
275  error_code);
276 
277  if (result)
278  {
279  success++;
280  std::vector<geometry_msgs::Pose> new_poses;
281  new_poses.resize(1);
282  result_fk = kinematics_solver_->getPositionFK(fk_names, solution, new_poses);
283 
284  EXPECT_NEAR(poses[0].position.x, new_poses[0].position.x, IK_NEAR);
285  EXPECT_NEAR(poses[0].position.y, new_poses[0].position.y, IK_NEAR);
286  EXPECT_NEAR(poses[0].position.z, new_poses[0].position.z, IK_NEAR);
287 
288  EXPECT_NEAR(poses[0].orientation.x, new_poses[0].orientation.x, IK_NEAR);
289  EXPECT_NEAR(poses[0].orientation.y, new_poses[0].orientation.y, IK_NEAR);
290  EXPECT_NEAR(poses[0].orientation.z, new_poses[0].orientation.z, IK_NEAR);
291  EXPECT_NEAR(poses[0].orientation.w, new_poses[0].orientation.w, IK_NEAR);
292  }
293 
294  if (!ros::ok())
295  break;
296  }
297  ROS_INFO("Success with callbacks (%%): %f", (double)success / num_actual_tests * 100.0);
298 }
299 
300 int main(int argc, char** argv)
301 {
302  testing::InitGoogleTest(&argc, argv);
303  ros::init(argc, argv, "right_arm_kinematics");
304  return RUN_ALL_TESTS();
305 }
TEST_F(ArmIKPlugin, initialize)
void joint_state_callback(const geometry_msgs::Pose &ik_pose, const std::vector< double > &joint_state, moveit_msgs::MoveItErrorCodes &error_code)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::shared_ptr< pluginlib::ClassLoader< kinematics::KinematicsBase > > kinematics_loader_
#define EXPECT_NEAR(a, b, prec)
#define IK_NEAR
#define ROS_DEBUG(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
#define EXPECT_EQ(a, b)
#define ROS_INFO(...)
bool getParam(const std::string &key, std::string &s) const
ROSCPP_DECL bool ok()
const srdf::ModelSharedPtr & getSRDF() const
const urdf::ModelInterfaceSharedPtr & getURDF() const
int main(int argc, char **argv)
std::shared_ptr< Model > ModelSharedPtr
static WallTime now()
#define EXPECT_TRUE(args)
boost::shared_ptr< kinematics::KinematicsBase > kinematics_solver_


pr2_moveit_tests
Author(s): Sachin Chitta
autogenerated on Mon Feb 28 2022 22:51:36