-
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
Convenience setter functions for positions/velocities/accelerations of FreeJoint #470
Conversation
I have two concerns about this:
|
I tend to agree with @mxgrey here. It's not even clear to me what the "best" solution is, since choosing an error metric depends a lot on the user's application. This seems best handled by the However, I do think it would be useful to have a helper function in DART for setting the generalized coordinates from a Maybe we could add something similar to DART? |
@mkoval, If I'm interpreting your suggestion correctly, I think that's what this pull request does. The only thing missing would be a On another note, I do think it would be appropriate to have these same mechanics for |
…t given classical velocities and accelerations
@mxgrey's two concerns sound reasonable to me as well. As @mkoval said, single-joint inverse kinematics problem looks solvable using
This is what I exactly did for Gazebo. But I'm also questionable to add something similar to DART under the function name of
Sounds good. Before we apply this to WeldJoint, I actually would like to discuss about the possibility on use of different meaning of two transformations over the current two transformations to avoid the ambiguity. Let me create an issue for it since it seems beyond the scope of this PR. |
@mxgrey This pull request adds a helper function to
I am also not thrilled with this idea, but I don't see a good alternative. Anytime you load a model from URDF or SDF (I think?) it returns a if(auto freeJoint = dynamic_cast<dart::dynamics::FreeJoint*>(skeleton->getRootBodyNode()->getParentJoint()))
freeJoint->setRelativeTransform(pose, dart::dynamics::Frame::World());
else
std::cout << "Something went wrong!" << std::endl; This is a lot of code to set the pose of a body and it's very easy to get the error checking wrong. In fact, this implementation is already missing something: it does not check Thoughts?
This method should definitely have a different name. There is a fundamental difference between updating the generalized coordinates of a joint (as
I don't feel too strongly about this, mostly because I cannot come up with a use case where I would use |
You make a lot of fair points. If the primary purpose is to set root transformations, what if we offered something like this:
This would modify This would be completely agnostic to the type of the parent Joint. I suppose the catch is that it wouldn't be setting the positions for FreeJoint even though that's what you're asking for, @mkoval , but is there a particular reason to set the Joint positions instead of setting the transform from the parent? |
I was thinking to implement If we want helper functions to set the root BodyNode transformation, then |
I've been putting off replying to this because I'm having a difficult time articulating why setting
I am fine with these functions being added, since they would be useful when programmatically constructing a |
I 100% agree with this, which is actually what led me to think we should just be using the My interpretation of the use case here is to set up the initial transform of the Skeleton's root within the scene, not to set the initial state of the Skeleton. If the point is to set the initial state of the Skeleton, then you should be setting the generalized coordinates to the desired initial values as a cohesive whole instead of using convenience functions to set a subsection of the state. Of course, the glaring flaw in all of my logic is that the URDF and SDF formats don't have a way of specifying initial states, so you can't actually encode that information into those model files, and that creates incentive for a convenience function that helps the user set up the initial state based on a desired root transform. So I do recognize the value of what you're asking for. But I guess key point of the case I'm trying to make is this: If the user wants to alter the generalized coordinate positions of their Skeleton, then user should know the meaning of the Skeleton's generalized coordinates and not rely on a convenience function that has limited applicability. Instead, the convenience function should operate in a way that is entirely agnostic to the particular details of the Skeleton's generalized coordinates, so that it works without exceptions.
This is absolutely true, and to me it's the most compelling argument in favor of a convenience function that modifies the generalized coordinates of the |
The initial pose of a In fact, I'd prefer to leave
URDF or SDF are the only practical ways of loading As a compromise, perhaps we could not add the helper method to |
I could be very easily convinced of this. Having it be external from the standard Joint API would be a very clean compromise. I think my preference would be to have it in |
I slightly prefer
However, I am not strongly opposed to |
I suppose having it in 👍 for
On a side note, I just noticed that the
versus
|
Should Also, from a "I just want to set the bloody pose of this static void FreeJoint::setTransform(Joint* joint, const Eigen::Isometry3d& tf, const Frame* withRespectTo);
static void FreeJoint::setTransform(BodyNode* joint, const Eigen::Isometry3d& tf, const Frame* withRespectTo);
static void FreeJoint::setTransform(Skeleton* joint, const Eigen::Isometry3d& tf, const Frame* withRespectTo); I think I'm pushing my luck now. 😓 |
It's not possible for So far in DART the convention has been that if something has the word
I think the only one that might be pushing it is the |
👍 Defaulting to
👍 I think that's reasonable. The |
Never mind, I read the description of the function, and now I get why they are passed as pointers. 👍 I also think that there's some API inconsistency that we should resolve. Specifically, consider the
I would propose we use a similar scheme for these other setter functions. A function named I think that we should either go with my proposal, or we should change the SimpleFrame API to match the new convention that's being used in this pull request (and deprecate the current API for it). |
…cc_setters Resolved conflicts: unittests/testJoints.cpp
Dirtying Jacobian update flags whenever the parent transform is changed -- master patch
In the recent commit, the APIs are updated to be consistent with our codebase, and |
Give default Frame::World parameters to setTransform functions
|
||
FreeJoint* freeJoint = dynamic_cast<FreeJoint*>(joint); | ||
|
||
if (nullptr == freeJoint) |
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.
Should we print a warning here?
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.
👍 Added warning.
Looks good 👍 |
Convenience setter functions for positions/velocities/accelerations of FreeJoint
Since a BodyNode whose parent joint is FreeJoint has full degrees of freedom, we can set its transformation, velocity, and acceleration without any concern of constraints in kinematics level. However, current API may not convenient to set them because they should be set through generalized coordinates that requires some conversion between them. Although we have some utility functions thanks to #322, it still requires more lines to handle transformations between parent/child BodyNode and joint and doesn't take velocity and acceleration into account.
This PR allows us to set generalized positions/velocities/accelerations of a FreeJoint given transformation, spatial velocity, and spatial acceleration. The new functions looks similar to SimpleFrame's ones.
We can consider another setter functions that takes classical terms like rotation, position, [linear/angular][velocity/acceleration]. Furthermore, it might be able to set these terms through BodyNode when the parent joint is FreeJoint, but I'm not sure if this makes sense in the point of API view.
Also, we can consider similar functions for other joints types (except for WeldJoint). For the other joints, we might need single-joint-level inverse kinematics to find best generalized coordinate terms given spatial terms. Would this be straightforward with #461 @mxgrey?