Skip to content

Commit 3b83598

Browse files
committed
refactor logic to handle ik_frame
fallbacks and verification.
1 parent f1fc447 commit 3b83598

File tree

4 files changed

+77
-67
lines changed

4 files changed

+77
-67
lines changed

core/include/moveit/task_constructor/utils.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,25 @@
4242
#include <type_traits>
4343
#include <initializer_list>
4444

45+
#include <Eigen/Geometry>
46+
47+
#include <moveit/macros/class_forward.h>
48+
49+
namespace planning_scene {
50+
MOVEIT_CLASS_FORWARD(PlanningScene);
51+
}
52+
4553
namespace moveit {
4654

4755
namespace core {
48-
class LinkModel;
49-
class RobotState;
56+
MOVEIT_CLASS_FORWARD(LinkModel);
57+
MOVEIT_CLASS_FORWARD(JointModelGroup);
58+
MOVEIT_CLASS_FORWARD(RobotState);
5059
} // namespace core
5160

5261
namespace task_constructor {
62+
MOVEIT_CLASS_FORWARD(Property);
63+
MOVEIT_CLASS_FORWARD(SolutionBase);
5364

5465
namespace utils {
5566

@@ -133,6 +144,10 @@ class Flags
133144

134145
const moveit::core::LinkModel* getRigidlyConnectedParentLinkModel(const moveit::core::RobotState& state,
135146
std::string frame);
147+
148+
bool getRobotTipForFrame(const Property& property, const planning_scene::PlanningScene& scene,
149+
const moveit::core::JointModelGroup* jmg, SolutionBase& solution,
150+
const moveit::core::LinkModel*& robot_link, Eigen::Isometry3d& tip_in_global_frame);
136151
} // namespace utils
137152
} // namespace task_constructor
138153
} // namespace moveit

