Pinocchio: Selectively "fixing" (actuated) joints at URDF-parsing time

Created on 5 Oct 2019  路  12Comments  路  Source: stack-of-tasks/pinocchio

Dear all,

I would like to bring up the following issue, regarding parsing URDF's including highly redundant URDFs in pinocchio.
The issue is best explained using an example: let's consider a setup where we have a manipulator, e.g. a robot arm combined with a very dexterous gripper, e.g. a hand with a three finger gripper. Usually, for controlling the arm, we can neglect the dynamic behaviour of the fingers, and simply aggregate all the finger inertia into the last link of the arm.

What I see many people doing nowadays, is that the simply keep track of multiple URDFs some containing the full dexterous model, some containing the simplified model. Here is a potential issue where pinocchio could differentiate itself: by implementing a URDF-parser which allows to selectively override the joint-types in URDFs at parsing time, for instance to selectively override revolute joints in gripper fingers as "fixed" joints.

Currently fixed joints are handled in the way that the following link parameters (inertia, mass..) are aggregated to its parent. Therefore, a simple solution would be to provide an optional argument to buildModel(), for example a list of actuated or blocked joints, which selectively override the original definition from the URDF.

Personally I feel that there might be a need for such a parser variant, but I'm curious to hear what you guys think!

Most helpful comment

I like the idea.

I would suggest to have a method name with lock somewhere inside, as I found the wording "reduce" somehow inaccurate. Maybe simply lockJoints(...) or createModelByLockingJoints(...).

I am surprised by the API with vector of string, instead of vector of joint indexes. It does not seem to follow the (implicit) standards, is it?

I thought during 2 minutes of proposing to create the reserve method, while it is obviously more suitable to keep the original (unlock) model and always restart from it when changing the joint status.

All 12 comments

Dear @markusgft,

This is a very good initiative and suggestion.
I would suggest to not put this feature at the URDF level but at the model level.
In Pinocchio, we already have some functions acting on two models to append them together.
We can imagine having a new function called:
Model lockJointsInModel(const Model & model, const std::vector<std::string> & list_of_joints_to_lock) which will return a new model where the joints present in the list will be locked.
@markusgft @traversaro What do you think?

I would suggest to not put this feature at the URDF level but at the model level.
Indeed that makes sense, I'd also prefer this solution!

I'd propose to even go so far to provide 2 different joint-locking-API's. One function could be called

Model lockJointsInModel(const Model & model, const std::vector<std::string> & list_of_joints_to_lock)

as you suggested above. But it could even be that the "inverse" of above solution with a list of joints to keep unlocked is more useful in practice (usually we know exactly which joints we want to control, and don't care about the rest!) So the function call would look like:
Model lockJointsInModel(const Model & model, const std::vector<std::string> & list_of_**unlocked**_joints)

Sounds great for me! @markusgft Do you validate the two new signatures:
Model lockSomeJoints(const Model & original_model, const std::vector<std::string> & list_of_joints_to_lock)
and for the second signature:
Model keepSomeJointsUnlocked(const Model & original_model, const std::vector<std::string> & list_of_**unlocked**_joints)
?

Concerning the suggested naming, feel free to adjust them ;)
I may be not good at choosing correct namings.

@markusgft @traversaro What do you think?

But it could even be that the "inverse" of above solution with a list of joints to keep unlocked is more useful in practice (usually we know exactly which joints we want to control, and don't care about the rest!) So the function call would look like:
Model lockJointsInModel(const Model & model, const std::vector<std::string> & list_of_**unlocked**_joints)

I totally agree with the proposal to have an API to just list the "not-locked" joints, we have that in iDynTree (see iDynTree::createReducedModel) and is fundamental for the users of whole-body control, as typically for the iCub robot we may have a lot of joints that are not relevant for whole-body control (e.g. hands, eyes, eyelids) that may or not be present depending on the specific URDF model used.

A variant that we never implemented, but as been requested by users for a long time is the possibility to specify the value of the joints that are being fixed, see https://github.com/robotology/idyntree/issues/495 .

Thanks @traversaro for this nice reply.
I think indeed important to specify the value of the locked joint. I will add this feature to both signatures.

A possible name for the signatures could also be:

pinocchio::createReducedModel(const Model & model, const std::vector<std::string> & list_of_joints, Enum::LockType lock_or_unlock)

But I'm happy to leave the final decision to you @jcarpent ! Thank you again for reacting so quickly!!!

I will adopt your signature. It is pretty concise and clear.

@markusgft @traversaro Thanks a lot for your feedback.

I like the idea.

I would suggest to have a method name with lock somewhere inside, as I found the wording "reduce" somehow inaccurate. Maybe simply lockJoints(...) or createModelByLockingJoints(...).

I am surprised by the API with vector of string, instead of vector of joint indexes. It does not seem to follow the (implicit) standards, is it?

I thought during 2 minutes of proposing to create the reserve method, while it is obviously more suitable to keep the original (unlock) model and always restart from it when changing the joint status.

Very useful feature. Maybe another possible API would be to first build the model and the call a function: aggregateTree(joint_id). I also think that would solve the problem with joint indexes vs. joints name because you can look up the ids before. However i cannot judge the complexity of this way, but it would make this feature independant from the urdf loader.

Solved by #927.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

beta1scat picture beta1scat  路  6Comments

Synxis picture Synxis  路  3Comments

nim65s picture nim65s  路  8Comments

astumpf picture astumpf  路  9Comments

CWEzio picture CWEzio  路  9Comments