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.