11 using namespace se2ez;
31 frame.second.dirty =
true;
32 frame.second.jc =
false;
38 for (
const auto &frame :
frames)
39 other->getEntry(frame.first) = frame.second;
44 auto inserted =
frames.emplace(frame_name,
Value{});
45 return inserted.first->second;
50 const auto &result =
frames.find(frame_name);
51 if (result ==
frames.end())
54 return result->second;
65 ss << (entry.dirty ?
"D" :
"C") <<
tf::printFrame(entry.pose) <<
"(";
66 for (
const auto &tf : entry.geometry)
74 return "X[ 0, 0, 0 ] ()";
96 const Eigen::Ref<const Eigen::VectorXd>
116 data_.emplace(
"root", std::make_shared<FrameData>());
135 if (frame->getName() ==
"root")
153 SE2EZ_WARN(
"frame %1 not in tree!", frame_name);
157 auto data =
data_[frame_name];
161 SE2EZ_WARN(
"frame %1 is movable thus it cannot be removed", frame_name);
166 for (
const auto &child : data->children)
170 data_.erase(frame_name);
175 for (
const auto &fname : frobot->getFrameNames())
180 auto nframe_name = scene_name +
":" + fname;
181 auto nframe = std::make_shared<Frame>(nframe_name, state->getPose(frobot, fname),
182 frobot->getFrame(fname)->getGeometry());
190 for (
const auto &fname : arobot->getFrameNames())
192 auto oframe = arobot->getFrame(fname);
196 auto nframe = std::make_shared<Frame>(fname, oframe->getTip(), oframe->getJoint().type,
197 oframe->getJoint().lower, oframe->getJoint().upper,
198 arobot->getFrame(fname)->getGeometry());
200 auto parent = arobot->getFrameParent(fname);
214 std::find_if(parent->children.begin(), parent->children.end(),
215 [child](
const FrameDataPtr &f) ->
bool {
return f->frame->getName() == child; });
217 if (found == parent->children.end())
219 log::format(
"Child %1% not found in parent %2%", child, parent->frame->getName()));
221 parent->children.erase(found);
228 const auto &frame_name = frame->getName();
232 auto inserted =
data_.emplace(frame->getName(), std::make_shared<FrameData>(frame, new_parent));
236 if (!inserted.second)
239 const auto &old_parent = data->parent;
246 data->parent = new_parent;
250 new_parent->children.emplace_back(data);
266 for (
auto &child : root->children)
276 auto &joint = frame->frame->getJoint();
280 joints_.emplace_back(name, frame);
282 const auto &bounds = joint.getBounds();
283 frame->getValues(
lower_) = bounds.first;
284 frame->getValues(
upper_) = bounds.second;
288 [](
const auto &a,
const auto &b) {
return a.second->index < b.second->index; });
290 jac_ = std::make_shared<KDL::TreeJntToJacSolver>(
tree_);
298 const auto &frame = data->frame;
299 const auto &name = data->frame->getName();
300 auto &children = data->children;
303 const auto &segments = frame->getSegments();
306 for (
const auto &segment : segments)
308 tree_.addSegment(segment, *parent);
309 parent = &segment.getName();
312 const bool isFixed = frame->getJoint().type ==
Joint::FIXED;
313 data->movable = !isFixed || movable;
314 data->depth = data->parent->depth + 1;
321 for (
auto &child : children)
325 data->index = GetTreeElementQNr(
tree_.getSegment(segments[0].getName())->second);
326 data->size = segments.size() - 1;
329 if (children.empty() && data->movable)
335 auto map = std::make_shared<FrameMap>(*this);
336 auto state = std::make_shared<State>(*this);
337 for (
const auto &data :
data_)
339 const auto &frame = data.second;
341 getPose(frame, state->data, map);
351 for (
const auto &joint : this->
getJoints())
353 const auto &jointName = joint.first;
355 ss << jointName <<
"_" << jointType <<
"_";
367 return tree_.getNrOfJoints();
400 return data_.count(name) > 0;
405 const auto &data =
data_.find(frame_name);
406 if (data !=
data_.end())
414 const auto &data =
data_.find(frame_name);
415 if (data !=
data_.end())
428 auto entry =
named_.find(name);
429 if (entry !=
named_.end())
430 entry->second->copy(state);
434 entry =
named_.emplace(name, std::make_shared<State>(*
this)).first;
435 entry->second->copy(state);
441 const auto &entry =
named_.find(name);
442 if (entry ==
named_.end())
445 state->copy(entry->second);
451 for (
const auto &named :
named_)
464 for (
const auto &e : named)
491 for (
const auto &joint :
joints_)
493 const auto &j = joint.second->frame->getJoint();
496 for (
unsigned int i = 0; i < j.n - 1; ++i)
501 for (
unsigned int i = 0; i < j.n; ++i)
523 Eigen::Ref<Eigen::VectorXd> q)
const 528 const Eigen::Ref<const Eigen::VectorXd>
534 void Robot::fk(
const Eigen::Ref<const Eigen::VectorXd> &q, FrameMapPtr frames)
const 536 for (
const auto &ee :
ees_)
543 const Eigen::Ref<const Eigen::VectorXd> &q, FrameMapPtr frames)
const 550 FrameMapPtr frames)
const 552 const auto &name = data->frame->getName();
553 auto &entry = frames->getEntry(name);
559 entry =
static_->getEntry(name);
563 const auto &values = data->getValuesConst(q);
564 const auto &local = data->frame->getPose(values);
568 entry.pose = parent.pose * local;
569 data->frame->getGeometryPoses(entry.pose, entry.geometry);
575 const Eigen::Ref<const Eigen::VectorXd> &q,
576 FrameMapPtr frames)
const 578 auto &entry = frames->getEntry(frame_name);
583 KDL::Jacobian j(q.size());
584 jac_->JntToJac(in, j, frame_name);
588 entry.jacobian = Eigen::MatrixXd(3, q.size());
589 entry.jacobian.row(0) = j.data.row(0);
590 entry.jacobian.row(1) = j.data.row(1);
591 entry.jacobian.row(2) = j.data.row(5);
601 for (
const auto &pair :
joints_)
603 const auto &frame = pair.second;
604 const auto &joint = frame->frame->getJoint();
606 const double m = frame->depth;
607 const double weight = (weighted) ? (n - m) / n : 1.;
609 d += weight * joint.distance(frame->getValuesConst(a->data), frame->getValuesConst(b->data));
617 for (
const auto &pair :
joints_)
619 const auto &frame = pair.second;
620 const auto &joint = frame->frame->getJoint();
622 joint.enforceBounds(frame->getValues(a->data));
630 for (
const auto &pair :
joints_)
632 const auto &frame = pair.second;
633 const auto &joint = frame->frame->getJoint();
635 if (!joint.inBounds(frame->getValues(a->data)))
644 for (
const auto &pair :
joints_)
646 const auto &frame = pair.second;
647 const auto &joint = frame->frame->getJoint();
649 joint.interpolate(frame->getValuesConst(from->data), frame->getValuesConst(to->data), t,
650 frame->getValues(state->data));
666 ss << frame->frame->printDebug();
668 for (
unsigned int i = 0; i < frame->children.size(); ++i)
669 ss << ((i > 0) ?
", " :
" C[") << frame->children[i]->frame->getName();
672 ss <<
log::format(
"] P[%1%]", frame->parent->frame->getName());
677 ss <<
log::format(
" [%1%/%2%]", frame->index, frame->size);
679 ss <<
log::format(
" D:%1% M:%2%", frame->depth, frame->movable);
697 ss << prefix <<
"\\_ " << frame->frame->getName();
700 ss <<
" (" <<
function(frame) <<
")";
704 for (
unsigned int i = 0; i < frame->children.size(); ++i)
706 prefix + ((i == frame->children.size() - 1) ?
" " :
"|"));
const FramePtr & getFrameConst(const std::string &name) const
Get the frame with name name.
bool inLimits(const StatePtr &a) const
Check if all configuration parameters are within limits.
Eigen::VectorXd upper_
Upper limits of joints.
void detachFrame(const FramePtr &frame)
Detach a frame from a kinematic tree. If frame has children all children will be detached as well...
const Eigen::VectorXd getUpperLimits() const
Get the upper limits of the joints for this robot.
A shared pointer wrapper for se2ez::State.
unsigned int size
Number of joint values for this frame.
const FrameDataPtr & getFrameDataConst(const std::string &frame_name) const
Retrieves kinematic tree data associated with the frame frame_name.
tf::EigenHash< std::string, Value > frames
Map of frame name to dirty / transform pairs.
double distance(const StatePtr &a, const StatePtr &b, bool weighted=true) const
Compute the distance between two states.
const Eigen::VectorXd getLowerLimits() const
Get the lower limits of the joints for this robot.
A shared pointer wrapper for se2ez::Robot::FrameData.
FrameMapPtr static_
Transforms for all non-movable links.
static const std::string & typeToString(const Type &type)
Converts a joint type into its string representation.
std::string printFrame(const Eigen::Isometry2d &frame)
Returns a string "[x, y, t]" of the translation (x, y) and rotation (t) component of a transform...
void interpolate(const StatePtr &from, const StatePtr &to, double t, StatePtr state) const
Interpolate between two states.
FrameDataPtr getFrameData(const std::string &frame_name)
Retrieves kinematic tree data associated with the frame frame_name.
const std::vector< bool > getContinuity() const
Returns a vector of booleans. If an entry is true, that index is a continuous joint.
void generateSignature()
Creates a unique signature (based on active joints).
std::vector< std::string > getNamedStates() const
Gets the names of all named states.
void removeChild(FrameDataPtr parent, const std::string &child)
Removes child from the parent in the tree.
An allowed collision map / matrix for the robot. Stores what frames are allowed to collide with each ...
FrameMap(const Robot &robot)
Constructor.
void fk(const Eigen::Ref< const Eigen::VectorXd > &q, FrameMapPtr frames) const
Compute the forward kinematics of the robot at a state q.
void insert(FrameMapPtr other)
Inserts all entries in this frame map into another frame map.
FrameData()
Constructor for the root element.
std::string printDebug() const
Returns a string of complete robot information for debugging purposes.
unsigned int maxDepth_
Maximum tree depth.
FramePtr getFrame(const std::string &name)
Get the frame with name name.
void compileTree()
Compiles the underlying kinematic tree representation after a call to attachFrame().
const FrameMap::Value & getJacobian(const std::string &frame_name, const Eigen::Ref< const Eigen::VectorXd > &q, FrameMapPtr frames) const
Gets the jacobian for frame_name at configuration q.
Fixed joint, just a rigid transformation.
void staticFK()
Compute the transform for all non-movable frames.
A shared pointer wrapper for se2ez::Frame.
void addFixedRobot(const RobotPtr &frobot, const StatePtr &state, const std::string &scene_name)
add a fixed Robot(frames with all joints fixed) on the current robot. The frame names are namespaced ...
A representation of a robot (in this case, a kinematic tree in the plane).
void printTreeRecursive(std::stringstream &ss, const FrameDataPtr &frame, const PrintHelper &function, const std::string &prefix="") const
Helper function to printTree() that recursively traverses the kinematic tree.
void getNamedState(const std::string &name, StatePtr state)
Gets a named state.
ACMPtr getACM()
Gets the robot's default ACM.
FramePtr getFrameParent(const std::string &name)
Get the parent of frame with name name. Throws Error if name is root.
const Eigen::Ref< const Eigen::VectorXd > getFrameValuesConst(const std::string &frame_name, const Eigen::Ref< const Eigen::VectorXd > &q) const
Returns a reference to the underlying subvector of the configuration associated with a specific frame...
KDL::Tree tree_
Underlying tree representation.
const KDL::Tree & getTree() const
Get the underlying KDL tree for this robot.
const std::map< std::string, StatePtr > & getNamedStatesMap()
Gets the names of all named states.
void setACM(const ACMPtr &acm)
Sets the robot's default ACM.
const std::vector< std::string > & getEEs() const
Gets the names of end-effectors of the tree (leaf nodes).
const std::vector< std::string > & getFrameNames() const
Get a vector of all the frame names within this robot.
std::string signature_
A string that represents the current kinematic chain.
#define SE2EZ_WARN(fmt,...)
void dirty()
Dirties all frames within the frame map.
std::vector< std::string > ees_
End-effectors (leaves) in the kinematic tree that are mobile.
void compileTreeRecursive(const std::string &previous, FrameDataPtr &data, bool movable=false)
Helper function to compileTree() that recursively build tree representation.
unsigned int index
Index within tree's configuration for the frame's joint values.
Eigen::Ref< Eigen::VectorXd > getValues(Eigen::Ref< Eigen::VectorXd > data) const
Returns a reference to the underlying subvector of the configuration associated with this frame...
A tuple that stores whether a transform is dirty (needs to be updated), the transform itself...
const Value & getEntryConst(const std::string &frame_name) const
Gets the entry in the frame map associated with frame_name. Throws error if it does not already exist...
void setNamedState(const std::string &name, const StatePtr &state)
Sets a named state.
std::string printFrames(const RobotPtr &robot) const
Prints out all current frame pose information. Attaches "_[ x, y, t ]" to the Robot::printTree(), where '_' is 'C' for clean, 'D' for dirty, and 'X' for uninitialized. "[ x, y, t ]" is the transform of the frame.
const FrameMap::Value & getPose(const std::string &frame_name, const Eigen::Ref< const Eigen::VectorXd > &q, FrameMapPtr frames) const
Gets the pose of a frame frame_name at a configuration q. Also updates all dependent frames in frames...
std::map< std::string, StatePtr > named_
Named states.
Eigen::VectorXd lower_
Lower limits of joints.
A shared pointer wrapper for se2ez::ACM.
void addActiveRobot(const RobotPtr &arobot)
adds an active Robot with all its frames and corresponding joints.
Representation of a single frame (possibly with a joint) in a kinematic tree.
FrameDataPtr parent
Parent of this frame.
Robot()
Constructor. Nothing interesting right now.
Eigen::Ref< Eigen::VectorXd > getFrameValues(const std::string &frame_name, Eigen::Ref< Eigen::VectorXd > q) const
Returns a reference to the underlying subvector of the configuration associated with a specific frame...
FramePtr frame
Underlying frame.
const Eigen::Ref< const Eigen::VectorXd > getValuesConst(const Eigen::Ref< const Eigen::VectorXd > &data) const
Returns a reference to the underlying subvector of the configuration associated with this frame...
KDL::JntArray EigenToKDLVec(const Eigen::VectorXd &vec)
Converts an Eigen vector into a KDL vector.
A shared pointer wrapper for se2ez::Robot.
std::string format(const std::string &fmt, Args &&... args)
bool inTree(const std::string &name) const
Checks if a frame name is in the tree.
std::vector< std::string > names_
Names of the the kinematic tree frames (ordered).
const std::vector< std::pair< std::string, FrameDataPtr > > & getJoints() const
Get the ordered list of active joints in this robot with their associated frame information.
std::string printTree(const PrintHelper &function={}) const
Returns a string that graphically shows the kinematic structure of the tree. For example: ...
Value & getEntry(const std::string &frame_name)
Gets the entry in the frame map associated with frame_name. Creates the entry if one does not already...
void updateFrame(const FramePtr &frame, const std::string &parent_name)
Updates a frame's entry in the kinematic tree with a possibly new parent parent_name.
ACMPtr acm_
Default robot ACM.
void attachFrame(const FramePtr &frame)
Attach a frame to the root of the kinematic tree. Will detach frame if attached elsewhere already...
std::map< std::string, FrameDataPtr > data_
Kinematic tree data for all frames.
void setNamedStates(const std::map< std::string, StatePtr > &named)
Sets a named state.
#define SE2EZ_ERROR(fmt,...)
std::vector< std::pair< std::string, FrameDataPtr > > joints_
Ordered vector of active joints.
const std::string & getSignature()
Returns the signature of the robot.
bool tree_update_
Does the tree need recompiling?
std::shared_ptr< KDL::TreeJntToJacSolver > jac_
Underlying tree representation.
unsigned int getNumJoints() const
Gets the number of controllable joints within the tree.
void clear()
Completely clears internal structures, a brand new robot!
void enforceLimits(StatePtr a) const
Enforce joint limits on a robot and renormalize angles if necessary.
T emplace_back(T... args)