Skip to content

Commit 1cad84d

Browse files
author
Divyansh Agrawal
committed
Added the Active Disturbance Rejection Control (ADRC) Algorithm
1 parent 74b540a commit 1cad84d

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

Diff for: control_algorithms/adrc.py

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
Active Disturbance Rejection Control (ADRC) is a robust control strategy
3+
that estimates and compensates for disturbances in real-time without needing
4+
an explicit mathematical model of the system.
5+
6+
It consists of:
7+
1. Tracking Differentiator (TD) - Smooths the reference signal
8+
2. Extended State Observer (ESO) - Estimates system states and disturbances
9+
3. Nonlinear State Error Feedback (NLSEF) - Generates the control signal
10+
11+
Refer - https://en.wikipedia.org/wiki/Active_disturbance_rejection_control
12+
"""
13+
14+
15+
class ADRC:
16+
def __init__(self, beta1: float, beta2: float, beta3: float, setpoint: float = 0.0):
17+
"""
18+
Initialize the ADRC controller.
19+
20+
:param beta1: Gain for error correction in ESO
21+
:param beta2: Gain for disturbance estimation in ESO
22+
:param beta3: Gain for acceleration estimation in ESO
23+
:param setpoint: Desired target value
24+
"""
25+
self.beta1 = beta1
26+
self.beta2 = beta2
27+
self.beta3 = beta3
28+
self.setpoint = setpoint
29+
30+
self.z1 = 0.0 # Estimated system output
31+
self.z2 = 0.0 # Estimated system velocity
32+
self.z3 = 0.0 # Estimated total disturbance
33+
34+
def compute(self, measured_value: float, dt: float) -> float:
35+
"""
36+
Compute the control signal based on error estimation and disturbance rejection.
37+
38+
:param measured_value: The current process variable
39+
:param dt: Time difference since the last update
40+
:return: Control output
41+
"""
42+
error = self.setpoint - measured_value
43+
44+
# Extended State Observer (ESO) Update
45+
self.z1 += dt * (self.z2 - self.beta1 * (self.z1 - measured_value))
46+
self.z2 += dt * (self.z3 - self.beta2 * (self.z1 - measured_value))
47+
self.z3 -= self.beta3 * (self.z1 - measured_value)
48+
49+
# Control Law (Nonlinear State Error Feedback - NLSEF)
50+
control_output = self.z2 - self.z3
51+
return control_output
52+
53+
def reset(self):
54+
"""Reset the estimated states."""
55+
self.z1 = 0.0
56+
self.z2 = 0.0
57+
self.z3 = 0.0
58+
59+
60+
if __name__ == "__main__":
61+
import doctest
62+
doctest.testmod()
63+
64+

0 commit comments

Comments
 (0)