rules

class ConstantPWM(timer: Timer, powertrain: Powertrain, target_pwm_value: float | int)

Bases: RuleBase

ConstantPWM object.

It can be used to make a gradual start of the powertrain’s motion, in order to avoid a peak in the powertrain’s DC motor absorbed electric current.

It checks whether the timer is active and, if so, it sets the pwm of powertrain motor to the constant target_pwm_value.

Methods

apply()

It checks if timer is active and, if so, it returns the pwm to apply to the powertrain motor, equal to target_pwm_value.

Raises

TypeError
  • If timer is not an instance of Timer,

  • if powertrain is not an instance of Powertrain,

  • if target_pwm_value is not a float or an int.

ValueError

If target_pwm_value is not within -1 and 1.

See Also

DCMotor.pwm

apply() None | float | int

It checks if timer is active and, if so, it returns the pwm to apply to the powertrain motor, equal to target_pwm_value.

Returns

float or int or None

PWM value to apply to the motor, equal to target_pwm_value.

class PositionAndVelocityControl(encoder: AbsoluteRotaryEncoder, tachometer: Tachometer, powertrain: Powertrain, position_PID: PIDController, velocity_PID: PIDController, trajectory: SCurveTrajectory)

Bases: RuleBase

Added in version 1.3.0.

PositionAndVelocityControl object.

It can be used to force the angular position of a rotating object, tracked by the encoder, to follow an S curve trajectory from a starting to a stopping position.

Methods

apply()

It computes the pwm to apply to the powertrain’s motor in order to stick to position and velocity set by the trajectory through the two nested position_PID and velocity_PID.

Raises

TypeError
apply() None | float | int

It computes the pwm to apply to the powertrain’s motor in order to stick to position and velocity set by the trajectory through the two nested position_PID and velocity_PID.

Returns

float or int or None

PWM value to apply to the powertrain’s motor in order to stick to the S curve trajectory.

Notes

It computes a velocity reference through the position_PID as:

\[\dot{\theta}_{ref} = PID_{pos}(\theta - \theta_{ref})\]

where:

  • \(\dot{\theta}_{ref}\) is the velocity reference,

  • \(\theta\) is the current angular position, tracked by the encoder,

  • \(\theta_{ref}\) is the reference angular position, get by the S curve trajectory.

Then, it computes a PWM through the velocity_PID as:

\[PWM_{ref} = PID_{vel}(\dot{\theta} - \dot{\theta}_{ref})\]

where:

  • \(PWM_{ref}\) is the reference PWM,

  • \(\dot{\theta}\) is the current angular speed, tracked by the tachometer.

class ReachAngularPosition(encoder: AbsoluteRotaryEncoder, powertrain: Powertrain, target_angular_position: AngularPosition, braking_angle: Angle)

Bases: RuleBase

ReachAngularPosition object.

It can be used to make the encoder’s target reach a target_angular_position within a braking_angle.

Methods

apply()

It computes the pwm to apply to the powertrain’s motor in order to reach a target_angular_position by the target rotating object of the encoder, within a specific braking_angle.

Raises

TypeError
ValueError

If powertrain.elements is an empty tuple.

See Also

DCMotor.pwm

apply() None | float | int

It computes the pwm to apply to the powertrain’s DC motor in order to reach a target_angular_position by the target rotating object of the encoder, within a specific braking_angle.

Returns

float or int or None

PWM value to apply to the motor in order to reach the target angular position.

Notes

The braking angle is the angle within which the motor’s pwm is controlled in order to brake and reach the target_angular_position.

The rule is applied only if the difference between target_angular_position and the encoder’s target angular_position is lower than or equal to the braking_angle.

The lower the braking_angle the higher the deceleration of the system, thus the higher the vibrations produced.

First of all, the rule computes the powertrain’s static error according to the following formula:

\[\theta_{err} \left( T_l \right) = \frac{T_l}{T_{max}} \, \frac{\theta_b}{\eta_t}\]

where:

  • \(\theta_{err}\) is the powertrain static error,

  • \(T_l\) is the load torque on the powertrain DC motor (DCMotor.load_torque),

  • \(T_{max}\) is the maximum torque developed by the powertrain DC motor (DCMotor.maximum_torque),

  • \(\theta_b\) is the braking_angle parameter,

  • \(\eta_t\) is the powertrain overall efficiency, computed as:

\[\eta_t = \prod_{i = 1}^N \eta_i\]

where:

Then it checks the applicability condition, defined as:

\[\theta \ge \theta_s = \theta_t - \theta_b + \theta_{err}\]

where:

  • \(\theta\) is the encoder’s target angular_position,

  • \(\theta_s\) is the braking starting angle,

  • \(\theta_t\) is the target_angular_position parameter.

If the applicability condition is not met, then it returns None, otherwise it computes the pwm as:

\[D \left( \theta \right) = 1 - \frac{\theta - \theta_s}{\theta_b}\]

where \(D\) is the supply voltage PWM duty cycle pwm to apply to the DC motor in order to reach the target_angular_position by the encoder’s target rotating object.

class RuleBase

Bases: ABC

RuleBase object.

Abstract base class for creating rules objects.

class StartLimitCurrent(encoder: AbsoluteRotaryEncoder, tachometer: Tachometer, motor: DCMotor, target_angular_position: AngularPosition, limit_electric_current: Current)

