pidctl

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2024 License: Apache-2.0 Imports: 3 Imported by: 1

README

PID Controller

GoDoc Go Report Card

A PIDController implementation in Go.

Credits
Initially done by Felix Geisendörfer (felix@debuggable.com) Refer to his original: https://github.com/felixge/pidctrl

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

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

func (p *Controller) Accumulate(pv *big.Rat, deltaTime time.Duration) *big.Rat

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

SetMax changes the maxium output value of the controller.

func (*ControllerFloat64) SetMin added in v1.1.0

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL