Index: firmware/App/Services/PIControllers.c =================================================================== diff -u -r832ca83805dc132cb753e79bdca81197331e03e6 -ra4236a98b2de7d007173862dfe6b114bce08f90f --- firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision 832ca83805dc132cb753e79bdca81197331e03e6) +++ firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision a4236a98b2de7d007173862dfe6b114bce08f90f) @@ -1,4 +1,4 @@ -/************************************************************************** +/**********************************************************************//** * * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * @@ -10,50 +10,60 @@ * @date 18-Dec-2019 * @author L. Baloa * - * @brief PIControllers service module. Creates a digital PI to be used as - * control loops + * @brief PIControllers source file. * **************************************************************************/ -#include "math.h" +#ifndef _VECTORCAST_ + #include "math.h" +#endif +#include "SystemCommMessages.h" #include "PIControllers.h" +/** + * @addtogroup PIControllers + * @{ + */ + // ********** private definitions ********** +/// minimum integral coefficient - cannot be zero #define MIN_KI NEARLY_ZERO +/// record for PI controller typedef struct { // -- PI's parameters -- - F32 Kp; // Proportional Value - F32 Ki; // Integral Value - F32 uMax; // Maximum control signal - F32 uMin; // Minimum control signal + F32 Kp; ///< Proportional Value + F32 Ki; ///< Integral Value + F32 uMax; ///< Maximum control signal + F32 uMin; ///< Minimum control signal // -- PI's signals -- - F32 referenceSignal; // reference signal - F32 measuredSignal; // measured signal - F32 errorSignal; // reference - measured signal - F32 errorSumBeforeWindUp; // error signal before windup correction - F32 errorSum; // error integral after windup correction - F32 controlSignal; // actual control signal + F32 referenceSignal; ///< reference signal + F32 measuredSignal; ///< measured signal + F32 errorSignal; ///< reference - measured signal + F32 errorSumBeforeWindUp; ///< error signal before windup correction + F32 errorSum; ///< error integral after windup correction + F32 controlSignal; ///< actual control signal } PI_CONTROLLER_T; -#define SET_CONTROLLER( c, id ) ((c) = &piControllers[id]) +#define SET_CONTROLLER( c, id ) ((c) = &piControllers[id]) ///< macro to set a local controller pointer to a given piController // ********** private data ********** -// PI Controllers -- definition - +/// PI Controllers -- initial configurations. static PI_CONTROLLER_T piControllers[ NUM_OF_PI_CONTROLLERS_IDS ] = { // Kp Ki uMax uMin ref meas err esw esum ctrl { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_LOAD_CELL { 0.0, 0.0, 0.90, 0.10, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // PI_CONTROLLER_ID_BLOOD_FLOW { 0.0, 0.0, 0.90, 0.10, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } // PI_CONTROLLER_ID_DIALYSATE_FLOW }; -/************************************************************************* +/**@}*/ + +/*********************************************************************//** * @brief initializePIController - * Initialize controller before operation. Make sure to call it before \n + * Initialize controller before operation. Make sure to call it before * first call to runController function. * * @param controllerID - ID filter number @@ -83,11 +93,15 @@ controller->uMax = controlMax; resetPIController( controllerID, initialControlSignal ); } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER, (U32)controllerID ) + } } -/************************************************************************* +/*********************************************************************//** * @brief resetPIController - * Reset controller before new set point. Make sure to call it before first \n + * Reset controller before new set point. Make sure to call it before first * call to runController function. * * @param controllerID - ID filter number @@ -109,9 +123,13 @@ controller->errorSumBeforeWindUp = controller->errorSum; controller->measuredSignal = 0.0; } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER, (U32)controllerID ) + } } -/************************************************************************* +/*********************************************************************//** * @brief runPIController * Call this function whenever a new measured signal sampled is acquired. * @@ -144,18 +162,39 @@ controlSignalBeforeWindup = ( controller->Kp * controller->errorSignal ) + ( controller->Ki * controller->errorSum ); controller->controlSignal = RANGE( controlSignalBeforeWindup, controller->uMin, controller->uMax ); // handle anti-windup for i term - windupError = controller->controlSignal - controlSignalBeforeWindup; + windupError = controlSignalBeforeWindup - controller->controlSignal; if ( fabs( windupError ) > NEARLY_ZERO ) { controller->errorSum -= ( windupError / controller->Ki ); } result = controller->controlSignal; +//#ifdef DEBUG_ENABLED +// { +// // TODO - temporary debug code - remove later +// char debugFlowStr[ 100 ]; +// S32 nums = (S32)(measuredSignal); +// S32 decs = (S32)(fabs(measuredSignal-(S32)(measuredSignal))*100.0); +// S32 nume = (S32)controller->errorSignal; +// S32 dece = (S32)(fabs(controller->errorSignal-(S32)controller->errorSignal)*100.0); +// S32 numes = (S32)controller->errorSum; +// S32 deces = (S32)((controller->errorSum-(S32)(controller->errorSum))*100.0); +// S32 nump = (S32)controller->controlSignal; +// S32 decp = (S32)((controller->controlSignal-(S32)controller->controlSignal)*10000.0); +// +// sprintf( debugFlowStr, "%6d.%02d %6d.%02d %10d.%02d %3d.%04d\n", nums, decs, nume, dece, numes, deces, nump, decp ); +// sendDebugData( (U08*)debugFlowStr, strlen(debugFlowStr) ); +// } +//#endif } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER, (U32)controllerID ) + } return result; } -/************************************************************************* +/*********************************************************************//** * @brief getPIControllerSignals * Returns the latest requested signal sample. * @@ -208,10 +247,14 @@ break; default: - output = 0; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_PI_CTRL_INVALID_SIGNAL, (U32)signalID ) break; } // end of switch } + else + { // invalid controller given + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER, (U32)controllerID ) + } return output; }