main
syneffort 11 months ago
parent a1e7772b11
commit ee7752458d
  1. 10
      AutomaticControl/AutomaticController/PIDController.cs
  2. 10
      AutomaticControl/Simulator/ViewModels/FixedSetpointPIDViewModel.cs
  3. 53
      AutomaticControl/Simulator/ViewModels/MovingSetpointPIDViewModel.cs
  4. 2
      AutomaticControl/Simulator/Views/MovingSetpointPIDView.xaml

@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace AutomaticController namespace AutomaticController
{ {
public class PIDController : IAutomaticController public class PIDController
{ {
public double Kp { get; set; } public double Kp { get; set; }
public double Ki { get; set; } public double Ki { get; set; }
@ -25,11 +25,11 @@ namespace AutomaticController
_integralError = 0; _integralError = 0;
} }
public double Compute(double setpoint, double processVariable) public double Compute(double setpoint, double actualValue, double deltaTime = 0.01)
{ {
double error = setpoint - processVariable; double error = setpoint - actualValue;
_integralError += error; _integralError += error * deltaTime;
double derivative = error - _prevError; double derivative = (error - _prevError) / deltaTime;
double output = Kp * error + Ki * _integralError + Kd * derivative; double output = Kp * error + Ki * _integralError + Kd * derivative;

@ -34,13 +34,13 @@ namespace Simulator.ViewModels
[ObservableProperty] [ObservableProperty]
private double _kd; private double _kd;
private readonly int SIMULATION_STEP = 200;
public FixedSetpointPIDViewModel() public FixedSetpointPIDViewModel()
{ {
Kp = 0.5; Kp = 0.1;
Ki = 0.1; Ki = 0.0;
Kd = 0.2; Kd = 0.0;
SetpointModel = new FixedPIDSetpointModel() SetpointModel = new FixedPIDSetpointModel()
{ {
@ -84,7 +84,7 @@ namespace Simulator.ViewModels
InsertData(SetpointModel.Setpoint, 0d); InsertData(SetpointModel.Setpoint, 0d);
for (int i = 0; i < 100; i++) for (int i = 0; i < SIMULATION_STEP; i++)
{ {
double current = ProcessHistory.LastOrDefault(); double current = ProcessHistory.LastOrDefault();
double output = SetpointModel.Controller.Compute(SetpointModel.Setpoint, current); double output = SetpointModel.Controller.Compute(SetpointModel.Setpoint, current);

@ -20,13 +20,16 @@ namespace Simulator.ViewModels
private MovingPIDSetpointModel _setpointModel; private MovingPIDSetpointModel _setpointModel;
[ObservableProperty] [ObservableProperty]
private ObservableCollection<double> _processHistory; private ObservableCollection<double> _processHistoryCollection;
[ObservableProperty] [ObservableProperty]
private ObservableCollection<double> _setpointHistory; private ObservableCollection<double> _setpointHistoryCollection;
[ObservableProperty] [ObservableProperty]
private SeriesCollection _series; private SeriesCollection _series;
private List<double> _processHistoryList;
private List<double> _setpointHistoryList;
[ObservableProperty] [ObservableProperty]
private double _kp; private double _kp;
@ -35,14 +38,14 @@ namespace Simulator.ViewModels
[ObservableProperty] [ObservableProperty]
private double _kd; private double _kd;
private readonly int SIMULATION_COUNT = 200; private readonly int SIMULATION_STEP = 1000;
public MovingSetpointPIDViewModel() public MovingSetpointPIDViewModel()
{ {
Kp = 0.5; Kp = 0.1;
Ki = 0.1; Ki = 0.0;
Kd = 0.2; Kd = 0.0;
SetpointModel = new MovingPIDSetpointModel() SetpointModel = new MovingPIDSetpointModel()
{ {
@ -51,14 +54,17 @@ namespace Simulator.ViewModels
}; };
// Generate setpoints // Generate setpoints
for (int i = 0; i < SIMULATION_COUNT; i++) for (int i = 0; i < SIMULATION_STEP; i++)
{ {
double cos = Math.Cos(0.5 / (2 * Math.PI) * i); double cos = Math.Cos(0.5 / (2 * Math.PI) * i);
SetpointModel.Setpoints.Add(cos); SetpointModel.Setpoints.Add(cos);
} }
ProcessHistory = new ObservableCollection<double>(); _processHistoryList = new List<double>();
SetpointHistory = new ObservableCollection<double>(); _setpointHistoryList = new List<double>();
ProcessHistoryCollection = new ObservableCollection<double>();
SetpointHistoryCollection = new ObservableCollection<double>();
Series = new SeriesCollection() Series = new SeriesCollection()
{ {
new LineSeries() new LineSeries()
@ -86,30 +92,39 @@ namespace Simulator.ViewModels
SetpointModel.Controller.Ki = Ki; SetpointModel.Controller.Ki = Ki;
SetpointModel.Controller.Kd = Kd; SetpointModel.Controller.Kd = Kd;
ProcessHistory.Clear(); _processHistoryList.Clear();
SetpointHistory.Clear(); _setpointHistoryList.Clear();
Series[0].Values.Clear();
Series[1].Values.Clear();
InsertData(SetpointModel.Setpoints[0], 0d); InsertData(SetpointModel.Setpoints[0], 0d);
for (int i = 1; i < SIMULATION_COUNT; i++) for (int i = 1; i < SIMULATION_STEP; i++)
{ {
double current = ProcessHistory.LastOrDefault(); double current = _processHistoryList.LastOrDefault();
double output = SetpointModel.Controller.Compute(SetpointModel.Setpoints[i], current); double output = SetpointModel.Controller.Compute(SetpointModel.Setpoints[i], current);
double actual = current + output; double actual = current + output;
if (!double.IsNormal(SetpointModel.Setpoints[i]) || !double.IsNormal(actual))
continue;
InsertData(SetpointModel.Setpoints[i], actual); InsertData(SetpointModel.Setpoints[i], actual);
} }
Series[0].Values.Clear();
Series[1].Values.Clear();
Series[0].Values = new ChartValues<double>(_processHistoryList);
Series[1].Values = new ChartValues<double>(_setpointHistoryList);
} }
private void InsertData(double setpoint, double actual) private void InsertData(double setpoint, double actual)
{ {
Series[1].Values.Add(setpoint); if (double.IsNaN(setpoint))
Series[0].Values.Add(actual); return;
if (double.IsNaN(actual))
return;
SetpointHistory.Add(setpoint); _setpointHistoryList.Add(setpoint);
ProcessHistory.Add(actual); _processHistoryList.Add(actual);
} }
} }
} }

@ -19,7 +19,7 @@
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<lvc:CartesianChart LegendLocation="Bottom" Series="{Binding Series}"/> <lvc:CartesianChart LegendLocation="Bottom" Series="{Binding Series, Mode=OneWay}" DisableAnimations="True"/>
<StackPanel Grid.Row="1" Orientation="Horizontal"> <StackPanel Grid.Row="1" Orientation="Horizontal">
<Label Content="Kp" /> <Label Content="Kp" />
<TextBox Width="50" <TextBox Width="50"

Loading…
Cancel
Save