38#include <geometric_shapes/check_isometry.h>
39#include <geometric_shapes/shape_operations.h>
43#include <rclcpp/clock.hpp>
44#include <rclcpp/logger.hpp>
45#include <rclcpp/logging.hpp>
46#include <rclcpp/time.hpp>
47#include <tf2_eigen/tf2_eigen.hpp>
67 : robot_model_(robot_model)
68 , has_velocity_(false)
69 , has_acceleration_(false)
71 , dirty_link_transforms_(nullptr)
72 , dirty_collision_body_transforms_(nullptr)
75 if (robot_model ==
nullptr)
77 throw std::invalid_argument(
"RobotState cannot be constructed with nullptr RobotModelConstPtr");
80 dirty_link_transforms_ = robot_model_->getRootJoint();
86 robot_model_ = other.robot_model_;
95void RobotState::init()
97 variable_joint_transforms_.resize(robot_model_->getJointModelCount(), Eigen::Isometry3d::Identity());
98 global_link_transforms_.resize(robot_model_->getLinkModelCount(), Eigen::Isometry3d::Identity());
99 global_collision_body_transforms_.resize(robot_model_->getLinkGeometryCount(), Eigen::Isometry3d::Identity());
100 dirty_joint_transforms_.resize(robot_model_->getJointModelCount(), 1);
101 position_.resize(robot_model_->getVariableCount());
102 velocity_.resize(robot_model_->getVariableCount());
103 effort_or_acceleration_.resize(robot_model_->getVariableCount());
113void RobotState::copyFrom(
const RobotState& other)
115 has_velocity_ = other.has_velocity_;
116 has_acceleration_ = other.has_acceleration_;
117 has_effort_ = other.has_effort_;
119 dirty_collision_body_transforms_ = other.dirty_collision_body_transforms_;
120 dirty_link_transforms_ = other.dirty_link_transforms_;
122 variable_joint_transforms_ = other.variable_joint_transforms_;
123 global_link_transforms_ = other.global_link_transforms_;
124 global_collision_body_transforms_ = other.global_collision_body_transforms_;
125 dirty_joint_transforms_ = other.dirty_joint_transforms_;
126 position_ = other.position_;
127 velocity_ = other.velocity_;
128 effort_or_acceleration_ = other.effort_or_acceleration_;
132 for (
const auto& attached_body : other.attached_body_map_)
136bool RobotState::checkJointTransforms(
const JointModel* joint)
const
140 RCLCPP_WARN(getLogger(),
"Returning dirty joint transforms for joint '%s'", joint->
getName().c_str());
146bool RobotState::checkLinkTransforms()
const
150 RCLCPP_WARN(
getLogger(),
"Returning dirty link transforms");
156bool RobotState::checkCollisionTransforms()
const
160 RCLCPP_WARN(
getLogger(),
"Returning dirty collision body transforms");
166void RobotState::markVelocity()
170 has_velocity_ =
true;
171 std::fill(velocity_.begin(), velocity_.end(), 0.0);
175void RobotState::markAcceleration()
177 if (!has_acceleration_)
179 has_acceleration_ =
true;
181 std::fill(effort_or_acceleration_.begin(), effort_or_acceleration_.end(), 0.0);
185void RobotState::markEffort()
189 has_acceleration_ =
false;
191 std::fill(effort_or_acceleration_.begin(), effort_or_acceleration_.end(), 0.0);
195void RobotState::updateMimicJoint(
const JointModel* joint)
197 if (joint->getVariableCount() == 0)
201 double v = position_[joint->getFirstVariableIndex()];
202 for (
const JointModel* jm : joint->getMimicRequests())
204 position_[jm->getFirstVariableIndex()] = jm->getMimicFactor() * v + jm->getMimicOffset();
205 markDirtyJointTransforms(jm);
210void RobotState::updateMimicJoints(
const JointModelGroup* group)
212 for (
const JointModel* jm : group->getMimicJointModels())
214 assert(jm->getVariableCount() != 0);
215 const int fvi = jm->getFirstVariableIndex();
216 position_[fvi] = jm->getMimicFactor() * position_[jm->getMimic()->getFirstVariableIndex()] + jm->getMimicOffset();
217 markDirtyJointTransforms(jm);
219 markDirtyJointTransforms(group);
224 has_velocity_ =
false;
230 has_acceleration_ =
false;
242 has_velocity_ =
false;
247 has_acceleration_ =
false;
265 robot_model_->getVariableRandomPositions(rng, position_);
266 std::fill(dirty_joint_transforms_.begin(), dirty_joint_transforms_.end(), 1);
267 dirty_link_transforms_ = robot_model_->getRootJoint();
282 joint->getVariableRandomPositions(rng, &position_[joint->getFirstVariableIndex()]);
283 updateMimicJoints(group);
287 const std::vector<double>& distances)
296 const std::vector<double>& distances,
297 random_numbers::RandomNumberGenerator& rng)
300 assert(distances.size() == joints.size());
301 for (std::size_t i = 0; i < joints.size(); ++i)
303 const int idx = joints[i]->getFirstVariableIndex();
304 joints[i]->getVariableRandomPositionsNearBy(rng, &position_.at(joints[i]->getFirstVariableIndex()),
305 &seed.position_.at(idx), distances[i]);
307 updateMimicJoints(group);
319 random_numbers::RandomNumberGenerator& rng)
324 const int idx = joint->getFirstVariableIndex();
325 joint->getVariableRandomPositionsNearBy(rng, &position_.at(joint->getFirstVariableIndex()), &seed.position_.at(idx),
328 updateMimicJoints(group);
333 std::map<std::string, double> m;
341 robot_model_->getVariableDefaultPositions(position_);
343 std::fill(velocity_.begin(), velocity_.end(), 0);
344 std::fill(effort_or_acceleration_.begin(), effort_or_acceleration_.end(), 0);
345 std::fill(dirty_joint_transforms_.begin(), dirty_joint_transforms_.end(), 1);
346 dirty_link_transforms_ = robot_model_->getRootJoint();
352 memcpy(position_.data(), position, robot_model_->getVariableCount() *
sizeof(
double));
357 std::fill(dirty_joint_transforms_.begin(), dirty_joint_transforms_.end(), 1);
358 dirty_link_transforms_ = robot_model_->getRootJoint();
363 for (
const std::pair<const std::string, double>& it : variable_map)
365 const int index = robot_model_->getVariableIndex(it.first);
366 position_[index] = it.second;
367 const JointModel* jm = robot_model_->getJointOfVariable(index);
368 markDirtyJointTransforms(jm);
369 updateMimicJoint(jm);
373void RobotState::getMissingKeys(
const std::map<std::string, double>& variable_map,
374 std::vector<std::string>& missing_variables)
const
376 missing_variables.clear();
377 const std::vector<std::string>& nm = robot_model_->getVariableNames();
378 for (
const std::string& variable_name : nm)
380 if (variable_map.find(variable_name) == variable_map.end())
382 if (robot_model_->getJointOfVariable(variable_name)->getMimic() ==
nullptr)
383 missing_variables.push_back(variable_name);
389 std::vector<std::string>& missing_variables)
392 getMissingKeys(variable_map, missing_variables);
396 const std::vector<double>& variable_position)
398 for (std::size_t i = 0; i < variable_names.size(); ++i)
400 const int index = robot_model_->getVariableIndex(variable_names[i]);
401 position_[index] = variable_position[i];
402 const JointModel* jm = robot_model_->getJointOfVariable(index);
403 markDirtyJointTransforms(jm);
404 updateMimicJoint(jm);
411 for (
const std::pair<const std::string, double>& it : variable_map)
412 velocity_[robot_model_->getVariableIndex(it.first)] = it.second;
416 std::vector<std::string>& missing_variables)
419 getMissingKeys(variable_map, missing_variables);
423 const std::vector<double>& variable_velocity)
426 assert(variable_names.size() == variable_velocity.size());
427 for (std::size_t i = 0; i < variable_names.size(); ++i)
428 velocity_[robot_model_->getVariableIndex(variable_names[i])] = variable_velocity[i];
434 for (
const std::pair<const std::string, double>& it : variable_map)
435 effort_or_acceleration_[robot_model_->getVariableIndex(it.first)] = it.second;
439 std::vector<std::string>& missing_variables)
442 getMissingKeys(variable_map, missing_variables);
446 const std::vector<double>& variable_acceleration)
449 assert(variable_names.size() == variable_acceleration.size());
450 for (std::size_t i = 0; i < variable_names.size(); ++i)
451 effort_or_acceleration_[robot_model_->getVariableIndex(variable_names[i])] = variable_acceleration[i];
457 for (
const std::pair<const std::string, double>& it : variable_map)
458 effort_or_acceleration_[robot_model_->getVariableIndex(it.first)] = it.second;
462 std::vector<std::string>& missing_variables)
465 getMissingKeys(variable_map, missing_variables);
469 const std::vector<double>& variable_effort)
472 assert(variable_names.size() == variable_effort.size());
473 for (std::size_t i = 0; i < variable_names.size(); ++i)
474 effort_or_acceleration_[robot_model_->getVariableIndex(variable_names[i])] = variable_effort[i];
481 for (
size_t i = 0; i < robot_model_->getVariableCount(); ++i)
493 markDirtyJointTransforms(joint);
494 updateMimicJoint(joint);
504 markDirtyJointTransforms(joint);
505 updateMimicJoint(joint);
514 has_velocity_ =
true;
556 if (has_acceleration_)
558 RCLCPP_ERROR(getLogger(),
"Unable to set joint efforts because array is being used for accelerations");
576 memcpy(&position_.at(il[0]), gstate, group->
getVariableCount() *
sizeof(
double));
580 for (std::size_t i = 0; i < il.size(); ++i)
581 position_[il[i]] = gstate[i];
583 updateMimicJoints(group);
589 for (std::size_t i = 0; i < il.size(); ++i)
590 position_[il[i]] = values(i);
591 updateMimicJoints(group);
601 i += jm->getVariableCount();
603 updateMimicJoints(group);
613 i += jm->getVariableCount();
615 updateMimicJoints(group);
623 memcpy(gstate, &position_.at(il[0]), group->
getVariableCount() *
sizeof(
double));
627 for (std::size_t i = 0; i < il.size(); ++i)
628 gstate[i] = position_[il[i]];
635 values.resize(il.size());
636 for (std::size_t i = 0; i < il.size(); ++i)
637 values(i) = position_[il[i]];
646 memcpy(&velocity_.at(il[0]), gstate, group->
getVariableCount() *
sizeof(
double));
650 for (std::size_t i = 0; i < il.size(); ++i)
651 velocity_[il[i]] = gstate[i];
659 for (std::size_t i = 0; i < il.size(); ++i)
660 velocity_[il[i]] = values(i);
668 memcpy(gstate, &velocity_.at(il[0]), group->
getVariableCount() *
sizeof(
double));
672 for (std::size_t i = 0; i < il.size(); ++i)
673 gstate[i] = velocity_[il[i]];
680 values.resize(il.size());
681 for (std::size_t i = 0; i < il.size(); ++i)
682 values(i) = velocity_[il[i]];
691 memcpy(&effort_or_acceleration_.at(il[0]), gstate, group->
getVariableCount() *
sizeof(
double));
695 for (std::size_t i = 0; i < il.size(); ++i)
696 effort_or_acceleration_[il[i]] = gstate[i];
704 for (std::size_t i = 0; i < il.size(); ++i)
705 effort_or_acceleration_[il[i]] = values(i);
713 memcpy(gstate, &effort_or_acceleration_.at(il[0]), group->
getVariableCount() *
sizeof(
double));
717 for (std::size_t i = 0; i < il.size(); ++i)
718 gstate[i] = effort_or_acceleration_[il[i]];
725 values.resize(il.size());
726 for (std::size_t i = 0; i < il.size(); ++i)
727 values(i) = effort_or_acceleration_[il[i]];
735 std::fill(dirty_joint_transforms_.begin(), dirty_joint_transforms_.end(), 1);
736 dirty_link_transforms_ = robot_model_->getRootJoint();
745 if (dirty_link_transforms_ !=
nullptr)
748 if (dirty_collision_body_transforms_ !=
nullptr)
751 dirty_collision_body_transforms_ =
nullptr;
755 const EigenSTL::vector_Isometry3d& ot = link->getCollisionOriginTransforms();
756 const std::vector<int>& ot_id = link->areCollisionOriginTransformsIdentity();
757 const int index_co = link->getFirstCollisionBodyTransformIndex();
758 const int index_l = link->getLinkIndex();
759 for (std::size_t j = 0, end = ot.size(); j != end; ++j)
763 global_collision_body_transforms_[index_co + j] = global_link_transforms_[index_l];
767 global_collision_body_transforms_[index_co + j].affine().noalias() =
768 global_link_transforms_[index_l].affine() * ot[j].matrix();
777 if (dirty_link_transforms_ !=
nullptr)
779 updateLinkTransformsInternal(dirty_link_transforms_);
780 if (dirty_collision_body_transforms_)
782 dirty_collision_body_transforms_ =
783 robot_model_->getCommonRoot(dirty_collision_body_transforms_, dirty_link_transforms_);
787 dirty_collision_body_transforms_ = dirty_link_transforms_;
789 dirty_link_transforms_ =
nullptr;
793void RobotState::updateLinkTransformsInternal(
const JointModel* start)
795 for (
const LinkModel* link : start->getDescendantLinkModels())
797 int idx_link = link->getLinkIndex();
802 if (link->parentJointIsFixed())
804 global_link_transforms_[idx_link].affine().noalias() =
805 global_link_transforms_[idx_parent].affine() * link->getJointOriginTransform().matrix();
809 if (link->jointOriginTransformIsIdentity())
811 global_link_transforms_[idx_link].affine().noalias() =
812 global_link_transforms_[idx_parent].affine() *
getJointTransform(link->getParentJointModel()).matrix();
816 global_link_transforms_[idx_link].affine().noalias() =
817 global_link_transforms_[idx_parent].affine() * link->getJointOriginTransform().matrix() *
824 const JointModel* root_joint = link->getParentJointModel();
825 if (root_joint->getVariableCount() == 0)
828 global_link_transforms_[idx_link] = Eigen::Isometry3d::Identity();
830 else if (link->jointOriginTransformIsIdentity())
836 global_link_transforms_[idx_link].affine().noalias() =
837 link->getJointOriginTransform().affine() *
getJointTransform(root_joint).matrix();
843 for (
const auto& attached_body : attached_body_map_)
845 attached_body.second->computeTransform(
846 global_link_transforms_[attached_body.second->getAttachedLink()->getLinkIndex()]);
855 if (dirty_collision_body_transforms_)
857 dirty_collision_body_transforms_ =
858 robot_model_->getCommonRoot(dirty_collision_body_transforms_, link->
getParentJointModel());
865 global_link_transforms_[link->
getLinkIndex()] = transform;
870 updateLinkTransformsInternal(joint);
879 child_link = parent_link;
895 updateLinkTransformsInternal(joint);
903 for (
const auto& attached_body : attached_body_map_)
906 global_link_transforms_[attached_body.second->getAttachedLink()->getLinkIndex()]);
910const LinkModel* RobotState::getLinkModelIncludingAttachedBodies(
const std::string& frame)
const
919 if (
const auto it = attached_body_map_.find(frame); it != attached_body_map_.end())
921 const auto& body{ it->second };
922 return body->getAttachedLink();
926 for (
const auto& it : attached_body_map_)
928 const auto& body{ it.second };
929 if (body->hasSubframeTransform(frame))
931 return body->getAttachedLink();
942 const LinkModel* link = getLinkModelIncludingAttachedBodies(frame);
944 return getRobotModel()->getRigidlyConnectedParentLinkModel(link, jmg);
952 return variable_joint_transforms_[idx];
955 unsigned char&
dirty = dirty_joint_transforms_[idx];
961 return variable_joint_transforms_[idx];
966 const std::vector<const JointModel*>& jm = robot_model_->getActiveJointModels();
988 const std::vector<const JointModel*>& jm = robot_model_->getActiveJointModels();
1008 markDirtyJointTransforms(joint);
1009 updateMimicJoint(joint);
1015 for (
const JointModel* jm : robot_model_->getActiveJointModels())
1034 updateMimicJoint(joint);
1057std::pair<double, const JointModel*>
1060 double distance = std::numeric_limits<double>::max();
1074 std::vector<double> lower_bounds(bounds.size()), upper_bounds(bounds.size());
1075 for (std::size_t j = 0; j < bounds.size(); ++j)
1077 lower_bounds[j] = bounds[j].min_position_;
1078 upper_bounds[j] = bounds[j].max_position_;
1080 double new_distance = joint->distance(joint_values, &lower_bounds[0]);
1086 new_distance = joint->
distance(joint_values, &upper_bounds[0]);
1093 return std::make_pair(
distance, index);
1101 const int idx = joint_id->getFirstVariableIndex();
1102 const std::vector<VariableBounds>& bounds = joint_id->getVariableBounds();
1105 for (std::size_t var_id = 0; var_id < joint_id->getVariableCount(); ++var_id)
1107 const double dtheta = std::abs(position_.at(idx + var_id) - *(other.
getVariablePositions() + idx + var_id));
1109 if (dtheta > dt * bounds[var_id].max_velocity_)
1122 const int idx = joint->getFirstVariableIndex();
1123 d += joint->getDistanceFactor() * joint->distance(&position_.at(idx), &other.position_.at(idx));
1135 return joint->
distance(&position_.at(idx), &other.position_.at(idx));
1140 checkInterpolationParamBounds(getLogger(), t);
1143 std::fill(state.dirty_joint_transforms_.begin(), state.dirty_joint_transforms_.end(), 1);
1144 state.dirty_link_transforms_ = state.robot_model_->getRootJoint();
1149 checkInterpolationParamBounds(getLogger(), t);
1153 const int idx = joint->getFirstVariableIndex();
1154 joint->interpolate(&position_.at(idx), &to.position_.at(idx), t, &state.position_.at(idx));
1156 state.updateMimicJoints(joint_group);
1167 joint->
interpolate(&position_.at(idx), &to.position_.at(idx), t, &state.position_.at(idx));
1168 state.markDirtyJointTransforms(joint);
1169 state.updateMimicJoint(joint);
1174 attached_body_update_callback_ = callback;
1179 return attached_body_map_.find(
id) != attached_body_map_.end();
1184 const auto it = attached_body_map_.find(
id);
1185 if (it == attached_body_map_.end())
1187 RCLCPP_ERROR(getLogger(),
"Attached body '%s' not found",
id.c_str());
1191 return it->second.get();
1200 if (attached_body_update_callback_)
1201 attached_body_update_callback_(attached_body.get(),
true);
1202 attached_body_map_[attached_body->getName()] = std::move(attached_body);
1206 const std::vector<shapes::ShapeConstPtr>&
shapes,
1207 const EigenSTL::vector_Isometry3d& shape_poses,
const std::set<std::string>& touch_links,
1208 const std::string& link,
const trajectory_msgs::msg::JointTrajectory& detach_posture,
1211 attachBody(std::make_unique<AttachedBody>(robot_model_->getLinkModel(link),
id, pose,
shapes, shape_poses,
1212 touch_links, detach_posture, subframe_poses));
1217 attached_bodies.clear();
1218 attached_bodies.reserve(attached_body_map_.size());
1219 for (
const auto& it : attached_body_map_)
1223 attached_bodies.push_back(it.second.get());
1230 attached_bodies.clear();
1231 for (
const auto& it : attached_body_map_)
1233 if (it.second && !it.first.empty())
1235 attached_bodies[it.first] = it.second.get();
1242 attached_bodies.clear();
1243 for (
const auto& it : attached_body_map_)
1245 if (group->
hasLinkModel(it.second->getAttachedLinkName()))
1246 attached_bodies.push_back(it.second.get());
1252 attached_bodies.clear();
1253 for (
const auto& it : attached_body_map_)
1255 if (it.second->getAttachedLink() == link_model)
1256 attached_bodies.push_back(it.second.get());
1262 for (
const auto& it : attached_body_map_)
1264 if (attached_body_update_callback_)
1265 attached_body_update_callback_(it.second.get(),
false);
1267 attached_body_map_.clear();
1272 for (
auto it = attached_body_map_.cbegin(); it != attached_body_map_.cend(); ++it)
1274 if (it->second->getAttachedLink() != link)
1278 if (attached_body_update_callback_)
1279 attached_body_update_callback_(it->second.get(),
false);
1280 const auto del = it++;
1281 attached_body_map_.erase(del);
1287 for (
auto it = attached_body_map_.cbegin(); it != attached_body_map_.cend(); ++it)
1289 if (!group->
hasLinkModel(it->second->getAttachedLinkName()))
1293 if (attached_body_update_callback_)
1294 attached_body_update_callback_(it->second.get(),
false);
1295 const auto del = it++;
1296 attached_body_map_.erase(del);
1302 const auto it = attached_body_map_.find(
id);
1303 if (it != attached_body_map_.end())
1305 if (attached_body_update_callback_)
1306 attached_body_update_callback_(it->second.get(),
false);
1307 attached_body_map_.erase(it);
1324 const auto& result =
getFrameInfo(frame_id, ignored_link, found);
1328 *frame_found = found;
1332 RCLCPP_WARN(getLogger(),
"getFrameTransform() did not find a frame with name %s.", frame_id.c_str());
1339 bool& frame_found)
const
1341 if (!frame_id.empty() && frame_id[0] ==
'/')
1342 return getFrameInfo(frame_id.substr(1), robot_link, frame_found);
1344 static const Eigen::Isometry3d IDENTITY_TRANSFORM = Eigen::Isometry3d::Identity();
1345 if (frame_id == robot_model_->getModelFrame())
1347 robot_link = robot_model_->getRootLink();
1349 return IDENTITY_TRANSFORM;
1351 if ((robot_link = robot_model_->getLinkModel(frame_id, &frame_found)))
1353 assert(checkLinkTransforms());
1354 return global_link_transforms_[robot_link->
getLinkIndex()];
1356 robot_link =
nullptr;
1359 const auto jt = attached_body_map_.find(frame_id);
1360 if (jt != attached_body_map_.end())
1362 const Eigen::Isometry3d& transform = jt->second->getGlobalPose();
1363 robot_link = jt->second->getAttachedLink();
1365 assert(checkLinkTransforms());
1370 for (
const auto& body : attached_body_map_)
1372 const Eigen::Isometry3d& transform = body.second->getGlobalSubframeTransform(frame_id, &frame_found);
1375 robot_link = body.second->getAttachedLink();
1376 assert(checkLinkTransforms());
1381 robot_link =
nullptr;
1382 frame_found =
false;
1383 return IDENTITY_TRANSFORM;
1388 if (!frame_id.empty() && frame_id[0] ==
'/')
1390 if (robot_model_->hasLinkModel(frame_id))
1394 const auto it = attached_body_map_.find(frame_id);
1395 if (it != attached_body_map_.end())
1396 return !it->second->getGlobalCollisionBodyTransforms().empty();
1399 for (
const auto& body : attached_body_map_)
1401 if (body.second->hasSubframeTransform(frame_id))
1408 const std_msgs::msg::ColorRGBA& color,
const std::string& ns,
1409 const rclcpp::Duration& dur,
bool include_attached)
const
1411 std::size_t cur_num = arr.markers.size();
1413 unsigned int id = cur_num;
1414 for (std::size_t i = cur_num; i < arr.markers.size(); ++i, ++id)
1416 arr.markers[i].ns = ns;
1417 arr.markers[i].id = id;
1418 arr.markers[i].lifetime = dur;
1419 arr.markers[i].color = color;
1424 bool include_attached)
const
1426 rclcpp::Clock clock;
1427 for (
const std::string& link_name : link_names)
1429 RCLCPP_DEBUG(getLogger(),
"Trying to get marker for link '%s'", link_name.c_str());
1430 const LinkModel* link_model = robot_model_->getLinkModel(link_name);
1433 if (include_attached)
1435 for (
const auto& it : attached_body_map_)
1437 if (it.second->getAttachedLink() == link_model)
1439 for (std::size_t j = 0; j < it.second->getShapes().size(); ++j)
1441 visualization_msgs::msg::Marker att_mark;
1442 att_mark.header.frame_id = robot_model_->getModelFrame();
1443 att_mark.header.stamp = clock.now();
1444 if (shapes::constructMarkerFromShape(it.second->getShapes()[j].get(), att_mark))
1447 if (fabs(att_mark.scale.x * att_mark.scale.y * att_mark.scale.z) < std::numeric_limits<double>::epsilon())
1449 att_mark.pose = tf2::toMsg(it.second->getGlobalCollisionBodyTransforms()[j]);
1450 arr.markers.push_back(att_mark);
1460 for (std::size_t j = 0; j < link_model->
getShapes().size(); ++j)
1462 visualization_msgs::msg::Marker mark;
1463 mark.header.frame_id = robot_model_->getModelFrame();
1464 mark.header.stamp = clock.now();
1468 if (mesh_resource.empty() || link_model->
getShapes().size() > 1)
1470 if (!shapes::constructMarkerFromShape(link_model->
getShapes()[j].get(), mark))
1473 if (fabs(mark.scale.x * mark.scale.y * mark.scale.z) < std::numeric_limits<double>::epsilon())
1480 mark.type = mark.MESH_RESOURCE;
1481 mark.mesh_use_embedded_materials =
false;
1482 mark.mesh_resource = mesh_resource;
1485 mark.scale.x = mesh_scale[0];
1486 mark.scale.y = mesh_scale[1];
1487 mark.scale.z = mesh_scale[2];
1491 arr.markers.push_back(mark);
1497 const Eigen::Vector3d& reference_point_position)
const
1499 Eigen::MatrixXd result;
1501 throw Exception(
"Unable to compute Jacobian");
1506 const Eigen::Vector3d& reference_point_position, Eigen::MatrixXd& jacobian,
1507 bool use_quaternion_representation)
const
1509 assert(checkLinkTransforms());
1514 RCLCPP_ERROR(getLogger(),
"The group '%s' is not a chain. Cannot compute Jacobian.", group->
getName().c_str());
1519 if (descendant_links.find(link) == descendant_links.end())
1521 RCLCPP_ERROR(getLogger(),
"Link name '%s' does not exist in the chain '%s' or is not a child for this chain",
1527 if (joint_models.empty())
1529 RCLCPP_ERROR(getLogger(),
"The group '%s' doesn't contain any joint models. Cannot compute Jacobian.",
1538 const Eigen::Isometry3d root_pose_world =
1540 const int rows = use_quaternion_representation ? 7 : 6;
1542 jacobian.resize(rows, columns);
1547 const Eigen::Vector3d tip_point = root_pose_tip * reference_point_position;
1554 for (
const JointModel* joint_model : joint_models)
1557 if (joint_model->getParentLinkModel() == link)
1562 const LinkModel* child_link_model = joint_model->getChildLinkModel();
1568 const Eigen::Vector3d axis_wrt_origin =
1569 root_pose_link.linear() *
static_cast<const RevoluteJointModel*
>(joint_model)->getAxis();
1570 jacobian.block<3, 1>(0, i) = axis_wrt_origin.cross(tip_point - root_pose_link.translation());
1571 jacobian.block<3, 1>(3, i) = axis_wrt_origin;
1575 const Eigen::Vector3d axis_wrt_origin =
1576 root_pose_link.linear() *
static_cast<const PrismaticJointModel*
>(joint_model)->getAxis();
1577 jacobian.block<3, 1>(0, i) = axis_wrt_origin;
1578 jacobian.block<3, 1>(3, i) = Eigen::Vector3d::Zero();
1582 jacobian.block<3, 1>(0, i) = root_pose_link.linear() * Eigen::Vector3d(1.0, 0.0, 0.0);
1583 jacobian.block<3, 1>(0, i + 1) = root_pose_link.linear() * Eigen::Vector3d(0.0, 1.0, 0.0);
1584 jacobian.block<3, 1>(0, i + 2) =
1585 (root_pose_link.linear() * Eigen::Vector3d(0.0, 0.0, 1.0)).cross(tip_point - root_pose_link.translation());
1586 jacobian.block<3, 1>(3, i + 2) = root_pose_link.linear() * Eigen::Vector3d(0.0, 0.0, 1.0);
1590 RCLCPP_ERROR(getLogger(),
"Unknown type of joint in Jacobian computation");
1594 i += joint_model->getVariableCount();
1597 if (use_quaternion_representation)
1604 Eigen::Quaterniond q(root_pose_tip.linear());
1605 double w = q.w(), x = q.x(), y = q.y(), z = q.z();
1606 Eigen::MatrixXd quaternion_update_matrix(4, 3);
1607 quaternion_update_matrix << -x, -y, -z, w, -z, y, z, w, -x, -y, x, w;
1608 jacobian.block(3, 0, 4, columns) = 0.5 * quaternion_update_matrix * jacobian.block(3, 0, 3, columns);
1616 Eigen::VectorXd qdot;
1624 Eigen::Matrix<double, 6, 1> t;
1625 tf2::fromMsg(twist, t);
1630 const Eigen::VectorXd& twist,
const LinkModel* tip)
const
1634 Eigen::Vector3d reference_point(0.0, 0.0, 0.0);
1639 Eigen::MatrixXd e_wb = Eigen::ArrayXXd::Zero(6, 6);
1640 e_wb.block(0, 0, 3, 3) = e_mb.matrix().block(0, 0, 3, 3);
1641 e_wb.block(3, 3, 3, 3) = e_mb.matrix().block(0, 0, 3, 3);
1645 Eigen::JacobiSVD<Eigen::MatrixXd> svd_of_j(j, Eigen::ComputeThinU | Eigen::ComputeThinV);
1646 const Eigen::MatrixXd& u = svd_of_j.matrixU();
1647 const Eigen::MatrixXd& v = svd_of_j.matrixV();
1648 const Eigen::VectorXd& s = svd_of_j.singularValues();
1650 Eigen::VectorXd sinv = s;
1651 static const double PINVTOLER = std::numeric_limits<double>::epsilon();
1653 for (std::size_t i = 0; i < static_cast<std::size_t>(s.rows()); ++i)
1655 if (fabs(s(i)) > maxsv)
1658 for (std::size_t i = 0; i < static_cast<std::size_t>(s.rows()); ++i)
1661 if (fabs(s(i)) > maxsv * PINVTOLER)
1663 sinv(i) = 1.0 / s(i);
1670 Eigen::MatrixXd jinv = (v * sinv.asDiagonal() * u.transpose());
1673 qdot = jinv * twist;
1687 std::vector<double> values;
1689 return constraint(
this, jmg, &values[0]);
1703 RCLCPP_ERROR(getLogger(),
"No kinematics solver instantiated for group '%s'", jmg->
getName().c_str());
1706 return setFromIK(jmg, pose, solver->getTipFrame(), timeout, constraint, options, cost_function);
1714 Eigen::Isometry3d mat;
1715 tf2::fromMsg(pose, mat);
1716 static std::vector<double> consistency_limits;
1717 return setFromIK(jmg, mat, tip, consistency_limits, timeout, constraint, options, cost_function);
1728 RCLCPP_ERROR(getLogger(),
"No kinematics solver instantiated for group '%s'", jmg->
getName().c_str());
1731 static std::vector<double> consistency_limits;
1732 return setFromIK(jmg, pose, solver->getTipFrame(), consistency_limits, timeout, constraint, options, cost_function);
1740 static std::vector<double> consistency_limits;
1741 return setFromIK(jmg, pose_in, tip_in, consistency_limits, timeout, constraint, options, cost_function);
1748 const std::vector<double>& ik_sol, moveit_msgs::msg::MoveItErrorCodes& error_code)
1751 std::vector<double> solution(bij.size());
1752 for (std::size_t i = 0; i < bij.size(); ++i)
1753 solution[bij[i]] = ik_sol[i];
1754 if (constraint(state, group, &solution[0]))
1756 error_code.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
1760 error_code.val = moveit_msgs::msg::MoveItErrorCodes::NO_IK_SOLUTION;
1777 getLinkModel((!ik_frame.empty() && ik_frame[0] ==
'/') ? ik_frame.substr(1) : ik_frame);
1780 RCLCPP_ERROR(getLogger(),
"The following IK frame does not exist: %s", ik_frame.c_str());
1789 const std::vector<double>& consistency_limits_in,
double timeout,
1795 EigenSTL::vector_Isometry3d poses;
1796 poses.push_back(pose_in);
1798 std::vector<std::string> tips;
1799 tips.push_back(tip_in);
1801 std::vector<std::vector<double> > consistency_limits;
1802 consistency_limits.push_back(consistency_limits_in);
1804 return setFromIK(jmg, poses, tips, consistency_limits, timeout, constraint, options, cost_function);
1808 const std::vector<std::string>& tips_in,
double timeout,
1813 const std::vector<std::vector<double> > consistency_limits;
1814 return setFromIK(jmg, poses_in, tips_in, consistency_limits, timeout, constraint, options, cost_function);
1818 const std::vector<std::string>& tips_in,
1819 const std::vector<std::vector<double> >& consistency_limit_sets,
double timeout,
1825 if (poses_in.size() != tips_in.size())
1827 RCLCPP_ERROR(getLogger(),
"Number of poses must be the same as number of tips");
1835 bool valid_solver =
true;
1838 valid_solver =
false;
1841 else if (poses_in.size() > 1)
1843 std::string error_msg;
1844 if (!solver->supportsGroup(jmg, &error_msg))
1847 RCLCPP_ERROR(getLogger(),
"Kinematics solver %s does not support joint group %s. Error: %s",
1848 typeid(solver_ref).name(), jmg->
getName().c_str(), error_msg.c_str());
1849 valid_solver =
false;
1856 if (poses_in.size() > 1)
1859 return setFromIKSubgroups(jmg, poses_in, tips_in, consistency_limit_sets, timeout, constraint, options);
1863 RCLCPP_ERROR(getLogger(),
"No kinematics solver instantiated for group '%s'", jmg->
getName().c_str());
1869 std::vector<double> consistency_limits;
1870 if (consistency_limit_sets.size() > 1)
1872 RCLCPP_ERROR(getLogger(),
1873 "Invalid number (%zu) of sets of consistency limits for a setFromIK request "
1874 "that is being solved by a single IK solver",
1875 consistency_limit_sets.size());
1878 else if (consistency_limit_sets.size() == 1)
1879 consistency_limits = consistency_limit_sets[0];
1881 const std::vector<std::string>& solver_tip_frames = solver->getTipFrames();
1884 std::vector<bool> tip_frames_used(solver_tip_frames.size(),
false);
1887 std::vector<geometry_msgs::msg::Pose> ik_queries(solver_tip_frames.size());
1890 for (std::size_t i = 0; i < poses_in.size(); ++i)
1893 Eigen::Isometry3d pose = poses_in[i];
1894 std::string pose_frame = tips_in[i];
1897 if (!pose_frame.empty() && pose_frame[0] ==
'/')
1898 pose_frame = pose_frame.substr(1);
1906 bool found_valid_frame =
false;
1907 std::size_t solver_tip_id;
1908 for (solver_tip_id = 0; solver_tip_id < solver_tip_frames.size(); ++solver_tip_id)
1911 if (tip_frames_used[solver_tip_id])
1915 std::string solver_tip_frame = solver_tip_frames[solver_tip_id];
1919 if (!solver_tip_frame.empty() && solver_tip_frame[0] ==
'/')
1920 solver_tip_frame = solver_tip_frame.substr(1);
1922 if (pose_frame != solver_tip_frame)
1927 RCLCPP_ERROR_STREAM(getLogger(),
"The following Pose Frame does not exist: " << pose_frame);
1934 RCLCPP_ERROR_STREAM(getLogger(),
"The following Solver Tip Frame does not exist: " << solver_tip_frame);
1938 if (pose_parent == tip_parent)
1941 pose = pose * pose_parent_to_frame.inverse() * tip_parent_to_tip;
1942 found_valid_frame =
true;
1948 found_valid_frame =
true;
1954 if (!found_valid_frame)
1956 RCLCPP_ERROR(getLogger(),
"Cannot compute IK for query %zu pose reference frame '%s'", i, pose_frame.c_str());
1958 std::stringstream ss;
1959 for (solver_tip_id = 0; solver_tip_id < solver_tip_frames.size(); ++solver_tip_id)
1960 ss << solver_tip_frames[solver_tip_id] <<
", ";
1961 RCLCPP_ERROR(getLogger(),
"Available tip frames: [%s]", ss.str().c_str());
1966 tip_frames_used[solver_tip_id] =
true;
1969 geometry_msgs::msg::Pose ik_query;
1970 ik_query = tf2::toMsg(pose);
1973 ik_queries[solver_tip_id] = ik_query;
1977 for (std::size_t solver_tip_id = 0; solver_tip_id < solver_tip_frames.size(); ++solver_tip_id)
1980 if (tip_frames_used[solver_tip_id])
1984 std::string solver_tip_frame = solver_tip_frames[solver_tip_id];
1988 if (!solver_tip_frame.empty() && solver_tip_frame[0] ==
'/')
1989 solver_tip_frame = solver_tip_frame.substr(1);
1999 geometry_msgs::msg::Pose ik_query;
2000 ik_query = tf2::toMsg(current_pose);
2003 ik_queries[solver_tip_id] = ik_query;
2006 tip_frames_used[solver_tip_id] =
true;
2010 if (timeout < std::numeric_limits<double>::epsilon())
2017 ik_callback_fn = ik_callback_fn = [
this, jmg, constraint](
const geometry_msgs::msg::Pose& pose,
2018 const std::vector<double>& joints,
2019 moveit_msgs::msg::MoveItErrorCodes& error_code) {
2020 ikCallbackFnAdapter(
this, jmg, constraint, pose, joints, error_code);
2027 std::vector<double> initial_values;
2029 std::vector<double> seed(bij.size());
2030 for (std::size_t i = 0; i < bij.size(); ++i)
2031 seed[i] = initial_values[bij[i]];
2034 std::vector<double> ik_sol;
2035 moveit_msgs::msg::MoveItErrorCodes error;
2037 if (solver->searchPositionIK(ik_queries, seed, timeout, consistency_limits, ik_sol, ik_callback_fn, cost_function,
2038 error, options,
this))
2040 std::vector<double> solution(bij.size());
2041 for (std::size_t i = 0; i < bij.size(); ++i)
2042 solution[bij[i]] = ik_sol[i];
2050 const std::vector<std::string>& tips_in,
2051 const std::vector<std::vector<double> >& consistency_limits,
double timeout,
2058 std::vector<const JointModelGroup*> sub_groups;
2062 if (poses_in.size() != sub_groups.size())
2064 RCLCPP_ERROR(getLogger(),
"Number of poses (%zu) must be the same as number of sub-groups (%zu)", poses_in.size(),
2069 if (tips_in.size() != sub_groups.size())
2071 RCLCPP_ERROR(getLogger(),
"Number of tip names (%zu) must be same as number of sub-groups (%zu)", tips_in.size(),
2076 if (!consistency_limits.empty() && consistency_limits.size() != sub_groups.size())
2078 RCLCPP_ERROR(getLogger(),
"Number of consistency limit vectors must be the same as number of sub-groups");
2082 for (std::size_t i = 0; i < consistency_limits.size(); ++i)
2086 RCLCPP_ERROR(getLogger(),
"Number of joints in consistency_limits[%zu] is %lu but it should be should be %u", i,
2093 std::vector<kinematics::KinematicsBaseConstPtr> solvers;
2094 for (std::size_t i = 0; i < poses_in.size(); ++i)
2096 kinematics::KinematicsBaseConstPtr solver = sub_groups[i]->getSolverInstance();
2099 RCLCPP_ERROR(getLogger(),
"Could not find solver for group '%s'", sub_groups[i]->getName().c_str());
2102 solvers.push_back(solver);
2106 EigenSTL::vector_Isometry3d transformed_poses = poses_in;
2107 std::vector<std::string> pose_frames = tips_in;
2110 for (std::size_t i = 0; i < poses_in.size(); ++i)
2112 ASSERT_ISOMETRY(transformed_poses[i])
2113 Eigen::Isometry3d& pose = transformed_poses[i];
2114 std::string& pose_frame = pose_frames[i];
2121 std::string solver_tip_frame = solvers[i]->getTipFrame();
2125 if (!solver_tip_frame.empty() && solver_tip_frame[0] ==
'/')
2126 solver_tip_frame = solver_tip_frame.substr(1);
2128 if (pose_frame != solver_tip_frame)
2134 pose = pose * body->
getPose().inverse();
2136 if (pose_frame != solver_tip_frame)
2143 for (
const std::pair<const LinkModel* const, Eigen::Isometry3d>& fixed_link : fixed_links)
2145 if (fixed_link.first->getName() == solver_tip_frame)
2147 pose_frame = solver_tip_frame;
2148 pose = pose * fixed_link.second;
2155 if (pose_frame != solver_tip_frame)
2157 RCLCPP_ERROR(getLogger(),
"Cannot compute IK for query pose reference frame '%s', desired: '%s'",
2158 pose_frame.c_str(), solver_tip_frame.c_str());
2164 std::vector<geometry_msgs::msg::Pose> ik_queries(poses_in.size());
2168 ik_callback_fn = [
this, jmg, constraint](
const geometry_msgs::msg::Pose pose,
const std::vector<double>& joints,
2169 moveit_msgs::msg::MoveItErrorCodes& error_code) {
2170 ikCallbackFnAdapter(
this, jmg, constraint, pose, joints, error_code);
2174 for (std::size_t i = 0; i < transformed_poses.size(); ++i)
2176 Eigen::Quaterniond quat(transformed_poses[i].linear());
2177 Eigen::Vector3d point(transformed_poses[i].translation());
2178 ik_queries[i].position.x = point.x();
2179 ik_queries[i].position.y = point.y();
2180 ik_queries[i].position.z = point.z();
2181 ik_queries[i].orientation.x = quat.x();
2182 ik_queries[i].orientation.y = quat.y();
2183 ik_queries[i].orientation.z = quat.z();
2184 ik_queries[i].orientation.w = quat.w();
2188 if (timeout < std::numeric_limits<double>::epsilon())
2191 auto start = std::chrono::system_clock::now();
2194 bool first_seed =
true;
2195 unsigned int attempts = 0;
2199 RCLCPP_DEBUG(getLogger(),
"IK attempt: %d", attempts);
2200 bool found_solution =
true;
2201 for (std::size_t sg = 0; sg < sub_groups.size(); ++sg)
2203 const std::vector<size_t>& bij = sub_groups[sg]->getKinematicsSolverJointBijection();
2204 std::vector<double> seed(bij.size());
2208 std::vector<double> initial_values;
2210 for (std::size_t i = 0; i < bij.size(); ++i)
2211 seed[i] = initial_values[bij[i]];
2217 std::vector<double> random_values;
2218 sub_groups[sg]->getVariableRandomPositions(rng, random_values);
2219 for (std::size_t i = 0; i < bij.size(); ++i)
2220 seed[i] = random_values[bij[i]];
2224 std::vector<double> ik_sol;
2225 moveit_msgs::msg::MoveItErrorCodes error;
2226 const std::vector<double>& climits = consistency_limits.empty() ? std::vector<double>() : consistency_limits[sg];
2227 if (solvers[sg]->searchPositionIK(ik_queries[sg], seed, (timeout - elapsed) / sub_groups.size(), climits, ik_sol,
2230 std::vector<double> solution(bij.size());
2231 for (std::size_t i = 0; i < bij.size(); ++i)
2232 solution[bij[i]] = ik_sol[i];
2237 found_solution =
false;
2243 std::vector<double> full_solution;
2245 if (constraint ? constraint(
this, jmg, &full_solution[0]) :
true)
2247 RCLCPP_DEBUG(getLogger(),
"Found IK solution");
2251 elapsed = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start).count();
2253 }
while (elapsed < timeout);
2259 assert(checkLinkTransforms());
2262 std::vector<const LinkModel*> links = robot_model_->getLinkModelsWithCollisionGeometry();
2266 const Eigen::Vector3d& extents = link->getShapeExtentsAtOrigin();
2267 transform.translate(link->getCenteredBoundingBoxOffset());
2270 for (
const auto& it : attached_body_map_)
2272 const EigenSTL::vector_Isometry3d& transforms = it.second->getGlobalCollisionBodyTransforms();
2273 const std::vector<shapes::ShapeConstPtr>&
shapes = it.second->getShapes();
2274 for (std::size_t i = 0; i < transforms.size(); ++i)
2276 Eigen::Vector3d extents = shapes::computeShapeExtents(
shapes[i].get());
2282 aabb.resize(6, 0.0);
2283 if (!bounding_box.isEmpty())
2287 Eigen::Map<Eigen::VectorXd, Eigen::Unaligned, Eigen::InnerStride<2> >(aabb.data(), 3) = bounding_box.min();
2288 Eigen::Map<Eigen::VectorXd, Eigen::Unaligned, Eigen::InnerStride<2> >(aabb.data() + 1, 3) = bounding_box.max();
2294 const std::vector<std::string>& nm = robot_model_->getVariableNames();
2295 for (std::size_t i = 0; i < nm.size(); ++i)
2296 out << nm[i] <<
'=' << position_[i] <<
'\n';
2310 if (joint->getVariableCount() > 1)
2323 out <<
" " << std::fixed << std::setprecision(5) << bound.
min_position_ <<
'\t';
2325 double step = delta / 20.0;
2327 bool marker_shown =
false;
2331 if (!marker_shown && current_value < value)
2334 marker_shown =
true;
2343 out <<
" \t" << std::fixed << std::setprecision(5) << bound.
max_position_ <<
" \t" << joint->getName()
2344 <<
" current: " << std::fixed << std::setprecision(5) << current_value <<
'\n';
2353 out <<
" * Dirty Joint Transforms: \n";
2354 const std::vector<const JointModel*>& jm = robot_model_->getJointModels();
2358 out <<
" " << joint->getName() <<
'\n';
2360 out <<
" * Dirty Link Transforms: " << (dirty_link_transforms_ ? dirty_link_transforms_->
getName() :
"NULL") <<
'\n';
2361 out <<
" * Dirty Collision Body Transforms: "
2362 << (dirty_collision_body_transforms_ ? dirty_collision_body_transforms_->
getName() :
"NULL\n");
2367 out <<
"Robot State @" <<
this <<
'\n';
2369 std::size_t n = robot_model_->getVariableCount();
2370 if (!position_.empty())
2372 out <<
" * Position: ";
2373 for (std::size_t i = 0; i < n; ++i)
2374 out << position_[i] <<
' ';
2378 out <<
" * Position: NULL\n";
2380 if (!velocity_.empty())
2382 out <<
" * Velocity: ";
2383 for (std::size_t i = 0; i < n; ++i)
2384 out << velocity_[i] <<
' ';
2388 out <<
" * Velocity: NULL\n";
2390 if (has_acceleration_)
2392 out <<
" * Acceleration: ";
2393 for (std::size_t i = 0; i < n; ++i)
2394 out << effort_or_acceleration_[i] <<
' ';
2398 out <<
" * Acceleration: NULL\n";
2400 out <<
" * Dirty Link Transforms: " << (dirty_link_transforms_ ? dirty_link_transforms_->
getName() :
"NULL\n");
2401 out <<
" * Dirty Collision Body Transforms: "
2402 << (dirty_collision_body_transforms_ ? dirty_collision_body_transforms_->
getName() :
"NULL\n");
2409 if (checkIsometry(transform, CHECK_ISOMETRY_PRECISION,
false))
2411 Eigen::Quaterniond q(transform.linear());
2412 out <<
"T.xyz = [" << transform.translation().x() <<
", " << transform.translation().y() <<
", "
2413 << transform.translation().z() <<
"], Q.xyzw = [" << q.x() <<
", " << q.y() <<
", " << q.z() <<
", " << q.w()
2418 out <<
"[NON-ISOMETRY] "
2419 << transform.matrix().format(
2420 Eigen::IOFormat(Eigen::StreamPrecision, Eigen::DontAlignCols,
", ",
"; ",
"",
"",
"[",
"]"));
2427 if (variable_joint_transforms_.empty())
2429 out <<
"No transforms computed\n";
2433 out <<
"Joint transforms:\n";
2434 const std::vector<const JointModel*>& jm = robot_model_->getJointModels();
2437 out <<
" " << joint->getName();
2438 const int idx = joint->getJointIndex();
2439 if (dirty_joint_transforms_[idx])
2445 out <<
"Link poses:\n";
2446 const std::vector<const LinkModel*>& link_model = robot_model_->getLinkModels();
2447 for (
const LinkModel* link : link_model)
2449 out <<
" " << link->getName() <<
": ";
2450 printTransform(global_link_transforms_[link->getLinkIndex()], out);
2456 std::stringstream ss;
2457 ss <<
"ROBOT: " << robot_model_->getName() <<
'\n';
2458 getStateTreeJointString(ss, robot_model_->getRootJoint(),
" ",
true);
2464void getPoseString(std::ostream& ss,
const Eigen::Isometry3d& pose,
const std::string& pfx)
2467 for (
int y = 0; y < 4; ++y)
2470 for (
int x = 0; x < 4; ++x)
2472 ss << std::setw(8) << pose(y, x) <<
' ';
2479void RobotState::getStateTreeJointString(std::ostream& ss,
const JointModel* jm,
const std::string& pfx0,
2482 std::string pfx = pfx0 +
"+--";
2484 ss << pfx <<
"Joint: " << jm->getName() <<
'\n';
2486 pfx = pfx0 + (last ?
" " :
"| ");
2488 for (std::size_t i = 0; i < jm->getVariableCount(); ++i)
2491 ss << pfx << jm->getVariableNames()[i] << std::setw(12) << position_[jm->getFirstVariableIndex() + i] <<
'\n';
2494 const LinkModel* link_model = jm->getChildLinkModel();
2496 ss << pfx <<
"Link: " << link_model->getName() <<
'\n';
2497 getPoseString(ss, link_model->getJointOriginTransform(), pfx +
"joint_origin:");
2498 if (!variable_joint_transforms_.empty())
2500 getPoseString(ss, variable_joint_transforms_[jm->getJointIndex()], pfx +
"joint_variable:");
2501 getPoseString(ss, global_link_transforms_[link_model->getLinkIndex()], pfx +
"link_global:");
2504 for (std::vector<const JointModel*>::const_iterator it = link_model->getChildJointModels().begin();
2505 it != link_model->getChildJointModels().end(); ++it)
2506 getStateTreeJointString(ss, *it, pfx, it + 1 == link_model->getChildJointModels().end());
Provides an interface for kinematics solvers.
std::function< double(const geometry_msgs::msg::Pose &, const moveit::core::RobotState &, const moveit::core::JointModelGroup *, const std::vector< double > &)> IKCostFn
Signature for a cost function used to evaluate IK solutions.
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.
This may be thrown if unrecoverable errors occur.
Represents an axis-aligned bounding box.
void extendWithTransformedBox(const Eigen::Isometry3d &transform, const Eigen::Vector3d &box)
Extend with a box transformed by the given transform.
Object defining bodies that can be attached to robot links.
const Eigen::Isometry3d & getPose() const
Get the pose of the attached body relative to the parent link.
const std::string & getAttachedLinkName() const
Get the name of the link this body is attached to.
double getDefaultIKTimeout() const
Get the default IK timeout.
bool isChain() const
Check if this group is a linear chain.
const std::string & getName() const
Get the name of the joint group.
const std::vector< const LinkModel * > & getLinkModels() const
Get the links that are part of this joint group.
const std::set< const LinkModel * > & getUpdatedLinkModelsSet() const
Return the same data as getUpdatedLinkModels() but as a set.
const std::vector< const JointModel * > & getActiveJointModels() const
Get the active joints in this group (that have controllable DOF). This does not include mimic joints.
const std::vector< int > & getVariableIndexList() const
Get the index locations in the complete robot state for all the variables in this group.
const kinematics::KinematicsBaseConstPtr getSolverInstance() const
const std::vector< size_t > & getKinematicsSolverJointBijection() const
Return the mapping between the order of the joints in this group and the order of the joints in the k...
bool hasLinkModel(const std::string &link) const
Check if a link is part of this group.
void getSubgroups(std::vector< const JointModelGroup * > &sub_groups) const
Get the groups that are subsets of this one (in terms of joints set)
unsigned int getVariableCount() const
Get the number of variables that describe this joint group. This includes variables necessary for mim...
bool getVariableDefaultPositions(const std::string &name, std::map< std::string, double > &values) const
Get the values that correspond to a named state as read from the URDF. Return false on failure.
bool isContiguousWithinState() const
unsigned int getActiveVariableCount() const
Get the number of variables that describe the active joints in this joint group. This excludes variab...
const std::vector< const JointModel * > & getJointModels() const
Get all the joints in this group (including fixed and mimic joints).
A joint from the robot. Models the transform that this joint applies in the kinematic chain....
virtual void computeVariablePositions(const Eigen::Isometry3d &transform, double *joint_values) const =0
Given the transform generated by joint, compute the corresponding joint values. Make sure the passed ...
size_t getJointIndex() const
Get the index of this joint within the robot model.
std::vector< VariableBounds > Bounds
The datatype for the joint bounds.
const std::vector< const LinkModel * > & getDescendantLinkModels() const
Get all the link models that descend from this joint, in the kinematic tree.
size_t getFirstVariableIndex() const
Get the index of this joint's first variable within the full robot state.
virtual bool harmonizePosition(double *values, const Bounds &other_bounds) const
virtual void interpolate(const double *from, const double *to, const double t, double *state) const =0
Computes the state that lies at time t in [0, 1] on the segment that connects from state to to state....
std::size_t getVariableCount() const
Get the number of variables that describe this joint.
const std::string & getName() const
Get the name of the joint.
virtual double distance(const double *value1, const double *value2) const =0
Compute the distance between two joint states of the same model (represented by the variable values)
bool enforceVelocityBounds(double *values) const
Force the specified velocities to be within bounds. Return true if changes were made.
virtual void computeTransform(const double *joint_values, Eigen::Isometry3d &transf) const =0
Given the joint values for a joint, compute the corresponding transform. The computed transform is gu...
bool enforcePositionBounds(double *values) const
Force the specified values to be inside bounds and normalized. Quaternions are normalized,...
const LinkModel * getParentLinkModel() const
Get the link that this joint connects to. The robot is assumed to start with a joint,...
A link from the robot. Contains the constant transform applied to the link and its geometry.
int getFirstCollisionBodyTransformIndex() const
const std::string & getName() const
The name of this link.
const Eigen::Isometry3d & getVisualMeshOrigin() const
Get the transform for the visual mesh origin.
const std::string & getVisualMeshFilename() const
Get the filename of the mesh resource used for visual display of this link.
const JointModel * getParentJointModel() const
Get the joint model whose child this link is. There will always be a parent joint.
const Eigen::Vector3d & getVisualMeshScale() const
Get the scale of the mesh resource for this link.
const LinkModel * getParentLinkModel() const
Get the link model whose child this link is (through some joint). There may not always be a parent li...
const std::vector< shapes::ShapeConstPtr > & getShapes() const
Get shape associated to the collision geometry for this link.
const Eigen::Isometry3d & getJointOriginTransform() const
When transforms are computed for this link, they are usually applied to the link's origin....
const std::vector< const JointModel * > & getChildJointModels() const
A link may have 0 or more child joints. From those joints there will certainly be other descendant li...
const LinkTransformMap & getAssociatedFixedTransforms() const
Get the set of links that are attached to this one via fixed transforms. The returned transforms are ...
size_t getLinkIndex() const
The index of this joint when traversing the kinematic tree in depth first fashion.
bool isContinuous() const
Check if this joint wraps around.
Representation of a robot's state. This includes position, velocity, acceleration and effort.
void setVariablePositions(const double *position)
It is assumed positions is an array containing the new positions for all variables in this state....
void zeroVelocities()
Set all velocities to 0.0.
RobotState & operator=(const RobotState &other)
Copy operator.
void setJointEfforts(const JointModel *joint, const double *effort)
void setAttachedBodyUpdateCallback(const AttachedBodyCallback &callback)
void setJointVelocities(const JointModel *joint, const double *velocity)
void printTransforms(std::ostream &out=std::cout) const
void printTransform(const Eigen::Isometry3d &transform, std::ostream &out=std::cout) const
void attachBody(std::unique_ptr< AttachedBody > attached_body)
Add an attached body to this state.
void updateStateWithLinkAt(const std::string &link_name, const Eigen::Isometry3d &transform, bool backward=false)
Update the state after setting a particular link to the input global transform pose.
bool getJacobian(const JointModelGroup *group, const LinkModel *link, const Eigen::Vector3d &reference_point_position, Eigen::MatrixXd &jacobian, bool use_quaternion_representation=false) const
Compute the Jacobian with reference to a particular point on a given link, for a specified group.
std::pair< double, const JointModel * > getMinDistanceToPositionBounds() const
Get the minimm distance from this state to the bounds. The minimum distance and the joint for which t...
void copyJointGroupVelocities(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the velocity values of the variables that make up the group into another loca...
const double * getJointPositions(const std::string &joint_name) const
void getAttachedBodies(std::vector< const AttachedBody * > &attached_bodies) const
Get all bodies attached to the model corresponding to this state.
void setJointGroupAccelerations(const std::string &joint_group_name, const double *gstate)
Given accelerations for the variables that make up a group, in the order found in the group (includin...
void setJointGroupVelocities(const std::string &joint_group_name, const double *gstate)
Given velocities for the variables that make up a group, in the order found in the group (including v...
void computeVariableVelocity(const JointModelGroup *jmg, Eigen::VectorXd &qdot, const Eigen::VectorXd &twist, const LinkModel *tip) const
Given a twist for a particular link (tip), compute the corresponding velocity for every variable and ...
void computeAABB(std::vector< double > &aabb) const
Compute an axis-aligned bounding box that contains the current state. The format for aabb is (minx,...
void setJointGroupPositions(const std::string &joint_group_name, const double *gstate)
Given positions for the variables that make up a group, in the order found in the group (including va...
void copyJointGroupPositions(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the position values of the variables that make up the group into another loca...
bool clearAttachedBody(const std::string &id)
Remove the attached body named id. Return false if the object was not found (and thus not removed)....
void harmonizePositions()
Call harmonizePosition() for all joints / all joints in group / given joint.
void setVariableVelocities(const double *velocity)
Given an array with velocity values for all variables, set those values as the velocities in this sta...
bool dirtyCollisionBodyTransforms() const
const double * getJointEffort(const std::string &joint_name) const
void zeroAccelerations()
Set all accelerations to 0.0.
bool isValidVelocityMove(const RobotState &other, const JointModelGroup *group, double dt) const
Check that the time to move between two waypoints is sufficient given velocity limits and time step.
const double * getJointVelocities(const std::string &joint_name) const
bool setFromDiffIK(const JointModelGroup *group, const Eigen::VectorXd &twist, const std::string &tip, double dt, const GroupStateValidityCallbackFn &constraint=GroupStateValidityCallbackFn())
Set the joint values from a Cartesian velocity applied during a time dt.
void printStatePositionsWithJointLimits(const moveit::core::JointModelGroup *jmg, std::ostream &out=std::cout) const
Output to console the current state of the robot's joint limits.
const LinkModel * getLinkModel(const std::string &link) const
Get the model of a particular link.
const RobotModelConstPtr & getRobotModel() const
Get the robot model this state is constructed for.
double * getVariablePositions()
Get a raw pointer to the positions of the variables stored in this state. Use carefully....
bool setFromIKSubgroups(const JointModelGroup *group, const EigenSTL::vector_Isometry3d &poses, const std::vector< std::string > &tips, const std::vector< std::vector< double > > &consistency_limits, double timeout=0.0, const GroupStateValidityCallbackFn &constraint=GroupStateValidityCallbackFn(), const kinematics::KinematicsQueryOptions &options=kinematics::KinematicsQueryOptions())
setFromIK for multiple poses and tips (end effectors) when no solver exists for the jmg that can solv...
void dropDynamics()
Reduce RobotState to kinematic information (remove velocity, acceleration and effort,...
bool dirtyJointTransform(const JointModel *joint) const
void setToRandomPositionsNearBy(const JointModelGroup *group, const RobotState &seed, double distance)
Set all joints in group to random values near the value in seed. distance is the maximum amount each ...
bool dirty() const
Returns true if anything in this state is dirty.
void updateLinkTransforms()
Update the reference frame transforms for links. This call is needed before using the transforms of l...
void interpolate(const RobotState &to, double t, RobotState &state) const
double distance(const RobotState &other) const
Return the sum of joint distances to "other" state. An L1 norm. Only considers active joints.
std::string getStateTreeString() const
const Eigen::Isometry3d & getFrameTransform(const std::string &frame_id, bool *frame_found=nullptr)
Get the transformation matrix from the model frame (root of model) to the frame identified by frame_i...
void setToRandomPositions()
Set all joints to random values. Values will be within default bounds.
bool satisfiesBounds(double margin=0.0) const
void setVariableEffort(const double *effort)
Given an array with effort values for all variables, set those values as the effort in this state.
void setJointGroupActivePositions(const JointModelGroup *group, const std::vector< double > &gstate)
Given positions for the variables of active joints that make up a group, in the order found in the gr...
bool dirtyLinkTransforms() const
void printStateInfo(std::ostream &out=std::cout) const
double getVariablePosition(const std::string &variable) const
Get the position of a particular variable. An exception is thrown if the variable is not known.
void update(bool force=false)
Update all transforms.
void dropAccelerations()
Remove accelerations from this state (this differs from setting them to zero)
void getRobotMarkers(visualization_msgs::msg::MarkerArray &arr, const std::vector< std::string > &link_names, const std_msgs::msg::ColorRGBA &color, const std::string &ns, const rclcpp::Duration &dur, bool include_attached=false) const
Get a MarkerArray that fully describes the robot markers for a given robot.
const AttachedBody * getAttachedBody(const std::string &name) const
Get the attached body named name. Return nullptr if not found.
bool setToIKSolverFrame(Eigen::Isometry3d &pose, const kinematics::KinematicsBaseConstPtr &solver)
Transform pose from the robot model's base frame to the reference frame of the IK solver.
void setToDefaultValues()
Set all joints to their default positions. The default position is 0, or if that is not within bounds...
void printStatePositions(std::ostream &out=std::cout) const
std::size_t getVariableCount() const
Get the number of variables that make up this state.
void printDirtyInfo(std::ostream &out=std::cout) const
void setVariableAccelerations(const double *acceleration)
Given an array with acceleration values for all variables, set those values as the accelerations in t...
const double * getJointAccelerations(const std::string &joint_name) const
void copyJointGroupAccelerations(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the acceleration values of the variables that make up the group into another ...
RobotState(const RobotModelConstPtr &robot_model)
A state can be constructed from a specified robot model. No values are initialized....
void dropEffort()
Remove effort values from this state (this differs from setting them to zero)
bool knowsFrameTransform(const std::string &frame_id) const
Check if a transformation matrix from the model frame (root of model) to frame frame_id is known.
const Eigen::Isometry3d & getJointTransform(const std::string &joint_name)
bool integrateVariableVelocity(const JointModelGroup *jmg, const Eigen::VectorXd &qdot, double dt, const GroupStateValidityCallbackFn &constraint=GroupStateValidityCallbackFn())
Given the velocities for the variables in this group (qdot) and an amount of time (dt),...
void enforcePositionBounds(const JointModel *joint)
bool hasAttachedBody(const std::string &id) const
Check if an attached body named id exists in this state.
const Eigen::Isometry3d & getGlobalLinkTransform(const std::string &link_name)
Get the link transform w.r.t. the root link (model frame) of the RobotModel. This is typically the ro...
void enforceVelocityBounds(const JointModel *joint)
void invertVelocity()
Invert velocity if present.
const Eigen::Isometry3d & getFrameInfo(const std::string &frame_id, const LinkModel *&robot_link, bool &frame_found) const
Get the transformation matrix from the model frame (root of model) to the frame identified by frame_i...
random_numbers::RandomNumberGenerator & getRandomNumberGenerator()
Return the instance of a random number generator.
void harmonizePosition(const JointModel *joint)
void clearAttachedBodies()
Clear all attached bodies. This calls delete on the AttachedBody instances, if needed.
void dropVelocities()
Remove velocities from this state (this differs from setting them to zero)
void zeroEffort()
Set all effort values to 0.0.
void updateCollisionBodyTransforms()
Update the transforms for the collision bodies. This call is needed before calling collision checking...
bool setFromIK(const JointModelGroup *group, const geometry_msgs::msg::Pose &pose, double timeout=0.0, const GroupStateValidityCallbackFn &constraint=GroupStateValidityCallbackFn(), const kinematics::KinematicsQueryOptions &options=kinematics::KinematicsQueryOptions(), const kinematics::KinematicsBase::IKCostFn &cost_function=kinematics::KinematicsBase::IKCostFn())
If the group this state corresponds to is a chain and a solver is available, then the joint values ca...
const moveit::core::LinkModel * getRigidlyConnectedParentLinkModel(const std::string &frame, const moveit::core::JointModelGroup *jmg=nullptr) const
Get the latest link upwards the kinematic tree which is only connected via fixed joints.
void setJointPositions(const std::string &joint_name, const double *position)
#define MOVEIT_CONSOLE_COLOR_RESET
#define MOVEIT_CONSOLE_COLOR_RED
rclcpp::Logger getLogger()
std::function< bool(RobotState *robot_state, const JointModelGroup *joint_group, const double *joint_group_variable_values)> GroupStateValidityCallbackFn
Signature for functions that can verify that if the group joint_group in robot_state is set to joint_...
std::map< const LinkModel *, Eigen::Isometry3d, std::less< const LinkModel * >, Eigen::aligned_allocator< std::pair< const LinkModel *const, Eigen::Isometry3d > > > LinkTransformMap
Map from link model instances to Eigen transforms.
std::ostream & operator<<(std::ostream &out, const VariableBounds &b)
Operator overload for printing variable bounds to a stream.
std::map< std::string, Eigen::Isometry3d, std::less< std::string >, Eigen::aligned_allocator< std::pair< const std::string, Eigen::Isometry3d > > > FixedTransformsMap
Map frame names to the transformation matrix that can transform objects from the frame name to the pl...
std::function< void(AttachedBody *body, bool attached)> AttachedBodyCallback
Main namespace for MoveIt.
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
A set of options for the kinematics solver.