-
Notifications
You must be signed in to change notification settings - Fork 285
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
Conversation
…ting joints + tests to make sure the functions work
/// between the parent BodyNode and the child BodyNode frames when applied to | ||
/// a BallJoint. | ||
template <typename RotationType> | ||
static Eigen::Vector3d convertToPositions(const RotationType& _rotation) |
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.
Eigen uses a variety of ways to express rotations
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 with math::logMap(Eigen::Matrix3d)
.
How about to create inverse conversion functions like For example, 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();
mPosition = convertToTransfom(mQ);
}
|
Making inverse versions and using them all inside the update functions makes perfect sense. |
I've added a convertToTransform( |
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 comment
The reason will be displayed to describe this comment to others. Learn more.
I've been using Eigen::Isometry3d::linear()
to get the rotation part of a transformation. Do you know what's the difference between linear()
and rotation()
?
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.
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 comment
The 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.
Changed If the build tests are happy, then +1. |
Added convenience functions to help with setting FreeJoint, EulerJoint, and BallJoint positions
I found that setting FreeJoint and other joint types that have rotations can be confusing or can require more lines of code than it ought to, so I made some functions to help users convert transform and rotation types into joint position vectors that they can pass into Joint::setPositions(VectorXd).