From 92c5ecac09b7e1b3e729c95031ec4bc1f97840f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steinar=20Elgs=C3=A6ter?= Date: Wed, 11 Dec 2024 15:12:49 +0100 Subject: [PATCH] - updating how the sign of the process gain is inferrred by CLUI --- .../Identification/ClosedLoopUnitIdentifier.cs | 13 ++++++++++++- .../ClosedLoopIdentifierTester_StaticSISO.cs | 15 +++++++-------- docs/articles/sysid_disturbance.md | 12 ++++++++---- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/Dynamic/Identification/ClosedLoopUnitIdentifier.cs b/Dynamic/Identification/ClosedLoopUnitIdentifier.cs index 9dbd557..14d93c8 100644 --- a/Dynamic/Identification/ClosedLoopUnitIdentifier.cs +++ b/Dynamic/Identification/ClosedLoopUnitIdentifier.cs @@ -835,9 +835,17 @@ double Range(double[] inSignal) /// /// /// - /// + /// returns 1 if gain is positive or -1 if gain is negative. private static double GuessSignOfProcessGain(UnitDataSet unitDataSet, PidParameters pidParams, int pidInputIdx) { + if (pidParams.Kp != 0 && !Double.IsNaN(pidParams.Kp) && pidParams.Kp != -9999) + { + if (pidParams.Kp > 0) + return 1; + else + return -1; + } + var vec = new Vec(unitDataSet.BadDataID); double[] e = vec.Subtract(unitDataSet.Y_meas, unitDataSet.Y_setpoint); double pidInput_processGainSign = 1; @@ -876,6 +884,9 @@ private static double GuessSignOfProcessGain(UnitDataSet unitDataSet, PidParamet /// private static UnitModel EstimateClosedLoopProcessGain(UnitDataSet unitDataSet, PidParameters pidParams, int pidInputIdx) { + + + var unitModel = new UnitModel(); var vec = new Vec(unitDataSet.BadDataID); diff --git a/TimeSeriesAnalysis.Tests/Tests/ClosedLoopIdentifierTester_StaticSISO.cs b/TimeSeriesAnalysis.Tests/Tests/ClosedLoopIdentifierTester_StaticSISO.cs index 1c275e2..bdaae08 100644 --- a/TimeSeriesAnalysis.Tests/Tests/ClosedLoopIdentifierTester_StaticSISO.cs +++ b/TimeSeriesAnalysis.Tests/Tests/ClosedLoopIdentifierTester_StaticSISO.cs @@ -82,20 +82,19 @@ public void SinusDisturbance(double distSinusAmplitude) // 0.25: saturates the controller - [TestCase(0.5, 0.1, Category = "NotWorking_AcceptanceTest")] - [TestCase(0.5, 1, Category = "NotWorking_AcceptanceTest")] - [TestCase(1, 0.1, Category = "NotWorking_AcceptanceTest")] - [TestCase(1, 1, Category = "NotWorking_AcceptanceTest")] - [TestCase(2, 0.1)] - [TestCase(2, 1)] + [TestCase(0.5, 0.1,20, Category = "NotWorking_AcceptanceTest")] + [TestCase(0.5, 1, 20, Category = "NotWorking_AcceptanceTest")] + [TestCase(1, 0.1, 20, Category = "NotWorking_AcceptanceTest")] + [TestCase(1, 1, 20, Category = "NotWorking_AcceptanceTest")] + [TestCase(2, 0.1, 20)] + [TestCase(2, 1, 20)] // gain of 5 starts giving huge oscillations... - public void RandomWalkDisturbance(double procGain, double distAmplitude) + public void RandomWalkDisturbance(double procGain, double distAmplitude, double precisionPrc) { // int seed = 50;// works fairly well.. // int seed = 100;// much harder for some reason int seed = 105; - double precisionPrc = 20; int N = 2000; diff --git a/docs/articles/sysid_disturbance.md b/docs/articles/sysid_disturbance.md index dead4a0..ec3a77d 100644 --- a/docs/articles/sysid_disturbance.md +++ b/docs/articles/sysid_disturbance.md @@ -113,12 +113,15 @@ G_0 = max(e)/(max(u)-min(u)) ``` The PID-controller integral effect time constant meant that a peak in the deviation ``e`` will not coincide with the peak -in ``u''. +in ``u``. The idea of creating an inital estimate withh ``min`` and ``max`` values is that it circumvents the lack of knowledge of the dynamics at this early stage of estimaton. It has been observed in unit tests that this estimate in some cases is spot on the actual gain, such as when -the disturbance is a perfect step. +the disturbance is a perfect step. + +It seems that the accuracy of this initial estimate may depend on how much the process is close to steady-state for different disturbance values, +as disturbance step produces far better gain estiamtes than if the disturbance is a steady sinus(so that the system never reaches steady-state.) Given the gain an inital UnitModel is created with a rudimentary bias and operating point ``u0``, so that the model can be simulated to give an inital ``y_mod(u)``, so that an estimate ``d_est(t)`` can be found. @@ -184,12 +187,13 @@ where there are changes in the setpoint, found as_ ``var uPidVariance = vec.Mean(vec.Abs(vec.Diff(u_pid_adjusted))).Value`` +The algorithm seems to in general give better estiamtes of the process if there are step changes in the external inputs +or in the pid-setpoint, and the algorithm appears to be able to handle both cases. - -### Estimating upper-and lower boundds on the process gain +### Estimating upper-and lower bounds on the process gain It may be that the algorithm has a better accuracy when there are setpoint changes in the dataset. It may also be that there the model will do better when there are large "wavy" disturbances than when the