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
Difference() behavior not consistent between joint types #1752
Comments
I believe it should report |
If you have an unbounded joint, then you should instead use the unbounded joint type, which is done for that. I would say that it is the role of the end-user to properly use the correct input and output of the difference operations (which act on Lie groups). |
For the case of FreeFlyer, the bounds on the rotation part have no meaning in general. The NaN comes from there. |
The bounds in translation can make sense though (e.g. a free-floating robot in a box, or the payload of a cable-driven parallel robot). Right now translation bounds are also nan-ed in free flyers.
Just tried it out, however it behaves differently from the two others: Unbounded revolute joints:>>> import pinocchio as pin
>>> model = pin.Model()
>>> model.addJoint(0, pin.JointModelRUBZ(), pin.SE3.Identity(), "foo")
1
>>> model.upperPositionLimit
array([1.79769313e+308, 1.79769313e+308])
>>> pin.difference(model, pin.neutral(model), model.upperPositionLimit)
array([0.]) I agree that the error here rather lies with
From const VectorXs min_config = VectorXs::Constant(joint_model.nq(), -std::numeric_limits<Scalar>::max());
const VectorXs max_config = VectorXs::Constant(joint_model.nq(), std::numeric_limits<Scalar>::max()); I get your point that |
The same for RBUZ joint types, there should be no bound on it. So, the questions are:
I'm in favour of (ii) as the first one will induce a lowering of performances and make the function hardly differentiable for autodiff tools. |
OK, I see the stakes better. I agree it would make sense to have well-formed configurations as a pre-requisite for By (ii), do you mean changing the type of position limits to be something more structured than a configuration vector? The use case I have in mind are joint position limits in a velocity-based IK. Currently it relies on Delta_q_max = pin.difference(configuration.model, q_act, q_max) And then some ad-hoc parsing on NaNs/big floats to figure out which tangent coordinates are not proper limits. One way to get rid of this would be to add something like a |
Good idea to add the notion of hasConfigurationLimits() for each joint. |
About this notion of limits, a FreeFlyer will have a bound on the translation but not on the rotation. |
I should have made it explicit, but what I have in mind are runtime limits, i.e. whether the user/URDF specified a limit explicitly. |
I think checking if the value is a max would do the job then. |
That works with configurations, the question is how to do the same with tangent vectors? slice = [joint.idx_v for joint in model.joints if joint.has_runtime_configuration_limits] Exposing the joint's |
This is in the Model, no? |
I don't understand your approach in fact. @stephane-caron Do you think is the right one? |
What we can do for sure, is to set the real bounds on the configuration for non-Euclidian manifolds. |
@stephane-caron To move forward in the current issue, I would suggest you clamp the limit values in the set [-1e20, 1e20] for instance to get correct output from |
Yep, that's in essence how joint limits are implemented in Pink v0.5. What's not great about this approach is that in relies on how Pinocchio is implemented, rather than on its API. To keep things in scope, let me spin a separate issue on this point: #1758 From my side, the initial point of this issue about the API for |
I don't understand this point. |
Arh, sorry you meant clamping the inputs to Clamping the inputs is not sufficient in itself because >>> model = pin.Model()
>>> model.addJoint(0, pin.JointModelFreeFlyer(), pin.SE3.Identity(), "root_joint")
1
>>> pin.difference(model, pin.neutral(model), np.array([1e20] * 7))
array([9618.35346861, 9618.35346861, 9618.35346861, 0. ,
0. , 0. ]) But if we make sure unbounded rotations have proper coordinates, then we get correct outputs for the other coordinates: >>> pin.difference(model, pin.neutral(model), np.array([1e20]*3 + [0, 0, 0, 1]))
array([1.e+20, 1.e+20, 1.e+20, 0.e+00, 0.e+00, 0.e+00]) No worries re. my issue which found a pleasant solution in stephane-caron/pink#12. I hope our exchange here was not too unstructured and somehow useful feedback for Pinocchio 😃 |
We need to fix in Pinocchio the proper value for the bounds limit for unbounded joints. |
As of Pinocchio 2.6.4,
pin.difference
doesn't behave the same for different joint types when infinity is involved:Free flyers:
Revolute joints:
Expected behavior:
I think the second behavior is the right one, as it is expected that "+infinity - finite = +infinity". (Also, that's the one that would trivialize computing joint limits in IK, which is my current use case 😉)
The text was updated successfully, but these errors were encountered: