Skip to content

Commit

Permalink
- intitalize internal structs when building TimeSeriesData from csv-f…
Browse files Browse the repository at this point in the history
…ile, to avoid issues with null references in certain cases

- comment out some plots in some unit test that where inadvertenty showing.
  • Loading branch information
Steinar Elgsæter committed Dec 16, 2024
1 parent 2b658ec commit 695c709
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 76 deletions.
107 changes: 33 additions & 74 deletions TimeSeriesAnalysis.Tests/Tests/PidIdentUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,19 @@ public void SetpointStep_WNoise_KpAndTiEstimatedOk(double ySetAmplitude, double
Assert.AreEqual(idResult.GetWarnings().Count(),0);
Console.WriteLine("Kp:" + idResult.Kp.ToString("F2") + " Ti:" + idResult.Ti_s.ToString("F2"));

// Shared.EnablePlots();
string caseId = TestContext.CurrentContext.Test.Name.Replace("(", "_").
Replace(")", "_").Replace(",", "_") + "y";
Plot.FromList(new List<double[]>{ pidDataSet.Y_meas, pidDataSet.Y_setpoint,
pidDataSet.U.GetColumn(0),pidDataSet.U_sim.GetColumn(0)},
new List<string> { "y1=y meas", "y1=y set", "y3=u","y3=u_sim" },
pidDataSet.GetTimeBase(), caseId);
//Shared.DisablePlots();

if (false)
{
Shared.EnablePlots();
string caseId = TestContext.CurrentContext.Test.Name.Replace("(", "_").
Replace(")", "_").Replace(",", "_") + "y";
Plot.FromList(new List<double[]>{ pidDataSet.Y_meas, pidDataSet.Y_setpoint,
pidDataSet.U.GetColumn(0),pidDataSet.U_sim.GetColumn(0)},
new List<string> { "y1=y meas", "y1=y set", "y3=u", "y3=u_sim" },
pidDataSet.GetTimeBase(), caseId);
Shared.DisablePlots();
}


Assert.IsTrue(Math.Abs(pidParameters1.Kp - idResult.Kp)< pidParameters1.Kp * tolerancePrc / 100, "Estimated Kp:"+ idResult.Kp + "True Kp:" + pidParameters1.Kp);
if (pidParameters1.Ti_s > 0)
Expand Down Expand Up @@ -118,15 +123,17 @@ public void SetpointStep_WNoise_Downsampled_KpAndTiEstimatedOk(int downsampleFac

Assert.AreEqual(idResult.GetWarnings().Count(), 0);

// Shared.EnablePlots();
string caseId = TestContext.CurrentContext.Test.Name.Replace("(", "_").
Replace(")", "_").Replace(",", "_") + "y";
Plot.FromList(new List<double[]>{ pidDataSet.Y_meas, pidDataSet.Y_setpoint,
if (false)
{
Shared.EnablePlots();
string caseId = TestContext.CurrentContext.Test.Name.Replace("(", "_").
Replace(")", "_").Replace(",", "_") + "y";
Plot.FromList(new List<double[]>{ pidDataSet.Y_meas, pidDataSet.Y_setpoint,
pidDataSet.U.GetColumn(0),pidDataSet.U_sim.GetColumn(0)},
new List<string> { "y1=y meas", "y1=y set", "y3=u", "y3=u_sim" },
pidDataSet.GetTimeBase(), caseId);
//Shared.DisablePlots();

new List<string> { "y1=y meas", "y1=y set", "y3=u", "y3=u_sim" },
pidDataSet.GetTimeBase(), caseId);
Shared.DisablePlots();
}
Assert.IsTrue(Math.Abs(pidParameters1.Kp - idResult.Kp) < pidParameters1.Kp * tolerancePrc / 100, "Kp too far off!:" + idResult.Kp);
if (pidParameters1.Ti_s > 0)
{
Expand Down Expand Up @@ -179,56 +186,6 @@ public void DistStep_WNoise_KpAndTiEstimatedOk(double stepAmplitude, double yNoi
Assert.IsTrue(idResult.Ti_s < 1);
}
}
/*
[TestCase(0)]
[TestCase(10)]
[TestCase(50)]
public void Pcontroller_estimateU0(double u0)
{
double yNoiseAmplitude = 0.1;
double stepAmplitude = 1;
double tolerancePrc = 10;
var pidParameters1 = new PidParameters()
{
Kp = 0.5,
Ti_s = 0,
u0 = u0,
};
var pidModel1 = new PidModel(pidParameters1, "PID1");
var processSim = new PlantSimulator(
new List<ISimulatableModel> { pidModel1, processModel1 });
processSim.ConnectModels(processModel1, pidModel1);
processSim.ConnectModels(pidModel1, processModel1);
var inputData = new TimeSeriesDataSet();
inputData.Add(processSim.AddExternalSignal(pidModel1, SignalType.Setpoint_Yset), TimeSeriesCreator.Constant(50, N));
inputData.Add(processSim.AddExternalSignal(processModel1, SignalType.Disturbance_D), TimeSeriesCreator.Step(N / 2, N, 0, stepAmplitude));
inputData.CreateTimestamps(timeBase_s);
var isOk = processSim.Simulate(inputData, out TimeSeriesDataSet simData);
simData.AddNoiseToSignal("SubProcess1-Output_Y", yNoiseAmplitude);
Assert.IsTrue(isOk);
var pidDataSet = processSim.GetUnitDataSetForPID(inputData.Combine(simData), pidModel1);
var idResult = new PidIdentifier().Identify(ref pidDataSet);
Shared.EnablePlots();
string caseId = TestContext.CurrentContext.Test.Name.Replace("(", "_").
Replace(")", "_").Replace(",", "_") + "y";
Plot.FromList(new List<double[]>{ pidDataSet.Y_meas, pidDataSet.Y_setpoint,
pidDataSet.U.GetColumn(0),pidDataSet.U_sim.GetColumn(0)},
new List<string> { "y1=y meas", "y1=y set", "y3=u", "y3=u_sim" },
pidDataSet.GetTimeBase(), caseId);
Shared.DisablePlots();
Console.WriteLine("Kp:" + idResult.Kp.ToString("F2") + " Ti:" + idResult.Ti_s.ToString("F2"));
Console.WriteLine("u0:" + idResult.u0.ToString("F2"));
Assert.IsTrue(Math.Abs(pidParameters1.Kp - idResult.Kp) < pidParameters1.Kp * tolerancePrc / 100, "Kp too far off:" + idResult.Kp);
Assert.IsTrue(idResult.Ti_s < 1);
Assert.IsTrue(Math.Abs(pidParameters1.u0 - idResult.u0) < pidParameters1.u0 * tolerancePrc / 100, "u0 too far off:" + idResult.u0);
}*/

// want to see how robust PidIdentifier is when it has to find Kp and Ti on a lower sampling rate than the "actual" rate

Expand Down Expand Up @@ -269,15 +226,17 @@ public void DistStep_WNoise_Downsampled_KpAndTiEstimatedOk(int downsampleFactor,
var idResult = new PidIdentifier().Identify(ref pidDataSet);

Console.WriteLine("Kp:" + idResult.Kp.ToString("F2") + " Ti:" + idResult.Ti_s.ToString("F2"));
// Shared.EnablePlots();
string caseId = TestContext.CurrentContext.Test.Name.Replace("(", "_").
Replace(")", "_").Replace(",", "_") + "y";
Plot.FromList(new List<double[]>{ pidDataSet.Y_meas, pidDataSet.Y_setpoint,
if (false)
{
Shared.EnablePlots();
string caseId = TestContext.CurrentContext.Test.Name.Replace("(", "_").
Replace(")", "_").Replace(",", "_") + "y";
Plot.FromList(new List<double[]>{ pidDataSet.Y_meas, pidDataSet.Y_setpoint,
pidDataSet.U.GetColumn(0),pidDataSet.U_sim.GetColumn(0)},
new List<string> { "y1=y meas", "y1=y set", "y3=u", "y3=u_sim" },
pidDataSet.GetTimeBase(), caseId);
// Shared.DisablePlots();

new List<string> { "y1=y meas", "y1=y set", "y3=u", "y3=u_sim" },
pidDataSet.GetTimeBase(), caseId);
Shared.DisablePlots();
}
// asserts
Assert.IsTrue(Math.Abs(pidParameters1.Kp - idResult.Kp) < pidParameters1.Kp * tolerancePrc / 100, "Kp estimate:"+ idResult.Kp + "versus true :" + pidParameters1.Kp);
if (pidParameters1.Ti_s > 0)
Expand Down
3 changes: 2 additions & 1 deletion TimeSeriesAnalysis.Tests/Tests/PlantSimulatorSISOTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ public void BasicPID_SimulateJustPID_sameresult()

var isOK = plantSim.SimulateSingle(newSet, pidModel1.ID,out TimeSeriesDataSet simData2);

if (false)
if (true)
{
Shared.EnablePlots();
Plot.FromList(new List<double[]> {
Expand All @@ -503,6 +503,7 @@ public void BasicPID_SimulateJustPID_sameresult()
}
double firstYsimE = Math.Abs(simData2.GetValues(pidModel1.GetID(), SignalType.PID_U).First() - simData.GetValues(pidModel1.GetID(), SignalType.PID_U).First());
double lastYsimE = Math.Abs(simData2.GetValues(pidModel1.GetID(), SignalType.PID_U).Last() - simData.GetValues(pidModel1.GetID(), SignalType.PID_U).Last());

Assert.IsTrue(isOk);
Assert.IsTrue(firstYsimE < 0.01, "System should start in steady-state");
Assert.IsTrue(lastYsimE < 0.01, "PID should bring system to setpoint after disturbance");
Expand Down
5 changes: 4 additions & 1 deletion TimeSeriesAnalysis/TimeSeriesDataSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public TimeSeriesDataSet()
dataset = new Dictionary<string, double[]>();
dataset_constants = new Dictionary<string, double>();
indicesToIgnore = null;
//didSimulationReturnOk = false;
}
/// <summary>
/// Constructor that copies another dataset into the returned object
Expand Down Expand Up @@ -69,6 +68,8 @@ public TimeSeriesDataSet(TimeSeriesDataSet inputDataSet)
/// <param name="dateTimeFormat">the format of date-time strings in the csv-file</param>
public TimeSeriesDataSet(CsvContent csvContent, char separator = ';', string dateTimeFormat = "yyyy-MM-dd HH:mm:ss")
{
dataset = new Dictionary<string, double[]>();
dataset_constants = new Dictionary<string, double>();
LoadFromCsv(csvContent, separator, dateTimeFormat);
}

Expand All @@ -80,6 +81,8 @@ public TimeSeriesDataSet(TimeSeriesDataSet inputDataSet)
/// <param name="dateTimeFormat">the format of date-time strings in the csv-file</param>
public TimeSeriesDataSet(string csvFileName, char separator = ';', string dateTimeFormat = "yyyy-MM-dd HH:mm:ss")
{
dataset = new Dictionary<string, double[]>();
dataset_constants = new Dictionary<string, double>();
LoadFromCsv(csvFileName, separator, dateTimeFormat);
}

Expand Down

0 comments on commit 695c709

Please sign in to comment.