PID

A classical PID controller agent.

A deterministic, stateful control policy that uses Proportional-Integral-Derivative (PID) control to minimize the error between an observed variable and a setpoint.

Control Law:

u(t) = Kp*e(t) + Ki*∫e(t)dt + Kd*de(t)/dt where e(t) = setpoint - obs[obs_field]

Action Space Behavior:
  • Box: Continuous control clipped to action_space bounds

  • Discrete(n): Continuous control discretized into n bins

Note: This is a non-learning agent (update() does nothing).

class myriad.agents.classical.pid.AgentParams(action_space, kp, ki, kd, setpoint, obs_field, dt, anti_windup, control_low, control_high, bin_edges=None)[source]

Bases: object

Static parameters for the PID controller agent.

Variables:
  • action_space (myriad.core.spaces.Space) – Action space (Box or Discrete)

  • kp (float) – Proportional gain

  • ki (float) – Integral gain

  • kd (float) – Derivative gain

  • setpoint (float) – Desired value for the controlled variable

  • obs_field (str) – Field name from the observation NamedTuple to control (ie, to compare to the setpoint)

  • dt (float) – Time step for integral/derivative computation (seconds)

  • anti_windup (float) – Maximum absolute value for integral term (prevents windup)

  • control_low (float) – Lower bound for continuous control signal (for discretization)

  • control_high (float) – Upper bound for continuous control signal (for discretization)

  • bin_edges (jax.jaxlib._jax.Array | None) – Bin edges for discretizing continuous control to discrete actions (Discrete only)

action_space: Space
kp: float
ki: float
kd: float
setpoint: float
obs_field: str
dt: float
anti_windup: float
control_low: float
control_high: float
bin_edges: Array | None = None
__init__(action_space, kp, ki, kd, setpoint, obs_field, dt, anti_windup, control_low, control_high, bin_edges=None)
replace(**updates)

Returns a new object replacing the specified fields with new values.

class myriad.agents.classical.pid.AgentState(obs_index, integral_error, previous_error)[source]

Bases: object

PID controller state.

Variables:
  • obs_index (int) – Array index corresponding to obs_field (computed at init time)

  • integral_error (jax.jaxlib._jax.Array) – Accumulated integral of error over time

  • previous_error (jax.jaxlib._jax.Array) – Error from previous timestep (for derivative term)

obs_index: int
integral_error: Array
previous_error: Array
__init__(obs_index, integral_error, previous_error)
replace(**updates)

Returns a new object replacing the specified fields with new values.

myriad.agents.classical.pid.make_agent(action_space, kp=1.0, ki=0.0, kd=0.0, setpoint=0.0, obs_field='theta', dt=1.0, anti_windup=10.0, control_low=None, control_high=None)[source]

Factory function to create a PID controller agent.

Parameters:
  • action_space (Space) – Action space (Box or Discrete)

  • kp (float) – Proportional gain. Higher values increase responsiveness but may cause oscillation. Default 1.0.

  • ki (float) – Integral gain. Eliminates steady-state error but may cause overshoot. Default 0.0 (no integral action).

  • kd (float) – Derivative gain. Dampens oscillations and improves stability. Default 0.0 (no derivative action).

  • setpoint (float) – Desired value for obs[obs_field]. Default 0.0.

  • obs_field (str) – Field name from observation NamedTuple to control. Default “theta” (pole angle for CartPole).

  • dt (float) – Time step in seconds for integral/derivative computation. Should match environment step rate. Default 1s (1Hz).

  • anti_windup (float) – Maximum absolute value for integral term to prevent windup. Default 10.0.

  • control_low (float | None) – Lower bound for continuous control signal. For Box action spaces, defaults to action_space.low. For Discrete, must be specified. Default None.

  • control_high (float | None) – Upper bound for continuous control signal. For Box action spaces, defaults to action_space.high. For Discrete, must be specified. Default None.

Returns:

Agent instance with PID control policy

Raises:

ValueError – If action_space is not Box/Discrete, obs_field is invalid, or control bounds are not specified for Discrete action space

Return type:

Agent[AgentState, AgentParams, Observation]