-
Notifications
You must be signed in to change notification settings - Fork 178
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
Allowing WORLD and LOCAL_WORLD_ALIGNED in ContactModel1D #1054
Allowing WORLD and LOCAL_WORLD_ALIGNED in ContactModel1D #1054
Conversation
bp::optional<Eigen::Vector2d> >( | ||
bp::args("self", "state", "id", "xref", "nu", "gains"), | ||
bp::optional<Eigen::Vector2d, std::size_t, pinocchio::ReferenceFrame> >( | ||
bp::args("self", "state", "id", "xref", "nu", "gains", "type", "pinRefFrame"), |
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.
Set default argument 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.
Also rename the arguments as follows:
type
tomask
pinRefFrame
totype
This latter follows the standard used in other classes.
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.
@jcarpent concerning the default argument I had
( bp::args("self", "state", "id", "xref", "nu", "gains", "type"), bp::arg("pinRefFrame")=pinocchio::LOCAL ),
but it seemed to make python unittest fail and caused an import error in python, I couldn't figure out why . I need to investigate this . Any clue?
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 addressed in fd58261
const Scalar xref, | ||
const std::size_t nu, | ||
const Vector2s& gains, | ||
const std::size_t& 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.
The reference is not needed as it is a basic 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.
Better, please define an enum for 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.
addressed in fd58261
|
||
if (gains_[0] != 0.) { | ||
d->a0[0] += gains_[0] * (d->pinocchio->oMf[id_].translation()[2] - xref_); | ||
if(pinReferenceFrame_ == pinocchio::WORLD){ |
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 WORLD case has no physical meaning I would say.
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 believe that Baumgarte stabilizing term is already expressed in WORLD for all contact models - which I also don't really understand as the acceleration and force computations are currently in LOCAL... Wouldn't it make sense to compute the Baumgarte terms in the pinocchio reference frame ?
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.
There are still many changes to be tackled.
However, I don't understand why you need to define a reference frame that is not LOCAL.
These classes are not aimed to track a reference acceleration for instance.
So, why?
bp::optional<Eigen::Vector2d> >( | ||
bp::args("self", "state", "id", "xref", "nu", "gains"), | ||
bp::optional<Eigen::Vector2d, std::size_t, pinocchio::ReferenceFrame> >( | ||
bp::args("self", "state", "id", "xref", "nu", "gains", "type", "pinRefFrame"), |
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.
Also rename the arguments as follows:
type
tomask
pinRefFrame
totype
This latter follows the standard used in other classes.
":param type: axis of the contact constraint (0=x, 1=y or 2=z)\n" | ||
":param pinRefFrame: pin.ReferenceFrame in {LOCAL, WORLD, LOCAL_WORLD_ALIGNED}")) |
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.
Please adapt the documentation as suggested above
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.
addressed in fd58261
bp::args("self", "state", "id", "xref", "gains"), | ||
"Initialize the contact model.\n\n" | ||
":param state: state of the multibody system\n" | ||
":param id: reference frame id of the contact\n" | ||
":param xref: contact position used for the Baumgarte stabilization\n" | ||
":param gains: gains of the contact model (default np.matrix([0.,0.]))")) | ||
":param gains: gains of the contact model (default np.matrix([0.,0.]))\n")) |
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.
Revert this back
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.
addressed in fd58261
@@ -68,7 +76,10 @@ void exposeContact1D() { | |||
&ContactModel1D::set_reference, "reference contact translation") | |||
.add_property("gains", | |||
bp::make_function(&ContactModel1D::get_gains, bp::return_value_policy<bp::return_by_value>()), | |||
"contact gains"); | |||
"contact gains") | |||
.add_property("pinReferenceFrame", |
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.
- Renamed this as suggested above
- Add the getter and setter for the
mask
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.
addressed in fd58261
"contact gains") | ||
.add_property("pinReferenceFrame", | ||
bp::make_function(&ContactModel1D::get_pinReferenceFrame, bp::return_value_policy<bp::return_by_value>()), | ||
&ContactModel1D::set_pinReferenceFrame, "pin.ReferenceFrame"); |
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.
Change documentation to reference type of contact
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.
addressed in fd58261
@@ -37,6 +37,7 @@ class ContactModel1DTpl : public ContactModelAbstractTpl<_Scalar> { | |||
typedef typename MathBase::Vector3s Vector3s; | |||
typedef typename MathBase::VectorXs VectorXs; | |||
typedef typename MathBase::Matrix3s Matrix3s; | |||
typedef typename MathBase::Vector6s Vector6s; |
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.
Remove this line. It doesn't seem to be needed
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.
addressed in fd58261
const pinocchio::FrameIndex id, | ||
const Scalar xref, | ||
const Vector2s& gains, | ||
const pinocchio::ReferenceFrame pinRefFrame) |
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.
Change the name of the arguments as suggested above.
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.
addressed in fd58261
const Vector2s& gains, | ||
const std::size_t& type, | ||
const pinocchio::ReferenceFrame pinRefFrame) | ||
: Base(state, 1, nu), xref_(xref), gains_(gains), type_(type), pinReferenceFrame_(pinRefFrame) { |
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.
Change the name of the arguments as suggested above
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.
addressed in fd58261
id_ = id; | ||
if(type_ < 0 || type_ > 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.
This doesn't follow the code format. Please run the code formatter as described in the wiki
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.
addressed in fd58261
const Scalar xref, | ||
const std::size_t nu, | ||
const Vector2s& gains, | ||
const std::size_t& 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.
Better, please define an enum for type
.
Thanks for your review , I will now implement some of the requested changes. I also noticed that the contact force residual computation needs to be updated as well , and therefore be aware of the mask of the contact model . @cmastalli the purpose of this enhancement is to allow force computations in the WORLD frame, which is necessary for e.g. sanding tasks where the desired force is defined in WORLD (the LOCAL z-axis is not necessarily aligned with the vertical direction). In that case , I believe we need to perform all contact-related computations in LOCAL_WORLD_ALIGNED , which is currently not allowed by Crocoddyl, as proposed in #812 |
…g names to mask, type + added getter/setter for mask + defined & binded enum for mask + formated code changed arg names into mask, type + updated doc + defined enum for mask corrected mistake ref -> type added enum in bindings removed default pinocchio reference arg in bindings causing unittest to fail and import error in python added getter setter for mask + formatted code
Concerning the force residual, I could add the mask to ContactData1D so that it can be accessed from the force residual . Also , I can add the pinocchio reference as an optional argument in force residual constructor so we can compute the 1D force residual in any frame . From there, this could be straightforwardly extended to other contact models I believe . What do you think ? |
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.
Please see all the comments below.
A part of them, we also need to unittest the different mask cases.
To do so, you need to extend the contact factory.
bp::enum_<Contact1DMaskType>("Contact1DMaskType") | ||
.value("X_MASK", X_MASK) | ||
.value("Y_MASK", Y_MASK) | ||
.value("Z_MASK", Z_MASK) | ||
.export_values(); |
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.
Let's make this class a bit more generic.
bp::enum_<Contact1DMaskType>("Contact1DMaskType") | |
.value("X_MASK", X_MASK) | |
.value("Y_MASK", Y_MASK) | |
.value("Z_MASK", Z_MASK) | |
.export_values(); | |
bp::enum_<Vector3MaskType>("Vector3MaskType") | |
.value("x", x) | |
.value("y", y) | |
.value("z", z) | |
.export_values(); | |
"The calc and calcDiff functions compute the contact Jacobian and drift (holonomic constraint) or\n" | ||
"the derivatives of the holonomic constraint, respectively.", | ||
bp::init<boost::shared_ptr<StateMultibody>, pinocchio::FrameIndex, double, std::size_t, | ||
bp::optional<Eigen::Vector2d> >( | ||
bp::args("self", "state", "id", "xref", "nu", "gains"), | ||
bp::optional<Eigen::Vector2d, Contact1DMaskType, pinocchio::ReferenceFrame> >( |
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.
You will need to adapt the code as now the class is Vector3MaskType
.
"The calc and calcDiff functions compute the contact Jacobian and drift (holonomic constraint) or\n" | ||
"the derivatives of the holonomic constraint, respectively.", | ||
bp::init<boost::shared_ptr<StateMultibody>, pinocchio::FrameIndex, double, std::size_t, | ||
bp::optional<Eigen::Vector2d> >( | ||
bp::args("self", "state", "id", "xref", "nu", "gains"), | ||
bp::optional<Eigen::Vector2d, Contact1DMaskType, pinocchio::ReferenceFrame> >( |
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.
You will need to adapt the code as now the class is Vector3MaskType
.
":param gains: gains of the contact model (default np.matrix([0.,0.]))")) | ||
.def(bp::init<boost::shared_ptr<StateMultibody>, pinocchio::FrameIndex, double, bp::optional<Eigen::Vector2d> >( | ||
":param gains: gains of the contact model (default np.matrix([0.,0.]))\n" | ||
":param mask: axis of the contact constraint (0=x, 1=y or 2=z)\n" |
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.
":param mask: axis of the contact constraint (0=x, 1=y or 2=z)\n" | |
":param mask: axis of the contact constraint (default z)\n" |
":param gains: gains of the contact model (default np.matrix([0.,0.]))")) | ||
.def(bp::init<boost::shared_ptr<StateMultibody>, pinocchio::FrameIndex, double, bp::optional<Eigen::Vector2d> >( | ||
":param gains: gains of the contact model (default np.matrix([0.,0.]))\n" | ||
":param mask: axis of the contact constraint (0=x, 1=y or 2=z)\n" |
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.
":param mask: axis of the contact constraint (0=x, 1=y or 2=z)\n" | |
":param mask: axis of the contact constraint (default z)\n" |
break; | ||
} | ||
case pinocchio::LOCAL_WORLD_ALIGNED: { | ||
jMc = pinocchio::SE3(Matrix3s::Identity(), d->jMf.translation()); |
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 allocating data dynamically.
Instead, you should modify the translation only, i.e.
jMc = pinocchio::SE3(Matrix3s::Identity(), d->jMf.translation()); | |
jMc_.translation = d->jMf.translation(); |
Then, you have to set the identity matrix only when you have define LOCAL_WORLD_ALIGNED
const Eigen::Ref<const Matrix3s> R = d->jMf.rotation(); | ||
data->f.linear() = R.col(2) * force[0]; | ||
data->f.angular() = d->jMf.translation().cross(data->f.linear()); | ||
pinocchio::SE3 jMc; |
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.
Let's define a global variable for this, and called it jMc_
.
This avoids to allocate data dynamically.
const Eigen::Ref<const Matrix3s> R = d->jMf.rotation(); | ||
data->f.linear() = R.col(2) * force[0]; | ||
data->f.angular() = d->jMf.translation().cross(data->f.linear()); | ||
pinocchio::SE3 jMc; |
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.
Let's define a global variable for this, and called it jMc_
.
This avoids to allocate data dynamically.
|
||
template <typename Scalar> | ||
void ContactModel1DTpl<Scalar>::set_mask(const Contact1DMaskType mask) { | ||
mask_ = mask; |
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.
If you change to LOCAL_WORLD_ALIGNED
, then define the identity matrix as pointed out above.
|
||
template <typename Scalar> | ||
void ContactModel1DTpl<Scalar>::set_mask(const Contact1DMaskType mask) { | ||
mask_ = mask; |
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.
If you change to LOCAL_WORLD_ALIGNED
, then define the identity matrix as pointed out above.
…cted mistakes in contact1d calcdiff transformations
Thanks for the review , I addressed the requested changes in 1fecfb4b . In addition to those , I implemented
Currently, the unittests pass only for LOCAL and WORLD frames. There seem to be a mistake in calcDiff for LOCAL_WORLD_ALIGNED . I can't find it... |
d743533
to
44b65f3
Compare
So we wrote down the maths with @nmansard and derived correct LOCAL_WORLD_ALIGNED derivatives for acceleration, I will fix the current implementation asap. Also @jcarpent since the WORLD case doesn't make sense as you say I can remove it from the API. But then I think we should also clarify the Baumgarte terms: is there a reason why they are expressed in WORLD currently? |
I will close this issue due to a lack of activity. @skleff1994 -- feel free to re-open it anytime you wish. |
Minor enhancements for the 1D contact model . Related to #812
type
in{0,1,2}
for{x,y,z}
the z-axis being the default oneLOCAL
,WORLD
,LOCAL_WORLD_ALIGNED
},LOCAL
being the default oneThe mask could be extended to 2D contact , and the pinocchio reference frame option could be propagated to other contact models , if deemed useful . But I think all of this will be handled in Pinocchio in the future...