37#include <geometry_msgs/msg/pose_stamped.hpp>
38#include <kdl_parser/kdl_parser.hpp>
39#include <tf2_kdl/tf2_kdl.hpp>
56 return moveit::getLogger(
"moveit.core.moveit_constraint_samplers.test.pr2_arm_kinematics_plugin");
60bool PR2ArmIKSolver::getCount(
int& count,
int max_count,
int min_count)
64 if (-count >= min_count)
69 else if (count + 1 <= max_count)
81 if (1 - count <= max_count)
86 else if (count - 1 >= min_count)
97 const std::string& tip_frame_name,
double search_discretization_angle,
int free_angle)
100 search_discretization_angle_ = search_discretization_angle;
101 free_angle_ = free_angle;
102 root_frame_name_ = root_frame_name;
114 const bool verbose =
false;
116 std::vector<std::vector<double> > solution_ik;
117 if (free_angle_ == 0)
120 RCLCPP_WARN(getLogger(),
"Solving with %f", q_init(0));
128 if (solution_ik.empty())
131 double min_distance = 1e6;
134 for (
int i = 0; i < static_cast<int>(solution_ik.size()); ++i)
138 RCLCPP_WARN(getLogger(),
"Solution : %d",
static_cast<int>(solution_ik.size()));
140 for (
int j = 0; j < static_cast<int>(solution_ik[i].size()); ++j)
142 RCLCPP_WARN(getLogger(),
"%d: %f", j, solution_ik[i][j]);
146 if (tmp_distance < min_distance)
148 min_distance = tmp_distance;
155 q_out.resize(
static_cast<int>(solution_ik[min_index].size()));
156 for (
int i = 0; i < static_cast<int>(solution_ik[min_index].size()); ++i)
158 q_out(i) = solution_ik[min_index][i];
169 const bool verbose =
false;
170 KDL::JntArray q_init = q_in;
171 double initial_guess = q_init(free_angle_);
173 rclcpp::Time start_time = rclcpp::Clock(RCL_ROS_TIME).now();
174 double loop_time = 0;
177 int num_positive_increments =
static_cast<int>(
179 int num_negative_increments =
static_cast<int>(
183 RCLCPP_WARN(getLogger(),
"%f %f %f %d %d \n\n", initial_guess,
186 num_negative_increments);
188 while (loop_time < timeout)
192 if (!getCount(count, num_positive_increments, -num_negative_increments))
194 q_init(free_angle_) = initial_guess + search_discretization_angle_ * count;
196 RCLCPP_WARN(getLogger(),
"%d, %f", count, q_init(free_angle_));
197 loop_time = rclcpp::Clock(RCL_ROS_TIME).now().seconds() - start_time.seconds();
199 if (loop_time >= timeout)
201 RCLCPP_WARN(getLogger(),
"IK Timed out in %f seconds", timeout);
206 RCLCPP_WARN(getLogger(),
"No IK solution was found");
207 return NO_IK_SOLUTION;
209 return NO_IK_SOLUTION;
212bool getKDLChain(
const urdf::ModelInterface& model,
const std::string& root_name,
const std::string& tip_name,
213 KDL::Chain& kdl_chain)
217 if (!kdl_parser::treeFromUrdfModel(model, tree))
219 RCLCPP_ERROR(getLogger(),
"Could not initialize tree object");
222 if (!tree.getChain(root_name, tip_name, kdl_chain))
224 RCLCPP_ERROR(getLogger(),
"Could not initialize chain object for base %s tip %s", root_name.c_str(),
233 Eigen::Isometry3f b = Eigen::Isometry3f::Identity();
234 for (
int i = 0; i < 3; ++i)
236 for (
int j = 0; j < 3; ++j)
248 for (
int i = 0; i < static_cast<int>(array_1.size()); ++i)
250 distance += (array_1[i] - array_2(i)) * (array_1[i] - array_2(i));
255void getKDLChainInfo(
const KDL::Chain& chain, moveit_msgs::msg::KinematicSolverInfo& chain_info)
258 while (i <
static_cast<int>(chain.getNrOfSegments()))
260 chain_info.link_names.push_back(chain.getSegment(i).getName());
276 const std::string& base_frame,
const std::vector<std::string>& tip_frames,
277 double search_discretization)
280 storeValues(robot_model, group_name, base_frame, tip_frames, search_discretization);
281 const bool verbose =
false;
282 std::string xml_string;
285 RCLCPP_WARN(getLogger(),
"Loading KDL Tree");
289 RCLCPP_ERROR(getLogger(),
"Could not load kdl tree");
298 RCLCPP_ERROR(getLogger(),
"Could not load ik");
311 RCLCPP_WARN(getLogger(),
"PR2Kinematics:: joint name: %s", joint_name.c_str());
315 RCLCPP_WARN(getLogger(),
"PR2Kinematics can solve IK for %s", link_name.c_str());
319 RCLCPP_WARN(getLogger(),
"PR2Kinematics can solve FK for %s", link_name.c_str());
321 RCLCPP_WARN(getLogger(),
"PR2KinematicsPlugin::active for %s", group_name.c_str());
329 const std::vector<double>& ,
330 std::vector<double>& ,
331 moveit_msgs::msg::MoveItErrorCodes& ,
338 const std::vector<double>& ik_seed_state,
double timeout,
339 std::vector<double>& solution,
340 moveit_msgs::msg::MoveItErrorCodes& error_code,
345 RCLCPP_ERROR(getLogger(),
"kinematics not active");
346 error_code.val = error_code.PLANNING_FAILED;
350 geometry_msgs::msg::PoseStamped ik_pose_stamped;
351 ik_pose_stamped.pose = ik_pose;
353 tf2::Stamped<KDL::Frame> pose_desired;
355 tf2::fromMsg(ik_pose_stamped, pose_desired);
358 KDL::JntArray jnt_pos_in;
359 KDL::JntArray jnt_pos_out;
363 jnt_pos_in(i) = ik_seed_state[i];
366 int ik_valid =
pr2_arm_ik_solver_->cartToJntSearch(jnt_pos_in, pose_desired, jnt_pos_out, timeout);
367 if (ik_valid == pr2_arm_kinematics::NO_IK_SOLUTION)
369 error_code.val = error_code.NO_IK_SOLUTION;
378 solution[i] = jnt_pos_out(i);
380 error_code.val = error_code.SUCCESS;
385 RCLCPP_WARN(getLogger(),
"An IK solution could not be found");
386 error_code.val = error_code.NO_IK_SOLUTION;
392 const std::vector<double>& ,
double ,
393 const std::vector<double>& ,
394 std::vector<double>& ,
395 moveit_msgs::msg::MoveItErrorCodes& ,
402 const std::vector<double>& ,
double ,
403 std::vector<double>& ,
405 moveit_msgs::msg::MoveItErrorCodes& ,
412 const std::vector<double>& ,
double ,
413 const std::vector<double>& ,
414 std::vector<double>& ,
416 moveit_msgs::msg::MoveItErrorCodes& ,
423 const std::vector<double>& ,
424 std::vector<geometry_msgs::msg::Pose>& )
const
433 RCLCPP_ERROR(getLogger(),
"kinematics not active");
442 RCLCPP_ERROR(getLogger(),
"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)
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, 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.
PR2ArmIKSolver(const urdf::ModelInterface &robot_model, const std::string &root_frame_name, const std::string &tip_frame_name, double search_discretization_angle, int free_angle)
void computeIKShoulderRoll(const Eigen::Isometry3f &g_in, 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, 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....
rclcpp::Logger getLogger()
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
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)
Eigen::Isometry3f kdlToEigenMatrix(const KDL::Frame &p)
A set of options for the kinematics solver.