import "cirello.io/pidctl"
Package pidctl implements a proportional–integral–derivative (PID) controller using rational numbers. Refer to https://en.wikipedia.org/wiki/PID_controller.
A car whose PID controller is going to act to try to stabilize its speed to the given setpoint.
Code:
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.Accumulate(new(big.Rat).SetFloat64(speed), time.Second) 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)
type Controller struct { // P is the proportional gain P *big.Rat // I is integral gain I *big.Rat // D is the derivative gain D *big.Rat // current setpoint Setpoint *big.Rat // Min the lowest value acceptable for the Output Min *big.Rat // Max the lowest value acceptable for the Output Max *big.Rat // contains filtered or unexported fields }
Controller implements a PID controller.
Accumulate updates the controller with the given value and duration since the last update. It returns the new output.
Package pidctl imports 3 packages (graph) and is imported by 3 packages. Updated 2019-09-28. Refresh now. Tools for package owners.