core/src/stages/move_relative.cpp

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -193,24 +193,11 @@ bool MoveRelative::compute(const InterfaceState& state, planning_scene::Planning
193193
success = planner_->plan(state.scene(), scene, jmg, timeout, robot_trajectory, path_constraints);
194194
} else {
195195
// Cartesian targets require an IK reference frame
196-
geometry_msgs::PoseStamped ik_pose_msg;
197196
const moveit::core::LinkModel* link;
198-
const boost::any& value = props.get("ik_frame");
199-
if (value.empty()) { // property undefined
200-
// determine IK link from group
201-
if (!(link = jmg->getOnlyOneEndEffectorTip())) {
202-
solution.markAsFailure("missing ik_frame");
203-
return false;
204-
}
205-
ik_pose_msg.header.frame_id = link->getName();
206-
ik_pose_msg.pose.orientation.w = 1.0;
207-
} else {
208-
ik_pose_msg = boost::any_cast<geometry_msgs::PoseStamped>(value);
209-
if (!(link = robot_model->getLinkModel(ik_pose_msg.header.frame_id))) {
210-
solution.markAsFailure("unknown link for ik_frame: " + ik_pose_msg.header.frame_id);
211-
return false;
212-
}
213-
}
197+
Eigen::Isometry3d ik_pose_world;
198+
199+
if (!utils::getRobotTipForFrame(props.property("ik_frame"), *scene, jmg, solution, link, ik_pose_world))
200+
return false;
214201

215202
bool use_rotation_distance = false; // measure achieved distance as rotation?
216203
Eigen::Vector3d linear; // linear translation
@@ -291,9 +278,7 @@ bool MoveRelative::compute(const InterfaceState& state, planning_scene::Planning
291278

292279
COMPUTE:
293280
// transform target pose such that ik frame will reach there if link does
294-
Eigen::Isometry3d ik_pose;
295-
tf2::fromMsg(ik_pose_msg.pose, ik_pose);
296-
target_eigen = target_eigen * ik_pose.inverse();
281+
target_eigen = target_eigen * scene->getCurrentState().getGlobalLinkTransform(link).inverse() * ik_pose_world;
297282

298283
success = planner_->plan(state.scene(), *link, target_eigen, jmg, timeout, robot_trajectory, path_constraints);
299284

core/src/stages/move_to.cpp

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -208,44 +208,10 @@ bool MoveTo::compute(const InterfaceState& state, planning_scene::PlanningSceneP
208208
// What frame+offset in the robot should go there?
209209
geometry_msgs::PoseStamped ik_pose_msg;
210210

211-
const boost::any& value = props.get("ik_frame");
212-
213-
auto get_tip{ [&jmg](std::string& out) {
214-
// determine IK frame from group
215-
std::vector<std::string> tips;
216-
jmg->getEndEffectorTips(tips);
217-
if (tips.size() != 1) {
218-
return false;
219-
}
220-
out = tips[0];
221-
return true;
222-
} };
223-
224-
if (value.empty()) { // property undefined
225-
if (!get_tip(ik_pose_msg.header.frame_id)) {
226-
solution.markAsFailure("missing ik_frame");
227-
return false;
228-
}
229-
ik_pose_msg.pose.orientation.w = 1.0;
230-
} else {
231-
ik_pose_msg = boost::any_cast<geometry_msgs::PoseStamped>(value);
232-
if (ik_pose_msg.header.frame_id.empty() && !get_tip(ik_pose_msg.header.frame_id)) {
233-
solution.markAsFailure("frame_id of ik_frame is empty and no unique group tip was found");
234-
return false;
235-
} else if (!scene->knowsFrameTransform(ik_pose_msg.header.frame_id)) {
236-
std::stringstream ss;
237-
ss << "ik_frame specified in unknown frame '" << ik_pose_msg << "'";
238-
solution.markAsFailure(ss.str());
239-
return false;
240-
}
241-
}
242-
243-
Eigen::Isometry3d ik_pose_world{ [&]() {
244-
Eigen::Isometry3d t;
245-
tf2::fromMsg(ik_pose_msg.pose, t);
246-
t = scene->getFrameTransform(ik_pose_msg.header.frame_id) * t;
247-
return t;
248-
}() };
211+
const moveit::core::LinkModel* link;
212+
Eigen::Isometry3d ik_pose_world;
213+
if (!utils::getRobotTipForFrame(props.property("ik_frame"), *scene, jmg, solution, link, ik_pose_world))
214+
return false;
249215

250216
if (!getPoseGoal(goal, scene, target) && !getPointGoal(goal, ik_pose_world, scene, target)) {
251217
solution.markAsFailure(std::string("invalid goal type: ") + goal.type().name());
@@ -263,16 +229,11 @@ bool MoveTo::compute(const InterfaceState& state, planning_scene::PlanningSceneP
263229
add_frame(target, "target frame");
264230
add_frame(ik_pose_world, "ik frame");
265231

266-
const moveit::core::LinkModel* parent{ utils::getRigidlyConnectedParentLinkModel(scene->getCurrentState(),
267-
ik_pose_msg.header.frame_id) };
268-
269232
// transform target pose such that ik frame will reach there if link does
270-
Eigen::Isometry3d ik_pose;
271-
tf2::fromMsg(ik_pose_msg.pose, ik_pose);
272-
target = target * ik_pose_world.inverse() * scene->getFrameTransform(parent->getName());
233+
target = target * ik_pose_world.inverse() * scene->getCurrentState().getGlobalLinkTransform(link);
273234

274235
// plan to Cartesian target
275-
success = planner_->plan(state.scene(), *parent, target, jmg, timeout, robot_trajectory, path_constraints);
236+
success = planner_->plan(state.scene(), *link, target, jmg, timeout, robot_trajectory, path_constraints);
276237
}
277238

278239
// store result

core/src/utils.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,14 @@
3535

3636
/* Authors: Michael Goerner, Robert Haschke */
3737

38+
#include <tf2_eigen/tf2_eigen.h>
39+
3840
#include <moveit/robot_state/robot_state.h>
41+
#include <moveit/planning_scene/planning_scene.h>
3942

4043
#include <moveit/task_constructor/moveit_compat.h>
44+
#include <moveit/task_constructor/properties.h>
45+
#include <moveit/task_constructor/storage.h>
4146

4247
namespace moveit {
4348
namespace task_constructor {
@@ -59,6 +64,50 @@ const moveit::core::LinkModel* getRigidlyConnectedParentLinkModel(const moveit::
5964
#endif
6065
}
6166

67+
bool getRobotTipForFrame(const Property& property, const planning_scene::PlanningScene& scene,
68+
const moveit::core::JointModelGroup* jmg, SolutionBase& solution,
69+
const moveit::core::LinkModel*& robot_link, Eigen::Isometry3d& tip_in_global_frame) {
70+
auto get_tip = [&jmg]() -> const moveit::core::LinkModel* {
71+
// determine IK frame from group
72+
std::vector<const moveit::core::LinkModel*> tips;
73+
jmg->getEndEffectorTips(tips);
74+
if (tips.size() != 1) {
75+
return nullptr;
76+
}
77+
return tips[0];
78+
};
79+
80+
if (property.value().empty()) { // property undefined
81+
robot_link = get_tip();
82+
if (!robot_link) {
83+
solution.markAsFailure("missing ik_frame");
84+
return false;
85+
}
86+
tip_in_global_frame = scene.getCurrentState().getGlobalLinkTransform(robot_link);
87+
} else {
88+
auto ik_pose_msg = boost::any_cast<geometry_msgs::PoseStamped>(property.value());
89+
if (ik_pose_msg.header.frame_id.empty()) {
90+
if (!(robot_link = get_tip())) {
91+
solution.markAsFailure("frame_id of ik_frame is empty and no unique group tip was found");
92+
return false;
93+
}
94+
tf2::fromMsg(ik_pose_msg.pose, tip_in_global_frame);
95+
tip_in_global_frame = scene.getCurrentState().getGlobalLinkTransform(robot_link) * tip_in_global_frame;
96+
} else if (scene.knowsFrameTransform(ik_pose_msg.header.frame_id)) {
97+
robot_link = getRigidlyConnectedParentLinkModel(scene.getCurrentState(), ik_pose_msg.header.frame_id);
98+
tf2::fromMsg(ik_pose_msg.pose, tip_in_global_frame);
99+
tip_in_global_frame = scene.getFrameTransform(ik_pose_msg.header.frame_id) * tip_in_global_frame;
100+
} else {
101+
std::stringstream ss;
102+
ss << "ik_frame specified in unknown frame '" << ik_pose_msg << "'";
103+
solution.markAsFailure(ss.str());
104+
return false;
105+
}
106+
}
107+
108+
return true;
109+
}
110+
62111
} // namespace utils
63112
} // namespace task_constructor
64113
} // namespace moveit

0 commit comments

Comments
 (0)