37 #include <geometry_msgs/msg/pose_stamped.hpp>
38 #include <kdl_parser/kdl_parser.hpp>
39 #include <tf2_kdl/tf2_kdl.hpp>
51 static const rclcpp::Logger LOGGER = rclcpp::get_logger(
"moveit_constraint_samplers.test.pr2_arm_kinematics_plugin");
53 bool PR2ArmIKSolver::getCount(
int& count,
const int& max_count,
const int& min_count)
57 if (-count >= min_count)
62 else if (count + 1 <= max_count)
74 if (1 - count <= max_count)
79 else if (count - 1 >= min_count)
89 PR2ArmIKSolver::PR2ArmIKSolver(
const urdf::ModelInterface& robot_model,
const std::string& root_frame_name,
90 const std::string& tip_frame_name,
const double& search_discretization_angle,
91 const int& free_angle)
94 search_discretization_angle_ = search_discretization_angle;
95 free_angle_ = free_angle;
96 root_frame_name_ = root_frame_name;
108 const bool verbose =
false;
110 std::vector<std::vector<double> > solution_ik;
111 if (free_angle_ == 0)
114 RCLCPP_WARN(LOGGER,
"Solving with %f", q_init(0));
122 if (solution_ik.empty())
125 double min_distance = 1e6;
128 for (
int i = 0; i < static_cast<int>(solution_ik.size()); ++i)
132 RCLCPP_WARN(LOGGER,
"Solution : %d",
static_cast<int>(solution_ik.size()));
134 for (
int j = 0; j < static_cast<int>(solution_ik[i].size()); ++j)
136 RCLCPP_WARN(LOGGER,
"%d: %f", j, solution_ik[i][j]);
138 RCLCPP_WARN(LOGGER,
" ");
139 RCLCPP_WARN(LOGGER,
" ");
142 if (tmp_distance < min_distance)
144 min_distance = tmp_distance;
151 q_out.resize(
static_cast<int>(solution_ik[min_index].size()));
152 for (
int i = 0; i < static_cast<int>(solution_ik[min_index].size()); ++i)
154 q_out(i) = solution_ik[min_index][i];
163 const double& timeout)
165 const bool verbose =
false;
166 KDL::JntArray q_init = q_in;
167 double initial_guess = q_init(free_angle_);
169 rclcpp::Time start_time = rclcpp::Clock(RCL_ROS_TIME).now();
170 double loop_time = 0;
173 int num_positive_increments =
static_cast<int>(
175 int num_negative_increments =
static_cast<int>(
178 RCLCPP_WARN(LOGGER,
"%f %f %f %d %d \n\n", initial_guess,
pr2_arm_ik_.
solver_info_.limits[free_angle_].max_position,
180 num_negative_increments);
181 while (loop_time < timeout)
185 if (!getCount(count, num_positive_increments, -num_negative_increments))
187 q_init(free_angle_) = initial_guess + search_discretization_angle_ * count;
189 RCLCPP_WARN(LOGGER,
"%d, %f", count, q_init(free_angle_));
190 loop_time = rclcpp::Clock(RCL_ROS_TIME).now().seconds() - start_time.seconds();
192 if (loop_time >= timeout)
194 RCLCPP_WARN(LOGGER,
"IK Timed out in %f seconds", timeout);
199 RCLCPP_WARN(LOGGER,
"No IK solution was found");
200 return NO_IK_SOLUTION;
202 return NO_IK_SOLUTION;
205 bool getKDLChain(
const urdf::ModelInterface& model,
const std::string& root_name,
const std::string& tip_name,
206 KDL::Chain& kdl_chain)
210 if (!kdl_parser::treeFromUrdfModel(model, tree))
212 RCLCPP_ERROR(LOGGER,
"Could not initialize tree object");
215 if (!tree.getChain(root_name, tip_name, kdl_chain))
217 RCLCPP_ERROR(LOGGER,
"Could not initialize chain object for base %s tip %s", root_name.c_str(), tip_name.c_str());
225 Eigen::Isometry3f b = Eigen::Isometry3f::Identity();
226 for (
int i = 0; i < 3; ++i)
228 for (
int j = 0; j < 3; ++j)
240 for (
int i = 0; i < static_cast<int>(array_1.size()); ++i)
242 distance += (array_1[i] - array_2(i)) * (array_1[i] - array_2(i));
247 void getKDLChainInfo(
const KDL::Chain& chain, moveit_msgs::msg::KinematicSolverInfo& chain_info)
250 while (i <
static_cast<int>(chain.getNrOfSegments()))
252 chain_info.link_names.push_back(chain.getSegment(i).getName());
268 const std::string& base_frame,
const std::vector<std::string>& tip_frames,
269 double search_discretization)
272 storeValues(robot_model, group_name, base_frame, tip_frames, search_discretization);
273 const bool verbose =
false;
274 std::string xml_string;
277 RCLCPP_WARN(
LOGGER,
"Loading KDL Tree");
281 RCLCPP_ERROR(
LOGGER,
"Could not load kdl tree");
290 RCLCPP_ERROR(
LOGGER,
"Could not load ik");
303 RCLCPP_WARN(
LOGGER,
"PR2Kinematics:: joint name: %s", joint_name.c_str());
307 RCLCPP_WARN(
LOGGER,
"PR2Kinematics can solve IK for %s", link_name.c_str());
311 RCLCPP_WARN(
LOGGER,
"PR2Kinematics can solve FK for %s", link_name.c_str());
313 RCLCPP_WARN(
LOGGER,
"PR2KinematicsPlugin::active for %s", group_name.c_str());
321 const std::vector<double>& ,
322 std::vector<double>& ,
323 moveit_msgs::msg::MoveItErrorCodes& ,
330 const std::vector<double>& ik_seed_state,
double timeout,
331 std::vector<double>& solution,
332 moveit_msgs::msg::MoveItErrorCodes& error_code,
337 RCLCPP_ERROR(
LOGGER,
"kinematics not active");
338 error_code.val = error_code.PLANNING_FAILED;
342 geometry_msgs::msg::PoseStamped ik_pose_stamped;
343 ik_pose_stamped.pose = ik_pose;
345 tf2::Stamped<KDL::Frame> pose_desired;
347 tf2::fromMsg(ik_pose_stamped, pose_desired);
350 KDL::JntArray jnt_pos_in;
351 KDL::JntArray jnt_pos_out;
355 jnt_pos_in(i) = ik_seed_state[i];
358 int ik_valid =
pr2_arm_ik_solver_->cartToJntSearch(jnt_pos_in, pose_desired, jnt_pos_out, timeout);
359 if (ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
361 error_code.val = error_code.NO_IK_SOLUTION;
370 solution[i] = jnt_pos_out(i);
372 error_code.val = error_code.SUCCESS;
377 RCLCPP_WARN(
LOGGER,
"An IK solution could not be found");
378 error_code.val = error_code.NO_IK_SOLUTION;
384 const std::vector<double>& ,
double ,
385 const std::vector<double>& ,
386 std::vector<double>& ,
387 moveit_msgs::msg::MoveItErrorCodes& ,
394 const std::vector<double>& ,
double ,
395 std::vector<double>& ,
397 moveit_msgs::msg::MoveItErrorCodes& ,
404 const std::vector<double>& ,
double ,
405 const std::vector<double>& ,
406 std::vector<double>& ,
408 moveit_msgs::msg::MoveItErrorCodes& ,
415 const std::vector<double>& ,
416 std::vector<geometry_msgs::msg::Pose>& )
const
425 RCLCPP_ERROR(
LOGGER,
"kinematics not active");
434 RCLCPP_ERROR(
LOGGER,
"kinematics not active");
void storeValues(const moveit::core::RobotModel &robot_model, const std::string &group_name, const std::string &base_frame, const std::vector< std::string > &tip_frames, double search_discretization)
static const rclcpp::Logger LOGGER
rclcpp::Node::SharedPtr node_
std::vector< std::string > tip_frames_
std::function< void(const geometry_msgs::msg::Pose &, const std::vector< double > &, moveit_msgs::msg::MoveItErrorCodes &)> IKCallbackFn
Signature for a callback to validate an IK solution. Typically used for collision checking.
Definition of a kinematic model. This class is not thread safe, however multiple instances can be cre...
const urdf::ModelInterfaceSharedPtr & getURDF() const
Get the parsed URDF model.
int cartToJntSearch(const KDL::JntArray &q_in, const KDL::Frame &p_in, KDL::JntArray &q_out, const double &timeout)
PR2ArmIK pr2_arm_ik_
The PR2 inverse kinematics solver.
void updateInternalDataStructures() override
int CartToJnt(const KDL::JntArray &q_init, const KDL::Frame &p_in, KDL::JntArray &q_out) override
bool active_
Indicates whether the solver has been successfully initialized.
void computeIKShoulderRoll(const Eigen::Isometry3f &g_in, const double &shoulder_roll_initial_guess, std::vector< std::vector< double > > &solution) const
compute IK based on an initial guess for the shoulder roll angle. h
bool init(const urdf::ModelInterface &robot_model, const std::string &root_name, const std::string &tip_name)
Initialize the solver by providing a urdf::Model and a root and tip name.
void computeIKShoulderPan(const Eigen::Isometry3f &g_in, const double &shoulder_pan_initial_guess, std::vector< std::vector< double > > &solution) const
compute IK based on an initial guess for the shoulder pan angle.
moveit_msgs::msg::KinematicSolverInfo solver_info_
get chain information about the arm.
bool isActive()
Specifies if the node is active or not.
moveit_msgs::msg::KinematicSolverInfo ik_solver_info_
const std::vector< std::string > & getJointNames() const override
Return all the joint names in the order they are used internally.
bool initialize(const rclcpp::Node::SharedPtr &node, const moveit::core::RobotModel &robot_model, const std::string &group_name, const std::string &base_frame, const std::vector< std::string > &tip_frames, double search_discretization) override
Initialization function for the kinematics.
const std::vector< std::string > & getLinkNames() const override
Return all the link names in the order they are represented internally.
pr2_arm_kinematics::PR2ArmIKSolverPtr pr2_arm_ik_solver_
moveit_msgs::msg::KinematicSolverInfo fk_solver_info_
bool getPositionIK(const geometry_msgs::msg::Pose &ik_pose, const std::vector< double > &ik_seed_state, std::vector< double > &solution, moveit_msgs::msg::MoveItErrorCodes &error_code, const kinematics::KinematicsQueryOptions &options=kinematics::KinematicsQueryOptions()) const override
Given a desired pose of the end-effector, compute the joint angles to reach it.
bool getPositionFK(const std::vector< std::string > &link_names, const std::vector< double > &joint_angles, std::vector< geometry_msgs::msg::Pose > &poses) const override
Given a set of joint angles and a set of links, compute their pose.
std::shared_ptr< KDL::ChainFkSolverPos_recursive > jnt_to_pose_solver_
bool searchPositionIK(const geometry_msgs::msg::Pose &ik_pose, const std::vector< double > &ik_seed_state, double timeout, std::vector< double > &solution, moveit_msgs::msg::MoveItErrorCodes &error_code, const kinematics::KinematicsQueryOptions &options=kinematics::KinematicsQueryOptions()) const override
Given a desired pose of the end-effector, search for the joint angles required to reach it....
Eigen::Isometry3f KDLToEigenMatrix(const KDL::Frame &p)
bool getKDLChain(const urdf::ModelInterface &model, const std::string &root_name, const std::string &tip_name, KDL::Chain &kdl_chain)
double distance(const urdf::Pose &transform)
void getKDLChainInfo(const KDL::Chain &chain, moveit_msgs::msg::KinematicSolverInfo &chain_info)
double computeEuclideanDistance(const std::vector< double > &array_1, const KDL::JntArray &array_2)
A set of options for the kinematics solver.