mpylab.tools.level_control module

This is mpylab.tools.level_control.

Provides different classes for level control

author:

Hans Georg Krauthäuser (main author)

license:

GPL-3 or higher

class mpylab.tools.level_control.ControlBase(actual_reader: Callable[[], float | int], setter: Callable[[float], object], initial: Sequence[float | int], abstol: float | int, max_iter: int = 20, min_cntrl: float | int | None = None, max_cntrl: float | int | None = None, stagnation_tol: float = 1e-12)

Bases: object

Base class for synchronous iterative inverse control.

Parameters:
  • actual_reader (callable) – Zero-argument callback returning the measured scalar value.

  • setter (callable) – Callback applying one scalar control value. Its return value is ignored; the resulting value is obtained from actual_reader.

  • initial (sequence of number) – At least two initial control values evaluated before inverse estimation starts.

  • abstol (number) – Positive absolute tolerance for abs(actual - nominal).

  • max_iter (int, optional) – Maximum number of estimated control steps after the initial values.

  • min_cntrl (number, optional) – Inclusive bounds applied to every control value before calling the setter.

  • max_cntrl (number, optional) – Inclusive bounds applied to every control value before calling the setter.

  • stagnation_tol (float, optional) – Absolute control-value difference below which two consecutive guesses are treated as stagnation.

Raises:
  • TypeError – If actual_reader or setter is not callable.

  • ValueError – If fewer than two initial values are supplied, a scalar configuration value is non-finite, a tolerance or iteration limit is invalid, or the control bounds are reversed.

Notes

A subclass implements guess() to estimate a new control value from measured (control, actual) pairs. This generic class has no knowledge of physical units or hardware protection; callers must express all values consistently and provide appropriate control bounds.

clamp_cntrl(cntrl: float | int) float

Clamp a control value to the configured inclusive bounds.

Parameters:

cntrl (number) – Proposed control value.

Returns:

Bounded control value.

Return type:

float

Raises:

ValueError – If cntrl is not finite.

do_cntrl(nominal: float | int, initial: Sequence[float | int] | None = None, return_result_object: bool = False) Tuple[float, float] | ControlResult

Drive the measured value towards a requested nominal value.

Parameters:
  • nominal (number) – Requested measured value in the caller’s consistent scalar unit.

  • initial (sequence of number, optional) – Initial control values for this run. When omitted, the values supplied to the constructor are used.

  • return_result_object (bool, optional) – Return ControlResult instead of the historical tuple.

Returns:

Final applied control and measured value, optionally accompanied by iteration and evaluation counts.

Return type:

tuple of (float, float) or ControlResult

Raises:
  • ValueError – If fewer than two initial values are available or a nominal, control, or measured value is not finite.

  • RuntimeError – If control stagnates, reaches a configured boundary without satisfying the tolerance, or exceeds max_iter.

guess(cntrl: Sequence[float], act: Sequence[float], nominal: float) float

Estimate the next control value from measurement history.

Parameters:
  • cntrl (sequence of float) – Previously applied control values.

  • act (sequence of float) – Measured values corresponding to cntrl.

  • nominal (float) – Desired measured value.

Returns:

Proposed next control value before common bounds are applied.

Return type:

float

Raises:

NotImplementedError – Always raised by the base implementation.

set_cntrl_val(cntrl: float | int) float

Apply a bounded control value and synchronously read the result.

Parameters:

cntrl (number) – Proposed control value. Bounds are applied before the setter is called.

Returns:

Scalar value returned by the reader after applying the control.

Return type:

float

Raises:

ValueError – If the proposed control or the reader result is not finite.

Notes

A successful reader call increments N. Exceptions raised by either callback propagate to the caller.

class mpylab.tools.level_control.ControlBracketInterpol(actual_reader, setter, initial, abstol, max_iter=20, min_cntrl=None, max_cntrl=None, stagnation_tol=1e-12, max_step_up=3.0, max_step_down=6.0, safety_margin=0.0, prefer_from_below=True)

Bases: ControlBase

Monotonic inverse control using guarded bracketing and interpolation.

The controller first searches measured points that bracket the nominal value. If no bracket exists yet, it performs bounded extrapolation with limited step sizes. Once a bracket exists, it applies inverse linear interpolation inside that interval.

Parameters:
  • actual_reader (callable) – Zero-argument callback returning the measured scalar value.

  • setter (callable) – Callback applying one scalar control value.

  • initial (sequence of number) – At least two initial control values.

  • abstol (number) – Positive absolute tolerance for the measured value.

  • max_iter (int, optional) – Maximum number of estimated steps after initial evaluation.

  • min_cntrl (number, optional) – Inclusive control bounds.

  • max_cntrl (number, optional) – Inclusive control bounds.

  • stagnation_tol (float, optional) – Control-value difference treated as stagnation.

  • max_step_up (number, optional) – Maximum increase of one estimated control step.

  • max_step_down (number, optional) – Maximum magnitude of one decreasing control step.

  • safety_margin (number, optional) – Offset below nominal used for interpolation inside a bracket when prefer_from_below is enabled.

  • prefer_from_below (bool, optional) – Approach an in-bracket target through nominal - safety_margin to reduce overshoot.

