-
Notifications
You must be signed in to change notification settings - Fork 294
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
JointPositionController not working for nested models #1844
JointPositionController not working for nested models #1844
Comments
InvestigationsWork in progress trying to tack down the origin of the issue. Notes below.
Notes
There are two places where nested models are constructed. The first for models that are direct children of the world: gz-sim/src/systems/physics/Physics.cc Lines 1123 to 1124 in 31f7d5b
and the second for models that are not (and so must be nested): gz-sim/src/systems/physics/Physics.cc Line 1175 in 31f7d5b
The first call will construct models recursively, so that when the second call is made the nested model is already constructed.
For the non-nested joints, the function gz-sim/src/systems/physics/Physics.cc Lines 1680 to 1689 in 31f7d5b
For the nested joints this test fails (which is odd because we see below there is an error message reporting the joint already exists). In any case the function continues until it hits: gz-sim/src/systems/physics/Physics.cc Lines 1723 to 1734 in 31f7d5b
where the test for a valid physics pointer to a joint fails and the the inserting of the joint into the
The attempt to create the nested joint fails here: gz-physics6/dartsim/src/SDFFeatures.cc#L1074-L1083 auto childsParentJoint = _child->getParentJoint();
if (childsParentJoint->getType() != "FreeJoint")
{
gzerr << "Asked to create a joint between links "
<< "[" << _parent->getName() << "] as parent and ["
<< _child->getName() << "] as child, but the child link already "
<< "has a parent joint of type [" << childsParentJoint->getType()
<< "].\n";
return this->GenerateInvalidId();
} because the joint has already been associated with a link, but for some reason is not recorded in the dart physics plugin as an existing link when queried using the entity management feature Update Added a trace into [Dbg] [SDFFeatures.cc:1164] SDFFeatures::ConstructSdfJoint: Before ConstructRevoluteJoint
ModelID: 2
LocalName: model3
Name: model3
NumJoints: 1
Joint: base3_link_FreeJoint
ModelID: 3
LocalName: model2
Name: model3::model2
NumJoints: 2
Joint: base2_link_FreeJoint
Joint: rotor2_joint
JointID 5
Name: base2_link_FreeJoint
JointID 8
Name: rotor2_joint
JointID 10
Name: rotor2_joint
JointID 12
Name: base3_link_FreeJoint
[Dbg] [SDFFeatures.cc:1174] SDFFeatures::ConstructSdfJoint: After ConstructRevoluteJoint
ModelID: 2
LocalName: model3
Name: model3
NumJoints: 3
Joint: base3_link_FreeJoint
Joint: Joint
Joint: rotor2_joint
ModelID: 3
LocalName: model2
Name: model3::model2
NumJoints: 0
JointID 5
Name: Joint
JointID 8
Name: rotor2_joint
JointID 10
Name: rotor2_joint
JointID 12
Name: base3_link_FreeJoint It appears that joints from the nested model are reassigned to the containing model by the function: // SDFFeatures.cc L1169-1170
joint = ConstructSingleAxisJoint<dart::dynamics::RevoluteJoint>(
_modelInfo, _sdfJoint, _parent, _child, T_joint); // SDFFeatures.cc L215
return _child->moveTo<JointType>(_parent, properties); Is this behaviour correct for nested models? There is also something odd about having repeated entries in the store for the rotor_joint. |
Thanks for sleuthing @srmainwaring. I'm wondering if this is a regression from #1560 or something that existed all along. |
I think it was around before then. I rolled back gz-sim to the commit before #1560 and the issue remained. I'm slowly zeroing in on possible causes - I suspect it may either be a recursion thing - where the dart model only reports its immediate child joints, or there is a double entry of the nested joint into the For some context: support for nested models is a huge plus for supporting models with configurable peripherals. I'm currently bringing a number of models controlled by ArduPilot up to date, and without nested position controller support adding and maintaining models with peripherals like gimbals gets complicated very fast. I'm hoping for a non-ABI breaking fix that can go into Garden. |
@azeey - the issue arises in the function It's not clear to me what the correct fix is - any change is going to have knock on effects elsewhere. Options seem to be:
I don't think Option 2 is a good choice - it would be very confusing and almost impossible to maintain (tracing the model state is quite difficult as it is). That leaves option 1, but I'm not familiar with DART to know how the object model will cope with this type of nesting. |
I've started a fix for this. The branches will probably change as I tidy things up and remove debug code but currently the changes are here:
The main changes are broken down as follows:
|
Environment
Description
Steps to reproduce
test_nested_model.sdf.zip
Output
The single yellow block is model1, the teal block is model3 and the yellow block attached to the teal block is model2 which is nested in model3. The rotors in the top level models (model1 and model2) both move. The rotor in the nested model (model2) does not respond.
When stepping through the joint controller plugin the
JointPositionController::PreUpdate
returns at L268 becausejointPosComp->Data()
is always empty for the nested joints.gz-sim/src/systems/joint_position_controller/JointPositionController.cc
Lines 267 to 268 in 31f7d5b
Server log:
The error:
[Err] [SDFFeatures.cc:1077] Asked to create a joint between links [base2_link] as parent and [rotor2_link] as child, but the child link already has a parent joint of type [RevoluteJoint].
Suggests that the physics engine may be attempting to build the nested model twice?
Related
The same issue is observed when composing models using the
<include>
element.The text was updated successfully, but these errors were encountered: