package TwoTankExample connector ActSignal Real act; end ActSignal; partial model BaseController parameter Real K = 2; parameter Real T(unit = "s") = 10; ReadSignal cIn; ActSignal cOut; parameter Real ref; Real error; Real outCtr; equation cOut.act = outCtr; error = ref - cIn.val; end BaseController; connector LiquidFlow Real lflow(unit = "m3/s"); end LiquidFlow; model LiquidSource LiquidFlow qOut; parameter Real flowLevel = 0.02; equation qOut.lflow = if time > 150 then 3*flowLevel else flowLevel; end LiquidSource; model PIcontinuousController extends BaseController(T = 10, K = 2); Real x; equation der(x) = error/T; outCtr = K*(error + x); end PIcontinuousController; connector ReadSignal Real val(unit = "m"); end ReadSignal; model Tank ReadSignal tSensor; ActSignal tActuator; LiquidFlow qIn; LiquidFlow qOut; parameter Real area(unit = "m2") = 0.5; parameter Real flowGain(unit = "m2/s") = 0.05; parameter Real minV = 0; parameter Real maxV = 10; Real h(start = 0.0, unit = "m"); equation tSensor.val = h; assert(minV >= 0, "minV - minimum Valve level must be >= 0 "); der(h) = (qIn.lflow - qOut.lflow)/area; qOut.lflow = limitValue(minV, maxV, -flowGain*tActuator.act); end Tank; model TanksConnectedPI LiquidSource source(flowLevel = 0.02); Tank tank1(area = 1); Tank tank2(area = 1.3); PIcontinuousController piContinuous1(ref = 0.25); PIcontinuousController piContinuous2(ref = 0.4); equation connect(tank2.tActuator,piContinuous2.cOut); connect(tank1.tActuator,piContinuous1.cOut); connect(tank1.tSensor,piContinuous1.cIn); connect(tank1.qOut,tank2.qIn); connect(tank2.tSensor,piContinuous2.cIn); connect(source.qOut,tank1.qIn); end TanksConnectedPI; function limitValue input Real pMin; input Real pMax; input Real p; output Real pLim; algorithm pLim := if p > pMax then pMax else if p < pMin then pMin else p; end limitValue; end TwoTankExample;