presets.go raw

   1  package pid
   2  
   3  import (
   4  	pidif "next.orly.dev/pkg/interfaces/pid"
   5  )
   6  
   7  // Presets for common PID controller use cases.
   8  // These provide good starting points that can be fine-tuned for specific applications.
   9  
  10  // RateLimitWriteTuning returns tuning optimized for write rate limiting.
  11  // - Aggressive response to prevent memory exhaustion
  12  // - Moderate integral for sustained load handling
  13  // - Small derivative with strong filtering
  14  func RateLimitWriteTuning() pidif.Tuning {
  15  	return pidif.Tuning{
  16  		Kp:                    0.5,
  17  		Ki:                    0.1,
  18  		Kd:                    0.05,
  19  		Setpoint:              0.85, // Target 85% of limit
  20  		DerivativeFilterAlpha: 0.2,  // Strong filtering
  21  		IntegralMin:           -2.0,
  22  		IntegralMax:           10.0,
  23  		OutputMin:             0.0,
  24  		OutputMax:             1.0, // Max 1 second delay
  25  	}
  26  }
  27  
  28  // RateLimitReadTuning returns tuning optimized for read rate limiting.
  29  // - Less aggressive than writes (reads are more latency-sensitive)
  30  // - Lower gains to avoid over-throttling queries
  31  func RateLimitReadTuning() pidif.Tuning {
  32  	return pidif.Tuning{
  33  		Kp:                    0.3,
  34  		Ki:                    0.05,
  35  		Kd:                    0.02,
  36  		Setpoint:              0.90, // Target 90% of limit
  37  		DerivativeFilterAlpha: 0.15, // Very strong filtering
  38  		IntegralMin:           -1.0,
  39  		IntegralMax:           5.0,
  40  		OutputMin:             0.0,
  41  		OutputMax:             0.5, // Max 500ms delay
  42  	}
  43  }
  44  
  45  // DifficultyAdjustmentTuning returns tuning for PoW difficulty adjustment.
  46  // Designed for block time targeting where:
  47  // - Process variable: actual_block_time / target_block_time (1.0 = on target)
  48  // - Output: difficulty multiplier (1.0 = no change, >1 = harder, <1 = easier)
  49  //
  50  // This uses:
  51  // - Low Kp to avoid overreacting to individual blocks
  52  // - Moderate Ki to converge on target over time
  53  // - Small Kd with strong filtering to anticipate trends
  54  func DifficultyAdjustmentTuning() pidif.Tuning {
  55  	return pidif.Tuning{
  56  		Kp:                    0.1,  // Low proportional (blocks are noisy)
  57  		Ki:                    0.05, // Moderate integral for convergence
  58  		Kd:                    0.02, // Small derivative
  59  		Setpoint:              1.0,  // Target: actual == expected block time
  60  		DerivativeFilterAlpha: 0.1,  // Very strong filtering (blocks are noisy)
  61  		IntegralMin:           -0.5, // Limit integral windup
  62  		IntegralMax:           0.5,
  63  		OutputMin:             0.5,  // Min 50% difficulty change
  64  		OutputMax:             2.0,  // Max 200% difficulty change
  65  	}
  66  }
  67  
  68  // TemperatureControlTuning returns tuning for temperature regulation.
  69  // Suitable for heating/cooling systems where:
  70  // - Process variable: current temperature
  71  // - Setpoint: target temperature
  72  // - Output: heater/cooler power level (0-1)
  73  func TemperatureControlTuning(targetTemp float64) pidif.Tuning {
  74  	return pidif.Tuning{
  75  		Kp:                    0.1,        // Moderate response
  76  		Ki:                    0.01,       // Slow integral (thermal inertia)
  77  		Kd:                    0.05,       // Some anticipation
  78  		Setpoint:              targetTemp,
  79  		DerivativeFilterAlpha: 0.3,        // Moderate filtering
  80  		IntegralMin:           -100.0,
  81  		IntegralMax:           100.0,
  82  		OutputMin:             0.0,
  83  		OutputMax:             1.0,
  84  	}
  85  }
  86  
  87  // MotorSpeedTuning returns tuning for motor speed control.
  88  // - Process variable: actual RPM / target RPM
  89  // - Output: motor power level
  90  func MotorSpeedTuning() pidif.Tuning {
  91  	return pidif.Tuning{
  92  		Kp:                    0.5,  // Quick response
  93  		Ki:                    0.2,  // Eliminate steady-state error
  94  		Kd:                    0.1,  // Dampen oscillations
  95  		Setpoint:              1.0,  // Target: actual == desired speed
  96  		DerivativeFilterAlpha: 0.4,  // Moderate filtering
  97  		IntegralMin:           -1.0,
  98  		IntegralMax:           1.0,
  99  		OutputMin:             0.0,
 100  		OutputMax:             1.0,
 101  	}
 102  }
 103  
 104  // NewRateLimitWriteController creates a controller for write rate limiting.
 105  func NewRateLimitWriteController() *Controller {
 106  	return New(RateLimitWriteTuning())
 107  }
 108  
 109  // NewRateLimitReadController creates a controller for read rate limiting.
 110  func NewRateLimitReadController() *Controller {
 111  	return New(RateLimitReadTuning())
 112  }
 113  
 114  // NewDifficultyAdjustmentController creates a controller for PoW difficulty.
 115  func NewDifficultyAdjustmentController() *Controller {
 116  	return New(DifficultyAdjustmentTuning())
 117  }
 118  
 119  // NewTemperatureController creates a controller for temperature regulation.
 120  func NewTemperatureController(targetTemp float64) *Controller {
 121  	return New(TemperatureControlTuning(targetTemp))
 122  }
 123  
 124  // NewMotorSpeedController creates a controller for motor speed control.
 125  func NewMotorSpeedController() *Controller {
 126  	return New(MotorSpeedTuning())
 127  }
 128