allow EnvironmentBodyRemover not to restore a grabbed body when the grabbing link does not exist#1359
allow EnvironmentBodyRemover not to restore a grabbed body when the grabbing link does not exist#1359eisoku9618 wants to merge 14 commits intoproductionfrom
Conversation
…rabbing link does not exist as we do for active manipulator
| } | ||
| } | ||
| if( !_pGrabbedInfos.empty() ) { | ||
| // it might be ok with grabbing link doesn't exist if ConnectedBody acitve state changes. |
There was a problem hiding this comment.
@eisoku9618 I think you should not change the behavior of EnvironmentBodyRemover. There is a complication like this: If there is a grabbed body that has _setIgnoreRobotLinkNames and some of links are removed by the CBAS change, it is not obvious how this class should be doing.
There was a problem hiding this comment.
@yoshikikanemoto Eventually we need to take care of grabbed bodies restoring failures either by
EnvironmentBodyRemover itself or by callers of EnvironmentBodyRemover.
My only concern is an inconsistency of current EnvironmentBodyRemover between active manipulator and grabbed bodies. EnvironmentBodyRemover tries to restore both active manipulator and grabbed bodies, and the inconsistency is that it allows not restoring active manipulator while it terminates the program (c++11 and later) if unable to restore grabbed bodies.
it is not obvious how this class should be doing.
How about adding the input arguments to EnvironmentBodyRemover to clarify how this class should behave?
EnvironmentBodyRemover(KinBodyPtr pBody, bool abortOnActiveManipulatorLost=false, bool abortOnGrabbedBodiesLost=true);If this is still not good and we can leave the inconsistent behavior of EnvironmentBodyRemover for now, I can make another utility function SetConnectedBodyActiveStatesKeepingGrabbedBodiesAsMuchAsPossible and move the implementation to this.
void SetConnectedBodyActiveStatesKeepingGrabbedBodiesAsMuchAsPossible(pRobot, requestedConnectedBodyActiveStates) {
std::vector<KinBody::GrabbedInfoPtr> pGrabbedInfos;
pRobot->GetGrabbedInfo(pGrabbedInfos);
// manually restore grabbed state instead of using EnvironmentBodyRemover because a grabbing link might get removed on connected body active state change.
pRobot->ReleaseAllGrabbed();
{
EnvironmentBodyRemover robotremover(pRobot);
pRobot->SetConnectedBodyActiveStates(requestedConnectedBodyActiveStates);
}
std::vector<KinBody::GrabbedInfoPtr>::iterator itRemoveFirst = pGrabbedInfos.begin();
for (std::vector<KinBody::GrabbedInfoPtr>::const_iterator itGrabbedInfo = pGrabbedInfos.begin(); itGrabbedInfo != pGrabbedInfos.end(); ++itGrabbedInfo) {
const KinBody::GrabbedInfoPtr pGrabbedInfo = *itGrabbedInfo;
bool needToDelete = false;
if( !pRobot->GetLink(pGrabbedInfo->_robotlinkname) ) {
RAVELOG_WARN_FORMAT("env=%s, body=%s, cannot re-grab '%s' because grabbing link '%s' does not exist anymore.", pRobot->GetEnv()->GetNameId()%pRobot->GetName()%pGrabbedInfo->_grabbedname%pGrabbedInfo->_robotlinkname);
needToDelete = true;
}
else if( !pRobot->GetEnv()->GetKinBody(pGrabbedInfo->_grabbedname) ) {
RAVELOG_WARN_FORMAT("env=%s, body=%s, cannot re-grab '%s' because it does not exist in the environment.", pRobot->GetEnv()->GetNameId()%pRobot->GetName()%pGrabbedInfo->_grabbedname);
needToDelete = true;
}
else {
for( std::set<std::string>::const_iterator itLinkName = pGrabbedInfo->_setIgnoreRobotLinkNames.begin(); itLinkName != pGrabbedInfo->_setIgnoreRobotLinkNames.end(); ++itLinkName ) {
if( !pRobot->GetLink(*itLinkName) ) {
RAVELOG_WARN_FORMAT("env=%s, body=%s, cannot re-grab '%s' because '%s' in _setIgnoreRobotLinkNames does not exist anymore.", pRobot->GetEnv()->GetNameId()%pRobot->GetName()%pGrabbedInfo->_grabbedname%(*itLinkName));
needToDelete = true;
break;
}
}
}
if( needToDelete ) {
continue;
}
// will regrasp this info
if( itRemoveFirst != itGrabbedInfo ) {
*itRemoveFirst = std::move(*itGrabbedInfo);
}
++itRemoveFirst;
}
const std::vector<KinBody::GrabbedInfoConstPtr> pConstGrabbedInfos(pGrabbedInfos.begin(), itRemoveFirst);
pRobot->ResetGrabbed(pConstGrabbedInfos);
}There was a problem hiding this comment.
discussed with @yoshikikanemoto
At least, it is better to use a bitmask instead of two booleans for the argument.
There was a problem hiding this comment.
@yoshikikanemoto As we discussed, I changed this PR to use a bit mask for the options. Could you check this PR and the changes in the related internal repositories? pipelineid=456553
…o allow-EnvironmentBodyRemover-to-give-up-regrasp
…o allow-EnvironmentBodyRemover-to-give-up-regrasp
|
@snozawa can you take a look at this MR? Thanks |
…EnvironmentBodyRemover-to-give-up-regrasp
|
As for the restoring of
The former one just restores the original ptr of In this case, the former one preserves So, I personally would like to revert the grabbed-restoring code, and would like to use the Then, the next discussion would be how to handle the exception from the Btw, throwing from |
| if( !!pmanip ) { | ||
| _pBodyRobot->SetActiveManipulator(pmanip); | ||
| } | ||
| else if( !(_restoreOptions & EBRRO_AbortOnActiveManipulatorLost) ) { |
There was a problem hiding this comment.
@eisoku9618
Is this equivalent to the followig?
the following is slightly readable since it does not invert the flag:
else if( (_restoreOptions & EBRRO_AbortOnActiveManipulatorLost) ) {
stringstream ss;
ss << "available manipulators are [";
for( const RobotBase::ManipulatorPtr& pManip : _pBodyRobot->GetManipulators() ) {
ss << pManip->GetName() << ", ";
}
ss << "]";
throw OPENRAVE_EXCEPTION_FORMAT(_("env=%s, robot=%s, cannot restore the original active manip=%s because it does not exist anymore. %s"), _pBodyRobot->GetEnv()->GetNameId()%_pBodyRobot->GetName()%_activeManipName%ss.str(), ORE_Failed);
}
else {
pmanip = _pBodyRobot->GetActiveManipulator();
RAVELOG_WARN_FORMAT("env=%s, robot=%s, cannot restore the original active manip=%s because it does not exist anymore. current active manip=%s", _pBodyRobot->GetEnv()->GetNameId()%_pBodyRobot->GetName()%_activeManipName%(!!pmanip ? pmanip->GetName() : ""));
}
|
|
||
| enum EnvironmentBodyRemoverRestoreOptions : uint8_t | ||
| { | ||
| EBRRO_NoAbortOnInfoLost = 0, ///< will not abort even if any info cannot be restored. |
There was a problem hiding this comment.
what about like this?
| EBRRO_NoAbortOnInfoLost = 0, ///< will not abort even if any info cannot be restored. | |
| EBRRO_NoAbortOnInfoLost = 0, ///< will not abort even if any info handled in this enum cannot be restored. Note that the remover would abort if there is an exception which is not handled in this enum. |
| // is re-added to the env. | ||
| _pBodyRobot = RaveInterfaceCast<RobotBase>(_pBody); | ||
| if( !!_pBodyRobot->GetActiveManipulator() ) { | ||
| _activeManipName = _pBodyRobot->GetActiveManipulator()->GetName(); |
There was a problem hiding this comment.
Any problem if we use RobotStateSaver's Save_ActiveManipulator here?
maybe you need to restore by the name, not by the pointer?
|
talked in person with @eisoku9618
what do you think? @kanbouchou @yoshikikanemoto |
@kanbouchou @yoshikikanemoto May I know your opinions about this. I also think this is a good direction. Some callers of EnvironmentBodyRemover for CBAS change need to reject the CBAS change request when restoring active manipulator and grabbed bodies is impossible, others accept CBAS change without trying restoring active manipulator and grabbed bodies. (i.e. depending on the context of the callers) |
Currently we allow
EnvironmentBodyRemovernot to restore active manipulator on restore if the active manipulator does not exist anymore in the body in case of CBAS change.I think that we should do the same thing for grabbed bodies because a grabbing link might not exist in case of CBAS change.
_setIgnoreRobotLinkNamesmight not exist