public void compute( FrameVector output, FrameOrientation desiredOrientation, FrameVector desiredAngularVelocity, FrameVector currentAngularVelocity, FrameVector feedForward) { computeProportionalTerm(desiredOrientation); if (currentAngularVelocity != null) computeDerivativeTerm(desiredAngularVelocity, currentAngularVelocity); computeIntegralTerm(); output.setToZero(proportionalTerm.getReferenceFrame()); output.add(proportionalTerm); output.add(derivativeTerm); output.add(integralTerm); // Limit the max acceleration of the feedback, but not of the feedforward... // JEP changed 150430 based on Atlas hitting limit stops. double feedbackAngularActionMagnitude = output.length(); double maximumAction = gains.getMaximumFeedback(); if (feedbackAngularActionMagnitude > maximumAction) { output.scale(maximumAction / feedbackAngularActionMagnitude); } feedbackAngularAction.set(output); rateLimitedFeedbackAngularAction.update(); rateLimitedFeedbackAngularAction.getFrameTuple(output); feedForward.changeFrame(bodyFrame); output.add(feedForward); }
private void computeIntegralTerm() { if (gains.getMaximumIntegralError() < 1e-5) { integralTerm.setToZero(bodyFrame); return; } double integratedErrorAngle = errorAngleAxis.getAngle() * dt; double errorIntegratedX = errorAngleAxis.getX() * integratedErrorAngle; double errorIntegratedY = errorAngleAxis.getY() * integratedErrorAngle; double errorIntegratedZ = errorAngleAxis.getZ() * integratedErrorAngle; rotationErrorCumulated.add(errorIntegratedX, errorIntegratedY, errorIntegratedZ); double errorMagnitude = rotationErrorCumulated.length(); if (errorMagnitude > gains.getMaximumIntegralError()) { rotationErrorCumulated.scale(gains.getMaximumIntegralError() / errorMagnitude); } rotationErrorCumulated.getFrameTuple(integralTerm); integralGainMatrix.transform(integralTerm.getVector()); }
public AxisAngleOrientationController( String prefix, ReferenceFrame bodyFrame, double dt, YoOrientationPIDGainsInterface gains, YoVariableRegistry parentRegistry) { this.dt = dt; this.bodyFrame = bodyFrame; registry = new YoVariableRegistry(prefix + getClass().getSimpleName()); if (gains == null) gains = new YoAxisAngleOrientationGains(prefix, registry); this.gains = gains; proportionalGainMatrix = gains.createProportionalGainMatrix(); derivativeGainMatrix = gains.createDerivativeGainMatrix(); integralGainMatrix = gains.createIntegralGainMatrix(); rotationErrorInBody = new YoFrameVector(prefix + "RotationErrorInBody", bodyFrame, registry); rotationErrorCumulated = new YoFrameVector(prefix + "RotationErrorCumulated", bodyFrame, registry); velocityError = new YoFrameVector(prefix + "AngularVelocityError", bodyFrame, registry); proportionalTerm = new FrameVector(bodyFrame); derivativeTerm = new FrameVector(bodyFrame); integralTerm = new FrameVector(bodyFrame); feedbackAngularAction = new YoFrameVector(prefix + "FeedbackAngularAction", bodyFrame, registry); rateLimitedFeedbackAngularAction = RateLimitedYoFrameVector.createRateLimitedYoFrameVector( prefix + "RateLimitedFeedbackAngularAction", "", registry, gains.getYoMaximumFeedbackRate(), dt, feedbackAngularAction); parentRegistry.addChild(registry); }
private void computeDerivativeTerm( FrameVector desiredAngularVelocity, FrameVector currentAngularVelocity) { desiredAngularVelocity.changeFrame(bodyFrame); currentAngularVelocity.changeFrame(bodyFrame); derivativeTerm.sub(desiredAngularVelocity, currentAngularVelocity); // Limit the maximum velocity error considered for control action double maximumVelocityError = gains.getMaximumDerivativeError(); double velocityErrorMagnitude = derivativeTerm.length(); if (velocityErrorMagnitude > maximumVelocityError) { derivativeTerm.scale(maximumVelocityError / velocityErrorMagnitude); } velocityError.set(derivativeTerm); derivativeGainMatrix.transform(derivativeTerm.getVector()); }
private void computeProportionalTerm(FrameOrientation desiredOrientation) { desiredOrientation.changeFrame(bodyFrame); desiredOrientation.getQuaternion(errorQuaternion); errorAngleAxis.set(errorQuaternion); errorAngleAxis.setAngle(AngleTools.trimAngleMinusPiToPi(errorAngleAxis.getAngle())); // Limit the maximum position error considered for control action double maximumError = gains.getMaximumProportionalError(); if (errorAngleAxis.getAngle() > maximumError) { errorAngleAxis.setAngle(Math.signum(errorAngleAxis.getAngle()) * maximumError); } proportionalTerm.set(errorAngleAxis.getX(), errorAngleAxis.getY(), errorAngleAxis.getZ()); proportionalTerm.scale(errorAngleAxis.getAngle()); rotationErrorInBody.set(proportionalTerm); proportionalGainMatrix.transform(proportionalTerm.getVector()); }
public void setMaxProportionalError(double maxProportionalError) { gains.setMaxProportionalError(maxProportionalError); }
public void setMaxDerivativeError(double maxDerivativeError) { gains.setMaxDerivativeError(maxDerivativeError); }
public void setMaxFeedbackAndFeedbackRate(double maxFeedback, double maxFeedbackRate) { gains.setMaxFeedbackAndFeedbackRate(maxFeedback, maxFeedbackRate); }
public void setIntegralGains(double[] integralGains, double maxIntegralError) { gains.setIntegralGains(integralGains, maxIntegralError); }
public void setDerivativeGains(double[] derivativeGains) { gains.setDerivativeGains(derivativeGains); }
public void setProportionalGains(double[] proportionalGains) { gains.setProportionalGains(proportionalGains); }
public void setIntegralGains( double integralGainX, double integralGainY, double integralGainZ, double maxIntegralError) { gains.setIntegralGains(integralGainX, integralGainY, integralGainZ, maxIntegralError); }
public void setDerivativeGains( double derivativeGainX, double derivativeGainY, double derivativeGainZ) { gains.setDerivativeGains(derivativeGainX, derivativeGainY, derivativeGainZ); }
public void setProportionalGains( double proportionalGainX, double proportionalGainY, double proportionalGainZ) { gains.setProportionalGains(proportionalGainX, proportionalGainY, proportionalGainZ); }