-
Notifications
You must be signed in to change notification settings - Fork 174
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
Contacts - 6D Loop contacts #1309
base: devel
Are you sure you want to change the base?
Contacts - 6D Loop contacts #1309
Conversation
cbaace3
to
40327f6
Compare
257f608
to
837ac62
Compare
This corrects the desired contact acceleration, by accouting for drift in position and velocity
for more information, see https://pre-commit.ci
837ac62
to
edebda5
Compare
@@ -399,14 +422,7 @@ void ContactModelMultipleTpl<Scalar>::updateRneaDiff( | |||
assert_pretty(it_m->first == it_d->first, | |||
"it doesn't match the contact name between data and model"); | |||
if (m_i->active) { | |||
switch (m_i->contact->get_type()) { |
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.
@cmastalli Please have a look here following our discussion
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.
Can you provide a test for this, either in C++ or in python ?
bindings/python/crocoddyl/multibody/contacts/contact-6d-loop.cpp
Outdated
Show resolved
Hide resolved
bindings/python/crocoddyl/multibody/contacts/contact-6d-loop.cpp
Outdated
Show resolved
Hide resolved
An entry in CHANGELOG.md would also be welcome |
Adding new tests to the factory for these contacts is not direct for me, I will provide a python test for now. |
I added a Changelog entry, @nim65s let me know if that is enough |
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.
calcDiff
is still full of memory allocation, being a result of temporary matrices storing the results of multiplications. Those super long operations will have to be split into several smaller ones, but in a somewhat smart way to let compiler properly optimize them. For today, I don't have more time to investigate it and propose some changes, though I will come back to it tomorrow.
For now, it seems ok and seems to be working fine. For the reference, I tested it with Pinocchio v2.7.1.
ref. LudovicDeMatteis#2 |
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.
The code looks much better now. The only thing left are dynamic memory allocations
62fe727
to
47f1672
Compare
@nim65s I added unitests in C++ to the PR. I decided to create a different factory for loop contacts as they are quite different from standard contacts. |
@Kotochleb most of the code should be fine now, I may have missed or overlook some things though. Let me know if some things should still be changed or if the PR is fine as it is. |
4617b2a
to
29fbf6e
Compare
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.
Aside from those very minor changes mentioned in this review, everything appears to be all right. I ran unittests for the code compiled in both Release
with -O3
and Release
with -O3 -march=native -mavx -mfma
. Both cases are passing. The same goes for dynamic memory allocation and and matrix resizing checks from Eigen. If the suggestions will be resolved I will approve the PR
bindings/python/crocoddyl/multibody/contacts/contact-6d-loop.cpp
Outdated
Show resolved
Hide resolved
bindings/python/crocoddyl/multibody/contacts/contact-6d-loop.cpp
Outdated
Show resolved
Hide resolved
Remove bindings for old data and change operation order for dvel_dq
I made these changes @Kotochleb. I compiled in Debug just fine |
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.
First of all, thanks for pushing this relevant feature, @LudovicDeMatteis!
This PR handles closed-loop kinematics based on an implicit method, which certainly looks like our acceleration-based scleronomic contact constraints. However, there are small, yet important differences, i.e.,
- "Closed-loop kinematics (or a chord) produces constraint forces in two bodies"
Moreover, in a general connectivity graph, we have a cluster composed of more than one close-loop kinematics (or chords). Each chord can be defined by two bodies that are constrained, with forces that, of course, propagate in each of them.
In short, I propose extending these notions to our "contact abstract class". To simplify the changes, I describe the action task for the simple case of a cluster with a single chord (your work) below. But, perhaps, we should later make it better. Let's discuss this in a meeting.
- Rename
ContactModelAbstractTpl
toKinematicConstraintModelAbstractTpl
andContactDataAbstractTpl
toKinematicConstraintDataAbstractTpl
. This involves a deprecation procedure for theContactModelAbstractTpl
andContactDataAbstractTpl
. - Rename
ContactItemTpl
toKinematicConstraintItemTpl
. This includes the deprecation ofContactItemTpl
. - Rename
ContactModelMultipleTpl
toKinematicConstraintModelMultipleTpl
and ContactDataMultipleTplto
KinematicConstraintDataMultipleTpl. Again, it involves a deprecation procedure for
ContactModelMultipleTpland
ContactDataMultipleTpl` - Update unit test given changes in 1, 2, 3, and 4. This includes renaming files.
- Introduce a
std::list
for the two bodies' frame IDs and placements in https://github.com/loco-3d/crocoddyl/blob/devel/include/crocoddyl/multibody/contact-base.hpp#L174-L175. This involves adapting setter and getter functions. Note that it assumes a single chord per cluster. - Introduce the notion of a list of forces in
ForceDataAbstractTpl
. This will allow us to storefext
for the two bodies. To do this, ourKinematicConstraintModelAbstract
needs to include the notion of "the number of constrained forces". - Introduce a
std::list
fora0
andda0_dx
for each body in https://github.com/loco-3d/crocoddyl/blob/devel/include/crocoddyl/multibody/contact-base.hpp#L212-L213. Optionally, we could take the opportunity to renamea0
andda0_dx
toac
anddac_dx
, respectively. - Rename
ContactModel6DLoopTpl
toKinematicLoopModelTpl
. Same for the data structure. - Simplify
ContactModel6DLoopTpl
andContactData6DLoopTpl
by reusing the objects in theKinematicConstraintModelAbstractTpl
,ForceDataAbstractTpl
, andKinematicConstraintDataAbstractTpl
classes. This requires changes in the Python bindings.
Unfortunately, I am asking for a bunch of painful things to develop. I am sorry about this and am open to discussing possibilities. However, I must say that this type of work should be done together to avoid these types of "extreme" changes.
I thank you for your effort, @LudovicDeMatteis and @nmansard! I am really interested in having such a feature in Crocoddyl, as you guys do. But, I believe we need to do it better.
I'll be in humanoids, perhaps we can also further discussing this topic there
ContactModel6DLoopTpl(boost::shared_ptr<StateMultibody> state, | ||
const int joint1_id, const SE3 &joint1_placement, | ||
const int joint2_id, const SE3 &joint2_placement, | ||
const pinocchio::ReferenceFrame ref, |
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.
To be consistent with other contacts, let's rename this to type, e.g.,
const pinocchio::ReferenceFrame ref, | |
const pinocchio::ReferenceFrame type, |
Please adapt the documentation, other constructors, and Python bindings appropriately.
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.
Keeping this for the discussion for now
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.
Following last week discussion, I changed ref to type to remain consistent with other contacts API. If we need some renaming, this should be done in another PR for refactoring
pinocchio::updateFramePlacements<Scalar>(*state_->get_pinocchio().get(), | ||
*d->pinocchio); |
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.
This is very inefficient. We should update the frame placements for joints 1 and 2.
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 removed this since we actually didn't need frame placements (but only joint placements)
d->j1Xf1.noalias() = joint1_placement_.toActionMatrix(); | ||
d->j2Xf2.noalias() = joint2_placement_.toActionMatrix(); |
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.
We are not interested in storing these values, but their inverses. Moreover, their inverses are constant and should be computed when creating data. See this example: https://github.com/loco-3d/crocoddyl/blob/devel/include/crocoddyl/multibody/contact-base.hpp#L193
As a final note, we are not using id
or fXj
from the base class. We should pick the joint 1 to store these values, similar spirit to the development in the paper. This indeed leads to many other comments such as
- We should use
get/set_reference
andget/set_id
to store joint 1 information.
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.
Indeed, I changed the way values are stored and computed. For the final note, I suggest that we wait for the discussion in case anything changes on that.
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.
Adding a comment for the final note. As discussed, we are using parent joint id and relative placement to identify the contact points here. However, Base::id is a FrameIndex not a jointIndex, so it cannot be used directly. I suggest we wait for a larger refactoring to change this properly.
gains_[1] * | ||
(joint1_placement_.toActionMatrixInverse() * d->v1_partial_dq - | ||
d->f1Mf2.act(d->f2vf2).toActionMatrix() * | ||
(d->f1Jf1 - d->f1Xf2 * d->f2Jf2) - |
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.
This is inefficient. We should use Jc
.
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.
This comment is on outdated code, it has been changed since
d->f1Xf2 * joint2_placement_.toActionMatrixInverse() * | ||
d->v2_partial_dq); | ||
d->da0_dx.rightCols(nv).noalias() += | ||
gains_[1] * (d->f1Jf1 - d->f1Xf2 * d->f2Jf2); |
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.
Same here, let's use Jc
.
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.
Same here, the code is outdated
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
This PR adds a new type of contact to Crocoddyl.
We defined loop contacts (i.e. between parts of the robot) with 6D constraints (constraint on the contact frames relative position and orientation)