-
Notifications
You must be signed in to change notification settings - Fork 6
/
controller.go
59 lines (52 loc) · 2.12 KB
/
controller.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package pid
import "time"
// Controller implements a basic PID controller.
type Controller struct {
// Config for the Controller.
Config ControllerConfig
// State of the Controller.
State ControllerState
}
// ControllerConfig contains configurable parameters for a Controller.
type ControllerConfig struct {
// ProportionalGain determines ratio of output response to error signal.
ProportionalGain float64
// IntegralGain determines previous error's affect on output.
IntegralGain float64
// DerivativeGain decreases the sensitivity to large reference changes.
DerivativeGain float64
}
// ControllerState holds mutable state for a Controller.
type ControllerState struct {
// ControlError is the difference between reference and current value.
ControlError float64
// ControlErrorIntegral is the integrated control error over time.
ControlErrorIntegral float64
// ControlErrorDerivative is the rate of change of the control error.
ControlErrorDerivative float64
// ControlSignal is the current control signal output of the controller.
ControlSignal float64
}
// ControllerInput holds the input parameters to a Controller.
type ControllerInput struct {
// ReferenceSignal is the reference value for the signal to control.
ReferenceSignal float64
// ActualSignal is the actual value of the signal to control.
ActualSignal float64
// SamplingInterval is the time interval elapsed since the previous call of the controller Update method.
SamplingInterval time.Duration
}
// Update the controller state.
func (c *Controller) Update(input ControllerInput) {
previousError := c.State.ControlError
c.State.ControlError = input.ReferenceSignal - input.ActualSignal
c.State.ControlErrorDerivative = (c.State.ControlError - previousError) / input.SamplingInterval.Seconds()
c.State.ControlErrorIntegral += c.State.ControlError * input.SamplingInterval.Seconds()
c.State.ControlSignal = c.Config.ProportionalGain*c.State.ControlError +
c.Config.IntegralGain*c.State.ControlErrorIntegral +
c.Config.DerivativeGain*c.State.ControlErrorDerivative
}
// Reset the controller state.
func (c *Controller) Reset() {
c.State = ControllerState{}
}