Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE )

# Define here the needed parameters
set (OPENRAVE_VERSION_MAJOR 0)
set (OPENRAVE_VERSION_MINOR 139)
set (OPENRAVE_VERSION_PATCH 1)
set (OPENRAVE_VERSION_MINOR 140)
set (OPENRAVE_VERSION_PATCH 0)
set (OPENRAVE_VERSION ${OPENRAVE_VERSION_MAJOR}.${OPENRAVE_VERSION_MINOR}.${OPENRAVE_VERSION_PATCH})
set (OPENRAVE_SOVERSION ${OPENRAVE_VERSION_MAJOR}.${OPENRAVE_VERSION_MINOR})
message(STATUS "Compiling OpenRAVE Version ${OPENRAVE_VERSION}, soversion=${OPENRAVE_SOVERSION}")
Expand Down
5 changes: 5 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ ChangeLog
Unreleased
==========

Version 0.140.0
===============

* Allow EnvironmentBodyRemover not to restore a grabbed body when the grabbing link does not exist as we do for active manipulator

Version 0.139.1
===============

Expand Down
14 changes: 14 additions & 0 deletions include/openrave/robot.h
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,20 @@ class OPENRAVE_API RobotBase : public KinBody
friend class Grabbed;
};

///\brief removes the robot from the environment temporarily while in scope
class OPENRAVE_API EnvironmentBodyRemover
{
public:
EnvironmentBodyRemover(KinBodyPtr pBody);
~EnvironmentBodyRemover();

private:
KinBodyPtr _pBody;
std::vector<KinBody::GrabbedInfoPtr> _pGrabbedInfos; ///< the list of the current grabbed info of pBody at the time of removal.
RobotBasePtr _pBodyRobot;
std::string _activeManipName; ///< the name of the current active manipulator of pBody at the time of removal.
};

} // end namespace OpenRAVE

#endif // ROBOT_H
87 changes: 57 additions & 30 deletions src/libopenrave/robot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,42 +447,69 @@ void RobotBase::RobotStateSaver::Release()
KinBodyStateSaver::Release();
}

///\brief removes the robot from the environment temporarily while in scope
class EnvironmentBodyRemover
{
public:
EnvironmentBodyRemover(OpenRAVE::KinBodyPtr pBody) : _pBody(pBody), _grabbedStateSaver(pBody, OpenRAVE::KinBody::Save_GrabbedBodies) {
if( _pBody->IsRobot() ) {
// If the manip comes from a connected body, the information of which manip is active is lost once the robot
// is removed from env. Need to save the active manip name so that we can set it back later when the robot
// is re-added to the env.
_pBodyRobot = OpenRAVE::RaveInterfaceCast<OpenRAVE::RobotBase>(_pBody);
if( !!_pBodyRobot->GetActiveManipulator() ) {
_activeManipName = _pBodyRobot->GetActiveManipulator()->GetName();
}
EnvironmentBodyRemover::EnvironmentBodyRemover(KinBodyPtr pBody) : _pBody(pBody) {
if( _pBody->IsRobot() ) {
// If the manip comes from a connected body, the information of which manip is active is lost once the robot
// is removed from env. Need to save the active manip name so that we can set it back later when the robot
// is re-added to the env.
_pBodyRobot = RaveInterfaceCast<RobotBase>(_pBody);
if( !!_pBodyRobot->GetActiveManipulator() ) {
_activeManipName = _pBodyRobot->GetActiveManipulator()->GetName();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eisoku9618

Any problem if we use RobotStateSaver's Save_ActiveManipulator here?
maybe you need to restore by the name, not by the pointer?

}
_pBody->GetEnv()->Remove(_pBody);
}
_pBody->GetGrabbedInfo(_pGrabbedInfos);
_pBody->GetEnv()->Remove(_pBody);
}

~EnvironmentBodyRemover() {
_pBody->GetEnv()->Add(_pBody, IAM_StrictNameChecking);
_grabbedStateSaver.Restore();
_grabbedStateSaver.Release();
if( !!_pBodyRobot && !_activeManipName.empty() ) {
OpenRAVE::RobotBase::ManipulatorPtr pmanip = _pBodyRobot->GetManipulator(_activeManipName);
// it might be ok with manipulator doesn't exist if ConnectedBody acitve state changes.
if( !!pmanip ) {
_pBodyRobot->SetActiveManipulator(pmanip);
EnvironmentBodyRemover::~EnvironmentBodyRemover() {
_pBody->GetEnv()->Add(_pBody, IAM_StrictNameChecking);
if( !!_pBodyRobot && !_activeManipName.empty() ) {
RobotBase::ManipulatorPtr pmanip = _pBodyRobot->GetManipulator(_activeManipName);
// it might be ok with manipulator doesn't exist if ConnectedBody acitve state changes.
if( !!pmanip ) {
_pBodyRobot->SetActiveManipulator(pmanip);
}
else {
pmanip = _pBodyRobot->GetActiveManipulator();
RAVELOG_WARN_FORMAT("env=%s, robot=%s, cannot restore previous active manip=%s because it does not exist anymore. current active manip=%s", _pBodyRobot->GetEnv()->GetNameId()%_pBodyRobot->GetName()%_activeManipName%(!!pmanip ? pmanip->GetName() : ""));
}
}
if( !_pGrabbedInfos.empty() ) {
// it might be ok with grabbing link doesn't exist if ConnectedBody acitve state changes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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);
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discussed with @yoshikikanemoto
At least, it is better to use a bitmask instead of two booleans for the argument.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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

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( !_pBody->GetLink(pGrabbedInfo->_robotlinkname) ) {
RAVELOG_WARN_FORMAT("env=%s, body=%s, cannot re-grab '%s' because grabbing link '%s' does not exist anymore.", _pBody->GetEnv()->GetNameId()%_pBody->GetName()%pGrabbedInfo->_grabbedname%pGrabbedInfo->_robotlinkname);
needToDelete = true;
}
else if( !_pBody->GetEnv()->GetKinBody(pGrabbedInfo->_grabbedname) ) {
RAVELOG_WARN_FORMAT("env=%s, body=%s, cannot re-grab '%s' because it does not exist in the environment.", _pBody->GetEnv()->GetNameId()%_pBody->GetName()%pGrabbedInfo->_grabbedname);
needToDelete = true;
}
else {
for( std::set<std::string>::const_iterator itLinkName = pGrabbedInfo->_setIgnoreRobotLinkNames.begin(); itLinkName != pGrabbedInfo->_setIgnoreRobotLinkNames.end(); ++itLinkName ) {
if( !_pBody->GetLink(*itLinkName) ) {
RAVELOG_WARN_FORMAT("env=%s, body=%s, cannot re-grab '%s' because '%s' in _setIgnoreRobotLinkNames does not exist anymore.", _pBody->GetEnv()->GetNameId()%_pBody->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);
_pBody->ResetGrabbed(pConstGrabbedInfos);
}

private:
OpenRAVE::KinBodyPtr _pBody;
OpenRAVE::KinBody::KinBodyStateSaver _grabbedStateSaver;
OpenRAVE::RobotBasePtr _pBodyRobot;
std::string _activeManipName; ///< the name of the current active manipulator of pBody at the time of removal.
};
}

void RobotBase::RobotStateSaver::_RestoreRobot(boost::shared_ptr<RobotBase> probot)
{
Expand Down