Documentation
¶
Overview ¶
Package pidctl implements a proportional–integral–derivative (PID) controller using rational numbers. Refer to https://en.wikipedia.org/wiki/PID_controller.
Example ¶
A car whose PID controller is going to act to try to stabilize its speed to the given setpoint.
package main
import (
"fmt"
"math"
"math/big"
"time"
"cirello.io/pidctl"
)
func main() {
car := pidctl.Controller{
P: big.NewRat(1, 5),
I: big.NewRat(1, 100),
D: big.NewRat(1, 15),
Min: big.NewRat(-1, 2), // min acceleration rate: 0.5 mps
Max: big.NewRat(10, 2), // max acceleration rate: 5 mps
Setpoint: big.NewRat(60, 1), // target speed: 60 mph
}
speed := float64(20) // the car starts in motion. 20mph
const travel = 15 * time.Second
for i := time.Second; i <= travel; i += time.Second {
desiredThrottle := car.Compute(new(big.Rat).SetFloat64(speed))
actualThrottle, _ := desiredThrottle.Float64()
actualThrottle = math.Ceil(actualThrottle)
fmt.Printf("%s speed: %.2f throttle: %.2f (desired: %s)\n", i, speed, actualThrottle, desiredThrottle.FloatString(2))
speed += actualThrottle
switch i % 5 {
case 0:
// head wind starts strong: 2mps
speed -= 2
case 1:
// head wind ends weak: 1mps
speed -= 1
}
}
}
Output: 1s speed: 20.00 throttle: 5.00 (desired: 5.00) 2s speed: 23.00 throttle: 5.00 (desired: 5.00) 3s speed: 26.00 throttle: 5.00 (desired: 5.00) 4s speed: 29.00 throttle: 5.00 (desired: 5.00) 5s speed: 32.00 throttle: 5.00 (desired: 5.00) 6s speed: 35.00 throttle: 5.00 (desired: 5.00) 7s speed: 38.00 throttle: 5.00 (desired: 5.00) 8s speed: 41.00 throttle: 5.00 (desired: 5.00) 9s speed: 44.00 throttle: 5.00 (desired: 5.00) 10s speed: 47.00 throttle: 5.00 (desired: 5.00) 11s speed: 50.00 throttle: 5.00 (desired: 4.55) 12s speed: 53.00 throttle: 5.00 (desired: 4.02) 13s speed: 56.00 throttle: 4.00 (desired: 3.46) 14s speed: 58.00 throttle: 4.00 (desired: 3.15) 15s speed: 60.00 throttle: 3.00 (desired: 2.75)
Example (Float64) ¶
A car whose PID controller is going to act to try to stabilize its speed to the given setpoint (float64 version).
package main
import (
"fmt"
"math"
"time"
"cirello.io/pidctl"
)
func main() {
car := pidctl.NewControllerFloat64(
1.0/5, 1.0/100, 1.0/15,
60). // target speed: 60 mph
SetMin(-0.5). // min acceleration rate: 0.5 mps
SetMax(5) // max acceleration rate: 5 mps
speed := float64(20) // the car starts in motion. 20mph
const travel = 15 * time.Second
for i := time.Second; i <= travel; i += time.Second {
desiredThrottle := car.Compute(speed)
actualThrottle := math.Ceil(desiredThrottle)
fmt.Printf("%s speed: %.2f throttle: %.2f (desired: %.2f)\n", i, speed, actualThrottle, desiredThrottle)
speed += actualThrottle
switch i % 5 {
case 0:
// head wind starts strong: 2mps
speed -= 2
case 1:
// head wind ends weak: 1mps
speed -= 1
}
}
}
Output: 1s speed: 20.00 throttle: 5.00 (desired: 5.00) 2s speed: 23.00 throttle: 5.00 (desired: 5.00) 3s speed: 26.00 throttle: 5.00 (desired: 5.00) 4s speed: 29.00 throttle: 5.00 (desired: 5.00) 5s speed: 32.00 throttle: 5.00 (desired: 5.00) 6s speed: 35.00 throttle: 5.00 (desired: 5.00) 7s speed: 38.00 throttle: 5.00 (desired: 5.00) 8s speed: 41.00 throttle: 5.00 (desired: 5.00) 9s speed: 44.00 throttle: 5.00 (desired: 5.00) 10s speed: 47.00 throttle: 5.00 (desired: 5.00) 11s speed: 50.00 throttle: 5.00 (desired: 4.55) 12s speed: 53.00 throttle: 5.00 (desired: 4.02) 13s speed: 56.00 throttle: 4.00 (desired: 3.46) 14s speed: 58.00 throttle: 4.00 (desired: 3.15) 15s speed: 60.00 throttle: 3.00 (desired: 2.75)
Index ¶
- type Controller
- type ControllerFloat64
- func (c *ControllerFloat64) Accumulate(pv float64, deltaTime time.Duration) float64
- func (c *ControllerFloat64) Compute(pv float64) float64
- func (c *ControllerFloat64) SetMax(max float64) *ControllerFloat64
- func (c *ControllerFloat64) SetMin(min float64) *ControllerFloat64
- func (c *ControllerFloat64) SetSetpoint(setpoint float64) *ControllerFloat64
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Controller ¶
type Controller struct {
// P is the proportional gain
P *big.Rat
// I is integral reset
I *big.Rat
// D is the derivative term
D *big.Rat
// Setpoint is the chased target
Setpoint *big.Rat
// Min the lowest value acceptable for the Output
Min *big.Rat
// Max the highest value acceptable for the Output
Max *big.Rat
// contains filtered or unexported fields
}
Controller implements a PID controller.
func (*Controller) Accumulate ¶
Accumulate updates the controller with the given process value and duration since the last update. It returns the new output that should be used by the device to reach the desired set point.
func (*Controller) Compute ¶
func (p *Controller) Compute(pv *big.Rat) *big.Rat
Compute updates the controller with the given process value since the last update. It returns the new output that should be used by the device to reach the desired set point. Internally it assumes the duration between calls is constant.
type ControllerFloat64 ¶ added in v1.1.0
type ControllerFloat64 struct {
// contains filtered or unexported fields
}
ControllerFloat64 implements a PID controller using float64 for inputs and outputs.
func NewControllerFloat64 ¶ added in v1.1.0
func NewControllerFloat64(p, i, d, setpoint float64) *ControllerFloat64
NewControllerFloat64 creates a new PID controller using float64 for inputs and outputs.
func (*ControllerFloat64) Accumulate ¶ added in v1.1.0
func (c *ControllerFloat64) Accumulate(pv float64, deltaTime time.Duration) float64
Accumulate updates the controller with the given process value and duration since the last update. It returns the new output that should be used by the device to reach the desired set point.
func (*ControllerFloat64) Compute ¶ added in v1.1.0
func (c *ControllerFloat64) Compute(pv float64) float64
Compute updates the controller with the given process value since the last update. It returns the new output that should be used by the device to reach the desired set point. Internally it assumes the duration between calls is constant.
func (*ControllerFloat64) SetMax ¶ added in v1.1.0
func (c *ControllerFloat64) SetMax(max float64) *ControllerFloat64
SetMax changes the maxium output value of the controller.
func (*ControllerFloat64) SetMin ¶ added in v1.1.0
func (c *ControllerFloat64) SetMin(min float64) *ControllerFloat64
SetMin changes the minimum output value of the controller.
func (*ControllerFloat64) SetSetpoint ¶ added in v1.1.0
func (c *ControllerFloat64) SetSetpoint(setpoint float64) *ControllerFloat64
SetSetpoint changes the desired setpoint of the controller.
Source Files
¶
- controller.go
- controller_float64.go
- doc.go