Raises:

ValueError – If step limits are not positive or safety_margin is negative.

Notes

Step limits constrain each estimate relative to the most recently applied control. The independent min_cntrl and max_cntrl bounds are then enforced by ControlBase before hardware is called.

guess(cntrl, act, nominal)

Estimate the next step using bracketing or guarded extrapolation.

Parameters:
  • cntrl (sequence of float) – Previously applied control values.

  • act (sequence of float) – Corresponding measured values.

  • nominal (float) – Desired measured value.

Returns:

Proposed control value with per-step increase or decrease limits applied. Common absolute bounds are applied later by ControlBase.clamp_cntrl().

Return type:

float

class mpylab.tools.level_control.ControlInterpol(actual_reader: Callable[[], float | int], setter: Callable[[float], object], initial: Sequence[float | int], abstol: float | int, max_iter: int = 20, min_cntrl: float | int | None = None, max_cntrl: float | int | None = None, stagnation_tol: float = 1e-12)

Bases: ControlBase

Inverse controller using interpolation or unbounded extrapolation.

Duplicate measured values are combined by averaging their control values. At least two distinct measured values are required.

guess(cntrl: Sequence[float], act: Sequence[float], nominal: float) float

Estimate control by inverse linear interpolation.

Parameters:
  • cntrl (sequence of float) – Previously applied control values.

  • act (sequence of float) – Corresponding measured values.

  • nominal (float) – Desired measured value.

Returns:

Interpolated or linearly extrapolated control value.

Return type:

float

Raises:

RuntimeError – If fewer than two distinct measured values are available.

class mpylab.tools.level_control.ControlPolyfit(actual_reader: Callable[[], float | int], setter: Callable[[float], object], initial: Sequence[float | int], abstol: float | int, maxorder: int = 2, **kwargs)

Bases: ControlBase

Inverse controller fitting control as a polynomial of measured value.

Parameters:
  • actual_reader (callable) – Zero-argument callback returning the measured scalar value.

  • setter (callable) – Callback applying one scalar control value.

  • initial (sequence of number) – At least two initial control values.

  • abstol (number) – Positive absolute tolerance for the measured value.

  • maxorder (int, optional) – Maximum inverse-polynomial order. The effective order is also limited to one less than the number of available support points.

  • **kwargs (object) – Additional ControlBase options such as control bounds and iteration limits.

Raises:

ValueError – If maxorder is less than one.

guess(cntrl: Sequence[float], act: Sequence[float], nominal: float) float

Estimate control by inverse polynomial evaluation.

Parameters:
  • cntrl (sequence of float) – Previously applied control values.

  • act (sequence of float) – Corresponding measured values.

  • nominal (float) – Desired measured value.

Returns:

Fitted inverse polynomial evaluated at nominal.

Return type:

float

class mpylab.tools.level_control.ControlRapp(actual_reader: Callable[[], float | int], setter: Callable[[float], object], initial: Sequence[float | int], abstol: float | int, p: float = 1.0, g: float = 1.0, sat: float = 20.0, **kwargs)

Bases: ControlBase

Inverse controller fitting a saturating Rapp model.

The fitted model is

y = g*x / (1 + (g*x/sat)^(2p))^(1/(2p)).

Parameters:
  • actual_reader (callable) – Zero-argument callback returning the measured scalar value.

  • setter (callable) – Callback applying one scalar control value.

  • initial (sequence of number) – At least two initial control values.

  • abstol (number) – Positive absolute tolerance for the measured value.

  • p (float, optional) – Positive smoothness parameter of the Rapp model.

  • g (float, optional) – Positive initial small-signal gain estimate.

  • sat (float, optional) – Positive initial saturation-value estimate.

  • **kwargs (object) – Additional ControlBase options.

Raises:

ValueError – If p, g, or sat is not positive.

guess(cntrl: Sequence[float], act: Sequence[float], nominal: float) float

Fit the Rapp model and solve it for the requested output.

Parameters:
  • cntrl (sequence of float) – Previously applied control values.

  • act (sequence of float) – Corresponding measured values.

  • nominal (float) – Desired measured value.

Returns:

Numerical solution for the required control value.

Return type:

float

Notes

The fitted parameters update the instance attributes g, p, and sat.

class mpylab.tools.level_control.ControlResult(guess: float, actual: float, iterations: int, evaluations: int)

Bases: object

Convergence result for one completed control run.

Parameters:
  • guess (float) – Final control value applied through the setter.

  • actual (float) – Measured value produced by guess.

  • iterations (int) – Number of inverse-estimation iterations after evaluating the initial support points.

  • evaluations (int) – Total number of reader calls, including the initial support points.

actual: float
evaluations: int
guess: float
iterations: int
mpylab.tools.level_control.control

alias of ControlBracketInterpol