vdr-plugin-softhddevice-drm-gles 1.6.4-d0291bb
pidcontroller.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
10#include <cmath>
11
12#include "logger.h"
13#include "pidcontroller.h"
14
15#ifdef PID_CONTROLLER_TUNING_AID_ADDRESS
16#include <arpa/inet.h>
17#include <cstdio>
18#include <cstring>
19#include <sys/socket.h>
20#include <unistd.h>
21#endif
22
31cPidController::cPidController(double kp, double ki, double kd, double maxOutput)
32 : proportionalGain(kp),
33 integralGain(ki),
34 derivativeGain(kd),
35 maxOutput(maxOutput)
36{
37 // Calculate max integral so the I-term alone can never exceed the max output
38 if (integralGain > 0)
40 else
42}
43
52{
53 if (dt <= 0.0)
54 return 0.0;
55
56 // Error > 0 means we are below target
58
60
61 if (!firstRun) { // the dt value is not yet valid on the first run
62 integralSum += error * dt;
63
64 // Anti-Windup: Clamp the integrator
67
70 }
71
72 double output = pTerm + iTerm + dTerm;
73
75 firstRun = false;
76
77 output = std::min(output, maxOutput);
78 output = std::max(output, -maxOutput);
79
80 if (std::abs(output) >= maxOutput) {
81 LOGWARNING("pidcontroller: max output value exceeded. Resetting.");
82 Reset();
83 }
84#ifdef PID_CONTROLLER_TUNING_AID_ADDRESS
86#endif
87
88 return output;
89}
90
95{
96 firstRun = true;
97 pTerm = 0;
98 iTerm = 0;
99 dTerm = 0;
100 integralSum = 0.0;
101 previousError = 0.0;
102}
103
104#ifdef PID_CONTROLLER_TUNING_AID_ADDRESS
116void cPidController::SendTuningAidData(double pTerm, double iTerm, double dTerm, double input, double output, double targetValue)
117{
118 static int sock = -1;
119 static struct sockaddr_in dest_addr;
120
121 // One-time setup check
122 if (sock < 0) {
124
125 memset(&dest_addr, 0, sizeof(dest_addr));
126 dest_addr.sin_family = AF_INET;
127 dest_addr.sin_port = htons(9870); // PlotJuggler port
128 inet_pton(AF_INET, PID_CONTROLLER_TUNING_AID_ADDRESS, &dest_addr.sin_addr); // replace with your PC's IP
129 }
130
131 // Actual Payload
132 char payload[512];
133 int len = snprintf(payload, sizeof(payload),
134 "{\"bufferFillLevelMs\":%g,\"targetBufferFillLevelMs\":%g,\"pTerm\":%g,\"iTerm\":%g,\"dTerm\":%g,\"outputPpm\":%g}",
136
137 // Send (Non-blocking usually, very fast)
138 sendto(sock, payload, len, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
139}
140#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()
Reset 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)
Create a PID Controller.
double dTerm
Derivative term.
double proportionalGain
Proportional Gain (Kp) - Reaction strength.
double Update(double, double)
Calculate 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.
#define LOGWARNING
log to LOG_WARN
Definition logger.h:41
Logger Header File.
PID (proportional, integral, derivative) Controller Header File.