-
Notifications
You must be signed in to change notification settings - Fork 342
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
WIP: Do not assume all-zero/initial robot pose as non-self-colliding pose and make non-self-colliding pose configurable #1072
base: production
Are you sure you want to change the base?
Conversation
…llidingPositionConfigurationsAndLinkTransformations
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! See comments inline.
include/openrave/kinbody.h
Outdated
|
||
std::string GetResolvedJointName() const; | ||
|
||
std::string _id; ///< id of joint configuration state, for incremental update |
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.
Is this the same id as the parent PositionConfiguration? If not, is it also unique?
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 is not. This field is used as a primary key when the data structure is stored in a database, thus is unique among JointConfigurationStates
.
if (!IS_PYTHONOBJECT_NONE(_vNonSelfCollidingPositionConfigurations)) { | ||
for (int positionConfigurationIndex = 0; positionConfigurationIndex < len(_vNonSelfCollidingPositionConfigurations); ++positionConfigurationIndex) { | ||
PyPositionConfigurationPtr pyPositionConfiguration = py::extract<PyPositionConfigurationPtr>(_vNonSelfCollidingPositionConfigurations[positionConfigurationIndex]); | ||
if (!!pyPositionConfiguration) { |
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 to look this up. It looks like I'm not alone in thinking that it's not very readable, but I see that it's used a lot in the code base already, so I won't fight wind mills.
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 is a part of the project coding style rather than my preference. Please talk to @rdiankov about this.
src/libopenrave/kinbody.cpp
Outdated
@@ -113,6 +114,7 @@ bool KinBody::KinBodyInfo::operator==(const KinBodyInfo& other) const { | |||
&& AreVectorsDeepEqual(_vLinkInfos, other._vLinkInfos) | |||
&& AreVectorsDeepEqual(_vJointInfos, other._vJointInfos) | |||
&& AreVectorsDeepEqual(_vGrabbedInfos, other._vGrabbedInfos) | |||
&& _vNonSelfCollidingPositionConfigurations == other._vNonSelfCollidingPositionConfigurations |
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.
When do we use AreVectorsDeepEqual
here and when do we not?
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 point. AreVectorsDeepEqual
checks value equality of each vector element, while ==
checks reference equality. Value equality needs to be checked here, so I updated the code.
@@ -4824,29 +4866,27 @@ void KinBody::_ComputeInternalInformation() | |||
} | |||
|
|||
_nHierarchyComputed = 2; | |||
// because of mimic joints, need to call SetDOFValues at least once, also use this to check for links that are off |
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 got lost. Was that intentional?
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 is an intended removal. Previously, SetDOFValues()
was called here while DOF values were not supposed to be changed by the call. In the new version, DOF values are supposed to be updated by a SetDOFValues()
call, thus the comment is no longer valid.
std::vector<bool> adjacentLinkFlags; | ||
_CalculateAdjacentLinkFlagsFromNonSelfCollidingPositionConfigurations(adjacentLinkFlags); | ||
|
||
// Constructs _vNonAdjacentLinks[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.
What does that mean? I can't even find why _vNonAdjacentLinks
has 4 elements. I guess [0]
is the list of adjacent links without a modification via adjacentoptions
.
Could you add some more comments about the logic anyway?
src/libopenrave/kinbody.cpp
Outdated
return _vNonAdjacentLinks.at(adjacentoptions); | ||
} | ||
|
||
void KinBody::_CalculateAdjacentLinkFlagsFromNonSelfCollidingPositionConfigurations(std::vector<bool>& adjacentLinkFlags) 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.
Did we profile this function? It looks pretty heavy.
Please add a description to the header, too.
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.
Though it takes some computation cost, it should not cause a problem practically thanks to the cache. I added an annotation to the function.
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'm not saying this feature is too heavy or not worth it - I would just like to know if we have benchmarking set up anywhere. Do we track OpenRAVE's performance like that?
src/libopenrave/kinbody.cpp
Outdated
_vNonAdjacentLinks[0].clear(); | ||
for( size_t ind0 = 0; ind0 < _veclinks.size(); ++ind0 ) { | ||
for( size_t ind1 = ind0 + 1; ind1 < _veclinks.size(); ++ind1 ) { | ||
if( !adjacentLinkFlags.at(_GetIndex1d(ind0, ind1)) && !AreAdjacentLinks(ind0, ind1) ) { |
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 second check happens inside _CalculateAdjacentLinkFlagsFromNonSelfCollidingPositionConfigurations
already.
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 is needed in a case no non-self-colliding position is given. The one in the calculation function is only for optimisation.
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.
True.
src/libopenrave/kinbody.cpp
Outdated
continue; // Already marked as adjacent, no need to check again | ||
} | ||
if( AreAdjacentLinks(ind0, ind1) ) { | ||
adjacentLinkFlags.at(adjacentLinkFlagIndex) = true; // Optimisation; allows skipping the check next time |
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 I understand correctly, adjacentLinkFlags
in this function has the same size and format as _vAdjacentLinks
which you check against here via AreAdjacentLinks
. In that case, why don't we initialize adjacentLinkFlags
to _vAdjacentLinks
in line 5455 and skip this comparison inside the loop?
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.
Those are not equivalent. _vAdjacentLinks
is calculated from actual link adjacencies and user-specified KinBodyInfo::_vForcedAdjacentLinks
, while this local variable is calculated from user-specified non-self-colliding configurations. Please see the implementation of KinBody::_ComputeInternalInformation()
.
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 a quick look at it and will read in detail tomorrow, but I don't think the calculation of _vAdjacentLink
is central to this question: Since you perform the check in this line, doesn't adjacentLinkFlags
become a superset of _vAdjacentLink
(which is a superset of _vForcedAdjacentLinks
)? If yes, shouldn't we just initialize it to that value?
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.
Sorry, I was misunderstanding your point. I updated the code to do so.
src/libopenrave/kinbody.cpp
Outdated
const bool bAdjacent = AreAdjacentLinks(ind0, ind1); | ||
if(!bAdjacent && !collisionchecker->CheckCollision(LinkConstPtr(_veclinks[ind0]), LinkConstPtr(_veclinks[ind1])) ) { | ||
_vNonAdjacentLinks[0].push_back(ind0|(ind1<<16)); | ||
// Constructs initial dofValueIsDeterminableFlags |
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.
Could you add the reason we need to do this to these comments?
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.
Added more comments.
Co-authored-by: Felix von Drigalski <[email protected]>
… into nonSelfColConfig
@felixvd Can we focus on the changes made in the patch, and spare readability issues derived from the original branch for now? It would be a good idea to create another PR for those. Thank you. |
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 we focus on the changes made in the patch, and spare readability issues derived from the original branch for now? It would be a good idea to create another PR for those.
As mentioned above, I didn't see that some of the lines weren't new, and there might have been a misunderstanding about some comments. That's my bad. As long as new code is clear and documented I'm happy.
(edited after a discussion with @yoshikikanemoto )
I'd like to consider one more point: when two non-self-colliding robot poses give different results for the adjacent links, is this intentional, or an error? I cannot think of a situation where it would be intended, but I might be missing something - can you come up with a counter example?
I imagine this flow:
- The user sets up multiple non-self-colliding poses - a very intuitive way to define "my robot can go here".
- The user adds cables/attachments as links to the robot to restrict unintended motion. They will be looking at the robot in one of the poses. If the new links collide in another pose, the links would be set to
adjacent
, and not restrict robot motion anymore. The behavior might be surprising, and similar to what this PR is trying to fix. - When settings are copied from another robot cell and the robot is replaced with another, links may similar be marked
adjacent
unintentionally.
It seems that using the intersection instead of the union here would add a layer of redundancy and make the system more robust to erroneous settings.
Adding this behavior isn't necessary to solve the bug that this PR is meant to fix, and this may not be the best place to implement it. But if you agree that this behavior would be useful, let's think about where it should live, before we have to make more or bigger changes later on.
Apart from that the PR looks good to me by the way.
return _vNonAdjacentLinks.at(adjacentoptions); | ||
} | ||
|
||
void KinBody::_CalculateAdjacentLinkFlagsFromNonSelfCollidingPositionConfigurations(std::vector<bool>& adjacentLinkFlags) const | ||
{ | ||
class TransformsSaver |
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.
class TransformsSaver | |
// Saves the link transformations and joint values of the body and applies them when this object is destroyed (at the end of the function) | |
class TransformsSaver |
Could you confirm that I didn't misread this? Thanks!
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.
That is a correct statement. However, one important aspect is missed: this is kind of a hackish replacement for KinBodyStateSaver(_, Save_LinkTransformation)
to allow making a change on a const KinBody. This limitation comes from the function signature of GetNonAdjacentLinks() const
.
src/libopenrave/kinbody.cpp
Outdated
@@ -5331,10 +5389,50 @@ bool CompareNonAdjacentFarthest(int pair0, int pair1) | |||
} | |||
|
|||
const std::vector<int>& KinBody::GetNonAdjacentLinks(int adjacentoptions) const | |||
{ | |||
CHECK_INTERNAL_COMPUTATION; | |||
if( _nNonAdjacentLinkCache & 0x80000000 ) { |
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. I didn't see that this was part of the original code.
Co-authored-by: Felix von Drigalski <[email protected]>
This patch addresses the problem that a robot link pair which is in a collision when a robot is at its initial pose or a pose that all DOF values are zeros is excluded from self collision checking unintentionally (regardless of whether the pair is marked as adjacent).
How it happens
robot.GetNonAdjacentLinks()
_vInitialLinkTransformations
_vInitialLinkTransformations
are set to link transforms of when a robot is added to an environment inKinBody::_ComputeInternalInformation()
,Changes made in this patch
KinBody::PositionConfiguration
which represents a pose of a robot with arbitrary connected body active statesnonSelfCollidingRobotConfigurations
inKinBody
, which type isList[PositionConfiguration]
. It's an empty list by default.Note that this patch includes a compatibility-breaking change (the first item in the list above). Some robot models may need additional adjacent link pair specifications or an entry in
nonSelfCollidingRobotConfigurations
.