[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Observers can be defined as software sensors. An Observer has Sensors and other Observers for inputs, maintains its state, and produces one or more estimated variables.
7.1 Observer Code Structure | ||
7.2 Observer Example |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The Observer code is structured in four steps, two of which are initialization steps and two of which are run during each control loop. These steps are:
The Setup step is where the Observer is described: the needed inputs are declared, and the produced estimated variables, parameters, and state variables are defined.
In that step, you will:
The Init step is where initial values are set.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Note that other examples can be found in the ‘observers’ directory of your Odin install.
//=================================================================== // // Copyright INRIA Sophia Antipolis 2008, all rights reserved // // Project : Odin // // Description: Biomass observer // // Author: Romain Primet <romain.primet@sophia.inria.fr> // //=================================================================== function hrs = secToDays(tSec) hrs = tSec/(24.*60.*60.); endfunction /// Computes the system state's derivative /// function ydot = obs(t,y) , qIn = Inputs("SensorB-qIn")("value"); sIn = Inputs("SensorB-sIn")("value"); vLiq = Parameters("vLiq")("value"); k1 = Parameters("k1")("value"); d = qIn/vLiq; ydot = -d*y + (k1)*d*sIn; , endfunction function y = doContinuousIntegration(Inputs, Parameters, StateVars), StateVarValue = [StateVars("z")("value")]; y = ode(StateVarValue,tLast,tCurr/(24.*60.*60.),obs); endfunction function sv = doDiscreteIntegration(Inputs, Parameters, StateVars), //fill in this function sv = 0. endfunction //// Control loop entry points //// select ObsJob, case 'Setup' then exec('./observers/factories.sci'); ObsName = 'obs'; ObsDescription = 'Asymptotic observer for biomass estimation'; continuousScheme = %t; //set to %f if integration step is to be discrete //EDIT InputsRequiredUid = ['SensorA-s'; 'SensorB-qIn'; 'SensorB-sIn']; //DO NOT EDIT Inputs = tlist([["Inputs"] ; InputsRequiredUid]); //Note that parameters are constant //EDIT ParametersUid = ['vLiq'; 'muMax'; 'ksm'; 'lambda'; 'k1'; 'k6' ]; //DO NOT EDIT Parameters = tlist([["Parameters"] ; ParametersUid]); //State variables (or estimated variables) //EDIT StateVarsUid = ['z' ]; //DO NOT EDIT StateVars = tlist([["StateVars"] ; StateVarsUid]); //Estimated variables //EDIT EstimatedVarsUid = ['obs-xc']; //DO NOT EDIT EstimatedVars = tlist([["EstimatedVars"] ; EstimatedVarsUid]); //EDIT //Initialize individual inputs IName = "SensorA-s"; Inputs(IName) = makeSensor(); Inputs(IName)("deviceUid") = 'SensorA-s'; Inputs(IName)("value") = 0.; Inputs(IName)("timestamp") = 0.; IName = "SensorB-qIn"; Inputs(IName) = makeSensor(); Inputs(IName)("deviceUid") = 'SensorB-qIn'; Inputs(IName)("value") = 0.; Inputs(IName)("timestamp") = 0.; IName = "SensorB-sIn"; Inputs(IName) = makeSensor(); Inputs(IName)("deviceUid") = 'SensorB-sIn'; Inputs(IName)("value") = 0.; Inputs(IName)("timestamp") = 0.; //Initialize individual parameters PName = "vLiq"; Parameters(PName) = makeParameter(); Parameters(PName)("label") = 'vLiq'; Parameters(PName)("uid") = 'vLiq'; Parameters(PName)("description") = 'Bioreactor volume'; Parameters(PName)("value") = 900.; Parameters(PName)("unit") = 'L'; PName = "k1"; Parameters(PName) = makeParameter(); Parameters(PName)("label") = 'k1'; Parameters(PName)("uid") = 'k1'; Parameters(PName)("description") = 'k1'; Parameters(PName)("value") = 1.; Parameters(PName)("unit") = 'mmol/g'; SVName = "z"; StateVars(SVName) = makeStateVar(); StateVars(SVName)("label") = 'z'; StateVars(SVName)("uid") = 'z'; StateVars(SVName)("description") = 'z'; StateVars(SVName)("value") = 0.; StateVars(SVName)("unit") = 'Day^{-1}'; //Attributes should exactly mirror input attributes. EVName = "obs-xc"; EstimatedVars(EVName) = makeEstimatedVar(); EstimatedVars(EVName)("physicalDeviceLabel") = 'Biomass concentration observer'; EstimatedVars(EVName)("physicalDeviceUid") = 'obs'; EstimatedVars(EVName)("deviceUid") = 'obs-xc'; EstimatedVars(EVName)("dataLabel") = 'xc'; EstimatedVars(EVName)("dataDescription") = 'Biomass concentration (estimated)'; EstimatedVars(EVName)("unit") = 'g/L'; EstimatedVars(EVName)("domain") = [-1000; 1000]; EstimatedVars(EVName)("validityPeriod") = -1.; EstimatedVars(EVName)("value") = 0.; EstimatedVars(EVName)("timestamp") = 0.; , case 'Init' then tLast = tCurr/(24*60*60); //EDIT initial values StateVars("z")("value") = 5.0; , //DO NOT EDIT this step, instead edit either doContinuousIntegration //or doDiscreteIntegration case 'Integration' then if continuousScheme then, y = doContinuousIntegration(); StateVars("z")("value") = y(1); else, doDiscreteIntegration(); end , //Computation of estimated variables case 'EstimatedVarsComputation' then z = StateVars("z")("value"); k1 = Parameters("k1")("value"); s = Inputs("SensorA-s")("value"); xc = max(0,(z - k1*s)); printf("z=%f, k1=%f, s=%f, xc=%f, sIn=%f, qIn=%f\n", z, k1, s, xc, Inputs("SensorB-sIn")("value"), Inputs("SensorB-qIn")("value")); EstimatedVars("obs-xc")("value") = xc; tLast = tCurr/(24*60*60); , //Otherwise else disp('Observer job flag unknown'); //make observer fail if the flag is unknown //(better fail explicitly than silently) pause; end;
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Fabien Dilet on July, 22 2010 using texi2html 1.78.