18static const unsigned int constraintCacheSize = 5;
20std::string Armature::m_root =
"root";
57 for (JointConstraintList::iterator it=m_constraints.begin(); it != m_constraints.end(); it++) {
63 m_constraints.clear();
67 segment(_segment), value(), values(), function(_function), y_nr(_y_nr), param(_param), freeParam(_freeParam), substep(_substep)
69 memset(values, 0,
sizeof(values));
70 memset(value, 0,
sizeof(value));
71 values[0].feedback = 20.0;
72 values[1].feedback = 20.0;
73 values[2].feedback = 20.0;
74 values[0].tolerance = 1.0;
75 values[1].tolerance = 1.0;
76 values[2].tolerance = 1.0;
77 values[0].values = &value[0];
78 values[1].values = &value[1];
79 values[2].values = &value[2];
83 switch (segment->second.segment.getJoint().getType()) {
132 if (freeParam && param)
144 m_qCCh = m_cache->
addChannel(
this,
"q", m_qKdl.
rows()*
sizeof(
double));
149 m_yCCh = m_cache->
addChannel(
this,
"y", m_nconstraint*constraintCacheSize*
sizeof(
double));
150 m_buf =
new double[m_nconstraint*constraintCacheSize];
159void Armature::pushQ(
CacheTS timestamp)
169bool Armature::popQ(
CacheTS timestamp)
174 if (item && m_qCTs != timestamp) {
175 double* q = m_qKdl(0);
176 memcpy(q, item, m_qKdl.
rows()*
sizeof(
double));
181 return (item) ?
true :
false;
186void Armature::pushConstraints(
CacheTS timestamp)
191 double *item = m_buf;
192 for (
unsigned int i=0; i<m_nconstraint; i++) {
193 JointConstraint_struct* pConstraint = m_constraints[i];
194 *item++ = pConstraint->values.feedback;
195 *item++ = pConstraint->values.tolerance;
196 *item++ = pConstraint->value.yd;
197 *item++ = pConstraint->value.yddot;
198 *item++ = pConstraint->values.alpha;
207bool Armature::popConstraints(
CacheTS timestamp)
211 if (item && m_yCTs != timestamp) {
212 for (
unsigned int i=0; i<m_nconstraint; i++) {
213 JointConstraint_struct* pConstraint = m_constraints[i];
214 if (pConstraint->function != Joint1DOFLimitCallback) {
215 pConstraint->values.feedback = *item++;
216 pConstraint->values.tolerance = *item++;
217 pConstraint->value.yd = *item++;
218 pConstraint->value.yddot = *item++;
219 pConstraint->values.alpha = *item++;
221 item += constraintCacheSize;
226 return (item) ?
true :
false;
238 if (!m_tree.
addSegment(segment, segment_name, hook_name))
241 for (
int dof=0; dof<ndof; dof++) {
243 m_joints.push_back(js);
251 SegmentMap::const_iterator sit = m_tree.
getSegment(name);
254 p_joint = &sit->second.segment.getJoint();
255 if (q_size < p_joint->getNDof())
257 p_tip = &sit->second.segment.getFrameToTip();
258 for (
unsigned int dof=0; dof<p_joint->
getNDof(); dof++) {
259 (&q_rest)[dof] = m_joints[sit->second.q_nr+dof].rest;
260 (&q)[dof] = m_qKdl[sit->second.q_nr+dof];
269 double maxJoint = 0.0;
270 for (
unsigned int i=0; i<m_njoint; i++) {
272 double joint =
fabs(m_oldqKdl[i]-m_qKdl[i]);
273 if (maxJoint < joint)
283 double maxDelta = 0.0;
286 for (
unsigned int i = 0; i<m_neffector; i++) {
287 twist =
diff(m_effectors[i].pose, m_effectors[i].oldpose);
288 delta = twist.rot.Norm();
289 if (delta > maxDelta)
291 delta = twist.vel.Norm();
292 if (delta > maxDelta)
300 SegmentMap::const_iterator segment_it = m_tree.
getSegment(segment_name);
303 if (_freeParam && _param)
307 JointConstraintList::iterator constraint_it;
310 for (iConstraint=0, constraint_it=m_constraints.begin(); constraint_it != m_constraints.end(); constraint_it++, iConstraint++) {
311 pConstraint = *constraint_it;
312 if (pConstraint->
segment == segment_it) {
318 pConstraint->
param = _param;
320 pConstraint->
substep = _substep;
325 if (_freeParam && _param)
331 m_constraints.push_back(pConstraint);
332 m_noutput += pConstraint->
v_nr;
333 return m_nconstraint++;
338 SegmentMap::const_iterator segment_it = m_tree.
getSegment(segment_name);
341 const Joint& joint = segment_it->second.segment.getJoint();
346 if ((joint.
getNDof() == 1 && dof > 0) || (joint.
getNDof() == 2 && dof > 1))
348 Joint_struct& p_joint = m_joints[segment_it->second.q_nr+dof];
358 if (segments.find(name) == segments.end())
361 EffectorList::const_iterator it;
363 for (it=m_effectors.begin(), ee=0; it!=m_effectors.end(); it++, ee++) {
364 if (it->name == name)
370 m_effectors.push_back(effector);
371 return m_neffector++;
376 unsigned int i, j, c;
382 for (i=c=0; i<m_nconstraint; i++) {
384 for (j=0; j<pConstraint->
v_nr; j++, c++) {
393 m_oldqKdl.
resize(m_njoint);
394 m_newqKdl.
resize(m_njoint);
395 m_qdotKdl.
resize(m_njoint);
396 for (i=0; i<m_njoint; i++) {
397 m_newqKdl[i] = m_oldqKdl[i] = m_qKdl[i] = m_joints[i].rest;
403 for (i=0; i<m_neffector; i++) {
405 KDL::SegmentMap::value_type
const *sit = m_tree.
getSegmentPtr(m_effectors[i].name);
406 while (sit->first !=
"root") {
407 Frame tip = sit->second.segment.pose(m_qKdl(sit->second.q_nr));
408 length += tip.
p.
Norm();
409 sit = sit->second.parent;
411 if (length > m_armlength)
452 double* qdot=m_qdotKdl(0);
454 double* newq=m_newqKdl(0);
455 double norm, qx, qz, CX, CZ, sx, sz;
459 for (q_nr=0; q_nr<
m_nq; ++q_nr)
462 for (q_nr=0; q_nr<
m_nq; ) {
465 switch (joint->
type) {
470 if (joint[0].useLimit) {
471 if (joint[1].useLimit) {
477 if (qx > 0.0 && qz > 0.0) {
480 }
else if (qx <= 0.0 && qz > 0.0) {
485 }
else if (qx <= 0.0 && qz <= 0.0) {
514 newq[0] = qx*
norm*CX*sx;
515 newq[1] = qz*
norm*CZ*sz;
522 if (qx > joint[0].max) {
523 newq[0] = joint[0].
max;
525 }
else if (qx < joint[0].
min) {
526 newq[0] = joint[0].
min;
530 }
else if (joint[1].useLimit) {
533 if (qz > joint[1].max) {
534 newq[1] = joint[1].
max;
536 }
else if (qz < joint[1].
min) {
537 newq[1] = joint[1].
min;
541 if (joint[0].locked) {
551 (base.
Inverse()*KDL::Rot(
KDL::Vector(newq[0],0.0,newq[1]))).GetXZRot().GetValue(deltaq);
554 callback.lockJoint(q_nr, 2, deltaq);
570 for (
unsigned int i=0; i<joint->
ndof; i++) {
572 if (joint[i].useLimit) {
573 if (newq[i] > joint[i].max) {
574 newq[i] = joint[i].
max;
576 }
else if (newq[i] < joint[i].
min) {
577 newq[i] = joint[i].
min;
582 if (joint[0].locked) {
586 for (
unsigned int i=0; i<joint->
ndof; i++) {
587 qdot[i] = newq[i] - q[i];
588 norm += qdot[i]*qdot[i];
595 for (
unsigned int i=0; i<joint->
ndof; i++) {
612 for ( ; q_nr<
m_nq; ) {
619 return (unlocked) ? locked :
false;
629 memcpy(m_qKdl(0), m_newqKdl(0),
sizeof(
double)*m_qKdl.
rows());
639 for (
unsigned int ee=0; ee<
m_nee; ee++) {
640 m_fksolver->
JntToCart(m_qKdl,m_effectors[ee].pose,m_effectors[ee].name,m_root);
641 m_jacsolver->
JntToJac(m_qKdl,*m_jac,m_effectors[ee].name);
646 for(
unsigned int i=0;i<6;i++) {
647 for(
unsigned int j=0;j<
m_nq;j++)
648 Jq(i,j)=(*m_jac)(i,j);
666 return (m_fksolver->
JntToCart(m_qKdl,result,segment_name,base_name) < 0) ?
false :
true;
682 memcpy(m_oldqKdl(0), m_qKdl(0),
sizeof(
double)*m_qKdl.
rows());
683 for (
unsigned int i=0; i<m_neffector; i++) {
684 m_effectors[i].oldpose = m_effectors[i].pose;
689 for (JointList::iterator
jit=m_joints.begin();
jit!=m_joints.end(); ++
jit) {
690 (*jit).locked =
false;
693 JointConstraintList::iterator it;
694 unsigned int iConstraint;
697 for (iConstraint=0, it=m_constraints.begin(); it!=m_constraints.end(); it++, iConstraint++) {
700 for (i=0, nr = pConstraint->
segment->second.q_nr; i<pConstraint->
v_nr; i++, nr++) {
701 *(
double *)&pConstraint->
value[i].
y = m_qKdl[nr];
702 *(
double *)&pConstraint->
value[i].
ydot = m_qdotKdl[nr];
708 for (i=0, nr=pConstraint->
y_nr; i<pConstraint->
v_nr; i++, nr++) {
717 unsigned int lastid, i;
720 lastid = m_nconstraint;
721 }
else if (constraintId < m_nconstraint) {
722 lastid = constraintId+1;
726 for ( ; constraintId<lastid; ++constraintId) {
729 for (i=0; i<pConstraint->
v_nr; i++) {
745 for (i=0; i<pConstraint->
v_nr; i++) {
746 if (valueId == pConstraint->
value[i].
id) {
749 pConstraint->
value[i].
yd = value;
770 for (i=0; i<pConstraint->
v_nr; i++)
void BLI_kdtree_nd_ free(KDTree *tree)
#define CONSTRAINT_ID_ALL
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
represents a frame transformation in 3D space (rotation + translation)
Vector p
origine of the Frame
unsigned int rows() const
void resize(unsigned int newSize)
This class encapsulates a simple joint, that is with one parameterized degree of freedom and with sca...
unsigned int getNDof() const
const JointType & getType() const
represents rotations in 3 dimensional space.
Rotation Inverse() const
Gives back the inverse rotation matrix of *this.
This class encapsulates a simple segment, that is a "rigid body" (i.e., a frame and an inertia) with ...
virtual int JntToCart(const JntArray &q_in, Frame &p_out, const std::string &segmentName, const std::string &baseName)
int JntToJac(const JntArray &q_in, Jacobian &jac, const std::string &segmentname)
SegmentMap::const_iterator getSegment(const std::string &segment_name) const
bool addSegment(const Segment &segment, const std::string &segment_name, const std::string &hook_name)
const SegmentMap & getSegments() const
SegmentMap::value_type const * getSegmentPtr(const std::string &segment_name) const
represents both translational and rotational velocities.
A concrete implementation of a 3 dimensional vector class.
virtual void initCache(Cache *_cache)
bool addSegment(const std::string &segment_name, const std::string &hook_name, const Joint &joint, const double &q_rest, const Frame &f_tip=F_identity, const Inertia &M=Inertia::Zero())
int addLimitConstraint(const std::string &segment_name, unsigned int dof, double _min, double _max)
virtual void updateControlOutput(const Timestamp ×tamp)
virtual void pushCache(const Timestamp ×tamp)
virtual bool updateJoint(const Timestamp ×tamp, JointLockCallback &callback)
virtual void updateKinematics(const Timestamp ×tamp)
bool getRelativeFrame(Frame &result, const std::string &segment_name, const std::string &base_name=m_root)
virtual const Frame & getPose(const unsigned int end_effector)
int addConstraint(const std::string &segment_name, ConstraintCallback _function, void *_param=NULL, bool _freeParam=false, bool _substep=false)
virtual int addEndEffector(const std::string &name)
bool getSegment(const std::string &segment_name, const unsigned int q_size, const Joint *&p_joint, double &q_rest, double &q, const Frame *&p_tip)
virtual void updateJacobian()
virtual bool setControlParameter(unsigned int constraintId, unsigned int valueId, ConstraintAction action, double value, double timestep=0.0)
double getMaxEndEffectorChange()
virtual bool setJointArray(const KDL::JntArray &joints)
double getMaxJointChange()
virtual const KDL::JntArray & getJointArray()
int addChannel(const void *device, const char *name, unsigned int maxItemSize)
double * addCacheVectorIfDifferent(const void *device, int channel, CacheTS timestamp, double *data, unsigned int length, double threshold)
const void * getPreviousCacheItem(const void *device, int channel, CacheTS *timestamp)
std::vector< e_matrix > m_JqArray
DEGForeachIDComponentCallback callback
ccl_device_inline float2 fabs(const float2 a)
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt=1)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > sqr(const Rall1d< T, V, S > &arg)
double epsilon2
power or 2 of epsilon
std::map< std::string, TreeElement, std::less< std::string >, Eigen::aligned_allocator< std::pair< const std::string, TreeElement > > > SegmentMap
void changeRefPoint(const Jacobian &src1, const Vector &base_AB, Jacobian &dest)
double epsilon
default precision while comparing with Equal(..,..) functions. Initialized at 0.0000001.
bool(* ConstraintCallback)(const Timestamp ×tamp, struct ConstraintValues *const _values, unsigned int _nvalues, void *_param)
JointConstraint_struct(SegmentMap::const_iterator _segment, unsigned int _y_nr, ConstraintCallback _function, void *_param, bool _freeParam, bool _substep)
ConstraintSingleValue value[3]
SegmentMap::const_iterator segment
ConstraintCallback function
ConstraintValues values[3]
~JointConstraint_struct()
KDL::Joint::JointType type