-
Notifications
You must be signed in to change notification settings - Fork 287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added convenience functions to help with setting FreeJoint, EulerJoint, and BallJoint positions #322
Added convenience functions to help with setting FreeJoint, EulerJoint, and BallJoint positions #322
Changes from 3 commits
9f29094
a3cca9d
31e7b4a
e5767fd
4401dcd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,15 +57,33 @@ FreeJoint::~FreeJoint() | |
{ | ||
} | ||
|
||
//============================================================================== | ||
Eigen::Vector6d FreeJoint::convertToPositions(const Eigen::Isometry3d& _tf) | ||
{ | ||
Eigen::Vector6d x; | ||
x.head<3>() = math::logMap(_tf.rotation()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've been using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question; I haven't given it much thought, I just use rotation() out of habit. Glancing through the Eigen headers, it looks like the difference is that linear() just returns a reference to the rotational part of the Isometry3d, whereas rotation() enforces orthonormality before returning a copy of the linear part (so it's not a reference). It sounds like it's a trade off between efficiency -- where linear() is the winner -- versus numerical accuracy -- where rotation() is the winner. Also, if you want to set the linear part directly, you have to use linear(). It might be better to use linear() here since it would be more efficient, and I suspect it's reasonable to expect that the incoming Isometry3d has an okay rotational part. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use linear() consistently, and let's see if the orthogonality does matter. |
||
x.tail<3>() = _tf.translation(); | ||
return x; | ||
} | ||
|
||
//============================================================================== | ||
Eigen::Isometry3d FreeJoint::convertToTransform( | ||
const Eigen::Vector6d& _positions) | ||
{ | ||
Eigen::Isometry3d tf; | ||
tf.linear() = math::expMapRot(_positions.head<3>()); | ||
tf.translation() = _positions.tail<3>(); | ||
return tf; | ||
} | ||
|
||
//============================================================================== | ||
void FreeJoint::integratePositions(double _dt) | ||
{ | ||
mQ.linear() = mQ.linear() * math::expMapRot(mJacobian.topRows<3>() | ||
* mVelocities * _dt); | ||
mQ.translation() = mQ.translation() + mVelocities.tail<3>() * _dt; | ||
|
||
mPositions.head<3>() = math::logMap(mQ.linear()); | ||
mPositions.tail<3>() = mQ.translation(); | ||
mPositions = convertToPositions(mQ); | ||
} | ||
|
||
//============================================================================== | ||
|
@@ -88,8 +106,7 @@ void FreeJoint::updateDegreeOfFreedomNames() | |
//============================================================================== | ||
void FreeJoint::updateLocalTransform() | ||
{ | ||
mQ.linear() = math::expMapRot(mPositions.head<3>()); | ||
mQ.translation() = mPositions.tail<3>(); | ||
mQ = convertToTransform(mPositions); | ||
|
||
mT = mT_ParentBodyToJoint * mQ * mT_ChildBodyToJoint.inverse(); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this function is made as a template function instead of taking
Eigen::Matrix3d
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's templated because Eigen uses a variety of ways to express rotations, and using a templated argument ensures that all of them can be covered by one function. I modelled it after the Isometry3d::rotate(~) function.
It would probably still work if it used a Matrix3d argument, since Eigen is pretty smart about converting its types, but the template usage here doesn't really hurt anything, because you don't need to use the template explicitly. If you look at an example of usage you'll see that C++ can infer the template argument so you don't even need to treat it like a templated function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean like
Quaternion3d
? Is there another types that express rotations in Eigen?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, Quaternion3d is an example. AngleAxisd is another one. I'm not sure if there are more than those three.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. It seems all the ration expressions can be converted to
Eigen::Matrix3d
so that it works withmath::logMap(Eigen::Matrix3d)
.