diff --git a/CMakeLists.txt b/CMakeLists.txt index 87500074b0..714d241598 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE ) # Define here the needed parameters set (OPENRAVE_VERSION_MAJOR 0) -set (OPENRAVE_VERSION_MINOR 160) +set (OPENRAVE_VERSION_MINOR 161) 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}) diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 495070c65b..861e2ba4c9 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -3,6 +3,12 @@ ChangeLog ######### +Version 0.161.0 +=============== + +- Remove the code for back electromotive force from torque limit calculation APIs. +- Add common utility function for torque limit calculation. + Version 0.160.0 =============== diff --git a/include/openrave/kinbody.h b/include/openrave/kinbody.h index f8791b02e9..b9156a1243 100644 --- a/include/openrave/kinbody.h +++ b/include/openrave/kinbody.h @@ -2200,6 +2200,16 @@ class OPENRAVE_API KinBody : public InterfaceBase /// \brief Return the velocity of the specified joint axis only. dReal _GetVelocity(int axis, const std::pair&linkparentvelocity, const std::pair&linkchildvelocity) const; + /// \brief compute torque limit from speed torque points. + /// \param[in] iaxis : index of axis. + /// \param[in] electricMotorActuatorInfo : electrical motor actuator info. + /// \param[in] vSpeedTorquePoints : vector of pairs of speed and torque, which is coming from electrical motor actuator info. + /// \param[in] fDefaultTorqueLimit : if vSpeedTorquePoints is empty, this value is used. + dReal _GetTorqueLimitFromSpeedTorquePoints(const int iaxis, + const ElectricMotorActuatorInfo& electricMotorActuatorInfo, + const std::vector >& vSpeedTorquePoints, + const dReal fDefaultTorqueLimit) const; + boost::array _doflastsetvalues; ///< the last set value by the kinbody (_voffsets not applied). For revolute joints that have a range greater than 2*pi, it is only possible to recover the joint value from the link positions mod 2*pi. In order to recover the branch, multiplies of 2*pi are added/subtracted to this value that is closest to _doflastsetvalues. For circular joints, the last set value can be ignored since they always return a value from [-pi,pi) private: diff --git a/src/libopenrave/kinbodyjoint.cpp b/src/libopenrave/kinbodyjoint.cpp index 519529abce..8fcb98e3fd 100644 --- a/src/libopenrave/kinbodyjoint.cpp +++ b/src/libopenrave/kinbodyjoint.cpp @@ -1907,49 +1907,63 @@ void KinBody::Joint::AddTorque(const std::vector& pTorques) GetParent()->GetEnv()->GetPhysicsEngine()->AddJointTorque(shared_from_this(), pTorques); } +dReal KinBody::Joint::_GetTorqueLimitFromSpeedTorquePoints(const int iaxis, + const ElectricMotorActuatorInfo& electricMotorActuatorInfo, + const std::vector >& vSpeedTorquePoints, + const dReal fDefaultTorqueLimit) const +{ + if( vSpeedTorquePoints.size() > 0 ) { + const std::pair& firstSpeedTorquePoint = vSpeedTorquePoints[0]; + if( vSpeedTorquePoints.size() == 1 ) { + // doesn't matter what the velocity is + return firstSpeedTorquePoint.second*electricMotorActuatorInfo.gear_ratio; + } + + const dReal rawvelocity = GetVelocity(iaxis); + const dReal velocity = RaveFabs(rawvelocity); + dReal revolutionsPerSecond = electricMotorActuatorInfo.gear_ratio * velocity; + if( IsRevolute(iaxis) ) { + revolutionsPerSecond /= 2*M_PI; + } + + if( revolutionsPerSecond <= firstSpeedTorquePoint.first ) { + return firstSpeedTorquePoint.second*electricMotorActuatorInfo.gear_ratio; + } + + for(size_t i = 1; i < vSpeedTorquePoints.size(); ++i) { + const std::pair& speedTorquePoint1 = vSpeedTorquePoints[i]; + if( revolutionsPerSecond <= speedTorquePoint1.first ) { + // linearly interpolate to get the desired torque + const std::pair& speedTorquePoint0 = vSpeedTorquePoints[i-1]; + const dReal rps0 = speedTorquePoint0.first; + const dReal torque0 = speedTorquePoint0.second; + const dReal rps1 = speedTorquePoint1.first; + const dReal torque1 = speedTorquePoint1.second; + if( rps1 - rps0 <= g_fEpsilonLinear ) { + return torque1*electricMotorActuatorInfo.gear_ratio; + } + else { + return ((revolutionsPerSecond - rps0)/(rps1 - rps0)*(torque1-torque0) + torque0)*electricMotorActuatorInfo.gear_ratio; + } + } + } + + // revolutionsPerSecond is huge, return the last point + return vSpeedTorquePoints.back().second*electricMotorActuatorInfo.gear_ratio; + } + else { + return fDefaultTorqueLimit*electricMotorActuatorInfo.gear_ratio; + } +} + dReal KinBody::Joint::GetMaxTorque(int iaxis) const { if( !_info._infoElectricMotor ) { return _info._vmaxtorque.at(iaxis); } else { - if( _info._infoElectricMotor->max_speed_torque_points.size() > 0 ) { - if( _info._infoElectricMotor->max_speed_torque_points.size() == 1 ) { - // doesn't matter what the velocity is - return _info._infoElectricMotor->max_speed_torque_points.at(0).second*_info._infoElectricMotor->gear_ratio; - } - - dReal velocity = RaveFabs(GetVelocity(iaxis)); - dReal revolutionsPerSecond = _info._infoElectricMotor->gear_ratio * velocity; - if( IsRevolute(iaxis) ) { - revolutionsPerSecond /= 2*M_PI; - } - - if( revolutionsPerSecond <= _info._infoElectricMotor->max_speed_torque_points.at(0).first ) { - return _info._infoElectricMotor->max_speed_torque_points.at(0).second*_info._infoElectricMotor->gear_ratio; - } - - for(size_t i = 1; i < _info._infoElectricMotor->max_speed_torque_points.size(); ++i) { - if( revolutionsPerSecond <= _info._infoElectricMotor->max_speed_torque_points.at(i).first ) { - // linearly interpolate to get the desired torque - dReal rps0 = _info._infoElectricMotor->max_speed_torque_points.at(i-1).first; - dReal torque0 = _info._infoElectricMotor->max_speed_torque_points.at(i-1).second; - dReal rps1 = _info._infoElectricMotor->max_speed_torque_points.at(i).first; - dReal torque1 = _info._infoElectricMotor->max_speed_torque_points.at(i).second; - if( rps1 - rps0 <= g_fEpsilonLinear ) { - return torque1*_info._infoElectricMotor->gear_ratio; - } - - return ((revolutionsPerSecond - rps0)/(rps1 - rps0)*(torque1-torque0) + torque0)*_info._infoElectricMotor->gear_ratio; - } - } - - // revolutionsPerSecond is huge, return the last point - return _info._infoElectricMotor->max_speed_torque_points.back().second*_info._infoElectricMotor->gear_ratio; - } - else { - return _info._infoElectricMotor->max_instantaneous_torque*_info._infoElectricMotor->gear_ratio; - } + const ElectricMotorActuatorInfo& electricMotorActuatorInfo = *_info._infoElectricMotor; + return _GetTorqueLimitFromSpeedTorquePoints(iaxis, electricMotorActuatorInfo, electricMotorActuatorInfo.max_speed_torque_points, electricMotorActuatorInfo.max_instantaneous_torque); } } @@ -1959,70 +1973,10 @@ std::pair KinBody::Joint::GetInstantaneousTorqueLimits(int iaxis) return std::make_pair(-_info._vmaxtorque.at(iaxis), _info._vmaxtorque.at(iaxis)); } else { - if( _info._infoElectricMotor->max_speed_torque_points.size() > 0 ) { - dReal fMaxTorqueAtZeroSpeed = _info._infoElectricMotor->max_speed_torque_points.at(0).second*_info._infoElectricMotor->gear_ratio; - if( _info._infoElectricMotor->max_speed_torque_points.size() == 1 ) { - // doesn't matter what the velocity is - return std::make_pair(-fMaxTorqueAtZeroSpeed, fMaxTorqueAtZeroSpeed); - } - - dReal rawvelocity = GetVelocity(iaxis); - dReal velocity = RaveFabs(rawvelocity); - dReal revolutionsPerSecond = _info._infoElectricMotor->gear_ratio * velocity; - if( IsRevolute(iaxis) ) { - revolutionsPerSecond /= 2*M_PI; - } - - if( revolutionsPerSecond <= _info._infoElectricMotor->max_speed_torque_points.at(0).first ) { - return std::make_pair(-fMaxTorqueAtZeroSpeed, fMaxTorqueAtZeroSpeed); - } - - for(size_t i = 1; i < _info._infoElectricMotor->max_speed_torque_points.size(); ++i) { - if( revolutionsPerSecond <= _info._infoElectricMotor->max_speed_torque_points.at(i).first ) { - // linearly interpolate to get the desired torque - dReal rps0 = _info._infoElectricMotor->max_speed_torque_points.at(i-1).first; - dReal torque0 = _info._infoElectricMotor->max_speed_torque_points.at(i-1).second; - dReal rps1 = _info._infoElectricMotor->max_speed_torque_points.at(i).first; - dReal torque1 = _info._infoElectricMotor->max_speed_torque_points.at(i).second; - - dReal finterpolatedtorque; - if( rps1 - rps0 <= g_fEpsilonLinear ) { - finterpolatedtorque = torque1*_info._infoElectricMotor->gear_ratio; - } - else { - finterpolatedtorque = ((revolutionsPerSecond - rps0)/(rps1 - rps0)*(torque1-torque0) + torque0)*_info._infoElectricMotor->gear_ratio; - } - - // due to back emf, the deceleration magnitude is less than acceleration? - if (abs(rawvelocity) < 1.0/360) { - return std::make_pair(-finterpolatedtorque, finterpolatedtorque); - } - else if( rawvelocity > 0 ) { - return std::make_pair(-0.9*finterpolatedtorque, finterpolatedtorque); - } - else { - return std::make_pair(-finterpolatedtorque, 0.9*finterpolatedtorque); - } - } - } - - // due to back emf, the deceleration magnitude is less than acceleration? - // revolutionsPerSecond is huge, return the last point - dReal f = _info._infoElectricMotor->max_speed_torque_points.back().second*_info._infoElectricMotor->gear_ratio; - if (abs(rawvelocity) < 1.0/360) { - return std::make_pair(-f, f); - } - else if( rawvelocity > 0 ) { - return std::make_pair(-0.9*f, f); - } - else { - return std::make_pair(-f, 0.9*f); - } - } - else { - dReal f = _info._infoElectricMotor->max_instantaneous_torque*_info._infoElectricMotor->gear_ratio; - return std::make_pair(-f, f); - } + const ElectricMotorActuatorInfo& electricMotorActuatorInfo = *_info._infoElectricMotor; + const dReal fLimit = _GetTorqueLimitFromSpeedTorquePoints(iaxis, electricMotorActuatorInfo, electricMotorActuatorInfo.max_speed_torque_points, electricMotorActuatorInfo.max_instantaneous_torque); + // TODO : if we'll need to consider the back electromotive force (emf), re-think the formulation and then add the corrsponding parameters to ElectricMotorActuatorInfo + return std::make_pair(-fLimit, fLimit); } } @@ -2032,70 +1986,10 @@ std::pair KinBody::Joint::GetNominalTorqueLimits(int iaxis) const return std::make_pair(-_info._vmaxtorque.at(iaxis), _info._vmaxtorque.at(iaxis)); } else { - if( _info._infoElectricMotor->nominal_speed_torque_points.size() > 0 ) { - dReal fMaxTorqueAtZeroSpeed = _info._infoElectricMotor->nominal_speed_torque_points.at(0).second*_info._infoElectricMotor->gear_ratio; - if( _info._infoElectricMotor->nominal_speed_torque_points.size() == 1 ) { - // doesn't matter what the velocity is - return std::make_pair(-fMaxTorqueAtZeroSpeed, fMaxTorqueAtZeroSpeed); - } - - dReal rawvelocity = GetVelocity(iaxis); - dReal velocity = RaveFabs(rawvelocity); - dReal revolutionsPerSecond = _info._infoElectricMotor->gear_ratio * velocity; - if( IsRevolute(iaxis) ) { - revolutionsPerSecond /= 2*M_PI; - } - - if( revolutionsPerSecond <= _info._infoElectricMotor->nominal_speed_torque_points.at(0).first ) { - return std::make_pair(-fMaxTorqueAtZeroSpeed, fMaxTorqueAtZeroSpeed); - } - - for(size_t i = 1; i < _info._infoElectricMotor->nominal_speed_torque_points.size(); ++i) { - if( revolutionsPerSecond <= _info._infoElectricMotor->nominal_speed_torque_points.at(i).first ) { - // linearly interpolate to get the desired torque - dReal rps0 = _info._infoElectricMotor->nominal_speed_torque_points.at(i-1).first; - dReal torque0 = _info._infoElectricMotor->nominal_speed_torque_points.at(i-1).second; - dReal rps1 = _info._infoElectricMotor->nominal_speed_torque_points.at(i).first; - dReal torque1 = _info._infoElectricMotor->nominal_speed_torque_points.at(i).second; - - dReal finterpolatedtorque; - if( rps1 - rps0 <= g_fEpsilonLinear ) { - finterpolatedtorque = torque1*_info._infoElectricMotor->gear_ratio; - } - else { - finterpolatedtorque = ((revolutionsPerSecond - rps0)/(rps1 - rps0)*(torque1-torque0) + torque0)*_info._infoElectricMotor->gear_ratio; - } - - // due to back emf, the deceleration magnitude is less than acceleration? - if (abs(rawvelocity) < 1.0/360) { - return std::make_pair(-finterpolatedtorque, finterpolatedtorque); - } - else if( rawvelocity > 0 ) { - return std::make_pair(-0.9*finterpolatedtorque, finterpolatedtorque); - } - else { - return std::make_pair(-finterpolatedtorque, 0.9*finterpolatedtorque); - } - } - } - - // due to back emf, the deceleration magnitude is less than acceleration? - // revolutionsPerSecond is huge, return the last point - dReal f = _info._infoElectricMotor->nominal_speed_torque_points.back().second*_info._infoElectricMotor->gear_ratio; - if (abs(rawvelocity) < 1.0/360) { - return std::make_pair(-f, f); - } - else if( rawvelocity > 0 ) { - return std::make_pair(-0.9*f, f); - } - else { - return std::make_pair(-f, 0.9*f); - } - } - else { - dReal f = _info._infoElectricMotor->nominal_torque*_info._infoElectricMotor->gear_ratio; - return std::make_pair(-f, f); - } + const ElectricMotorActuatorInfo& electricMotorActuatorInfo = *_info._infoElectricMotor; + const dReal fLimit = _GetTorqueLimitFromSpeedTorquePoints(iaxis, electricMotorActuatorInfo, electricMotorActuatorInfo.nominal_speed_torque_points, electricMotorActuatorInfo.nominal_torque); + // TODO : if we'll need to consider the back electromotive force (emf), re-think the formulation and then add the corrsponding parameters to ElectricMotorActuatorInfo + return std::make_pair(-fLimit, fLimit); } }