Bases: RuleBase

StartLimitCurrent object.

It can be used to make a gradual start of the powertrain’s motion and limit the motor absorbed electric current to be lower than or equal to a limit_electric_current value. It computes a pwm to apply to the motor up until the encoder’s target’s angular_position equals target_angular_position.

For an optimal pwm management, it is suggested to set the motor as the tachometer’s target.

Methods

apply()

It computes the pwm to apply to the motor in order to limit its absorbed electric current to be lower or equal to limit_electric_current, until the encoder’s target rotating object’s angular_position equals the target_angular_position.

Raises

TypeError
ValueError
  • If the motor cannot compute electric_current property (DCMotor.electric_current),

  • if limit_electric_current is negative or null.

See Also

DCMotor.pwm

apply() None | float | int

It computes the pwm to apply to the motor in order to limit its absorbed electric current to be lower or equal to limit_electric_current, until the encoder’s target rotating object’s angular_position equals the target_angular_position.

Returns

float or int or None

PWM value to apply to the motor in order to limit its absorbed electric current to be lower or equal to limit_electric_current.

Notes

It checks the applicability condition, defined as:

\[\theta \le \theta_t\]

where:

  • \(\theta\) is the encoder’s target angular_position,

  • \(\theta_t\) is the target_angular_position.

If the applicability condition is not met, then it returns None, otherwise it computes the pwm as:

\[D \left( \dot{\theta} \right) = \frac{1}{2} \, \left( \frac{\dot{\theta}}{\dot{\theta}_0} + \frac{i_{lim}}{i_{max}} + \sqrt{ \left( \frac{\dot{\theta}}{\dot{\theta}_0} \right)^2 + \left( \frac{i_{lim}}{i_{max}} \right)^2 + 2 \frac{\dot{\theta}}{\dot{\theta}_0} \frac{i_{lim} - 2 i_0}{i_{max}} } \right)\]

where:

class StartProportionalToAngularPosition(encoder: AbsoluteRotaryEncoder, powertrain: Powertrain, target_angular_position: AngularPosition, pwm_min_multiplier: float | int, pwm_min: float | None = None)

Bases: RuleBase

StartProportionalToAngularPosition object.

It can be used to make a gradual start of the powertrain’s motion, in order to avoid a peak in the powertrain’s DC motor absorbed electric current.

It computes a pwm to apply to the powertrain’s DC motor which increases linearly with the encoder’s target rotating object’s angular_position. The computed pwm starts from a minimum value, based on powertrain’s elements properties and pwm_min_multiplier or solely on pwm_min parameter. The computed pwm increases up to 1 when the encoder’s target’s angular_position equals target_angular_position.

Methods

apply()

It computes the pwm to apply to the powertrain motor, proportional to the encoder’s target angular_position until it reaches the target_angular_position.

Raises

TypeError
ValueError
  • If powertrain.elements is an empty tuple,

  • if the powertrain motor cannot compute electric_current property (DCMotor.electric_current),

  • if pwm_min_multiplier is less than or equal to 1,

  • if pwm_min is defined and it is negative or null.

See Also

DCMotor.pwm

apply() None | float | int

It computes the pwm to apply to the powertrain motor, proportional to the encoder’s target angular_position until it reaches the target_angular_position.

Returns

float or int or None

PWM value to apply to the motor, proportional to the encoder’s target angular_position.

Notes

The powertrain’s motor has a minimum pwm which, as is, cannot be used to control the motor, since at this value the motor will remain still. So, in order to properly control the motor motion, it is required to apply a pwm greater than the minimum pwm, therefore the motor minimum pwm is multiplied by pwm_min_multiplier to get a starting pwm to be applied to the motor.

If the motor’s minimum pwm is null, then it is useless to multiply this value by pwm_min_multiplier in order to get a starting pwm; therefore, only in this case, pwm_min is directly used as starting pwm.

First of all, the rule computes a candidate minimum applicable pwm as:

\[D_{min}^c \left( T_l \right) = \frac{1}{\eta_t} \, \frac{T_l}{T_{max}} \, \frac{i_{max} - i_0}{i_{max}} + \frac{i_0}{i_{max}}\]

where:

\[\eta_t = \prod_{i = 1}^N \eta_i\]

where:

If both the load torque on the powertrain DC motor \(T_l\) and the motor no load electric current \(i_0\) are null, then also the computed candidate minimum applicable pwm \(D_{min}^c\) is null. Only in this case, the computed candidate minimum applicable pwm is discarded and it is taken into account the pwm_min parameter, which must have been set (don’t used otherwise):

\[D_{min} = D_{min}^p\]

where:

  • \(D_{min}\) is the minimum applicable pwm,

  • \(D_{min}^p\) is the pwm_min parameter.

Otherwise, the candidate \(D_{min}\) is multiplied by the pwm_min_multiplier parameter.

\[D_{min} = D_{min}^c \, g\]

where \(g\) is the pwm_min_multiplier parameter.

Then it checks the applicability condition, defined as:

\[\theta \le \theta_t\]

where:

  • \(\theta\) is the encoder’s target angular_position,

  • \(\theta_t\) is the target_angular_position.

If the applicability condition is not met, then it returns None, otherwise it computes the pwm as:

\[D \left( \theta \right) = \left( 1 - D_{min} \right) \frac{\theta}{\theta_t} + D_{min}\]