vdr-plugin-softhddevice-drm-gles 1.5.9-20e15de
pidcontroller.cpp
Go to the documentation of this file.
1
18#include <cmath>
19
20#include "logger.h"
21#include "pidcontroller.h"
22
23#ifdef PID_CONTROLLER_TUNING_AID_ADDRESS
24#include <arpa/inet.h>
25#include <cstdio>
26#include <cstring>
27#include <sys/socket.h>
28#include <unistd.h>
29#endif
30
39cPidController::cPidController(double kp, double ki, double kd, double maxOutput)
40 : proportionalGain(kp),
41 integralGain(ki),
42 derivativeGain(kd),
43 maxOutput(maxOutput)
44{
45 // Calculate max integral so the I-term alone can never exceed the max output
46 if (integralGain > 0)
48 else
50}
51
59double cPidController::Update(double currentValue, double dt)
60{
61 if (dt <= 0.0)
62 return 0.0;
63
64 // Error > 0 means we are below target
65 double error = targetValue - currentValue;
66
67 pTerm = proportionalGain * error;
68
69 if (!firstRun) { // the dt value is not yet valid on the first run
70 integralSum += error * dt;
71
72 // Anti-Windup: Clamp the integrator
75
77 dTerm = derivativeGain * ((error - previousError) / dt);
78 }
79
80 double output = pTerm + iTerm + dTerm;
81
82 previousError = error;
83 firstRun = false;
84
85 output = std::min(output, maxOutput);
86 output = std::max(output, -maxOutput);
87
88 if (std::abs(output) >= maxOutput) {
89 LOGWARNING("pidcontroller: max output value exceeded. Resetting.");
90 Reset();
91 }
92#ifdef PID_CONTROLLER_TUNING_AID_ADDRESS
93 SendTuningAidData(pTerm, iTerm, dTerm, currentValue, output, targetValue);
94#endif
95
96 return output;
97}
98
103{
104 firstRun = true;
105 pTerm = 0;
106 iTerm = 0;
107 dTerm = 0;
108 integralSum = 0.0;
109 previousError = 0.0;
110}
111
112#ifdef PID_CONTROLLER_TUNING_AID_ADDRESS
124void cPidController::SendTuningAidData(double pTerm, double iTerm, double dTerm, double input, double output, double targetValue)
125{
126 static int sock = -1;
127 static struct sockaddr_in dest_addr;
128
129 // One-time setup check
130 if (sock < 0) {
131 sock = socket(AF_INET, SOCK_DGRAM, 0);
132
133 memset(&dest_addr, 0, sizeof(dest_addr));
134 dest_addr.sin_family = AF_INET;
135 dest_addr.sin_port = htons(9870); // PlotJuggler port
136 inet_pton(AF_INET, PID_CONTROLLER_TUNING_AID_ADDRESS, &dest_addr.sin_addr); // replace with your PC's IP
137 }
138
139 // Actual Payload
140 char payload[512];
141 int len = snprintf(payload, sizeof(payload),
142 "{\"bufferFillLevelMs\":%g,\"targetBufferFillLevelMs\":%g,\"pTerm\":%g,\"iTerm\":%g,\"dTerm\":%g,\"outputPpm\":%g}",
143 input, targetValue, pTerm, iTerm, dTerm, output);
144
145 // Send (Non-blocking usually, very fast)
146 sendto(sock, payload, len, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
147}
148#endif
double integralGain
Integral Gain (Ki) - Drift correction.
double targetValue
The desired buffer fill level in frames.
double integralSum
Accumulator for the I-term.
void Reset()
Resets the internal state (integral sum and error history)
double maxOutput
Hard limit for output correction.
double maxIntegral
Anti-windup limit for the integral term.
double iTerm
Integral term.
cPidController(double, double, double, double)
Constructor for the PID Controller.
double dTerm
Derivative term.
double proportionalGain
Proportional Gain (Kp) - Reaction strength.
double Update(double, double)
Calculates the new output value.
double pTerm
Proportional term.
bool firstRun
Flag for first run.
double previousError
Error from the previous step (for D-term)
double derivativeGain
Derivative Gain (Kd) - Dampening.
Logger class header file.
#define LOGWARNING
Definition logger.h:42
Proportinal, Integral, Derivative Controller.