-
Notifications
You must be signed in to change notification settings - Fork 75
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
Two frames contact pr #218
Two frames contact pr #218
Conversation
…dings. Some rudimentary methods from contact-base exist
…ple URDF model added
Hi ! This project doesn't usually accept pull requests on the main branch. |
for more information, see https://pre-commit.ci
Thanks for this PR. I'm currently very busy, but I'll try to review this next week. |
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've reviewed the code and overall it looks great. I've left some comments on small things that should be fixed before merging this PR. The main one is removing the STL/urdf files, which should not stay in this repo in my opinion. I know we have the model of a robot in TSID, but that was introduced a long time ago, and it was justified by the need to give students an easy way to use the software. Nowadays, with packages as example-robot-data, I think this is no longer necessary. Let me know your thoughts, and thanks for the great work!
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
Hello Andrea! |
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.
Nice job addressing all my comments, thanks! I've left just one additional comment related to the dummyMotionTask you mentioned.
void updateForceGeneratorMatrix(); | ||
|
||
TaskTwoFramesEquality m_motionTask; | ||
TaskSE3Equality m_dummyMotionTask; |
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 had not noticed this in my first review, thanks for pointing it out. Indeed using this dummyMotionTask is not ideal. It would probably be better to change the API of ContactBase, so that the method getMotionTask
returns a MotionTaskBase
rather than an SE3EqualityTask
. Would you agree with 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.
For me the MotionTask approach looks neat, so I implemented it.
The resultant ContactTwoFramePositions contact works OK.
The implementation requires static_cast here inTaskCopEquality, this task is not covered by unit tests, can you check if its OK too?
…w contacts use different motion tasks, not only TaskSE3Equality
for more information, see https://pre-commit.ci
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.
Thanks for implementing these changes. There's still something unclear to me (See comments below), but apart from this, everything looks fine!
@@ -68,7 +68,7 @@ class ContactTwoFramePositions : public ContactBase { | |||
virtual const ConstraintEquality& computeForceRegularizationTask( | |||
const double t, ConstRefVector q, ConstRefVector v, const Data& data); | |||
|
|||
const TaskSE3Equality& getMotionTask() const; | |||
const TaskTwoFramesEquality& getMotionTask() const; |
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.
Shouldn't the getMotionTask
method return a TaskMotion
?
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 pure virtual method TaskMotion& getMotionTask
of the parent class ContactBase
should be implemented in this class, shouldn't it?
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.
Hello Andrea!
Sorry for the delay. I tried both variants (getMotionTask returns TaskTwoFramesEquality or TaskMotion) and both works.
The reason I'm using TaskTwoFramesEquality returning variant is because I'm trying to be as close as possible in my realization with existing realizations of the same methods in contact-6d class and others.
So in contact-6d.cpp the pure virtual method TaskMotion& getMotionTask of the parent class ContactBase is also implemented via returning TaskSE3Equality.
Please advice which variant should I use in this PR.
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.
It's really weird that both work. In theory, if a class does not implement all the pure virtual methods of the parent class, then it is an abstract class and therefore cannot be instantiated. Implementing a method with the same name but with a different return type is also weird and should give you an error because you can't overload methods based on return type.
Therefore, you should get a compilation error when you try to create an object of class Contact6d
or ContactTwoFramesPositions
. Do you have some tests where objects of these classes are created?
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.
Hello Andrea!
Yes, I'm checking my code before pushing with this minimalistic example mentioned above by creating ContactTwoFramePositions object here. Everything works as expected.
Should I create a more sophisticated test?
AFAIK the only part which uses getMotionTask() method of contact object is the TaskCopEquality, which casts the returned object to TaskSE3Equality. So returning the TaskSE3Equality class (as vanilla contact-6d does) by GetMotionTask method is the solution from the "classic" TSID code without my modifications.
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're right. It works. I've recreated the same situation with this minimalistic code, and indeed the compiler doesn't complain. I didn't know you could do this. At this point I am fine with this PR and I am gonna merge it. Thanks again for the great contribution!
#include <iostream>
using namespace std;
class TaskMotion {};
class TaskTwoFramesEquality : public TaskMotion {};
class ContactBase {
public:
virtual const TaskMotion& getMotionTask() const = 0;
};
class ContactTwoFramePositions : public ContactBase {
public:
TaskTwoFramesEquality m_task;
const TaskTwoFramesEquality& getMotionTask() const{
cout<<"TaskTwoFramesEquality& getMotionTask"<<endl;
return m_task;
}
};
int main(){
ContactTwoFramePositions c;
const TaskMotion& task = c.getMotionTask();
const TaskTwoFramesEquality& task2 = c.getMotionTask();
return 0;
}
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.
Good, thank you once again for this great repository!
merge #218 from master into devel
* TaskTwoFramesEquality and ContactTwoFramePositions added with appropriate bindings. * getMotionTask type changed from TaskSE3Equality to TaskMotion to allow contacts use different motion tasks, not only TaskSE3Equality * python demo of talos gripper with closed kinematic chain, using URDF/STLs in external repo --------- Authored-by: @egordv
This PR is related to the issue "TSID for "pantograph/biarticular" robot leg design" #165
I want to share the code I wrote to create a new type of contact following the discussion in the mentioned PR.
The main aim of this PR is to give the TSID dynamics formulation the ability to work with closed kinematic chains specified via user code (not URDF).
This PR adds two new items:
The usage of TwoFramesContact alongside with zero actuation bounds allows to create a closed kinematic chains in current TSID formulation (with current version of Pinocchio and URDF parser). The contact should be created bu user via TwoFramesContact creation.
The PR also includes a minimal example showing how to add a closed kinematic chain to Talos gripper mechanism via demo/demo_talos_gripper_closed_kinematic_chain.py
This is the sample how this gripper works without additional contact:
This is the sample how this gripper works with additional contact via TwoFramesContact thus creating a closed kinematic chain:
Regarding the code: there are many virtual methods in conact-base.hpp not relevant to the concept of TwoFramesContact like setContactNormal, etc. Also the underlying motion task can be only the SE3Equality so the PR code contains some rudimentary methods to mitigate this in not very elegant way, may be some refactoring is required?