diff --git a/source/getting-started/control-with-amdc/index.md b/source/getting-started/control-with-amdc/index.md index c7b5d929..b0f838db 100644 --- a/source/getting-started/control-with-amdc/index.md +++ b/source/getting-started/control-with-amdc/index.md @@ -1,13 +1,15 @@ # Control with AMDC -The AMDC Platform provides a versatile and open foundation for establishing high performance motor controls. This section of the documentation explains how to use the AMDC's capabilties to implement standard motor control functionality. +The AMDC Platform provides a versatile and open foundation for establishing high performance motor controls. This section of the documentation explains how to use the AMDC's capabilities to implement standard motor control functionality. | Control Topic | Aim / Goal / Outcome | |---|---| | [Current Sensor Calibration](current-sensor-cal/index.md) | Approach and tools to calibrate current sensor gain and offset. | +| [Integrator Anti-Windup](integrator-anti-windup/index.md) | Anti-Windup performance evaluation. | ```{toctree} :hidden: Current Sensor Calibration +Integrator Anti-Windup ``` diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/.gitignore b/source/getting-started/control-with-amdc/integrator-anti-windup/.gitignore new file mode 100644 index 00000000..05bf92ae --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/.gitignore @@ -0,0 +1,2 @@ +slprj/ +*slxc \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-advanced-better.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-advanced-better.svg new file mode 100644 index 00000000..5fd3febb --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-advanced-better.svg @@ -0,0 +1,109 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-advanced-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-advanced-c.svg new file mode 100644 index 00000000..8b5d8ab4 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-advanced-c.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-back-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-back-c.svg new file mode 100644 index 00000000..a530072f --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-back-c.svg @@ -0,0 +1,404 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-sat-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-sat-c.svg new file mode 100644 index 00000000..05ab0663 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-sat-c.svg @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-simple-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-simple-c.svg new file mode 100644 index 00000000..71d95b93 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/Iout-simple-c.svg @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/anti-windup-advanced-clamping.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/anti-windup-advanced-clamping.svg new file mode 100644 index 00000000..ac92190e --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/anti-windup-advanced-clamping.svg @@ -0,0 +1,4105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + And Gate + + + + + + image/svg+xmlTRIout0preSatSignSignErrorpostSatNotEqualEqualAND > 0 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/anti-windup-back-tracking.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/anti-windup-back-tracking.svg new file mode 100644 index 00000000..24f0f961 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/anti-windup-back-tracking.svg @@ -0,0 +1,1431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xmlpreSatErrorpostSatTRIout + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/anti-windup-simple-clamping.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/anti-windup-simple-clamping.svg new file mode 100644 index 00000000..f5ce0446 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/anti-windup-simple-clamping.svg @@ -0,0 +1,3800 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + And Gate + + + + + + + + + image/svg+xmlTRIout0preSatErrorpostSatNotEqual > 0 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/control-diagram-overview.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/control-diagram-overview.svg new file mode 100644 index 00000000..9499aa25 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/control-diagram-overview.svg @@ -0,0 +1,1623 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xmlReferenceErrorSaturationPlantIntegratorwith anti-winduppreSatIoutpostSat + + + + + + + + + + + + + + + + + + + + + + + + + + +DisturbanceOutput + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/control-diagram-sat.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/control-diagram-sat.svg new file mode 100644 index 00000000..fe8a02f8 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/control-diagram-sat.svg @@ -0,0 +1,1025 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xmlControllerReferenceErrorOutputSaturationpreSatPlant + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +postSatDisturbance diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/disturbance-advanced-better.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/disturbance-advanced-better.svg new file mode 100644 index 00000000..351e80eb --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/disturbance-advanced-better.svg @@ -0,0 +1,112 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/disturbance.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/disturbance.svg new file mode 100644 index 00000000..f8bf6acf --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/disturbance.svg @@ -0,0 +1,112 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/error-advanced-better.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/error-advanced-better.svg new file mode 100644 index 00000000..82dc29ec --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/error-advanced-better.svg @@ -0,0 +1,110 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-advanced-better.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-advanced-better.svg new file mode 100644 index 00000000..37c8e650 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-advanced-better.svg @@ -0,0 +1,192 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-advanced-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-advanced-c.svg new file mode 100644 index 00000000..8bf84a1c --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-advanced-c.svg @@ -0,0 +1,192 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-back-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-back-c.svg new file mode 100644 index 00000000..504ace62 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-back-c.svg @@ -0,0 +1,215 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-back-d.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-back-d.svg new file mode 100644 index 00000000..71319b57 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-back-d.svg @@ -0,0 +1,219 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-sat-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-sat-c.svg new file mode 100644 index 00000000..661af16b --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-sat-c.svg @@ -0,0 +1,180 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-sat-d.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-sat-d.svg new file mode 100644 index 00000000..ff54b108 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-sat-d.svg @@ -0,0 +1,184 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-simple-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-simple-c.svg new file mode 100644 index 00000000..b6df620c --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-simple-c.svg @@ -0,0 +1,166 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-simple-d.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-simple-d.svg new file mode 100644 index 00000000..7a301e87 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/output-simple-d.svg @@ -0,0 +1,170 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/postSat-advanced-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/postSat-advanced-c.svg new file mode 100644 index 00000000..6c1d990c --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/postSat-advanced-c.svg @@ -0,0 +1,416 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/postSat-back-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/postSat-back-c.svg new file mode 100644 index 00000000..eb3f080a --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/postSat-back-c.svg @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/postSat-simple-c.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/postSat-simple-c.svg new file mode 100644 index 00000000..4760a8ef --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/postSat-simple-c.svg @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/preSat-advanced-better.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/preSat-advanced-better.svg new file mode 100644 index 00000000..91732e03 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/preSat-advanced-better.svg @@ -0,0 +1,111 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/images/preSat-postSat.svg b/source/getting-started/control-with-amdc/integrator-anti-windup/images/preSat-postSat.svg new file mode 100644 index 00000000..889352c9 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/images/preSat-postSat.svg @@ -0,0 +1,156 @@ + + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/index.md b/source/getting-started/control-with-amdc/integrator-anti-windup/index.md new file mode 100644 index 00000000..1fe7ebb5 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/index.md @@ -0,0 +1,264 @@ +# Integrator Anti-Windup + +This article describes how to evaluate performance of anti-windup. A windup might occur when the controller with an integrator faces limitations on the manipulated variables, leading to degraded system response and stability. + +The effectiveness of an anti-windup strategy depends on both the duration and the extent of saturation of the windup. Since perfect anti-windup is unachievable, it is crucial to simulate realistic windup and anti-windup behaviors to examine specific scenarios that are likely to occur in practice. To help readers understand this, an example of Simulink model (available [here](../integrator-anti-windup/simulink/)) is provided in this article to demonstrate how such scenario can be simulated and how the anti-windup strategy can address them. + +## Exploring Windup Phenomena in Integrators + +### Block Diagram with Saturation + +Generally, the primary components of a control diagram are the controller and plant. The controller provides a manipulated variable to actuate the plant model. However, in practice, manipulated variables are limited by the actuator’s capability. The figure below illustrates a practical block diagram considering the `Saturation` block, demonstrating the physical limitations of the actuator input. + +```{image} images/control-diagram-sat.svg + :align: center +``` + +In this example, a simple plant model of 1/(s+1) is employed, with the saturation block located before the plant. Note the saturation block produces an output signal bounded to the upper saturation value of `+Limit` and lower saturation value of `-Limit`. This system can be interpreted from following examples: + +1. Current regulation: + - Plant input: Voltage command + - Plant output: Current + - Physical limitation: The realistic command voltage to the plant is restricted by the capability of the DC power supply + +2. Speed control: + - Plant input: $q$-axis current command + - Output: Rotational speed of the electric machinery + - Physical limitation: The practical command current to the plant is limited by the coil current density. + +3. Temperature control: + - Plant input: Heat + - Output: Resulting system temperature + - Physical limitation: The heater’s power rating (e.g., 1 kW) limits the actuator. + +In this example, the PI controller is employed to achieve the desired system response. The PI gains are set to achieve the first response with a bandwidth of 10 Hz, i.e., $K_\text{p} = 2\pi \times 10$, and $K_\text{i} = 2\pi \times 10$. + +### Technical Challenges on Windup + +This section provides the practical challenges from the actuator’s input limitations, especially on the command tracking and disturbance suppression, and introduces the definition of an integral windup. + +#### Command Tracking without/with Actuator Limitations + +Let us analyze the simulation result with the block diagram above to investigate the technical challenges of windup. The objective of this analysis is to evaluate the impact of the saturation block on the output performance. The simulation results are shown below, where two scenarios are compared: one “without saturation block (red line)” and one “with the saturation block (blue line)”. Assume a step command of 1 is generated as a reference at 0.2 seconds and the plant has a known input saturation limit defined as `Limit = 10`. + +```{image} images/Output-sat-c.svg + :align: center + :width: 600 +``` + +```{image} images/Iout-sat-c.svg + :align: center + :width: 600 +``` + +As observed in the top figure, the command tracks correctly when no saturation block is present, whereas overshoot occurs when the saturation block is included. The bottom figure illustrates the output of the integrator `Iout`. With the saturated block, `Iout` becomes larger than that without the saturation block. + +Let us examine why this phenomenon occurs by analyzing the manipulated variable before and after the saturation block. + +```{image} images/preSat-postSat.svg + :align: center + :width: 600 +``` + +In the previous saturation block (`preSat`), the manipulated variable instantaneously exceeds 60, which is beyond the saturation range of 10. In contrast, the voltage reference in the post saturation block (`postSat`) is limited to 10. As demonstrated in this example, the controller disregards the presence of the saturation block because it has no information about real-world saturation. Consequently, the PI controller continue to increase the manipulated variable after getting the larger error. If this error is continuously accumulated, the system exhibits delayed convergence, a condition known as an integral windup. + +#### Disturbance Suppression without/with Actuator Limitations + +Disturbances can degrade the system by introducing unexpected/rapid changes. Let us examine whether disturbances affect the behavior of the integrator. In this scenario, the command is set as 0, and the disturbance of 15 (i.e., higher value than `Limit = 10`) is injected at 0.2 seconds and ends at 0.3 seconds, requiring the disturbance to be suppressed and the output to track back to 0. + +```{image} images/Disturbance.svg + :align: center + :width: 600 +``` + +```{image} images/output-sat-d.svg + :align: center + :width: 600 +``` + +In the transient response of `Output` when the disturbance ends, it is observed that with the saturation block, there is a larger negative overshoot and slower convergence to 0 compared to the case without the saturation block. This is because the integrator continues to integrate error caused by the disturbance. + +## Anti-Windup Techniques + +To avoid the integral windup, the mitigation strategy known as the anti-windup strategy is now introduced. The block diagram incorporating an integrator with the anti-windup is shown in the figure below. + +```{image} images/control-diagram-overview.svg + :align: center +``` + +In the anti-windup methods, if the manipulated variable reaches the specified `Limit`, the integrator is to keep the integrated value from increasing past the specified limit. There are multiple ways to implement integrator anti-windup, however, two common methods are introduced in this article: + +1. [**Clamping**](#clamping): Turn off the integrator to stop further accumulation of the value. This can be divided into two methods, i.e., [simple clamping](#simple-clamping) and [advanced clamping](#advanced-clamping). + +2. [**Back-tracking**](#back-tracking): Subtract a specific value from the integrator. + +These two methods are now explained in detail. + +### Clamping + +Clamping is a straightforward anti-windup strategy where the integrator is simply "clamped" to prevent it from exceeding a certain limitation, which is called simple clamping in this article. Advanced clamping, on the other hand, is a more sophisticated from simple clamping that engages only under specific conditions. + +### Simple Clamping + +The simple version of clamping simply stops integrating when `preSat` $\neq$ `postSat`. The block diagram of the integrator with the simple clamping method is shown below. + +```{image} images/anti-windup-simple-clamping.svg + :align: center + :width: 70% +``` + +Here is a Simulink simulation of the no anti-windup and simple clamping. + +#### Command Tracking + +```{image} images/output-simple-c.svg + :align: center + :width: 600 +``` + +```{image} images/postSat-simple-c.svg + :align: center + :width: 600 +``` + +```{image} images/Iout-simple-c.svg + :align: center + :width: 600 +``` + +In the `Output` waveforms, an overshoot is observed when there is no anti-windup. However, with the simple clamping method, the overshoot is eliminated. In the `postSat`, the manipulated variables are saturated up to 10, where the manipulated variable converge more rapidly in the simple clamping. In the integrator output, no overshoots are present when using simple clamping. + +#### Disturbance Suppression + +```{image} images/Disturbance.svg + :align: center + :width: 600 +``` + +```{image} images/output-simple-d.svg + :align: center + :width: 600 +``` + +From the disturbance suppression simulation results, it is evident that the overshoot and convergence are significantly improved when the simple clamping method is employed. + +### Advanced Clamping + +Now, the advanced version of clamping is introduced as shown below the block diagram. + +```{image} images/anti-windup-advanced-clamping.svg + :align: center + :width: 70% +``` + +In the advanced clamping method, the behavior itself is essentially similar to that of simple clamping. However, it includes an additional condition as a trigger of anti-windup, i.e., clamping occurs only when the signs of the `Error` and `preSat` are the same. Here is the workflow of the advanced clamping: + +**Step 1.** Compare the `preSat` and `postSat`. If these values are not equal, i.e., the manipulated variable reaches saturation, the block outputs 1. If they are equal, then no saturation takes place, and the block outputs 0 -- this is the same purpose of the simple clamping. + +**Step 2.** Compare the sign of the `preSat` and the `Error`. And then, if both signs are equal, the block outputs 1. If not, the block outputs 0 -- this is the additional condition necessary for advanced clamping. + +**Step 3.** The anti-windup output denoted as tracking-signal `TR` becomes 1 to clamp the integrator only if both outputs of **Step 1.** and **Step 2.** are 1. In other words, the integrator clamps integration if the output is saturating AND the `Error` is the same sign as the `preSat`. + +If the `TR` is 1, the input of the integrator becomes 0 as the switch is triggered, i.e., the integrator will effectively shut down the integration during the windup condition. + +Here is a Simulink simulation of the no anti-windup, simple clamping, and advanced clamping. + +```{image} images/output-advanced-c.svg + :align: center + :width: 600 +``` + +```{image} images/postSat-advanced-c.svg + :align: center + :width: 600 +``` + +```{image} images/Iout-advanced-c.svg + :align: center + :width: 600 +``` + +Notice that the above assumptions cause the simple and advanced clamping to behave identical in this example. + +Based on this, a highly specific scenario is now introduced where advanced clamping demonstrates better performance. Here is simulation scenario to demonstrate the superiority of advanced clamping than simple clamping: + +1. A `Disturbance` with amplitude of 3 is applied at 0.5 seconds, causing the system to saturate. +2. Once the `Output` has stabilized at 0, a positive reference of 1 is commanded at 5 seconds. + +Here are simulation results based on the above scenarios: + +```{image} images/disturbance-advanced-better.svg + :align: center + :width: 600 +``` + +```{image} images/output-advanced-better.svg + :align: center + :width: 600 +``` + +```{image} images/error-advanced-better.svg + :align: center + :width: 600 +``` + +```{image} images/preSat-advanced-better.svg + :align: center + :width: 600 +``` + +As indicated in `Output` plot, the advanced clamping performs better, whereas the simple clamping can no longer track the reference. Interestingly, the simple clamping can be even worse than having no anti-windup in this example. _However_, this can be observed only if the proportional gain of $K_\text{p}$ is very small ($= 0.0001 \times 2\pi \times 10$ in this case). + +Significant differences in the advanced clamping only appear when the system saturates **AND** signs are different from error vs control output, which is uncommon since the difference in signs usually moves out immediately. In this example, the `Error` suddenly becomes positive at 5 seconds, while the `preSat` remains negative due to low P gain. This brakes the equal sign condition (i.e., `Error` does not have the same sign as the `preSat`) and unclamps the integrator. Because setting a significantly low P gain is generally undesirable, this suggests that the additional effort to implement the advanced clamping is probably not worth for the typical motor control systems. + +### Back-tracking + +The idea of back-tracking method is to use a feedback loop to unwind the internal integrator when the manipulated variable hits the `Limit`. The block diagram of the integrator with the back-tracking method is shown below. + +```{image} images/anti-windup-back-tracking.svg + :align: center + :width: 70% +``` + +For example, if saturation occurs, `TR` is calculated as `TR = Kb(postSat-preSat)` and added into the integrator to avoid the windup, where $K_\text{b}$ is a feedback gain of the back-tracking. In contrast, if the saturation does not occur, `preSat` and `postSat` must be equal, and `TR` is 0, i.e., the anti-windup is deactivated. + +```{tip} +The selection of $K_\text{b}$ is highly nuanced upon the specific event being managed. Making an incorrect choice for $K_\text{b}$ can lead to the clamping method better. In practice, the feedback gain of $K_\text{b}$ is determined by trial and error, depending on the user’s requirements, such as the allowable overshoot and desired response speed. There is a paper that shows an example of how to determine the $K_\text{b}$ known as a `conditioned PI controller`. In this literature, the $K_\text{b}$ is determined as $K_\text{b} = K_\text{i}/K_\text{p}$. For detailed information, refer to [this paper](https://www.sciencedirect.com/science/article/pii/000510988790029X). +``` + +Here is a Simulink simulation of the no anti-windup, simple clamping, advanced clamping, and back-tracking. + +#### Command Tracking + +```{image} images/postSat-back-c.svg + :align: center + :width: 600 +``` + +```{image} images/Output-back-c.svg + :align: center + :width: 600 +``` + +```{image} images/Iout-back-c.svg + :align: center + :width: 600 +``` + +From the `Output` waveform, it is evident that the back-tracking technique marginally improves its response than clamping. + +#### Disturbance Suppression + +```{image} images/Disturbance.svg + :align: center + :width: 600 +``` + +```{image} images/output-back-d.svg + :align: center + :width: 600 +``` + +The disturbance suppression results demonstrate that both the clamping and the back-tracking methods improved the performance. Interestingly, the clamping methods is better to suppress disturbance than the back-tracking in this example. It should be noted that these results were achieved using the back-tracking gain of $K_\text{b} = K_\text{i}/K_\text{p}$, which might be required to adjust based on the specific condition and simulation outcomes. + + diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/simulink/main.m b/source/getting-started/control-with-amdc/integrator-anti-windup/simulink/main.m new file mode 100644 index 00000000..d01ead02 --- /dev/null +++ b/source/getting-started/control-with-amdc/integrator-anti-windup/simulink/main.m @@ -0,0 +1,103 @@ +clc +clear +close all + +%% Set simulation parameters +Tsim = 1e-5; % Simulation sampling time [s] +Tend = 1; % Simulation end time [s] + +ref = 1; % Reference +start = 0.2; % Reference start time [s] +stop = 1.5; % Reference end time [s] + +d_ref = 0; % Disturbance +d_start = 0.2; % Disturbance start time [s] +d_stop = 0.3; % Disturbance end time [s] + +upper_limit = 10; % Upper limit +lower_limit = -10; % Lower limit + +%% Set controller parameters +fb = 10; % Controller bandwidth [Hz] +wb = 2*pi*fb; % Controller bandwidth [rad/s] + +Kp = wb; % P gain +Ki = wb; % I gain + +Kb = Ki/Kp; % Back-calculation coefficient + +% Select anti-windup methods that you want to simulate +sim_scenario = ["No anti-windup","Simple clamping","Advanced clamping","Back-tracking"]; +num_sim_scenario = length(sim_scenario); + +% List of variables to extract from Simulink +interested_signals = {'time','Reference','Output','Error','Iout','preSat','postSat','Disturbance'}; + +% Preallocate the cell array to store results +results = cell(round(Tend/Tsim+1), length(interested_signals)); + +%% Implement each simulation scenario +for i = 1:num_sim_scenario + switch sim_scenario(i) + case "No anti-windup" + Clamping_enable = 0; Advanced_clamping_enable = 0; Back_tracking_enable = 0; + case "Simple clamping" + Clamping_enable = 1; Advanced_clamping_enable = 0; Back_tracking_enable = 0; + case "Advanced clamping" + Clamping_enable = 1; Advanced_clamping_enable = 1; Back_tracking_enable = 0; + case "Back-tracking" + Clamping_enable = 0; Advanced_clamping_enable = 0; Back_tracking_enable = 1; + end + + % Run simulation + out = sim('simpleModel'); + + % Extract simulation data + runObj = Simulink.sdi.Run.getLatest; + + % Get signal IDs and store signals into array + for idx = 2:length(interested_signals) + sigID = getSignalIDsByName(runObj,interested_signals{idx}); + sig_obj.(interested_signals{idx}) = Simulink.sdi.getSignal(sigID); + sig_val.(interested_signals{idx}) = sig_obj.(interested_signals{idx}).Values.Data; + end + + % Store simulation results + time = sig_obj.(interested_signals{2}).Values.Time; + results{i} = [time,sig_val.Reference,sig_val.Output,sig_val.Error, ... + sig_val.Iout,sig_val.preSat,sig_val.postSat,sig_val.Disturbance]; +end + +%% Plot figures +% Define figure size +width = 5.43; height = 4.38/3; +set(0,'units','inches') +Inch_SS = get(0,'screensize'); + +% Define plot line parameters +lw = 1; colors = {'r', 'b', 'c', 'g'}; lineStyles = {'-', '-', '--', '-'}; + +% Plot figures +for j = 3:length(interested_signals) + figure + hold on + if j == 3 % This is special handling for 'Output' plot with 'Command' + plot(results{1}(:, 1),results{1}(:, 2),'color','k','Linewidth',lw); + for i = 1:num_sim_scenario + plot(results{i}(:, 1), results{i}(:, j), ... + 'color',colors{i},'LineStyle',lineStyles{i},'Linewidth',lw); + end + legend(['Command', sim_scenario],'Interpreter','latex','Location','east'); + else + for i = 1:num_sim_scenario + plot(results{i}(:, 1),results{i}(:, j), ... + 'color',colors{i},'LineStyle',lineStyles{i},'Linewidth',lw); + end + legend(sim_scenario,'Interpreter','latex','Location','east'); + end + xlabel('Time [s]','Interpreter','latex'); + ylabel(interested_signals{j},'Interpreter','latex'); + xlim([0 Tend]); + set(gcf,'Units','inches','Position',[(Inch_SS(3)-width)/2,(Inch_SS(4)-height)/2,width,height]); + print('-dsvg','-noui',['../images/' interested_signals{j}]); +end diff --git a/source/getting-started/control-with-amdc/integrator-anti-windup/simulink/simpleModel.slx b/source/getting-started/control-with-amdc/integrator-anti-windup/simulink/simpleModel.slx new file mode 100644 index 00000000..8bf1ae92 Binary files /dev/null and b/source/getting-started/control-with-amdc/integrator-anti-windup/simulink/simpleModel.slx differ