Index: PIControllers.c =================================================================== diff -u -r9df9aaf6055e195e2139b07d8c6976d9c46c7480 -r5d71138b70dda45a66fda6f3841392f1be55fe61 --- PIControllers.c (.../PIControllers.c) (revision 9df9aaf6055e195e2139b07d8c6976d9c46c7480) +++ PIControllers.c (.../PIControllers.c) (revision 5d71138b70dda45a66fda6f3841392f1be55fe61) @@ -55,22 +55,25 @@ F32 controlSignal; ///< Actual control signal. F32 maxErrorSumStep; ///< Maximum change in I (error sum) for a single control interval. PI_CONTROLLER_DIRECTIONS_T direction; ///< PI controller control direction. + BOOL isFeedForwardEnabled; ///< Eanble or disable Feed forward term + F32 feedForward; ///< Feed forward term + F32 controlInterval; ///< Control interval for integral calculation( default : 1.0 sec control interval) } PI_CONTROLLER_T; // ********** private data ********** /// PI Controllers - initial configurations. static PI_CONTROLLER_T piControllers[ NUM_OF_PI_CONTROLLERS_IDS ] = -{ // Kp Ki uMax uMin ref meas err esw esum ctrl Ilimit controller type +{ // Kp Ki uMax uMin ref meas err esw esum ctrl Ilimit controller type, feedfwdEnabled, feedfwdValue, Control Interval #ifdef _DD_ - { 0.0, 0.0, 2650, 350, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, CONTROLLER_BIDIRECTIONAL }, // PI_CONTROLLER_ID_D12_PUMP - { 0.0, 0.0, 2650, 350, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, CONTROLLER_BIDIRECTIONAL }, // PI_CONTROLLER_ID_D48_PUMP - { 0.0, 0.0, 100.0,0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, CONTROLLER_BIDIRECTIONAL }, // PI_CONTROLLER_ID_D5_HEAT - { 0.0, 0.0, 100.0,0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, CONTROLLER_BIDIRECTIONAL }, // PI_CONTROLLER_ID_D45_HEAT + { 0.0, 0.0, 2650, 350, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, CONTROLLER_BIDIRECTIONAL, 0, 0.0, 1.0 }, // PI_CONTROLLER_ID_D12_PUMP + { 0.0, 0.0, 2650, 350, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, CONTROLLER_BIDIRECTIONAL, 0, 0.0, 1.0 }, // PI_CONTROLLER_ID_D48_PUMP + { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 15.0, CONTROLLER_BIDIRECTIONAL, 1, 0.0, 1.0 }, // PI_CONTROLLER_ID_D5_HEAT + { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, CONTROLLER_BIDIRECTIONAL, 0, 0.0, 1.0 }, // PI_CONTROLLER_ID_D45_HEAT #endif #ifdef _RO_ - { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, CONTROLLER_UNIDIRECTIONAL }, // PI_CONTROLLER_ID_RO_PUMP - { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, CONTROLLER_UNIDIRECTIONAL }, // PI_CONTROLLER_ID_RO_PUMP_MAX_PRES + { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, CONTROLLER_UNIDIRECTIONAL,0, 0.0, 1.0 }, // PI_CONTROLLER_ID_RO_PUMP + { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, CONTROLLER_UNIDIRECTIONAL,0, 0.0, 1.0 }, // PI_CONTROLLER_ID_RO_PUMP_MAX_PRES #endif }; @@ -88,10 +91,15 @@ * @param kI Coefficient for integral * @param controlMin Minimum control output * @param controlMax Maximum control output + * @param isFeedForwardEnabled Feed forward enabled if true, otherwise not. + * @param feedFowardSignal feedforward value to be applied to the control output + * @param controlInterval The task control interval for given heater to determine + * sample period * @return none *************************************************************************/ void initializePIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal, - F32 kP, F32 kI, F32 controlMin, F32 controlMax ) + F32 kP, F32 kI, F32 controlMin, F32 controlMax, + BOOL isFeedForwardEnabled, F32 feedFowardSignal, F32 controlInterval ) { if ( controllerID < NUM_OF_PI_CONTROLLERS_IDS ) { @@ -110,7 +118,9 @@ } controller->uMin = controlMin; controller->uMax = controlMax; - resetPIController( controllerID, initialControlSignal ); + controller->isFeedForwardEnabled = isFeedForwardEnabled; + controller-> controlInterval = controlInterval; + resetPIController( controllerID, initialControlSignal, feedFowardSignal ); } else { @@ -133,9 +143,10 @@ * Id is passed. * @param controllerID ID filter number * @param initialControlSignal Value of the output on the first iteration + * @param feedFowardSignal Value of feed froward calculation if exists. * @return none *************************************************************************/ -void resetPIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal ) +void resetPIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal, F32 feedFowardSignal ) { PI_CONTROLLER_T *controller; @@ -148,6 +159,7 @@ controller->errorSum = controller->controlSignal / controller->Ki; controller->errorSumBeforeWindUp = controller->errorSum; controller->measuredSignal = 0.0; + controller->feedForward = feedFowardSignal; } else { @@ -217,18 +229,34 @@ // Calculate control signal from i term controller->errorSumBeforeWindUp = controller->errorSum; - controlSignalBeforeWindup = ( controller->Ki * controller->errorSum ); - controller->controlSignal = RANGE( controlSignalBeforeWindup, controller->uMin, controller->uMax ); + controlSignalBeforeWindup = ( controller->Ki * controller->controlInterval * controller->errorSum ); + if ( FALSE == controller->isFeedForwardEnabled ) + { + controller->controlSignal = RANGE( controlSignalBeforeWindup, controller->uMin, controller->uMax ); + } + else + { + controller->controlSignal = RANGE( controlSignalBeforeWindup, controller->uMin, ( controller->uMax - controller->feedForward ) ); + } + // Handle anti-windup for i term windupError = controlSignalBeforeWindup - controller->controlSignal; if ( fabs( windupError ) > NEARLY_ZERO ) { - controller->errorSum -= ( windupError / controller->Ki ); + controller->errorSum -= ( windupError / ( controller->Ki * controller->controlInterval ) ); } - // Add p term to control signal and re-apply range limits + // Add p term to control signal controller->controlSignal += ( controller->Kp * controller->errorSignal ); + + // Add feed forward term to control signal + if ( FALSE != controller->isFeedForwardEnabled ) + { + controller->controlSignal = controller->controlSignal + controller->feedForward; + } + + //Re-apply range limits controller->controlSignal = RANGE( controller->controlSignal, controller->uMin, controller->uMax ); result = controller->controlSignal; @@ -298,6 +326,10 @@ output = controller->Ki * controller->errorSum; break; + case CONTROLLER_SIGNAL_FEEDFORWARD_OUTPUT: + output = controller->feedForward; + break; + case CONTROLLER_SIGNAL_CONTROL: output = controller->controlSignal; break; Index: PIControllers.h =================================================================== diff -u -rf352febbad947e7ae4afbd9a5eaa87e434648f37 -r5d71138b70dda45a66fda6f3841392f1be55fe61 --- PIControllers.h (.../PIControllers.h) (revision f352febbad947e7ae4afbd9a5eaa87e434648f37) +++ PIControllers.h (.../PIControllers.h) (revision 5d71138b70dda45a66fda6f3841392f1be55fe61) @@ -64,6 +64,7 @@ CONTROLLER_SIGNAL_ERROR_SUM_AFTER_WINDUP, ///< Error sum after anti-windup CONTROLLER_SIGNAL_PROPORTIONAL_OUTPUT, ///< P portion of controller output signal CONTROLLER_SIGNAL_INTEGRAL_OUTPUT, ///< I portion of controller output signal + CONTROLLER_SIGNAL_FEEDFORWARD_OUTPUT, ///< Feed forward portion of controller output signal CONTROLLER_SIGNAL_CONTROL, ///< Controller output signal NUM_OF_CONTROLLER_SIGNAL ///< Number of PI controller signals } PI_CONTROLLER_SIGNALS_ID; @@ -82,8 +83,9 @@ // ********** public function prototypes ********** void initializePIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal, - F32 kP, F32 kI, F32 controlMin, F32 controlMax ); -void resetPIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal ); + F32 kP, F32 kI, F32 controlMin, F32 controlMax, + BOOL isFeedForwardEnabled, F32 feedFowardSignal, F32 controlInterval ); +void resetPIController( PI_CONTROLLER_ID_T controllerID, F32 initialControlSignal, F32 feedFowardSignal ); F32 runPIController( PI_CONTROLLER_ID_T controllerID, F32 referenceSignal, F32 measuredSignal ); F32 getPIControllerSignals( PI_CONTROLLER_ID_T controllerID, PI_CONTROLLER_SIGNALS_ID signalID ); void setPIControllerStepLimit( PI_CONTROLLER_ID_T controllerID, F32 stepLimit );