3737*/
3838
3939#include < moveit/task_constructor/solvers/cartesian_path.h>
40+ #include < moveit/task_constructor/utils.h>
4041#include < moveit/planning_scene/planning_scene.h>
4142#include < moveit/trajectory_processing/time_parameterization.h>
4243#include < moveit/kinematics_base/kinematics_base.h>
4344#include < moveit/robot_state/cartesian_interpolator.h>
45+ #include < tf2_eigen/tf2_eigen.h>
4446
4547using namespace trajectory_processing ;
4648
@@ -50,6 +52,7 @@ namespace solvers {
5052
5153CartesianPath::CartesianPath () {
5254 auto & p = properties ();
55+ p.declare <geometry_msgs::PoseStamped>(" ik_frame" , " frame to move linearly (use for joint-space target)" );
5356 p.declare <double >(" step_size" , 0.01 , " step size between consecutive waypoints" );
5457 p.declare <double >(" jump_threshold" , 1.5 , " acceptable fraction of mean joint motion per step" );
5558 p.declare <double >(" min_fraction" , 1.0 , " fraction of motion required for success" );
@@ -59,18 +62,31 @@ CartesianPath::CartesianPath() {
5962
6063void CartesianPath::init (const core::RobotModelConstPtr& /* robot_model*/ ) {}
6164
65+ void CartesianPath::setIKFrame (const Eigen::Isometry3d& pose, const std::string& link) {
66+ geometry_msgs::PoseStamped pose_msg;
67+ pose_msg.header .frame_id = link;
68+ pose_msg.pose = tf2::toMsg (pose);
69+ setIKFrame (pose_msg);
70+ }
71+
6272PlannerInterface::Result CartesianPath::plan (const planning_scene::PlanningSceneConstPtr& from,
6373 const planning_scene::PlanningSceneConstPtr& to,
6474 const moveit::core::JointModelGroup* jmg, double timeout,
6575 robot_trajectory::RobotTrajectoryPtr& result,
6676 const moveit_msgs::Constraints& path_constraints) {
67- const moveit::core::LinkModel* link = jmg->getOnlyOneEndEffectorTip ();
68- if (!link)
69- return { false , " no unique tip for joint model group: " + jmg->getName () };
77+ const auto & props = properties ();
78+ const moveit::core::LinkModel* link;
79+ std::string error_msg;
80+ Eigen::Isometry3d ik_pose_world;
81+
82+ if (!utils::getRobotTipForFrame (props.property (" ik_frame" ), *from, jmg, error_msg, link, ik_pose_world))
83+ return { false , error_msg };
84+
85+ Eigen::Isometry3d offset = from->getCurrentState ().getGlobalLinkTransform (link).inverse () * ik_pose_world;
7086
7187 // reach pose of forward kinematics
72- return plan (from, *link, Eigen::Isometry3d::Identity () , to->getCurrentState ().getGlobalLinkTransform (link), jmg,
73- std::min (timeout, properties () .get <double >(" timeout" )), result, path_constraints);
88+ return plan (from, *link, offset , to->getCurrentState ().getGlobalLinkTransform (link), jmg,
89+ std::min (timeout, props .get <double >(" timeout" )), result, path_constraints);
7490}
7591
7692PlannerInterface::Result CartesianPath::plan (const planning_scene::PlanningSceneConstPtr& from,
0 commit comments