39 #include <octomap_msgs/Octomap.h> 42 #include <kdl/frames_io.hpp> 61 Hessian Hzero = Hessian::Constant(6, Eigen::MatrixXd::Zero(_n, _n));
62 if (_flags &
KIN_J)
jacobian = ArrayJacobian::Constant(_size, Jzero);
63 if (_flags &
KIN_H)
hessian = ArrayHessian::Constant(_size, Hzero);
84 new (&
Phi) Eigen::Map<ArrayFrame>(solution->Phi.data() +
start,
length);
85 new (&
X) Eigen::Map<Eigen::VectorXd>(solution->x.data(), solution->x.rows());
93 return num_controlled_joints_;
103 if (!model)
ThrowPretty(
"No robot model provided!");
104 model_joints_names_ = model->getVariableNames();
108 const robot_model::JointModelGroup* group = model->getJointModelGroup(joint_group);
111 auto names = model->getJointModelGroupNames();
114 if (!joint_group.empty())
116 std::stringstream ss;
117 ss <<
"Joint group '" << joint_group <<
"' not defined in the robot model. " << names.size() <<
" joint groups available";
118 if (names.size() >
static_cast<std::size_t
>(0))
121 for (
const auto& joint_group_name : names)
122 ss << joint_group_name <<
", ";
130 for (
auto joint_model : model->getActiveJointModels())
131 controlled_joints_names_.push_back(joint_model->getName());
137 controlled_joints_names_ = group->getVariableNames();
144 BuildTree(robot_kinematics);
153 shapes_pub_ = Server::Advertise<visualization_msgs::MarkerArray>(name_ + (name_ ==
"" ?
"" :
"/") +
"CollisionShapes", 1,
true);
154 octomap_pub_ = Server::Advertise<octomap_msgs::Octomap>(name_ + (name_ ==
"" ?
"" :
"/") +
"OctoMap", 1,
true);
155 debug_scene_changed_ =
true;
157 visualization_msgs::MarkerArray msg;
158 msg.markers.resize(1);
159 msg.markers[0].action = 3;
160 shapes_pub_.publish(msg);
169 model_joints_map_.clear();
170 model_link_names_.clear();
171 controlled_link_names_.clear();
174 const robot_model::JointModel* root_joint = model_->getRootJoint();
175 root_joint_name_ = root_joint->getName();
176 std::string world_frame_name;
179 if (
s.name_ == root_joint->getName())
181 world_frame_name =
s.parent_frame_;
185 if (world_frame_name.empty())
187 world_frame_name =
"world_frame";
188 WARNING_NAMED(
"KinematicTree",
"No virtual joint defined. Defaulting world frame to " << world_frame_name)
192 double root_mass = 0.0;
194 auto& urdf_root_inertial = model_->getURDF()->getRoot()->inertial;
195 if (urdf_root_inertial)
197 root_mass = urdf_root_inertial->mass;
198 root_cog =
KDL::Vector(urdf_root_inertial->origin.position.x,
199 urdf_root_inertial->origin.position.y,
200 urdf_root_inertial->origin.position.z);
203 <<
" kg - CoG: " << root_cog);
218 model_tree_.resize(7);
220 const std::vector<std::string> floating_base_suffix = {
221 "/trans_x",
"/trans_y",
"/trans_z",
222 "/rot_z",
"/rot_y",
"/rot_x"};
223 for (
size_t i = 0; i < 6; ++i)
225 model_tree_[i + 1] = std::make_shared<KinematicElement>(i, model_tree_[i],
KDL::Segment(world_frame_name + floating_base_suffix[i],
KDL::Joint(root_joint_name_ + floating_base_suffix[i], types[i])));
226 model_tree_[i]->children.push_back(model_tree_[i + 1]);
233 auto RotW = std::find(controlled_joints_names_.begin(), controlled_joints_names_.end(), root_joint->getVariableNames()[6]);
234 if (RotW != controlled_joints_names_.end()) controlled_joints_names_.erase(RotW);
235 RotW = std::find(model_joints_names_.begin(), model_joints_names_.end(), root_joint->getVariableNames()[6]);
236 if (RotW != model_joints_names_.end()) model_joints_names_.erase(RotW);
244 model_tree_.resize(4);
247 for (
int i = 0; i < 3; ++i)
249 model_tree_[i + 1] = std::make_shared<KinematicElement>(
252 root_joint->getVariableNames()[i],
253 KDL::Joint(root_joint->getVariableNames()[i], types[i])));
254 model_tree_[i]->children.push_back(model_tree_[i + 1]);
259 ThrowPretty(
"Unsupported root joint type: " << root_joint->getTypeName());
262 AddElementFromSegmentMapIterator(robot_kinematics.
getRootSegment(), *(model_tree_.end() - 1));
267 model_tree_[2]->segment.setInertia(root_inertial);
271 model_tree_[7]->segment.setInertia(root_inertial);
275 model_tree_[4]->segment.setInertia(root_inertial);
278 for (
auto element : model_tree_) tree_.push_back(element);
281 tree_state_.setZero();
285 for (
int i = 0; i < tree_.size() - 1; ++i)
287 "Tree",
"Joint: " << tree_[i].lock()->segment.getJoint().getName() <<
" - Link: " << tree_[i].lock()->segment.getName()
288 <<
", mass: " << tree_[i].lock()->segment.getInertia().getMass()
289 <<
", CoM: " << tree_[i].lock()->segment.getInertia().getCOG());
292 num_joints_ = model_joints_names_.size();
293 num_controlled_joints_ = controlled_joints_names_.size();
294 state_size_ = num_controlled_joints_;
295 if (num_controlled_joints_ < 1)
ThrowPretty(
"No update joints specified!");
296 controlled_joints_.resize(num_controlled_joints_);
297 for (std::shared_ptr<KinematicElement> Joint : model_tree_)
299 Joint->is_robot_link =
true;
300 Joint->control_id = IsControlled(Joint);
301 Joint->is_controlled = Joint->control_id >= 0;
302 model_joints_map_[Joint->segment.getJoint().getName()] = Joint;
303 model_link_names_.push_back(Joint->segment.getName());
304 if (Joint->is_controlled)
306 controlled_joints_[Joint->control_id] = Joint;
307 controlled_joints_map_[Joint->segment.getJoint().getName()] = Joint;
308 controlled_link_names_.push_back(Joint->segment.getName());
318 if (Joint->segment.getJoint().getName().find(
319 root_joint->getName()) != std::string::npos)
320 controlled_base_type_ = model_base_type_;
323 model_tree_[0]->is_robot_link =
false;
325 joint_limits_ = Eigen::MatrixXd::Zero(num_controlled_joints_, 2);
326 velocity_limits_ = Eigen::VectorXd::Zero(num_controlled_joints_);
327 acceleration_limits_ = Eigen::VectorXd::Zero(num_controlled_joints_);
330 if (debug)
HIGHLIGHT_NAMED(
"KinematicTree::BuildTree",
"Number of controlled joints: " << num_controlled_joints_ <<
" - Number of model joints: " << num_joints_);
333 generator_ = std::mt19937(rd_());
336 const urdf::ModelInterfaceSharedPtr&
urdf = model_->getURDF();
337 std::vector<urdf::LinkSharedPtr> urdf_links;
338 urdf->getLinks(urdf_links);
339 for (urdf::LinkSharedPtr urdf_link : urdf_links)
341 if (urdf_link->visual_array.size() > 0)
343 std::shared_ptr<KinematicElement> element = tree_map_[urdf_link->name].lock();
345 element->visual.reserve(urdf_link->visual_array.size());
346 for (urdf::VisualSharedPtr urdf_visual : urdf_link->visual_array)
349 visual.
name = urdf_link->name +
"_visual_" + std::to_string(i);
350 visual.
frame =
KDL::Frame(
KDL::Rotation::Quaternion(urdf_visual->origin.rotation.x, urdf_visual->origin.rotation.y, urdf_visual->origin.rotation.z, urdf_visual->origin.rotation.w),
KDL::Vector(urdf_visual->origin.position.x, urdf_visual->origin.position.y, urdf_visual->origin.position.z));
351 if (urdf_visual->material)
353 urdf::MaterialSharedPtr material = urdf_visual->material->name ==
"" ? urdf_visual->material : urdf->getMaterial(urdf_visual->material->name);
354 visual.
color(0) = material->color.r;
355 visual.
color(1) = material->color.g;
356 visual.
color(2) = material->color.b;
357 visual.
color(3) = material->color.a;
365 switch (urdf_visual->geometry->type)
367 case urdf::Geometry::BOX:
369 std::shared_ptr<urdf::Box> box = std::static_pointer_cast<urdf::Box>(
ToStdPtr(urdf_visual->geometry));
370 visual.
shape = std::shared_ptr<shapes::Box>(
new shapes::Box(box->dim.x, box->dim.y, box->dim.z));
373 case urdf::Geometry::SPHERE:
375 std::shared_ptr<urdf::Sphere> sphere = std::static_pointer_cast<urdf::Sphere>(
ToStdPtr(urdf_visual->geometry));
379 case urdf::Geometry::CYLINDER:
381 std::shared_ptr<urdf::Cylinder> cylinder = std::static_pointer_cast<urdf::Cylinder>(
ToStdPtr(urdf_visual->geometry));
382 visual.
shape = std::shared_ptr<shapes::Cylinder>(
new shapes::Cylinder(cylinder->radius, cylinder->length));
385 case urdf::Geometry::MESH:
387 std::shared_ptr<urdf::Mesh> mesh = std::static_pointer_cast<urdf::Mesh>(
ToStdPtr(urdf_visual->geometry));
389 visual.
scale = Eigen::Vector3d(mesh->scale.x, mesh->scale.y, mesh->scale.z);
394 ThrowPretty(
"Unknown geometry type: " << urdf_visual->geometry->type);
396 element->visual.push_back(visual);
405 root_ = tree_[0].lock();
406 tree_state_.conservativeResize(tree_.size());
407 for (std::weak_ptr<KinematicElement> joint : tree_)
409 tree_map_[joint.lock()->segment.getName()] = joint.lock();
411 debug_tree_.resize(tree_.size() - 1);
413 debug_scene_changed_ =
true;
418 collision_tree_map_.clear();
420 environment_tree_.clear();
421 tree_.resize(model_tree_.size());
423 debug_scene_changed_ =
true;
428 visualization_msgs::Marker mrk;
430 marker_array_msg_.markers.push_back(mrk);
436 if (tree_map_.find(name) == tree_map_.end())
ThrowPretty(
"Attempting to attach unknown frame '" << name <<
"'!");
437 std::shared_ptr<KinematicElement> child = tree_map_.find(name)->second.lock();
438 if (child->id < model_tree_.size())
ThrowPretty(
"Can't re-attach robot link '" << name <<
"'!");
439 if (child->shape)
ThrowPretty(
"Can't re-attach collision shape without reattaching the object! ('" << name <<
"')");
440 std::shared_ptr<KinematicElement> parent;
441 if (parent_name ==
"")
443 if (tree_map_.find(root_->segment.getName()) == tree_map_.end())
ThrowPretty(
"Attempting to attach to unknown frame '" << root_->segment.getName() <<
"'!");
444 parent = tree_map_.find(root_->segment.getName())->second.lock();
448 if (tree_map_.find(parent_name) == tree_map_.end())
ThrowPretty(
"Attempting to attach to unknown frame '" << parent_name <<
"'!");
449 parent = tree_map_.find(parent_name)->second.lock();
451 if (parent->shape)
ThrowPretty(
"Can't attach object to a collision shape object! ('" << parent_name <<
"')");
454 child->segment =
KDL::Segment(child->segment.getName(), child->segment.getJoint(), pose, child->segment.getInertia());
458 child->segment =
KDL::Segment(child->segment.getName(), child->segment.getJoint(), parent->frame.Inverse() * child->frame * pose, child->segment.getInertia());
462 for (
auto it = child->parent.lock()->children.begin(); it != child->parent.lock()->children.end();)
464 std::shared_ptr<KinematicElement> childOfParent = it->lock();
465 if (childOfParent == child)
467 child->parent.lock()->children.erase(it);
475 child->parent = parent;
476 child->parent_name = parent->segment.
getName();
477 parent->children.push_back(child);
478 child->UpdateClosestRobotLink();
479 debug_scene_changed_ =
true;
484 std::shared_ptr<KinematicElement> element = AddElement(name, transform, parent, shape, inertia, color, visual, is_controlled);
485 environment_tree_.push_back(element);
489 std::shared_ptr<KinematicElement>
KinematicTree::AddElement(
const std::string& name,
const Eigen::Isometry3d& transform,
const std::string& parent,
const std::string& shape_resource_path, Eigen::Vector3d scale,
const KDL::RigidBodyInertia& inertia,
const Eigen::Vector4d& color,
const std::vector<VisualElement>& visual,
bool is_controlled)
491 std::string shape_path(shape_resource_path);
492 if (shape_path.empty())
497 else if (shape_path.substr(0, 1) ==
"{")
499 shape_path =
"file://" +
ParsePath(shape_path);
502 else if (shape_path.substr(0, 10) ==
"package://" || shape_path.substr(0, 8) ==
"file:///")
511 std::shared_ptr<KinematicElement> element = AddElement(name, transform, parent, shape, inertia, color, visual, is_controlled);
512 element->shape_resource_path = shape_path;
513 element->scale = scale;
519 std::shared_ptr<KinematicElement> parent_element;
522 parent_element = root_;
527 for (
const auto& element : tree_)
529 if (element.lock()->segment.getName() == parent)
531 parent_element = element.lock();
536 if (!found)
ThrowPretty(
"Can't find parent link named '" << parent <<
"'!");
540 std::shared_ptr<KinematicElement> new_element = std::make_shared<KinematicElement>(tree_.size(), parent_element,
KDL::Segment(name,
KDL::Joint(
KDL::Joint::None), transform_kdl, inertia));
543 new_element->shape = shape;
544 collision_tree_map_[new_element->segment.getName()] = new_element;
547 if (color != Eigen::Vector4d::Zero()) new_element->color = color;
549 new_element->parent_name = parent;
550 new_element->is_controlled = is_controlled;
551 tree_.push_back(new_element);
552 parent_element->children.push_back(new_element);
553 new_element->UpdateClosestRobotLink();
554 tree_map_[name] = new_element;
555 new_element->visual = visual;
556 debug_scene_changed_ =
true;
562 std::shared_ptr<KinematicElement> new_element = std::make_shared<KinematicElement>(model_tree_.size(), parent, segment->second.segment);
563 model_tree_.push_back(new_element);
564 if (parent) parent->children.push_back(new_element);
565 for (KDL::SegmentMap::const_iterator child : segment->second.children)
567 AddElementFromSegmentMapIterator(child, new_element);
573 for (
int i = 0; i < controlled_joints_names_.size(); ++i)
575 if (controlled_joints_names_[i] == joint->segment.getJoint().getName())
return i;
584 auto element = tree_map_[link_name].lock();
586 if (element && element->is_controlled)
588 return element->control_id;
593 element = element->parent.lock();
595 if (element && element->is_controlled)
597 return element->control_id;
601 catch (
const std::out_of_range& e)
610 flags_ = request.
flags;
614 state_size_ = num_controlled_joints_;
616 for (
int i = 0; i < request.
frames.size(); ++i)
618 if (request.
frames[i].frame_A_link_name ==
"")
619 solution_->frame[i].frame_A = root_;
623 solution_->frame[i].frame_A = tree_map_.at(request.
frames[i].frame_A_link_name);
625 catch (
const std::out_of_range& e)
627 ThrowPretty(
"No frame_A link exists named '" << request.
frames[i].frame_A_link_name <<
"'");
629 if (request.
frames[i].frame_B_link_name ==
"")
630 solution_->frame[i].frame_B = root_;
634 solution_->frame[i].frame_B = tree_map_.at(request.
frames[i].frame_B_link_name);
636 catch (
const std::out_of_range& e)
638 ThrowPretty(
"No frame_B link exists named '" << request.
frames[i].frame_B_link_name <<
"'");
641 solution_->frame[i].frame_A_offset = request.
frames[i].frame_A_offset;
642 solution_->frame[i].frame_B_offset = request.
frames[i].frame_B_offset;
653 debug_frames_.resize(solution_->frame.size() * 2);
660 if (x.size() != state_size_)
ThrowPretty(
"Wrong state vector size! Got " << x.size() <<
" expected " << state_size_);
662 for (
int i = 0; i < num_controlled_joints_; ++i)
663 tree_state_(controlled_joints_[i].lock()->id) = x(i);
670 if (flags_ &
KIN_J) UpdateJ();
671 if (flags_ & KIN_J && flags_ &
KIN_H) UpdateH();
672 if (debug) PublishFrames();
677 std::queue<std::shared_ptr<KinematicElement>> elements;
678 elements.push(root_);
679 root_->RemoveExpiredChildren();
680 while (elements.size() > 0)
682 auto element = elements.front();
686 if (element->id > -1)
688 if (element->segment.getJoint().getType() != KDL::Joint::JointType::None)
690 element->frame = element->parent.lock()->frame * element->GetPose(tree_state_(element->id));
694 element->frame = element->parent.lock()->frame * element->GetPose();
702 element->frame = element->GetPose();
704 element->RemoveExpiredChildren();
705 for (std::weak_ptr<KinematicElement> child : element->children)
707 elements.push(child.lock());
721 for (std::weak_ptr<KinematicElement> element : tree_)
743 if (debug_scene_changed_)
745 debug_scene_changed_ =
false;
746 marker_array_msg_.markers.clear();
747 for (
int i = 0; i < tree_.size(); ++i)
750 if (tree_[i].lock()->shape_resource_path !=
"")
752 visualization_msgs::Marker mrk;
753 mrk.action = visualization_msgs::Marker::ADD;
754 mrk.frame_locked =
true;
756 mrk.ns =
"CollisionObjects";
757 mrk.color =
GetColor(tree_[i].lock()->color);
758 mrk.header.frame_id = tf_prefix +
"/" + tree_[i].lock()->segment.getName();
759 mrk.pose.orientation.w = 1.0;
760 mrk.type = visualization_msgs::Marker::MESH_RESOURCE;
761 mrk.mesh_resource = tree_[i].lock()->shape_resource_path;
762 mrk.mesh_use_embedded_materials =
true;
763 mrk.scale.x = tree_[i].lock()->scale(0);
764 mrk.scale.y = tree_[i].lock()->scale(1);
765 mrk.scale.z = tree_[i].lock()->scale(2);
766 marker_array_msg_.markers.push_back(mrk);
769 else if (tree_[i].lock()->shape && (!tree_[i].lock()->closest_robot_link.lock() || !tree_[i].lock()->closest_robot_link.lock()->is_robot_link))
771 if (tree_[i].lock()->shape->type != shapes::ShapeType::OCTREE)
773 visualization_msgs::Marker mrk;
775 mrk.action = visualization_msgs::Marker::ADD;
776 mrk.frame_locked =
true;
778 mrk.ns =
"CollisionObjects";
779 mrk.color =
GetColor(tree_[i].lock()->color);
780 mrk.header.frame_id = tf_prefix +
"/" + tree_[i].lock()->segment.getName();
781 mrk.pose.orientation.w = 1.0;
782 marker_array_msg_.markers.push_back(mrk);
790 octomap_msgs::Octomap octomap_msg;
792 octomap_msg.header.frame_id = tf_prefix +
"/" + tree_[i].lock()->segment.getName();
793 octomap_pub_.publish(octomap_msg);
797 shapes_pub_.publish(marker_array_msg_);
812 if (!element_A)
ThrowPretty(
"The pointer to KinematicElement A is dead.");
815 frame.
frame_B = (element_B ==
nullptr) ? root_ : element_B;
823 std::string name_a = element_A ==
"" ? root_->segment.getName() : element_A;
824 std::string name_b = element_B ==
"" ? root_->segment.getName() : element_B;
825 auto A = tree_map_.find(name_a);
826 if (
A == tree_map_.end())
ThrowPretty(
"Can't find link '" << name_a <<
"'!");
827 auto B = tree_map_.find(name_b);
828 if (B == tree_map_.end())
ThrowPretty(
"Can't find link '" << name_b <<
"'!");
829 return FK(
A->second.lock(), offset_a, B->second.lock(), offset_b);
837 solution_->Phi(i) = FK(frame);
844 if (!element_A)
ThrowPretty(
"The pointer to KinematicElement A is dead.");
847 frame.
frame_B = (element_B ==
nullptr) ? root_ : element_B;
851 ComputeJ(frame, ret);
857 std::string name_a = element_A ==
"" ? root_->segment.getName() : element_A;
858 std::string name_b = element_B ==
"" ? root_->segment.getName() : element_B;
859 auto A = tree_map_.find(name_a);
860 if (
A == tree_map_.end())
ThrowPretty(
"Can't find link '" << name_a <<
"'!");
861 auto B = tree_map_.find(name_b);
862 if (B == tree_map_.end())
ThrowPretty(
"Can't find link '" << name_b <<
"'!");
863 return Jacobian(
A->second.lock(), offset_a, B->second.lock(), offset_b);
868 if (!element_A)
ThrowPretty(
"The pointer to KinematicElement A is dead.");
871 frame.
frame_B = (element_B ==
nullptr) ? root_ : element_B;
876 exotica::Hessian hessian = exotica::Hessian::Constant(6, Eigen::MatrixXd::Zero(num_controlled_joints_, num_controlled_joints_));
877 ComputeH(frame, J, hessian);
883 std::string name_a = element_A ==
"" ? root_->segment.getName() : element_A;
884 std::string name_b = element_B ==
"" ? root_->segment.getName() : element_B;
885 auto A = tree_map_.find(name_a);
886 if (
A == tree_map_.end())
ThrowPretty(
"Can't find link '" << name_a <<
"'!");
887 auto B = tree_map_.find(name_b);
888 if (B == tree_map_.end())
ThrowPretty(
"Can't find link '" << name_b <<
"'!");
889 return this->
Hessian(
A->second.lock(), offset_a, B->second.lock(), offset_b);
894 jacobian.
data.setZero();
896 std::shared_ptr<KinematicElement> it = frame.
frame_A.lock();
897 while (it !=
nullptr)
899 if (it->is_controlled)
902 if (it->parent.lock() !=
nullptr) segment_reference = it->parent.lock()->frame;
903 jacobian.
setColumn(it->control_id, frame.
temp_B.
M.
Inverse() * (segment_reference.
M * it->segment.twist(tree_state_(it->id), 1.0)).RefPoint(frame.
temp_A.
p - it->frame.p));
905 it = it->parent.lock();
908 while (it !=
nullptr)
910 if (it->is_controlled)
913 if (it->parent.lock() !=
nullptr) segment_reference = it->parent.lock()->frame;
914 jacobian.
setColumn(it->control_id, jacobian.
getColumn(it->control_id) - (frame.
temp_B.
M.
Inverse() * (segment_reference.
M * it->segment.twist(tree_state_(it->id), 1.0)).RefPoint(frame.
temp_A.
p - it->frame.p)));
916 it = it->parent.lock();
922 hessian.conservativeResize(6);
923 for (
int i = 0; i < 6; ++i)
931 for (
int i = 0; i < jacobian.
columns(); ++i)
934 for (
int j = i; j < jacobian.
columns(); ++j)
958 ComputeJ(frame, solution_->jacobian(i));
968 ComputeH(frame, solution_->jacobian(i), solution_->hessian(i));
975 return model_base_type_;
980 return controlled_base_type_;
985 std::map<std::string, std::vector<double>> limits;
986 for (
auto it : controlled_joints_)
988 limits[it.lock()->segment.getJoint().getName()] = it.lock()->joint_limits;
1000 Eigen::VectorXd q_rand(num_controlled_joints_);
1001 for (
unsigned int i = 0; i < num_controlled_joints_; ++i)
1003 q_rand(i) = random_state_distributions_[i](generator_);
1010 if (lower_in.rows() == num_controlled_joints_)
1012 for (
unsigned int i = 0; i < num_controlled_joints_; ++i)
1019 ThrowPretty(
"Got " << lower_in.rows() <<
" but " << num_controlled_joints_ <<
" expected.");
1022 UpdateJointLimits();
1027 if (upper_in.rows() == num_controlled_joints_)
1029 for (
unsigned int i = 0; i < num_controlled_joints_; ++i)
1036 ThrowPretty(
"Got " << upper_in.rows() <<
" but " << num_controlled_joints_ <<
" expected.");
1039 UpdateJointLimits();
1044 if (velocity_in.rows() == num_controlled_joints_)
1046 for (
unsigned int i = 0; i < num_controlled_joints_; ++i)
1048 controlled_joints_[i].lock()->velocity_limit = velocity_in(i);
1053 ThrowPretty(
"Got " << velocity_in.rows() <<
" but " << num_controlled_joints_ <<
" expected.");
1056 UpdateJointLimits();
1061 if (acceleration_in.rows() == num_controlled_joints_)
1063 for (
unsigned int i = 0; i < num_controlled_joints_; ++i)
1065 controlled_joints_[i].lock()->acceleration_limit = acceleration_in(i);
1068 has_acceleration_limit_ =
true;
1072 ThrowPretty(
"Got " << acceleration_in.rows() <<
" but " << num_controlled_joints_ <<
" expected.");
1075 UpdateJointLimits();
1079 const std::vector<double>& lower,
const std::vector<double>& upper)
1085 if (lower.size() != 6 || upper.size() != 6)
1089 for (
int i = 0; i < 6; ++i)
1091 controlled_joints_[i].lock()->joint_limits = {lower[i], upper[i]};
1094 UpdateJointLimits();
1098 const std::vector<double>& lower,
const std::vector<double>& upper,
const std::vector<double>& velocity,
const std::vector<double>& acceleration)
1104 if (lower.size() != 6 || upper.size() != 6)
1108 if (velocity.size() != 6 && velocity.size() != 0)
1112 if (acceleration.size() != 6 && acceleration.size() != 0)
1116 for (
int i = 0; i < 6; ++i)
1118 controlled_joints_[i].lock()->joint_limits = {lower[i], upper[i]};
1119 controlled_joints_[i].lock()->velocity_limit = {velocity.size() != 0 ? velocity[i] :
inf};
1120 controlled_joints_[i].lock()->acceleration_limit = {acceleration.size() != 0 ? acceleration[i] :
inf};
1123 UpdateJointLimits();
1127 const std::vector<double>& lower,
const std::vector<double>& upper)
1133 if (lower.size() != 3 || upper.size() != 3)
1137 for (
int i = 0; i < 3; ++i)
1139 controlled_joints_[i].lock()->joint_limits = {lower[i], upper[i]};
1142 UpdateJointLimits();
1146 const std::vector<double>& lower,
const std::vector<double>& upper,
const std::vector<double>& velocity,
const std::vector<double>& acceleration)
1152 if (lower.size() != 3 || upper.size() != 3)
1156 if (velocity.size() != 3 && velocity.size() != 0)
1160 if (acceleration.size() != 3 && acceleration.size() != 0)
1164 for (
int i = 0; i < 3; ++i)
1166 controlled_joints_[i].lock()->joint_limits = {lower[i], upper[i]};
1167 controlled_joints_[i].lock()->velocity_limit = {velocity.size() != 0 ? velocity[i] :
inf};
1168 controlled_joints_[i].lock()->acceleration_limit = {acceleration.size() != 0 ? acceleration[i] :
inf};
1171 UpdateJointLimits();
1176 std::vector<std::string> vars = model_->getVariableNames();
1177 for (
int i = 0; i < vars.size(); ++i)
1179 if (controlled_joints_map_.find(vars[i]) != controlled_joints_map_.end())
1181 auto& ControlledJoint = controlled_joints_map_.at(vars[i]);
1182 int index = ControlledJoint.lock()->control_id;
1188 if (model_->getVariableBounds(vars[i]).position_bounded_)
1190 controlled_joints_[index].lock()->joint_limits = {model_->getVariableBounds(vars[i]).min_position_, model_->getVariableBounds(vars[i]).max_position_};
1194 controlled_joints_[index].lock()->joint_limits = {-
inf,
inf};
1196 if (model_->getVariableBounds(vars[i]).velocity_bounded_)
1198 controlled_joints_[index].lock()->velocity_limit = {model_->getVariableBounds(vars[i]).max_velocity_};
1202 controlled_joints_[index].lock()->velocity_limit = {
inf};
1204 if (model_->getVariableBounds(vars[i]).acceleration_bounded_)
1206 controlled_joints_[index].lock()->acceleration_limit = {model_->getVariableBounds(vars[i]).max_acceleration_};
1210 controlled_joints_[index].lock()->acceleration_limit = {
inf};
1219 controlled_joints_[0].lock()->joint_limits = {-
inf,
inf};
1220 controlled_joints_[1].lock()->joint_limits = {-
inf, inf};
1221 controlled_joints_[2].lock()->joint_limits = {-
inf, inf};
1222 controlled_joints_[3].lock()->joint_limits = {-
pi,
pi};
1223 controlled_joints_[4].lock()->joint_limits = {-
pi, pi};
1224 controlled_joints_[5].lock()->joint_limits = {-
pi, pi};
1228 controlled_joints_[0].lock()->joint_limits = {-
inf,
inf};
1229 controlled_joints_[1].lock()->joint_limits = {-
inf, inf};
1230 controlled_joints_[2].lock()->joint_limits = {-
pi,
pi};
1233 UpdateJointLimits();
1238 joint_limits_.setZero();
1239 for (
int i = 0; i < num_controlled_joints_; ++i)
1243 velocity_limits_(i) = controlled_joints_[i].lock()->velocity_limit;
1244 acceleration_limits_(i) = controlled_joints_[i].lock()->acceleration_limit;
1248 random_state_distributions_.clear();
1249 for (
int i = 0; i < num_controlled_joints_; ++i)
1258 return root_->segment.getName();
1263 return root_joint_name_;
1268 Eigen::VectorXd ret(model_joints_names_.size());
1270 for (
int i = 0; i < model_joints_names_.size(); ++i)
1272 ret(i) = tree_state_(model_joints_map_.at(model_joints_names_[i]).lock()->id);
1279 std::map<std::string, double> ret;
1280 for (
const std::string& joint_name : model_joints_names_)
1282 ret[joint_name] = tree_state_(model_joints_map_.at(joint_name).lock()->id);
1290 for (
const std::string& l : {begin, end})
1292 if (!tree_map_.count(l))
1299 std::vector<std::string> chain;
1300 for (std::weak_ptr<KinematicElement> l = tree_map_.at(end);
1301 l.lock()->segment.getName() != begin;
1302 l = l.lock()->parent, chain.push_back(l.lock()->segment.getJoint().getName()))
1304 if (l.lock()->parent.lock() ==
nullptr)
1306 ThrowPretty(
"There is no connection between '" + begin +
"' and '" + end +
"'!");
1311 std::reverse(chain.begin(), chain.end());
1318 for (
const std::string& l : {begin, end})
1320 if (!tree_map_.count(l))
1327 std::vector<std::string> chain;
1328 for (std::shared_ptr<const KinematicElement> l = tree_map_.at(end).lock(); l->segment.getName() != begin; l = l->parent.lock())
1330 chain.push_back(l->segment.getName());
1331 if (l->parent.lock() ==
nullptr)
1333 ThrowPretty(
"There is no connection between '" + begin +
"' and '" + end +
"'!");
1338 std::reverse(chain.begin(), chain.end());
1345 if (x.rows() == num_controlled_joints_)
1351 if (x.rows() != model_joints_names_.size())
ThrowPretty(
"Model state vector has wrong size, expected " << model_joints_names_.size() <<
" got " << x.rows());
1352 for (
int i = 0; i < model_joints_names_.size(); ++i)
1354 tree_state_(model_joints_map_.at(model_joints_names_[i]).lock()->id) = x(i);
1358 if (flags_ &
KIN_J) UpdateJ();
1359 if (debug) PublishFrames();
1364 for (
auto& joint : x)
1368 tree_state_(model_joints_map_.at(joint.first).lock()->id) = joint.second;
1370 catch (
const std::out_of_range& e)
1372 WARNING(
"Robot model does not contain joint '" << joint.first <<
"' - ignoring.");
1377 if (flags_ &
KIN_J) UpdateJ();
1378 if (debug) PublishFrames();
1383 Eigen::VectorXd
x(num_controlled_joints_);
1384 for (
int i = 0; i < controlled_joints_.size(); ++i)
1386 x(i) = tree_state_(controlled_joints_[i].lock()->
id);
1393 return std::find(std::begin(model_link_names_), std::end(model_link_names_), link) != std::end(model_link_names_);
1398 Eigen::VectorXd
x(num_controlled_joints_);
1399 for (
int i = 0; i < controlled_joints_.size(); ++i)
1401 x(i) = controlled_joints_[i].lock()->segment.getInertia().getMass();
1408 std::map<std::string, shapes::ShapeType> ret;
1409 for (
const auto& element : collision_tree_map_)
1411 ret[element.second.lock()->segment.getName()] = element.second.lock()->shape->type;
1419 return tree_map_.find(name) != tree_map_.end();
1424 auto it = tree_map_.find(frame_name);
1425 if (it == tree_map_.end())
ThrowPretty(
"KinematicElement does not exist:" << frame_name);
1427 return it->second.lock();
Eigen::Map< ArrayJacobian > jacobian
std::map< std::string, double > GetModelStateMap() const
void Create(std::shared_ptr< KinematicResponse > solution)
void ComputeH(KinematicFrame &frame, const KDL::Jacobian &jacobian, exotica::Hessian &hessian) const
bool DoesLinkWithNameExist(std::string name) const
Checks whether a link with this name exists in any of the trees.
std::vector< KinematicFrameRequest > frames
void Update(Eigen::VectorXdRefConst x)
KDL_PARSER_PUBLIC bool treeFromUrdfModel(const urdf::ModelInterface &robot_model, KDL::Tree &tree)
Eigen::VectorXd GetRandomControlledState()
Random state generation.
std::map< std::string, shapes::ShapeType > GetCollisionObjectTypes() const
int IsControlled(std::shared_ptr< KinematicElement > joint)
std::weak_ptr< KinematicElement > frame_B
KDL::Frame frame_A_offset
BaseType GetModelBaseType() const
std::shared_ptr< KinematicElement > FindKinematicElementByName(const std::string &frame_name)
#define WARNING_NAMED(name, x)
Eigen::MatrixXd Jacobian(std::shared_ptr< KinematicElement > element_A, const KDL::Frame &offset_a, std::shared_ptr< KinematicElement > element_B, const KDL::Frame &offset_b) const
void AddElementFromSegmentMapIterator(KDL::SegmentMap::const_iterator segment, std::shared_ptr< KinematicElement > parent)
void transformKDLToTF(const KDL::Frame &k, tf::Transform &t)
static Rotation Quaternion(double x, double y, double z, double w)
Eigen::Map< Eigen::VectorXd > X
Eigen::Map< ArrayHessian > hessian
exotica::Hessian Hessian(std::shared_ptr< KinematicElement > element_A, const KDL::Frame &offset_a, std::shared_ptr< KinematicElement > element_B, const KDL::Frame &offset_b) const
std::vector< std::string > GetKinematicChainLinks(const std::string &begin, const std::string &end) const
GetKinematicChainLinks get the links between begin and end of kinematic chain.
Eigen::VectorXd GetControlledLinkMass() const
KinematicRequestFlags flags
std_msgs::ColorRGBA GetColor(double r, double g, double b, double a=1.0)
std::shared_ptr< Shape > ShapePtr
static bool binaryMapToMsg(const OctomapT &octomap, Octomap &msg)
std::weak_ptr< KinematicElement > frame_A
void transformEigenToKDL(const Eigen::Affine3d &e, KDL::Frame &k)
const std::string & GetRootJointName() const
unsigned int columns() const
Eigen::VectorXd GetModelState() const
std::shared_ptr< KinematicElement > AddEnvironmentElement(const std::string &name, const Eigen::Isometry3d &transform, const std::string &parent="", shapes::ShapeConstPtr shape=shapes::ShapeConstPtr(nullptr), const KDL::RigidBodyInertia &inertia=KDL::RigidBodyInertia::Zero(), const Eigen::Vector4d &color=Eigen::Vector4d(0.5, 0.5, 0.5, 1.0), const std::vector< VisualElement > &visual={}, bool is_controlled=false)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Matrix< double, 6, Eigen::Dynamic > data
std::string resolve(const std::string &prefix, const std::string &frame_name)
void SetJointLimitsLower(Eigen::VectorXdRefConst lower_in)
static void SendTransform(const tf::StampedTransform &transform)
const std::string & getName() const
void SetJointLimitsUpper(Eigen::VectorXdRefConst upper_in)
void Instantiate(const std::string &joint_group, robot_model::RobotModelPtr model, const std::string &name)
int GetNumModelJoints() const
std::string ToString(const KDL::Frame &s)
Eigen::VectorXd GetControlledState() const
KinematicRequestFlags flags
Eigen::Array< Eigen::MatrixXd, Eigen::Dynamic, 1 > Hessian
void BuildTree(const KDL::Tree &RobotKinematics)
KDL::Frame FK(KinematicFrame &frame) const
const std::string & GetRootFrameName() const
int IsControlledLink(const std::string &link_name)
bool HasModelLink(const std::string &link) const
std::vector< std::string > GetKinematicChain(const std::string &begin, const std::string &end) const
GetKinematicChain get list of joints in a kinematic chain.
void setColumn(unsigned int i, const Twist &t)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW std::string name
Eigen::Map< ArrayFrame > Phi
bool constructMarkerFromShape(const Shape *shape, visualization_msgs::Marker &mk, bool use_mesh_triangle_list=false)
void ComputeJ(KinematicFrame &frame, KDL::Jacobian &jacobian) const
Twist getColumn(unsigned int i) const
void SetJointAccelerationLimits(Eigen::VectorXdRefConst acceleration_in)
const Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
Convenience wrapper for storing references to sub-matrices/vectors.
int GetNumControlledJoints() const
void ChangeParent(const std::string &name, const std::string &parent, const KDL::Frame &pose, bool relative)
Eigen::Map< ArrayTwist > Phi_dot
SegmentMap::const_iterator getRootSegment() const
KDL::Frame frame_B_offset
void SetPlanarBaseLimitsPosXYEulerZ(const std::vector< double > &lower, const std::vector< double > &upper)
std::vector< KinematicFrame > frame
std::string ParsePath(const std::string &path)
Mesh * createMeshFromResource(const std::string &resource)
#define HIGHLIGHT_NAMED(name, x)
void SetJointVelocityLimits(Eigen::VectorXdRefConst velocity_in)
The KinematicResponse is the container to keep kinematic update data. The corresponding KinematicSolu...
void SetFloatingBaseLimitsPosXYZEulerZYX(const std::vector< double > &lower, const std::vector< double > &upper)
robot_model::RobotModelPtr GetRobotModel() const
std::string shape_resource_path
void PublishFrames(const std::string &tf_prefix="exotica")
BaseType GetControlledBaseType() const
std::shared_ptr< KinematicElement > AddElement(const std::string &name, const Eigen::Isometry3d &transform, const std::string &parent="", shapes::ShapeConstPtr shape=shapes::ShapeConstPtr(nullptr), const KDL::RigidBodyInertia &inertia=KDL::RigidBodyInertia::Zero(), const Eigen::Vector4d &color=Eigen::Vector4d(0.5, 0.5, 0.5, 1.0), const std::vector< VisualElement > &visual={}, bool is_controlled=false)
std::shared_ptr< KinematicResponse > RequestFrames(const KinematicsRequest &request)
#define WARNING(x)
With endline.
void SetModelState(Eigen::VectorXdRefConst x)
std::map< std::string, std::vector< double > > GetUsedJointLimits() const
std::shared_ptr< const Shape > ShapeConstPtr