48 const std::string
LOGNAME =
"kinematic_constraint_utils";
50 moveit_msgs::Constraints
mergeConstraints(
const moveit_msgs::Constraints& first,
const moveit_msgs::Constraints& second)
52 moveit_msgs::Constraints
r;
56 for (
const moveit_msgs::JointConstraint& jc_first : first.joint_constraints)
59 for (
const moveit_msgs::JointConstraint& jc_second : second.joint_constraints)
60 if (jc_second.joint_name == jc_first.joint_name)
64 moveit_msgs::JointConstraint m;
65 const moveit_msgs::JointConstraint& a = jc_first;
66 const moveit_msgs::JointConstraint& b = jc_second;
67 double low = std::max(a.position - a.tolerance_below, b.position - b.tolerance_below);
68 double high = std::min(a.position + a.tolerance_above, b.position + b.tolerance_above);
71 "Attempted to merge incompatible constraints for joint '%s'. Discarding constraint.",
72 a.joint_name.c_str());
75 m.joint_name = a.joint_name;
77 std::max(low, std::min((a.position * a.weight + b.position * b.weight) / (a.weight + b.weight), high));
78 m.weight = (a.weight + b.weight) / 2.0;
79 m.tolerance_above = std::max(0.0, high - m.position);
80 m.tolerance_below = std::max(0.0, m.position - low);
81 r.joint_constraints.push_back(m);
86 r.joint_constraints.push_back(jc_first);
90 for (
const moveit_msgs::JointConstraint& jc_second : second.joint_constraints)
93 for (
const moveit_msgs::JointConstraint& jc_first : first.joint_constraints)
94 if (jc_second.joint_name == jc_first.joint_name)
100 r.joint_constraints.push_back(jc_second);
104 r.position_constraints = first.position_constraints;
105 for (
const moveit_msgs::PositionConstraint& position_constraint : second.position_constraints)
106 r.position_constraints.push_back(position_constraint);
108 r.orientation_constraints = first.orientation_constraints;
109 for (
const moveit_msgs::OrientationConstraint& orientation_constraint : second.orientation_constraints)
110 r.orientation_constraints.push_back(orientation_constraint);
112 r.visibility_constraints = first.visibility_constraints;
113 for (
const moveit_msgs::VisibilityConstraint& visibility_constraint : second.visibility_constraints)
114 r.visibility_constraints.push_back(visibility_constraint);
119 bool isEmpty(
const moveit_msgs::Constraints& constr)
126 return constr.position_constraints.size() + constr.orientation_constraints.size() +
127 constr.visibility_constraints.size() + constr.joint_constraints.size();
138 double tolerance_above)
140 moveit_msgs::Constraints goal;
141 std::vector<double> vals;
143 goal.joint_constraints.resize(vals.size());
144 for (std::size_t i = 0; i < vals.size(); ++i)
147 goal.joint_constraints[i].position = vals[i];
148 goal.joint_constraints[i].tolerance_above = tolerance_above;
149 goal.joint_constraints[i].tolerance_below = tolerance_below;
150 goal.joint_constraints[i].weight = 1.0;
157 double tolerance_pos,
double tolerance_angle)
159 moveit_msgs::Constraints goal;
161 goal.position_constraints.resize(1);
162 moveit_msgs::PositionConstraint& pcm = goal.position_constraints[0];
163 pcm.link_name = link_name;
164 pcm.target_point_offset.x = 0;
165 pcm.target_point_offset.y = 0;
166 pcm.target_point_offset.z = 0;
167 pcm.constraint_region.primitives.resize(1);
168 shape_msgs::SolidPrimitive& bv = pcm.constraint_region.primitives[0];
169 bv.type = shape_msgs::SolidPrimitive::SPHERE;
170 bv.dimensions.resize(geometric_shapes::solidPrimitiveDimCount<shape_msgs::SolidPrimitive::SPHERE>());
171 bv.dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS] = tolerance_pos;
173 pcm.header = pose.header;
174 pcm.constraint_region.primitive_poses.resize(1);
175 pcm.constraint_region.primitive_poses[0].position = pose.pose.position;
178 pcm.constraint_region.primitive_poses[0].orientation.x = 0.0;
179 pcm.constraint_region.primitive_poses[0].orientation.y = 0.0;
180 pcm.constraint_region.primitive_poses[0].orientation.z = 0.0;
181 pcm.constraint_region.primitive_poses[0].orientation.w = 1.0;
184 goal.orientation_constraints.resize(1);
185 moveit_msgs::OrientationConstraint& ocm = goal.orientation_constraints[0];
186 ocm.parameterization = moveit_msgs::OrientationConstraint::ROTATION_VECTOR;
187 ocm.link_name = link_name;
188 ocm.header = pose.header;
189 ocm.orientation = pose.pose.orientation;
190 ocm.absolute_x_axis_tolerance = tolerance_angle;
191 ocm.absolute_y_axis_tolerance = tolerance_angle;
192 ocm.absolute_z_axis_tolerance = tolerance_angle;
199 const std::vector<double>& tolerance_pos,
200 const std::vector<double>& tolerance_angle)
203 if (tolerance_pos.size() == 3)
205 shape_msgs::SolidPrimitive& bv = goal.position_constraints[0].constraint_region.primitives[0];
206 bv.type = shape_msgs::SolidPrimitive::BOX;
207 bv.dimensions.resize(geometric_shapes::solidPrimitiveDimCount<shape_msgs::SolidPrimitive::BOX>());
208 bv.dimensions[shape_msgs::SolidPrimitive::BOX_X] = tolerance_pos[0];
209 bv.dimensions[shape_msgs::SolidPrimitive::BOX_Y] = tolerance_pos[1];
210 bv.dimensions[shape_msgs::SolidPrimitive::BOX_Z] = tolerance_pos[2];
212 if (tolerance_angle.size() == 3)
214 moveit_msgs::OrientationConstraint& ocm = goal.orientation_constraints[0];
215 ocm.absolute_x_axis_tolerance = tolerance_angle[0];
216 ocm.absolute_y_axis_tolerance = tolerance_angle[1];
217 ocm.absolute_z_axis_tolerance = tolerance_angle[2];
223 const geometry_msgs::QuaternionStamped& quat,
double tolerance)
225 moveit_msgs::Constraints goal;
226 goal.orientation_constraints.resize(1);
227 moveit_msgs::OrientationConstraint& ocm = goal.orientation_constraints[0];
228 ocm.link_name = link_name;
229 ocm.header = quat.header;
230 ocm.orientation = quat.quaternion;
231 ocm.absolute_x_axis_tolerance =
tolerance;
232 ocm.absolute_y_axis_tolerance =
tolerance;
233 ocm.absolute_z_axis_tolerance =
tolerance;
239 const geometry_msgs::PointStamped& goal_point,
double tolerance)
241 geometry_msgs::Point p;
249 const geometry_msgs::Point& reference_point,
250 const geometry_msgs::PointStamped& goal_point,
double tolerance)
252 moveit_msgs::Constraints goal;
253 goal.position_constraints.resize(1);
254 moveit_msgs::PositionConstraint& pcm = goal.position_constraints[0];
255 pcm.link_name = link_name;
256 pcm.target_point_offset.x = reference_point.x;
257 pcm.target_point_offset.y = reference_point.y;
258 pcm.target_point_offset.z = reference_point.z;
259 pcm.constraint_region.primitives.resize(1);
260 pcm.constraint_region.primitives[0].type = shape_msgs::SolidPrimitive::SPHERE;
261 pcm.constraint_region.primitives[0].dimensions.resize(
262 geometric_shapes::solidPrimitiveDimCount<shape_msgs::SolidPrimitive::SPHERE>());
263 pcm.constraint_region.primitives[0].dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS] =
tolerance;
265 pcm.header = goal_point.header;
266 pcm.constraint_region.primitive_poses.resize(1);
267 pcm.constraint_region.primitive_poses[0].position = goal_point.point;
270 pcm.constraint_region.primitive_poses[0].orientation.x = 0.0;
271 pcm.constraint_region.primitive_poses[0].orientation.y = 0.0;
272 pcm.constraint_region.primitive_poses[0].orientation.z = 0.0;
273 pcm.constraint_region.primitive_poses[0].orientation.w = 1.0;
281 if (!
isStruct(it->second, {
"frame_id",
"position",
"orientation" }, it->first))
283 pose.header.frame_id =
static_cast<std::string
>(it->second[
"frame_id"]);
285 if (!
isArray(it->second[
"orientation"], 3,
"orientation",
"RPY values"))
287 auto& rpy = it->second[
"orientation"];
290 pose.pose.orientation =
toMsg(q);
292 if (!
isArray(it->second[
"position"], 3,
"position",
"xyz position"))
294 pose.pose.position.x =
parseDouble(it->second[
"position"][0]);
295 pose.pose.position.y =
parseDouble(it->second[
"position"][1]);
296 pose.pose.position.z =
parseDouble(it->second[
"position"][2]);
305 if (it->first ==
"type")
307 else if (it->first ==
"joint_name")
308 constraint.joint_name =
static_cast<std::string
>(it->second);
309 else if (it->first ==
"weight")
311 else if (it->first ==
"position")
315 else if (it->first ==
"tolerance")
317 constraint.tolerance_below =
parseDouble(it->second);
318 constraint.tolerance_above =
parseDouble(it->second);
320 else if (it->first ==
"tolerances")
322 if (!
isArray(it->second, 2, it->first,
"lower/upper tolerances"))
325 constraint.tolerance_below =
parseDouble(it->second[0]);
326 constraint.tolerance_above =
parseDouble(it->second[1]);
328 else if (it->first ==
"bounds")
330 if (!
isArray(it->second, 2, it->first,
"lower/upper bound"))
333 const double lower_bound =
parseDouble(it->second[0]);
334 const double upper_bound =
parseDouble(it->second[1]);
336 constraint.position = (lower_bound + upper_bound) / 2;
337 constraint.tolerance_below = constraint.position - lower_bound;
338 constraint.tolerance_above = upper_bound - constraint.position;
352 if (it->first ==
"type")
354 else if (it->first ==
"frame_id")
355 constraint.header.frame_id =
static_cast<std::string
>(it->second);
356 else if (it->first ==
"weight")
358 else if (it->first ==
"link_name")
359 constraint.link_name =
static_cast<std::string
>(it->second);
360 else if (it->first ==
"target_offset")
362 if (!
isArray(it->second, 3, it->first,
"x/y/z position"))
365 constraint.target_point_offset.x =
parseDouble(it->second[0]);
366 constraint.target_point_offset.y =
parseDouble(it->second[1]);
367 constraint.target_point_offset.z =
parseDouble(it->second[2]);
369 else if (it->first ==
"region")
371 if (!
isStruct(it->second, {
"x",
"y",
"z" },
"region"))
374 constraint.constraint_region.primitive_poses.emplace_back();
375 constraint.constraint_region.primitives.emplace_back();
377 geometry_msgs::Pose& region_pose = constraint.constraint_region.primitive_poses.back();
378 shape_msgs::SolidPrimitive& region_primitive = constraint.constraint_region.primitives.back();
380 region_primitive.type = shape_msgs::SolidPrimitive::BOX;
381 region_primitive.dimensions.resize(3);
389 parse_dimension(it->second[
"x"], region_pose.position.x,
390 region_primitive.dimensions[shape_msgs::SolidPrimitive::BOX_X]);
391 parse_dimension(it->second[
"y"], region_pose.position.y,
392 region_primitive.dimensions[shape_msgs::SolidPrimitive::BOX_Y]);
393 parse_dimension(it->second[
"z"], region_pose.position.z,
394 region_primitive.dimensions[shape_msgs::SolidPrimitive::BOX_Z]);
396 region_pose.orientation.w = 1.0;
410 if (it->first ==
"type")
412 else if (it->first ==
"frame_id")
413 constraint.header.frame_id =
static_cast<std::string
>(it->second);
414 else if (it->first ==
"weight")
416 else if (it->first ==
"link_name")
417 constraint.link_name =
static_cast<std::string
>(it->second);
418 else if (it->first ==
"orientation")
420 if (!
isArray(it->second, 3, it->first,
"RPY values"))
425 constraint.orientation =
toMsg(q);
427 else if (it->first ==
"tolerances")
429 if (!
isArray(it->second, 3, it->first,
"xyz tolerances"))
432 constraint.absolute_x_axis_tolerance =
parseDouble(it->second[0]);
433 constraint.absolute_y_axis_tolerance =
parseDouble(it->second[1]);
434 constraint.absolute_z_axis_tolerance =
parseDouble(it->second[2]);
448 if (it->first ==
"type")
450 else if (it->first ==
"weight")
452 else if (it->first ==
"target_radius")
453 constraint.target_radius =
parseDouble(it->second);
454 else if (it->first ==
"target_pose")
459 else if (it->first ==
"cone_sides")
460 constraint.cone_sides =
static_cast<int>(it->second);
461 else if (it->first ==
"sensor_pose")
466 else if (it->first ==
"max_view_angle")
467 constraint.max_view_angle =
parseDouble(it->second);
468 else if (it->first ==
"max_range_angle")
469 constraint.max_range_angle =
parseDouble(it->second);
476 constraint.sensor_view_direction = moveit_msgs::VisibilityConstraint::SENSOR_X;
489 for (
int i = 0; i < params.
size(); ++i)
491 if (!params[i].hasMember(
"type"))
495 else if (params[i][
"type"] ==
"joint")
497 constraints.joint_constraints.emplace_back();
501 else if (params[i][
"type"] ==
"position")
503 constraints.position_constraints.emplace_back();
507 else if (params[i][
"type"] ==
"orientation")
509 constraints.orientation_constraints.emplace_back();
513 else if (params[i][
"type"] ==
"visibility")
515 constraints.visibility_constraints.emplace_back();
526 if (!
isStruct(params, {
"name",
"constraints" },
"Parameter"))
529 constraints.name =
static_cast<std::string
>(params[
"name"]);
535 for (
auto& c : constraints.position_constraints)
545 if (c.link_name != robot_link->
getName())
548 Eigen::Vector3d offset_link_name(c.target_point_offset.x, c.target_point_offset.y, c.target_point_offset.z);
549 Eigen::Vector3d offset_robot_link = robot_link_to_link_name * offset_link_name;
551 c.link_name = robot_link->
getName();
552 tf2::toMsg(offset_robot_link, c.target_point_offset);
556 for (
auto& c : constraints.orientation_constraints)
567 if (c.link_name != robot_link->
getName())
569 if (c.parameterization == moveit_msgs::OrientationConstraint::XYZ_EULER_ANGLES)
572 LOGNAME,
"Euler angles parameterization is not supported for non-link frames in orientation constraints. \n"
573 "Switch to rotation vector parameterization.");
576 c.link_name = robot_link->
getName();
577 Eigen::Quaterniond link_name_to_robot_link(
transform.linear().transpose() *
580 Eigen::Quaterniond quat_target;
582 c.orientation =
tf2::toMsg(quat_target * link_name_to_robot_link);