| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // Copyright (c) 2000-2019 Ericsson Telecom AB // |
| // // |
| // All rights reserved. This program and the accompanying materials // |
| // are made available under the terms of the Eclipse Public License v2.0 // |
| // which accompanies this distribution, and is available at // |
| // https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| /////////////////////////////////////////////////////////// |
| // Module: EPTF_CLL_LoadRegulator_Functions |
| // |
| // Purpose: |
| // This module contains function definitions for EPTF LoadRegulator |
| // |
| // Module Parameters: |
| // tsp_debug_EPTF_CLL_LoadRegulator_Functions - *boolean*, default value: false |
| // tsp_debug_EPTF_CLL_LoadRegulator_Functions_smoothing - *boolean*, default value: false |
| // tsp_EPTF_loadRegulator_measWinSize - *integer*, default value: 3 |
| // tsp_EPTF_loadRegulator_updateTimeout - *float*, default value: 2.0 |
| // tsp_EPTF_loadRegulator_LoadVarianceThreshold - *float*, default value: 5.0 |
| // tsp_EPTF_loadregulator_cpsDelta - *float*, default value: 10.0 |
| // tsp_EPTF_loadRegulator_errorTolerance - *float*, default value: 5.0 |
| // tsp_EPTF_loadRegulator_smoothingFactor - *float*, default value: 0.5 |
| // |
| // Module depends on: |
| // <EPTF_CLL_Common_Definitions> |
| // <EPTF_CLL_Common_Functions> |
| // <EPTF_CLL_LoadRegulator_Definitions> |
| // <EPTF_CLL_Variable_Definitions> |
| // <EPTF_CLL_Variable_Functions> |
| // <EPTF_CLL_Base_Functions> |
| // <EPTF_CLL_Logging_Definitions> |
| // <EPTF_CLL_Logging_Functions> |
| // |
| // Current Owner: |
| // Gabor Tatarka (egbotat) |
| // |
| // Last Review Date: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| /////////////////////////////////////////////////////////// |
| |
| module EPTF_CLL_LoadRegulator_Functions |
| { |
| import from EPTF_CLL_DataSourceClient_Functions all; |
| |
| import from EPTF_CLL_DataSource_Definitions all; |
| |
| |
| //========================================================================= |
| // Imports |
| //======================================================================= |
| import from EPTF_CLL_Common_Definitions all; |
| import from EPTF_CLL_Common_Functions all; |
| import from EPTF_CLL_LoadRegulator_Definitions all; |
| import from EPTF_CLL_Variable_Definitions all; |
| import from EPTF_CLL_Variable_Functions all; |
| import from EPTF_CLL_Base_Functions all; |
| import from EPTF_CLL_Logging_Definitions all; |
| import from EPTF_CLL_Logging_Functions all; |
| import from EPTF_CLL_DataSource_Functions all; |
| |
| //FIXME: |
| friend module EPTF_CLL_LoadRegulatorUI_Functions; |
| |
| modulepar boolean tsp_debug_EPTF_CLL_LoadRegulator_Functions := false; |
| modulepar boolean tsp_debug_EPTF_CLL_LoadRegulator_Functions_smoothing := false; |
| |
| modulepar integer tsp_EPTF_loadRegulator_measWinSize := 3; |
| modulepar float tsp_EPTF_loadRegulator_updateTimeout := 2.0; // 2 secs |
| modulepar float tsp_EPTF_loadRegulator_LoadVarianceThreshold := 5.0; // in % |
| modulepar float tsp_EPTF_loadregulator_cpsDelta := 10.0; |
| modulepar float tsp_EPTF_loadRegulator_errorTolerance := 5.0; // in % |
| modulepar float tsp_EPTF_loadRegulator_smoothingFactor := 0.5; // should be between 0.0:extreme smoothing and 1,0:no smoothing |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_init_CT |
| // |
| // Purpose: |
| // initialisation for EPTF_LoadRegulator_CT |
| // |
| // Parameters: |
| // pl_selfName - *in charstring* - name of the component |
| // pl_getSutLoad - <ft_EPTF_LoadRegulator_getSUTLoad> - the function that |
| // determines the SUT load |
| // pl_calcNextCps - <ft_EPTF_LoadRegulator_calculateNextCps> - the algorithm |
| // to change the CPS so that the SUT load reach the target load. |
| // pl_postCalcCps - <ft_EPTF_LoadRegulator_postCalculateCPS> - function that will be |
| // called after the CPS value is changed |
| // pl_EPTF_loadRegulator_measWinSize - *in integer* - measure window size |
| // pl_EPTF_loadRegulator_updateTimeout - *in float* - the period of SUT load measurement |
| // pl_EPTF_loadRegulator_LoadVarianceThreshold - *in float* - load variance threshold (percentage) |
| // pl_EPTF_loadregulator_cpsDelta - *in float* - the max value that the CPS value |
| // will be changed with |
| // pl_EPTF_loadRegulator_errorTolerance - *in float* - the precision of the target load (percentage) |
| // pl_EPTF_loadRegulator_smoothingFactor - *in float* - a smoothing is applied on the |
| // measured load values to avoid spikes. The amount of smoothing can be set here. |
| // Its value should be between 0.0:extreme smoothing and 1,0:no smoothing. |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_LoadRegulator_init_CT( |
| in charstring pl_selfName, |
| in ft_EPTF_LoadRegulator_getSUTLoad pl_getSutLoad, |
| in ft_EPTF_LoadRegulator_calculateNextCps pl_calcNextCps := null, |
| in ft_EPTF_LoadRegulator_postCalculateCPS pl_postCalcCps := null, |
| in integer pl_EPTF_loadRegulator_measWinSize := tsp_EPTF_loadRegulator_measWinSize, |
| in float pl_EPTF_loadRegulator_updateTimeout := tsp_EPTF_loadRegulator_updateTimeout, // 2 secs |
| in float pl_EPTF_loadRegulator_LoadVarianceThreshold := tsp_EPTF_loadRegulator_LoadVarianceThreshold, // in % |
| in float pl_EPTF_loadregulator_cpsDelta := tsp_EPTF_loadregulator_cpsDelta, |
| in float pl_EPTF_loadRegulator_errorTolerance := tsp_EPTF_loadRegulator_errorTolerance, // in % |
| in float pl_EPTF_loadRegulator_smoothingFactor := tsp_EPTF_loadRegulator_smoothingFactor, // should be between 0.0:extreme smoothing and 1,0:no smoothing |
| in EPTF_DataSource_CT pl_dataSource_compRef := null |
| ) |
| runs on EPTF_LoadRegulator_CT |
| { |
| f_EPTF_Logging_init_CT(pl_selfName); |
| var charstring vl_selfName := f_EPTF_Base_selfName(); |
| v_LoadRegulator_loggingMaskId := f_EPTF_Logging_registerComponentMasks(tsp_EPTF_LoadRegulator_loggingComponentMask, c_EPTF_LoadRegulator_loggingEventClasses, EPTF_Logging_CLL); |
| if(tsp_debug_EPTF_CLL_LoadRegulator_Functions) { |
| f_EPTF_Logging_enableLocalMask(v_LoadRegulator_loggingMaskId, c_EPTF_LoadRegulator_loggingClassIdx_Debug); |
| } else { |
| f_EPTF_Logging_disableLocalMask(v_LoadRegulator_loggingMaskId, c_EPTF_LoadRegulator_loggingClassIdx_Debug); |
| } |
| |
| if(v_EPTF_LoadRegulator_initialized) { |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_init_CT(): already initialized"); |
| return; |
| } |
| |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_init_CT() started"); |
| |
| f_EPTF_Var_init_CT(vl_selfName); |
| |
| // initialize parameters: |
| v_EPTF_loadRegulator_measWinSize := pl_EPTF_loadRegulator_measWinSize; |
| v_EPTF_loadRegulator_updateTimeout := pl_EPTF_loadRegulator_updateTimeout; |
| v_EPTF_loadRegulator_LoadVarianceThreshold := pl_EPTF_loadRegulator_LoadVarianceThreshold; |
| v_EPTF_loadregulator_cpsDelta := pl_EPTF_loadregulator_cpsDelta; |
| v_EPTF_loadRegulator_errorTolerance := pl_EPTF_loadRegulator_errorTolerance; |
| v_EPTF_loadRegulator_smoothingFactor := pl_EPTF_loadRegulator_smoothingFactor; |
| |
| //Connect to DataSource server |
| f_EPTF_DataSourceClient_init_CT(vl_selfName, pl_dataSource_compRef); |
| if(null != pl_dataSource_compRef){ |
| f_EPTF_DataSourceClient_registerData(c_LoadRegulator_sourceId, vl_selfName, refers(f_EPTF_LoadRegulator_ProcessData)); |
| f_EPTF_DataSourceClient_registerDataValue(c_LoadRegulator_sourceId, vl_selfName, refers(f_EPTF_LoadRegulator_DSProcessDataValue)); |
| } |
| |
| |
| for (var integer i:=0;i<v_EPTF_loadRegulator_measWinSize;i:=i+1) { |
| vc_loadRegMeasWindow[i] := 0.0; |
| } |
| |
| vc_EPTF_getSutLoad := pl_getSutLoad; |
| |
| // Setting defalult regulation algorithm, the user may overwrite it in f_loadRegulator_user_init() |
| if(pl_calcNextCps == null) { |
| vc_EPTF_calculateNextCps := refers(f_EPTF_LoadRegulator_calculateNextCps); |
| } else { |
| vc_EPTF_calculateNextCps := pl_calcNextCps; |
| } |
| |
| //Create EPTF vars for former component vars |
| f_EPTF_Var_newBool(f_EPTF_Base_selfName()&c_LoadRegulator_loadIsStableVarName, false, v_LoadRegulator_loadIsStableVarIdx); |
| |
| |
| //------------------------------ |
| |
| // create var for the totalCPS variable: |
| var charstring pl_varName := c_LoadRegulator_totalValueVarName&f_EPTF_Base_selfName(); |
| f_EPTF_Var_newFloat( |
| pl_varName, |
| 0.0, |
| v_LoadRegulator_cpsToReachVarIdx |
| ); |
| // create var for the targetLoad variable: |
| pl_varName := c_LoadRegulator_targetLoadVarName&f_EPTF_Base_selfName(); |
| f_EPTF_Var_newFloat( |
| pl_varName, |
| 0.0, |
| v_LoadRegulator_loadToReachVarIdx |
| ); |
| // create var for the currentLoad variable: |
| pl_varName := c_LoadRegulator_currentLoadVarName&f_EPTF_Base_selfName(); |
| f_EPTF_Var_newFloat( |
| pl_varName, |
| 0.0, |
| v_LoadRegulator_currentLoadVarIdx |
| ); |
| f_EPTF_Var_setSubsCanAdjust(v_LoadRegulator_currentLoadVarIdx,false); |
| // create var for the connected variable: |
| pl_varName := "EPTF_LoadRegulator.Regulator.status."&f_EPTF_Base_selfName(); |
| f_EPTF_Var_newStatusLED( |
| pl_varName, |
| {led_red, "Disconnected"}, |
| v_EPTF_loadRegulator_execCtrlVar_statusIdx |
| ); |
| f_EPTF_Var_setSubsCanAdjust(v_EPTF_loadRegulator_execCtrlVar_statusIdx,false); |
| // create var for regulator enable: |
| pl_varName := c_LoadRegulator_enabledVarName&f_EPTF_Base_selfName(); |
| f_EPTF_Var_newBool( |
| pl_varName, |
| false, |
| v_LoadRegulator_enabledVarIdx |
| ); |
| |
| f_EPTF_DataSourceClient_sendReady(c_LoadRegulator_sourceId,f_EPTF_Base_selfName()); |
| |
| v_EPTF_postCalcCPS := pl_postCalcCps; |
| |
| v_EPTF_LoadRegulator_altstep := activate(as_EPTF_LoadRegulator_behavior()); |
| T_EPTF_loadReg.start(v_EPTF_loadRegulator_updateTimeout); |
| |
| v_EPTF_loadRegulator_originalCPS := -1.0; |
| |
| |
| v_EPTF_LoadRegulator_initialized := true; |
| f_EPTF_Base_registerCleanup(refers(f_EPTF_LoadRegulator_cleanup_CT)); |
| |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_init_CT() finished"); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_ProcessData |
| // |
| // Purpose: |
| // Processes the incoming Data requests - iterators and external data elements - and gives back a variable name. |
| // It should be registered in the ExecCtrl_init_CT. Type function fcb_EPTF_DataSourceClient_dataHandler |
| // |
| // Parameters: |
| // *out charstring pl_dataVarName* - this variable contains the value of the data or the iterator result |
| // *in charstring pl_source* - the name of the data source 'feature' |
| // *in charstring pl_ptcName* - the name of the ptc (ID of the PTC) |
| // *in charstring pl_element* - the name of the data element |
| // *in* <EPTF_DataSource_Params> *pl_params* - the parameters |
| // of the data for the dataElement |
| // |
| // Return Value: |
| // integer - error code (0 of OK, non zero if unsuccessful: e.g. invalid parameters given in pl_params) |
| // |
| // Detailed Comments: |
| // When this function is called in the first time it creates the variable that contains the |
| // names of the variables that store the values of the elements of the data or the iterator. This variable name |
| // is returned in pl_dataVarName. |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_LoadRegulator_ProcessData(out charstring pl_dataVarName, |
| in charstring pl_source, |
| in charstring pl_ptcName, |
| in charstring pl_element, |
| in EPTF_DataSource_Params pl_params) |
| runs on EPTF_LoadRegulator_CT |
| return integer{ |
| select( pl_element ) |
| { |
| case (c_LoadRegulator_dataElement_enabled){ |
| pl_dataVarName :=c_LoadRegulator_enabledVarName&f_EPTF_Base_selfName(); |
| } |
| case (c_LoadRegulator_dataElement_cpsToReach){ |
| pl_dataVarName :=c_LoadRegulator_totalValueVarName&f_EPTF_Base_selfName(); |
| } |
| case (c_LoadRegulator_dataElement_loadToReach){ |
| pl_dataVarName :=c_LoadRegulator_targetLoadVarName&f_EPTF_Base_selfName(); |
| } |
| case (c_LoadRegulator_dataElement_currentLoad){ |
| pl_dataVarName :=c_LoadRegulator_currentLoadVarName&f_EPTF_Base_selfName(); |
| } |
| case (c_LoadRegulator_dataElement_loadIsStable){ |
| pl_dataVarName :=f_EPTF_Base_selfName()&c_LoadRegulator_loadIsStableVarName; |
| } |
| case else{ |
| pl_dataVarName := ""; |
| f_EPTF_LoadRegulator_warning(%definitionId& ": unhandled element: "& pl_element); |
| return -1; |
| } |
| } |
| var integer vl_iteratorVarIdx := f_EPTF_Var_getId(pl_dataVarName); |
| if(vl_iteratorVarIdx == -1){ |
| f_EPTF_LoadRegulator_warning(%definitionId&": Invalid externalData: "& |
| "\nSource: "&pl_source& |
| "\nPTC : "&pl_ptcName & |
| "\nElement Name : " &pl_element/*& |
| "\nParams: " & log2str(pl_params)*/); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_DSProcessDataValue |
| // |
| // Purpose: |
| // Processes the incoming DataValue requests - iterators and external data elements - and gives back the value. |
| // It should be registered in the LoadRegulator_init_CT. Type function fcb_EPTF_DataSourceClient_dataValueHandler |
| // |
| // Parameters: |
| // *out *<EPTF_Var_DirectContent>* pl_dataValue* - the value of the data or the iterator result |
| // *in charstring pl_source* - the name of the data source 'feature' |
| // *in charstring pl_ptcName* - the name of the ptc (ID of the PTC) |
| // *in charstring pl_element* - the name of the data element |
| // *in* <EPTF_DataSource_Params> *pl_params* - the parameters |
| // of the data for the dataElement |
| // |
| // Return Value: |
| // integer - error code (0 of OK, non zero if unsuccessful: e.g. invalid parameters given in pl_params) |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_LoadRegulator_DSProcessDataValue(out EPTF_Var_DirectContent pl_dataValue, |
| in charstring pl_source, |
| in charstring pl_ptcName, |
| in charstring pl_element, |
| in EPTF_DataSource_Params pl_params) |
| runs on EPTF_LoadRegulator_CT return integer{ |
| var integer vl_errorCode := -1; |
| pl_dataValue := {unknownVal := {omit}}; // set it to invalid |
| select( pl_element ) |
| { |
| case(c_EPTF_DataSource_dataElement_Help) { |
| vl_errorCode := f_EPTF_DataSource_handleHelp(pl_dataValue,pl_source,pl_params,c_EPTF_LoadRegulator_help); |
| } |
| case else |
| { |
| } |
| } |
| return vl_errorCode; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_getCpsToReach |
| // |
| // Purpose: |
| // Returns the current CPS-to-reach value. |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // *float* - CPS-to-reach value |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_LoadRegulator_getCpsToReach() |
| runs on EPTF_LoadRegulator_CT |
| return float |
| { |
| return f_EPTF_Var_getFloatValue(v_LoadRegulator_cpsToReachVarIdx); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_getLoadToReach |
| // |
| // Purpose: |
| // Returns the current Load-to-reach value. |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // *float* - Load-to-reach value |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_LoadRegulator_getLoadToReach() |
| runs on EPTF_LoadRegulator_CT |
| return float |
| { |
| return f_EPTF_Var_getFloatValue(v_LoadRegulator_loadToReachVarIdx); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_setLoadToReach |
| // |
| // Purpose: |
| // Sets the Load-to-reach value. |
| // |
| // Parameters: |
| // pl_loadToReach - *in* *float* |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_LoadRegulator_setLoadToReach(in float pl_loadToReach) |
| runs on EPTF_LoadRegulator_CT |
| { |
| if(v_LoadRegulator_loadToReachVarIdx >= 0) { |
| f_EPTF_LoadRegulator_adjustTargetLoadInExecCtrl(pl_loadToReach); |
| } else { |
| f_EPTF_Var_adjustContent(v_LoadRegulator_loadToReachVarIdx, {floatVal := pl_loadToReach}); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_cleanup_CT() |
| // |
| // Purpose: |
| // Load regulator interface cleanup for EPTF_LoadRegulator_CT |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_LoadRegulator_cleanup_CT() runs on EPTF_LoadRegulator_CT |
| { |
| if(not v_EPTF_LoadRegulator_initialized) { |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_cleanup_CT(): not yet initialized"); |
| return; |
| } |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_cleanup_CT() started"); |
| |
| if(T_EPTF_loadReg.running) { T_EPTF_loadReg.stop; } |
| deactivate(v_EPTF_LoadRegulator_altstep); |
| v_EPTF_LoadRegulator_initialized := false; |
| |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_cleanup_CT() finished"); |
| } |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_registerToExecCtrl |
| // |
| // Purpose: |
| // Register the load regulator into execCtrl: it uses selfName to identify the loadRegulator in tsp_EPTF_ExecCtrl_RegulatorNames |
| // |
| // Parameters: |
| // pl_execCtrlCompRef - *in* <EPTF_Var_CT> - the component reference of the ExecCtrl component |
| // |
| // Return Value: |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // Automatically subscribes for the targetValue variable in ExecCtrl that belongs to the load regulator with name selfName. |
| // Also subscribes for the start/stop variable to enable/disable regulation automatically if start/stop button is pressed |
| // Automatically sets the v_EPTF_postCalcCPS function to adjust the correct targetValue in ExecCtrl |
| // |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_LoadRegulator_registerToExecCtrl( |
| in EPTF_Var_CT pl_execCtrlCompRef |
| ) runs on EPTF_LoadRegulator_CT { |
| |
| timer t_wait; |
| |
| if(T_EPTF_loadReg.running) { T_EPTF_loadReg.stop; } |
| f_EPTF_Base_registerCleanup(refers(f_EPTF_LoadRegulator_cleanup_ExecCtrl)); |
| t_wait.start(2.0); |
| t_wait.timeout; |
| |
| var integer pl_idx; |
| var float vl_current_loadToReach := f_EPTF_Var_getFloatValue(v_LoadRegulator_loadToReachVarIdx); // save the original value |
| var charstring pl_varName; |
| |
| // register |
| // set remote vars to signal registration to ExecCtrl: |
| f_EPTF_Var_adjustRemoteContent(pl_execCtrlCompRef,"EPTF_ExecCtrl.Regulator.currentLoad."&f_EPTF_Base_selfName(),{floatVal := int2float(f_EPTF_Base_upcast(self))}); |
| f_EPTF_Var_adjustRemoteContent(pl_execCtrlCompRef,"EPTF_ExecCtrl.Regulator.status."&f_EPTF_Base_selfName(),{ statusLEDVal := {led_yellow, "Registering..."} }); |
| // set local vars |
| f_EPTF_Var_adjustContent(v_EPTF_loadRegulator_execCtrlVar_statusIdx, { statusLEDVal := {led_green, "Connected"} }); |
| f_EPTF_Var_adjustContent(v_LoadRegulator_currentLoadVarIdx,{floatVal := 0.0}); |
| |
| // set the ft_EPTF_LoadRegulator_postCalculateCPS: |
| v_EPTF_postCalcCPS := refers(f_EPTF_LoadRegulator_postCalcCPS_ExecCtrl); |
| f_EPTF_LoadRegulator_adjustTargetLoadInExecCtrl(vl_current_loadToReach); // restore the original value |
| T_EPTF_loadReg.start(v_EPTF_loadRegulator_updateTimeout); |
| } |
| |
| private function f_EPTF_LoadRegulator_cleanup_ExecCtrl() runs on EPTF_LoadRegulator_CT { |
| if (v_EPTF_loadRegulator_execCtrlVar_statusIdx != -1) { |
| f_EPTF_Var_adjustContent(v_EPTF_loadRegulator_execCtrlVar_statusIdx, { statusLEDVal := {led_red, "Disconnected"} }); |
| v_EPTF_loadRegulator_execCtrlVar_statusIdx := -1; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_adjustTargetLoadInExecCtrl |
| // |
| // Purpose: |
| // This function is used as to set the targetLoad via ExecCtrl for this load regulator |
| // |
| // Parameters: |
| // pl_targetLoad - *in* *float* - target load |
| // |
| // Return Value: |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_LoadRegulator_adjustTargetLoadInExecCtrl(in float pl_targetLoad) runs on EPTF_LoadRegulator_CT { |
| f_EPTF_Var_adjustContent(v_LoadRegulator_loadToReachVarIdx,{ floatVal := pl_targetLoad }); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_postCalcCPS_ExecCtrl |
| // |
| // Purpose: |
| // This function is used as the postCalcCPS function for ExecCtrl regulation |
| // |
| // Parameters: |
| // |
| // Return Value: |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_LoadRegulator_postCalcCPS_ExecCtrl() runs on EPTF_LoadRegulator_CT { |
| var float vl_temp :=f_EPTF_Var_getFloatValue(v_LoadRegulator_cpsToReachVarIdx); |
| if (f_EPTF_Var_getFloatValue(v_LoadRegulator_cpsToReachVarIdx)!=vl_temp) { |
| f_EPTF_LoadRegulator_debug(%definitionId&"TotalValue updated to "&float2str(vl_temp)); |
| f_EPTF_Var_adjustContent(v_LoadRegulator_cpsToReachVarIdx,{floatVal := vl_temp}); |
| } |
| } |
| |
| // refreshes the value of the statusLed and currentLoad |
| private function f_EPTF_LoadRegulator_ExecCtrl_refreshVars() runs on EPTF_LoadRegulator_CT { |
| if (v_LoadRegulator_currentLoadVarIdx==-1) { |
| return; // not registered into execCtrl |
| } |
| if (f_EPTF_Var_getFloatValue(v_LoadRegulator_currentLoadVarIdx)!=v_EPTF_LoadRegulator_ctx.vl_currLoad) { |
| f_EPTF_Var_adjustContent(v_LoadRegulator_currentLoadVarIdx,{ floatVal := v_EPTF_LoadRegulator_ctx.vl_currLoad /*vl_measuredLoad /*v_EPTF_LoadRegulator_currentLoad*/ }); |
| } |
| var EPTF_StatusLED vl_currentVal := f_EPTF_Var_getStatusLEDValue(v_EPTF_loadRegulator_execCtrlVar_statusIdx); |
| if (not f_EPTF_Var_getBoolValue(v_LoadRegulator_enabledVarIdx)) { |
| if (vl_currentVal != {led_blue, "Disabled"}) { |
| f_EPTF_Var_adjustContent(v_EPTF_loadRegulator_execCtrlVar_statusIdx,{ statusLEDVal := {led_blue, "Disabled"} }); |
| } |
| } else if (f_EPTF_Var_getBoolValue(v_LoadRegulator_loadIsStableVarIdx)) { |
| if (vl_currentVal.text != "Auto-off" and vl_currentVal != {led_green, "Stable"}) { |
| f_EPTF_Var_adjustContent(v_EPTF_loadRegulator_execCtrlVar_statusIdx,{ statusLEDVal := {led_green, "Stable"} }); |
| } |
| } else { |
| if (vl_currentVal.text != "Auto-off" and vl_currentVal != {led_yellow, "Unstable"}) { |
| f_EPTF_Var_adjustContent(v_EPTF_loadRegulator_execCtrlVar_statusIdx,{ statusLEDVal := {led_yellow, "Unstable"} }); |
| } |
| } |
| } |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_calculateNextCps_limitMax |
| // |
| // Purpose: |
| // A variation of the function <f_EPTF_LoadRegulator_calculateNextCps>. |
| // It only regulates the CPS if the current load reaches the target load |
| // setting. Below that boundary the original CPS is used, no regulation |
| // takes place. |
| // |
| // Parameters: |
| // loadToReach - *in* *float* - the target load level to reach |
| // oldCps - *in* *float* - previous CPS value |
| // |
| // Return Value: |
| // *float* - new CPS value |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // The generic load regulator algorithm is a simple fuzzy regulator. |
| // It calculates the next cps from the previous cps and the last two |
| // cpu/network loads, according to the specified load to reach. |
| // |
| // If the target load is above the current load, the algorithm |
| // continues regulation until the original CPS value, that before |
| // the regulation was started, is restored. The regulator |
| // switches to "Auto-off" mode: regulation is disabled, |
| // the CPS value of the regulated items can be changed. |
| // |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_LoadRegulator_calculateNextCps_limitMax( |
| in float loadToReach, |
| in float oldCps) |
| runs on EPTF_LoadRegulator_CT |
| return float |
| { |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_calculateNextCps_limitMax() started"); |
| |
| if (v_LoadRegulator_cpsToReachVarIdx==-1) { |
| return oldCps; |
| } |
| |
| if (loadToReach == 0.0) { return 0.0 } |
| |
| var integer measWindowSize := sizeof(vc_loadRegMeasWindow); |
| var float loadNew := 0.0; |
| var float loadErrorNew := 0.0; |
| |
| //calculate last two load values |
| if(vc_measWinIdx == 0) { |
| loadNew := vc_loadRegMeasWindow[measWindowSize-1]; |
| } |
| else if(vc_measWinIdx == 1) { |
| loadNew := vc_loadRegMeasWindow[0]; |
| } |
| else { |
| loadNew := vc_loadRegMeasWindow[vc_measWinIdx-1]; |
| } |
| |
| //calculate load error and delta-error |
| loadErrorNew := loadToReach-loadNew; |
| |
| var float errorTolerance := 0.0;//v_EPTF_loadRegulator_errorTolerance; // eg. +- x% of load is tolerated |
| |
| f_EPTF_LoadRegulator_debug(log2str("loadToReach: ", loadToReach, " oldCps: ", oldCps, " errorTolerance: ", errorTolerance, " loadErrorNew: ", loadErrorNew)); |
| if(loadErrorNew >= errorTolerance) { |
| // no regulation needed: |
| f_EPTF_LoadRegulator_debug("LOW LOAD, NO REGULATION NEEDED"); |
| // update status led: |
| if (v_EPTF_loadRegulator_execCtrlVar_statusIdx!=-1) { |
| var EPTF_StatusLED vl_currentVal := f_EPTF_Var_getStatusLEDValue(v_EPTF_loadRegulator_execCtrlVar_statusIdx); |
| if (vl_currentVal.text != "Auto-off" and (oldCps == v_EPTF_loadRegulator_originalCPS or v_EPTF_loadRegulator_originalCPS == -1.0)) { |
| f_EPTF_Var_adjustContent(v_EPTF_loadRegulator_execCtrlVar_statusIdx,{ statusLEDVal := {led_blue, "Auto-off"} }) |
| } |
| } |
| // if regulation is on: |
| if (v_EPTF_loadRegulator_originalCPS>=0.0) { |
| // if original cps level is not reached: |
| if (oldCps<v_EPTF_loadRegulator_originalCPS) { |
| // continue regulation until original CPS level is reached: |
| var float vl_newCps := f_EPTF_LoadRegulator_calculateNextCps(loadToReach,oldCps); |
| // if new cps is below the original, continue regulation: |
| if (vl_newCps<v_EPTF_loadRegulator_originalCPS) { |
| f_EPTF_LoadRegulator_debug("Regulation enabled until original CPS is restored"); |
| return vl_newCps; |
| } |
| // otherwise restore original cps |
| } |
| // restore original cps if old or new cps is above the original: |
| oldCps := v_EPTF_loadRegulator_originalCPS; |
| v_EPTF_loadRegulator_originalCPS := -1.0; |
| f_EPTF_LoadRegulator_debug(log2str("Regulation switched off, original cps restored: ", oldCps)); |
| } else { |
| // use current CPS: |
| //if (oldCps==0.0) { |
| oldCps := f_EPTF_Var_getFloatValue(v_LoadRegulator_cpsToReachVarIdx); |
| //} |
| } |
| f_EPTF_LoadRegulator_debug(log2str("using original cps: ", oldCps)); |
| // regulation disabled |
| return oldCps; |
| } |
| else { |
| // regulation enabled |
| // store the original CPS value: |
| f_EPTF_LoadRegulator_debug(log2str("REGULATION ON!!!")); |
| if (v_EPTF_loadRegulator_originalCPS<0.0) { |
| v_EPTF_loadRegulator_originalCPS := f_EPTF_Var_getFloatValue(v_LoadRegulator_cpsToReachVarIdx); |
| f_EPTF_LoadRegulator_debug(log2str("original CPS stored: ",v_EPTF_loadRegulator_originalCPS)); |
| oldCps := v_EPTF_loadRegulator_originalCPS; |
| } |
| // prevent increment cps above the original: |
| var float vl_newCps := f_EPTF_LoadRegulator_calculateNextCps(loadToReach,oldCps); |
| if (vl_newCps>v_EPTF_loadRegulator_originalCPS) { |
| vl_newCps := v_EPTF_loadRegulator_originalCPS; |
| } |
| if (v_EPTF_loadRegulator_execCtrlVar_statusIdx!=-1) { |
| var EPTF_StatusLED vl_currentVal := f_EPTF_Var_getStatusLEDValue(v_EPTF_loadRegulator_execCtrlVar_statusIdx); |
| if (vl_currentVal.text == "Auto-off" and vl_newCps<v_EPTF_loadRegulator_originalCPS) { |
| f_EPTF_Var_adjustContent(v_EPTF_loadRegulator_execCtrlVar_statusIdx,{ statusLEDVal := {led_yellow, "Unstable"} }) |
| } |
| } |
| return vl_newCps; |
| } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_calculateNextCps |
| // |
| // Purpose: |
| // The generic load regulation algorithm is implemented here |
| // |
| // Parameters: |
| // loadToReach - *in* *float* - the target load to reach |
| // oldCps - *in* *float* - the previous CPS value |
| // |
| // Return Value: |
| // *float* - new CPS value |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // The generic load regulator algorithm is a simple fuzzy regulator. |
| // It calculates the next cps from the previous cps and the last two |
| // cpu/network loads, according to the specified load to reach. |
| // |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_LoadRegulator_calculateNextCps( |
| in float loadToReach, |
| in float oldCps) |
| runs on EPTF_LoadRegulator_CT |
| return float |
| { |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_calculateNextCps() started"); |
| |
| if (loadToReach == 0.0) { return 0.0 } |
| |
| var integer measWindowSize := sizeof(vc_loadRegMeasWindow); |
| var float loadNew := 0.0; |
| var float loadOld := 0.0; |
| var float loadErrorNew := 0.0; |
| var float loadErrorOld := 0.0; |
| var float loadErrorDelta := 0.0; |
| |
| //calculate last two load values |
| if(vc_measWinIdx == 0) { |
| loadNew := vc_loadRegMeasWindow[measWindowSize-1]; |
| loadOld := vc_loadRegMeasWindow[measWindowSize-2]; |
| } |
| else if(vc_measWinIdx == 1) { |
| loadNew := vc_loadRegMeasWindow[0]; |
| loadOld := vc_loadRegMeasWindow[measWindowSize-1]; |
| } |
| else { |
| loadNew := vc_loadRegMeasWindow[vc_measWinIdx-1]; |
| loadOld := vc_loadRegMeasWindow[vc_measWinIdx-2]; |
| } |
| |
| //calculate load error and delta-error |
| loadErrorNew := loadToReach-loadNew; |
| loadErrorOld := loadToReach-loadOld; |
| loadErrorDelta := loadErrorNew-loadErrorOld; |
| |
| |
| //parameters of LoadRegulator (to be tuned for specific project) |
| var float errorTolerance := v_EPTF_loadRegulator_errorTolerance; // eg. +- x% of load is tolerated |
| var float errorDeltaTolerance := v_EPTF_loadRegulator_errorTolerance; // eg. +- x% of delta is tolerated |
| var float cpsDelta := v_EPTF_loadregulator_cpsDelta; // max cpsToReach increas/decrease parameter value |
| |
| /* Regulation "functions" */ |
| |
| // (errorNew > 0) && (errorDelta > 0) --> output > 0 |
| var float h1, h1a, h1b; |
| |
| if(loadErrorNew <= -errorTolerance) { h1a := 0.0; } |
| else if(loadErrorNew >= errorTolerance) { h1a := 1.0; } |
| else { |
| h1a := (1.0 / (2.0*errorTolerance)) * (loadErrorNew + errorTolerance); |
| } |
| |
| if(loadErrorDelta <= -errorDeltaTolerance) { h1b := 0.0; } |
| else if(loadErrorDelta >= errorDeltaTolerance) { h1b := 1.0; } |
| else { |
| h1b := (1.0 / (2.0*errorDeltaTolerance)) * (loadErrorDelta + errorDeltaTolerance); |
| } |
| |
| if(h1a < h1b) { h1 := h1a; } |
| else { h1 := h1b; } |
| |
| |
| // (errorNew < 0) && (errorDelta > 0) --> output = 0 |
| var float h2, h2a, h2b; |
| |
| if(loadErrorNew <= -errorTolerance) { h2a := 1.0; } |
| else if(loadErrorNew >= errorTolerance) { h2a := 0.0; } |
| else { |
| h2a := (-1.0 / (2.0*errorTolerance)) * (loadErrorNew - errorTolerance); |
| } |
| |
| h2b := h1b; |
| |
| if(h2a < h2b) { h2 := h2a; } |
| else { h2 := h2b; } |
| |
| |
| // (errorNew > 0) && (errorDelta < 0) --> output = 0 |
| var float h3, h3a, h3b; |
| |
| h3a := h1a; |
| |
| if(loadErrorDelta <= -errorDeltaTolerance) { h3b := 1.0; } |
| else if(loadErrorDelta >= errorDeltaTolerance) { h3b := 0.0; } |
| else { |
| h3b := (-1.0 / (2.0*errorDeltaTolerance)) * (loadErrorDelta - errorDeltaTolerance); |
| } |
| |
| if(h3a < h3b) { h3 := h3a; } |
| else { h3 := h3b; } |
| |
| |
| // (errorNew < 0) && (errorDelta < 0) --> output < 0 |
| var float h4, h4a, h4b; |
| |
| h4a := h2a; |
| |
| h4b := h3b; |
| |
| if(h4a < h4b) { h4 := h4a; } |
| else { h4 := h4b; } |
| |
| |
| var float delta := (cpsDelta*h1 - cpsDelta*h4) / (h1+h2+h3+h4); |
| var float newCps := oldCps + delta; |
| |
| |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_calculateNextCps() -------- regulation data start --------"); |
| f_EPTF_LoadRegulator_debug(log2str("f_EPTF_LoadRegulator_calculateNextCps() --- Load to reach is: ", loadToReach)); |
| f_EPTF_LoadRegulator_debug(log2str("f_EPTF_LoadRegulator_calculateNextCps() --- Load old: ",loadOld)); |
| f_EPTF_LoadRegulator_debug(log2str("f_EPTF_LoadRegulator_calculateNextCps() --- Load new: ",loadNew)); |
| f_EPTF_LoadRegulator_debug(log2str("f_EPTF_LoadRegulator_calculateNextCps() --- Load error: [",loadErrorOld,", ",loadErrorNew,"]")); |
| f_EPTF_LoadRegulator_debug(log2str("f_EPTF_LoadRegulator_calculateNextCps() --- Load error delta: ",loadErrorDelta)); |
| f_EPTF_LoadRegulator_debug(log2str("f_EPTF_LoadRegulator_calculateNextCps() --- delta cps: ",delta)); |
| f_EPTF_LoadRegulator_debug(log2str("f_EPTF_LoadRegulator_calculateNextCps() --- new cps: ",newCps)); |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_calculateNextCps() -------- regulation data finish -------"); |
| |
| f_EPTF_LoadRegulator_debug("f_EPTF_LoadRegulator_calculateNextCps() finished"); |
| |
| |
| if(newCps > 0.0) { return newCps; } |
| else { return oldCps; } |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: as_EPTF_LoadRegulator_behavior |
| // |
| // Purpose: |
| // Main behavior altstep for EPTF_LoadRegulator |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // This altstep is activated as default by f_EPTF_LoadRegulator_init_CT |
| /////////////////////////////////////////////////////////// |
| private altstep as_EPTF_LoadRegulator_behavior() |
| runs on EPTF_LoadRegulator_CT |
| { |
| [] T_EPTF_loadReg.timeout |
| { |
| f_EPTF_LoadRegulator_ExecCtrl_refreshVars(); |
| |
| v_EPTF_LoadRegulator_ctx.vl_measuredLoad := vc_EPTF_getSutLoad.apply(); |
| v_EPTF_LoadRegulator_ctx.vl_currLoad := f_EPTF_exponentialSmoothingFunction( |
| v_EPTF_LoadRegulator_ctx.vl_measuredLoad, |
| v_EPTF_LoadRegulator_ctx.vl_currLoad, |
| v_EPTF_loadRegulator_smoothingFactor); |
| |
| // Storing the value in the meas list |
| vc_loadRegMeasWindow[vc_measWinIdx] := v_EPTF_LoadRegulator_ctx.vl_currLoad; |
| vc_measWinIdx := vc_measWinIdx + 1; |
| if (vc_measWinIdx == v_EPTF_loadRegulator_measWinSize) { |
| vc_measWinIdx := 0; |
| } |
| |
| if (v_EPTF_LoadRegulator_ctx.vl_currLoad>v_EPTF_LoadRegulator_ctx.vl_prevLoad) { |
| v_EPTF_LoadRegulator_ctx.vl_diffLoad := v_EPTF_LoadRegulator_ctx.vl_currLoad - v_EPTF_LoadRegulator_ctx.vl_prevLoad; |
| } else { |
| v_EPTF_LoadRegulator_ctx.vl_diffLoad := v_EPTF_LoadRegulator_ctx.vl_prevLoad - v_EPTF_LoadRegulator_ctx.vl_currLoad; |
| } |
| |
| if (v_EPTF_LoadRegulator_ctx.vl_diffLoad>v_EPTF_loadRegulator_LoadVarianceThreshold) { |
| // Update the new load value |
| f_EPTF_Var_adjustContent(v_LoadRegulator_currentLoadVarIdx, {floatVal := v_EPTF_LoadRegulator_ctx.vl_currLoad}) |
| //v_EPTF_LoadRegulator_currentLoad := v_EPTF_LoadRegulator_ctx.vl_currLoad; |
| v_EPTF_LoadRegulator_ctx.vl_prevLoad := v_EPTF_LoadRegulator_ctx.vl_currLoad; |
| } |
| |
| if (v_EPTF_LoadRegulator_ctx.vl_currLoad>v_EPTF_LoadRegulator_ctx.vl_prevLoad) { |
| v_EPTF_LoadRegulator_ctx.vl_diffLoad := v_EPTF_LoadRegulator_ctx.vl_currLoad - v_EPTF_LoadRegulator_ctx.vl_prevLoad; |
| } else { |
| v_EPTF_LoadRegulator_ctx.vl_diffLoad := v_EPTF_LoadRegulator_ctx.vl_prevLoad - v_EPTF_LoadRegulator_ctx.vl_currLoad; |
| } |
| |
| |
| // Calculate loadToReachDiff |
| v_EPTF_LoadRegulator_ctx.vl_loadToReach := f_EPTF_Var_getFloatValue(v_LoadRegulator_loadToReachVarIdx); |
| if (v_EPTF_LoadRegulator_ctx.vl_currLoad>v_EPTF_LoadRegulator_ctx.vl_loadToReach) { |
| v_EPTF_LoadRegulator_ctx.vl_loadToReachDiff := v_EPTF_LoadRegulator_ctx.vl_currLoad - v_EPTF_LoadRegulator_ctx.vl_loadToReach; |
| } else { |
| v_EPTF_LoadRegulator_ctx.vl_loadToReachDiff := v_EPTF_LoadRegulator_ctx.vl_loadToReach - v_EPTF_LoadRegulator_ctx.vl_currLoad; |
| } |
| |
| // Storing the value in the stable list |
| if (v_EPTF_LoadRegulator_ctx.vl_loadToReachDiff>v_EPTF_loadRegulator_LoadVarianceThreshold) { |
| vc_loadRegStableWindow[vc_stableWinIdx] := 0.0; //not stable |
| } else { |
| vc_loadRegStableWindow[vc_stableWinIdx] := 1.0; //stable |
| } |
| |
| // Updating stable list index |
| vc_stableWinIdx := vc_stableWinIdx + 1; |
| if (vc_stableWinIdx == 3) { |
| vc_stableWinIdx := 0; |
| } |
| |
| // Calculate sum of StableWindow |
| var float sumStableWindow := 0.0; |
| if(sizeof(vc_loadRegStableWindow)==3) { |
| for(var integer i:=0; i<3; i:=i+1) { |
| sumStableWindow := sumStableWindow + vc_loadRegStableWindow[i]; |
| } |
| } |
| |
| |
| // Calculate and update new cpsToReach only if load regulation is required... |
| // Update loadIsStable if necessary |
| if (f_EPTF_Var_getBoolValue(v_LoadRegulator_enabledVarIdx)) { |
| f_EPTF_Var_adjustContent(v_LoadRegulator_cpsToReachVarIdx,{floatVal := |
| vc_EPTF_calculateNextCps.apply( |
| f_EPTF_Var_getFloatValue(v_LoadRegulator_loadToReachVarIdx), |
| f_EPTF_Var_getFloatValue(v_LoadRegulator_cpsToReachVarIdx))}); |
| |
| if(v_EPTF_postCalcCPS != null) { |
| v_EPTF_postCalcCPS.apply(); |
| } |
| |
| if(sumStableWindow == 3.0) { |
| f_EPTF_Var_adjustContent(v_LoadRegulator_loadIsStableVarIdx,{boolVal := true}); |
| } |
| else { |
| f_EPTF_Var_adjustContent(v_LoadRegulator_loadIsStableVarIdx,{boolVal := false}); |
| } |
| } |
| if(null != v_LoadRegulator_updateCallback){ |
| v_LoadRegulator_updateCallback.apply(); |
| } |
| |
| T_EPTF_loadReg.start(v_EPTF_loadRegulator_updateTimeout); |
| |
| repeat; |
| } |
| } |
| |
| friend function f_EPTF_LoadRegulator_setUpdateCallback( |
| in EPTF_LoadRegulator_updateCallback_FT pl_callback) |
| runs on EPTF_LoadRegulator_CT |
| { |
| v_LoadRegulator_updateCallback := pl_callback; |
| } |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_exponentialSmoothingFunction |
| // |
| // Purpose: |
| // This function is used to smooth the measured load using exponential smoothing |
| // |
| // Parameters: |
| // pl_measuredLoad - *in* *float* - value of the currently measured load |
| // |
| // pl_prevLoad - *in* *float* - value of the previous smoothed load |
| // |
| // pl_smoothingFactor - *in* *float* - smoothing factor, should be between |
| // 0.0 (extreme smoothing) and 1.0 (no smoothing) |
| // |
| // Return Value: |
| // float - smoothed load |
| // |
| // Errors: |
| // - |
| // |
| // Detailed Comments: |
| // This function can be used to remove high fluctuations of the measured data. |
| // The function uses exponetial smoothing, which is based on the following formula: |
| // |
| // s_0 = x_0 |
| // |
| // s_t = alpha * x_t + (1-alpha) * s_(t-1) |
| // |
| // x_t is the measured data at t iteration, s_t is the smoothed value |
| // |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_exponentialSmoothingFunction(in float pl_measuredLoad, in float pl_prevLoad, in float pl_smoothingFactor) |
| return float |
| { |
| if(tsp_debug_EPTF_CLL_LoadRegulator_Functions_smoothing){f_EPTF_Common_user(log2str("f_EPTF_exponentialSmoothingFunction: measured load: " & float2str(pl_measuredLoad)));} |
| var float vl_currLoad := pl_smoothingFactor*pl_measuredLoad+(1.0-pl_smoothingFactor)*pl_prevLoad; |
| if(tsp_debug_EPTF_CLL_LoadRegulator_Functions_smoothing){f_EPTF_Common_user(log2str("f_EPTF_exponentialSmoothingFunction: smoothed load: " & float2str(vl_currLoad)));} |
| |
| return vl_currLoad; |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Group: Private |
| // |
| // Purpose: |
| // Private functions. These functions must not be called by the user of <EPTF_LoadRegulator_CT> |
| // |
| // Elements: |
| /////////////////////////////////////////////////////////// |
| group Private { |
| group Logging { |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_error |
| // |
| // Purpose: |
| // Function to log an error from LoadRegulator feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| friend function f_EPTF_LoadRegulator_error(in charstring pl_message) |
| runs on EPTF_LoadRegulator_CT |
| { |
| f_EPTF_Logging_error(true, tsp_EPTF_LoadRegulator_loggingComponentMask&": "&pl_message); |
| f_EPTF_Base_stopAll(); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_warning |
| // |
| // Purpose: |
| // Function to log a warning from LoadRegulator feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| friend function f_EPTF_LoadRegulator_warning(in @lazy charstring pl_message) |
| runs on EPTF_LoadRegulator_CT |
| { |
| f_EPTF_Logging_warningV2(pl_message, v_LoadRegulator_loggingMaskId, {c_EPTF_LoadRegulator_loggingClassIdx_Warning}); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_debug |
| // |
| // Purpose: |
| // Function to log a debug message from LoadRegulator feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| friend function f_EPTF_LoadRegulator_debug(in @lazy charstring pl_message) |
| runs on EPTF_LoadRegulator_CT |
| { |
| f_EPTF_Logging_debugV2(pl_message, v_LoadRegulator_loggingMaskId, {c_EPTF_LoadRegulator_loggingClassIdx_Debug}); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_LoadRegulator_debugEnabled |
| // |
| // Purpose: |
| // Function to check if debug is enabled for LoadRegulator |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // *boolean* - true if debug enalbed |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_LoadRegulator_debugEnabled() |
| runs on EPTF_LoadRegulator_CT |
| return boolean |
| { |
| return f_EPTF_Logging_isEnabled(v_LoadRegulator_loggingMaskId, c_EPTF_LoadRegulator_loggingClassIdx_Debug); |
| } |
| } // group Logging |
| |
| public function f_EPTF_LoadRegulator_getVarRef_enabled() |
| runs on EPTF_LoadRegulator_CT |
| return integer |
| { |
| return v_LoadRegulator_enabledVarIdx; |
| } |
| |
| public function f_EPTF_LoadRegulator_getVarRef_cpsToReach() |
| runs on EPTF_LoadRegulator_CT |
| return integer |
| { |
| return v_LoadRegulator_cpsToReachVarIdx; |
| } |
| |
| public function f_EPTF_LoadRegulator_getVarRef_loadToReach() |
| runs on EPTF_LoadRegulator_CT |
| return integer |
| { |
| return v_LoadRegulator_loadToReachVarIdx; |
| } |
| |
| public function f_EPTF_LoadRegulator_getVarRef_currentLoad() |
| runs on EPTF_LoadRegulator_CT |
| return integer |
| { |
| return v_LoadRegulator_currentLoadVarIdx; |
| } |
| |
| public function f_EPTF_LoadRegulator_getVarRef_loadIsStable() |
| runs on EPTF_LoadRegulator_CT |
| return integer |
| { |
| return v_LoadRegulator_loadIsStableVarIdx; |
| } |
| |
| } // group Private |
| |
| } // module |
| |