Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rruiter87/tccontrol
TwinCAT library for PID control and signal filtering
https://github.com/rruiter87/tccontrol
beckhoff control iir-filters industrial-automation pid-control plc twincat twincat3
Last synced: about 2 months ago
JSON representation
TwinCAT library for PID control and signal filtering
- Host: GitHub
- URL: https://github.com/rruiter87/tccontrol
- Owner: rruiter87
- License: mit
- Created: 2022-10-06T11:39:17.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-02-16T08:38:33.000Z (11 months ago)
- Last Synced: 2024-02-16T16:28:31.124Z (11 months ago)
- Topics: beckhoff, control, iir-filters, industrial-automation, pid-control, plc, twincat, twincat3
- Language: Python
- Homepage:
- Size: 1.06 MB
- Stars: 22
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# TcControl
TwinCAT library for PID control and signal filtering.
## Examples
### `Signal`
The basic unit of this library is the `Signal` function block. The most basic usage would be the following where a new value is added and can be retrieved.
```
PROGRAM MAIN
VAR
signal : Signal;
value : LREAL;
END_VARsignal.Update(value:=5); // Add new value to signal
value := signal.Out; // Retrieve the current value, in this case it would be 5
```The power of signal becomes clear when combined with `.Differentiate`
```
PROGRAM MAIN
VAR
signal : Signal;
value : LREAL;
END_VARsignal.Update(value:=1).Differentiate(deltaTime:=1);
value := signal.Update(value:=2).Differentiate(deltaTime:=1).Out; // 1
```Or `.Iir`
```
PROGRAM MAIN
VAR
signal : Signal;
value : LREAL;
END_VARsignal.Update(value:=1.4).Iir(decay:=0.5);
value := signal.Update(value:=8.6).Iir(decay:=0.5).Out; // 4.65
```Or combining both
```
PROGRAM MAIN
VAR
signal : Signal;
END_VARsignal.Update(value:=7).Differentiate(deltaTime:=1).Iir(decay:=0.5); // singal.Out = 0
signal.Update(value:=8).Differentiate(deltaTime:=1).Iir(decay:=0.5); // signal.Out = 0.5
signal.Update(value:=9).Differentiate(deltaTime:=1).Iir(decay:=0.5); // signal.Out = 0.75
```Finally the differentiated/filtered signal can be put into a controller. Currently the library only contains the simple `PidController`
```
PROGRAM MAIN
VAR
signal : Signal;
parameters : PidParameters := (Kp:=2, Ki:=0.25, Kd:=0.5);
pid : PidController;
END_VARpid(parameters:=parameters, cycleTime:=1);
signal.Controller := pid;
signal.Update(3).Control(setpoint:=4); // signal.Out = 2.75
signal.Update(3.5).Control(setpoint:=4); // signal.Out = 1.125
```See the unit tests `Singal_Tests` for more examples.
## Custom controller
You can define your own controller, as long as it implements the `IController` interface. Then you pass it to your signal instance via `signal.Controller := customController;`.
## Other function blocks
The function blocks used in `Signal` can also be used as stand-alone function blocks. The following function blocks are defined.
- `Derivative`: Take derivative of a value.
- `InfiniteImpulseResponse`: Infinite impulse response (IIR) filter.
- `Pid`: PID controller
- `Pid.DifferentialPartLimit`: Limit the differential part. Convenient when the output is calculated for the first time. The limit prevents it from having a very large value after the first call.
- `Pid.PreviousIntegralPart`: Set previous integral part on first call. Prevents integrator term for needing to build up.### `Derivative`
```
PROGRAM MAIN
VAR
derivative : Derivative;
END_VARderivative(value:=1, deltatime:=1); // derivative.Out = 0 (derivative is always 0 on the initial call)
derivative(value:=2, deltatime:=1); // derivative.Out = 1
```See `Derivative_Tests` for more examples.
### `InfiniteImpulseResponse`
```
PROGRAM MAIN
VAR
iir : InfiniteImpulseResponse;
END_VARiir(new:=5, decay:=0.95); // iir.Out = 0.25
iir(new:=5, decay:=0.95); // iir.Out = 0.4875
iir(new:=5, decay:=0.95); // iir.Out = 0.71313
```See `InfiniteImpulseResponse_Tests` for more examples.
### `PidController`
```
PROGRAM MAIN
VAR
pid : PidController;
parameters : PidParameters := (Kp:=0.1, Ki:=0, Kd:=0.01);
END_VAR// limits the difference on the initial call
pid.DifferentialPartLimit := 3;
// pass the pid parameters (only need to be done once, unless you change them)
pid(parameters:=parameters, cycleTime:=1);
// Cyclicly call Update
pid.Update(setpoint:=10, actual:=6); // pid.Out = 0.4
pid.Update(setpoint:=10, actual:=8); // pid.Out = 0.18
```