00001 #include "robodyn_utilities/EncoderStateCalculator.h" 00002 00003 EncoderStateCalculator::EncoderStateCalculator(const double& jointGearRatio, const double& pwmFrequency, const double& pwmDeadTime, const double& busVoltage, const double& motorCurrentLimit, const double& phaseResistance, 00004 const double& backEmfConstant, const double& jointKinematicDirection, const double& encoderMountingDirection, 00005 const double& encoderGlitchScalar, const double& encoderVelocityBlendStop, const double& encoderVelocityBlendStart) 00006 : encoderVelocityLowFrequency(0.0), 00007 encoderVelocityLowFrequencyPrevious(0.0), 00008 encoderVelocityHighFrequency(0.0), 00009 encoderVelocityBlended(0.0), 00010 encoderPosition(0.0), 00011 encoderAccumulationPrevious(0), 00012 gammaBlend(0.0), 00013 jointGearRatio(jointGearRatio), 00014 pwmFrequency(pwmFrequency), 00015 pwmDeadTime(pwmDeadTime), 00016 busVoltage(busVoltage), 00017 motorCurrentLimit(motorCurrentLimit), 00018 phaseResistance(phaseResistance), 00019 backEmfConstant(backEmfConstant), 00020 jointKinematicDirection(jointKinematicDirection), 00021 encoderMountingDirection(encoderMountingDirection), 00022 encoderGlitchScalar(encoderGlitchScalar), 00023 encoderVelocityBlendStop(encoderVelocityBlendStop), 00024 encoderVelocityBlendStart(encoderVelocityBlendStart), 00025 encoderTickTimeout(8388607), 00026 clockFrequency(50000000.0), 00027 backEmfConstantMinimum(0.0001) 00028 { 00029 busVoltageRatio = 1.0 - (2.0 * pwmFrequency * pwmDeadTime); 00030 00032 if (backEmfConstant >= backEmfConstantMinimum) 00033 { 00034 maxEncoderVelocity = ((busVoltageRatio * busVoltage) - (motorCurrentLimit * phaseResistance)) / backEmfConstant; 00035 } 00036 else 00037 { 00038 throw std::runtime_error("EncoderStateCalculator() - backEmfConstant must be greater than 0.0001."); 00039 } 00040 00041 00042 gammaBlendDenominator = encoderVelocityBlendStop - encoderVelocityBlendStart; 00043 00045 if (gammaBlendDenominator < 0) 00046 { 00047 gammaBlendDenominator = -gammaBlendDenominator; 00048 } 00049 00050 } 00051 00052 EncoderStateCalculator::~EncoderStateCalculator() 00053 { 00054 } 00055 00059 double EncoderStateCalculator::getPosition(const double& encoderPositionReference, const int32_t& incrementalEncoderReference, const int32_t& incrementalEncoderNow) 00060 { 00061 encoderPosition = encoderPositionReference + ((incrementalEncoderNow - incrementalEncoderReference) * encoderCountsToJointRadians * encoderMountingDirection * jointKinematicDirection); 00062 00063 return encoderPosition; 00064 } 00065 00069 double EncoderStateCalculator::getVelocity(int32_t timer, const int32_t& timeout, const int32_t& encoderAccumulation, const double& measuredControlRateHz) 00070 { 00072 if (timer >= 0) 00073 { 00074 if (timeout > timer) 00075 { 00076 timer = timeout; 00077 } 00078 } 00079 else 00080 { 00081 if (-timeout < timer) 00082 { 00083 timer = -timeout; 00084 } 00085 } 00086 00088 if (timer == 0) 00089 { 00090 timer = 1; 00091 } 00092 00094 if (timeout >= encoderTickTimeout) 00095 { 00096 encoderVelocityLowFrequency = 0.0; 00097 } 00098 else 00099 { 00100 encoderVelocityLowFrequency = (clockFrequency / timer) * (encoderRadiansPerCount * encoderMountingDirection); 00101 } 00102 00104 if (std::abs(encoderVelocityLowFrequency) > (encoderGlitchScalar * maxEncoderVelocity)) 00105 { 00106 encoderVelocityLowFrequency = encoderVelocityLowFrequencyPrevious; 00107 } 00108 00109 encoderVelocityLowFrequencyPrevious = encoderVelocityLowFrequency; 00110 00111 encoderVelocityHighFrequency = (measuredControlRateHz * (encoderAccumulation - encoderAccumulationPrevious)) * (encoderRadiansPerCount * encoderMountingDirection); 00112 encoderAccumulationPrevious = encoderAccumulation; 00113 00114 gammaBlend = 0.0; 00115 00116 if (gammaBlendDenominator > 1.0) 00117 { 00118 gammaBlend = (std::abs(encoderVelocityBlended) - encoderVelocityBlendStart) / gammaBlendDenominator; 00119 gammaBlend = applyLimits(gammaBlend, 0.0, 1.0); 00120 } 00121 else 00122 { 00123 gammaBlend = 0; 00124 } 00125 00126 encoderVelocityBlended = (encoderVelocityLowFrequency * (1.0 - gammaBlend)) + (encoderVelocityHighFrequency * gammaBlend); 00127 00128 return encoderVelocityBlended * jointKinematicDirection; 00129 } 00130 00131 double EncoderStateCalculator::applyLimits(const double& value, const double& lowerLimit, const double& upperLimit) 00132 { 00133 if (value > upperLimit) 00134 { 00135 return upperLimit; 00136 } 00137 else if (value < lowerLimit) 00138 { 00139 return lowerLimit; 00140 } 00141 else 00142 { 00143 return value; 00144 } 00145 } 00146 00147 MotorEncoderStateCalculator::MotorEncoderStateCalculator(const double& jointGearRatio, const double& pwmFrequency, const double& pwmDeadTime, const double& busVoltage, const double& motorCurrentLimit, const double& phaseResistance, 00148 const double& backEmfConstant, const double& jointKinematicDirection, const double& encoderMountingDirection, const double& encoderCountsPerRevolution, 00149 const double& encoderGlitchScalar, const double& encoderVelocityBlendStop, const double& encoderVelocityBlendStart) 00150 : EncoderStateCalculator(jointGearRatio, pwmFrequency, pwmDeadTime, busVoltage, motorCurrentLimit, phaseResistance, 00151 backEmfConstant, jointKinematicDirection, encoderMountingDirection, 00152 encoderGlitchScalar, encoderVelocityBlendStop, encoderVelocityBlendStart), 00153 encoderCountsPerRevolution(encoderCountsPerRevolution) 00154 { 00155 encoderCountsPerMotorRevolution = 4.0 * encoderCountsPerRevolution; 00156 encoderRadiansPerCount = 2.0 * boost::math::constants::pi<double>() / encoderCountsPerMotorRevolution; 00157 encoderCountsToJointRadians = encoderRadiansPerCount / jointGearRatio; 00158 } 00159 00160 MotorEncoderStateCalculator::~MotorEncoderStateCalculator() 00161 { 00162 } 00163 00164 HallsEncoderStateCalculator::HallsEncoderStateCalculator(const double& jointGearRatio, const double& pwmFrequency, const double& pwmDeadTime, const double& busVoltage, const double& motorCurrentLimit, const double& phaseResistance, 00165 const double& backEmfConstant, const double& jointKinematicDirection, const double& encoderMountingDirection, const double& motorPoleCount, 00166 const double& encoderGlitchScalar, const double& encoderVelocityBlendStop, const double& encoderVelocityBlendStart) 00167 : EncoderStateCalculator(jointGearRatio, pwmFrequency, pwmDeadTime, busVoltage, motorCurrentLimit, phaseResistance, 00168 backEmfConstant, jointKinematicDirection, encoderMountingDirection, 00169 encoderGlitchScalar, encoderVelocityBlendStop, encoderVelocityBlendStart), 00170 motorPoleCount(motorPoleCount) 00171 { 00172 encoderCountsPerMotorRevolution = 3.0 * motorPoleCount; 00173 encoderRadiansPerCount = 2.0 * boost::math::constants::pi<double>() / encoderCountsPerMotorRevolution; 00174 encoderCountsToJointRadians = encoderRadiansPerCount / jointGearRatio; 00175 } 00176 00177 HallsEncoderStateCalculator::~HallsEncoderStateCalculator() 00178 { 00179 }