api/builtins/Control: introduce Control class

This is a generic class to interact with PID Controllers. A Motor has one control instance (for angle) and a drivebase will have two (one for heading, one for distance).

This will replace the motor specific settings
This commit is contained in:
Laurens Valk
2020-01-28 16:25:53 +01:00
parent 4faa5d3df8
commit 36a393c927
3 changed files with 113 additions and 21 deletions
+15 -14
View File
@@ -40,13 +40,23 @@ The Motor Class
.. automethod:: pybricks.builtins.Motor.track_target
.. rubric:: Changing motor settings
.. rubric:: Control settings and status
.. automethod:: pybricks.builtins.Motor.set_run_settings
The motors use PID control to accurately track the speed and
angle targets that you specify. Use the following methods to adjust the
behavior of this controller and get its current status.
.. automethod:: pybricks.builtins.Motor.set_dc_settings
.. automethod:: pybricks.builtins::Motor.control.limits
.. automethod:: pybricks.builtins.Motor.set_pid_settings
.. automethod:: pybricks.builtins::Motor.control.pid
.. automethod:: pybricks.builtins::Motor.control.target_tolerances
.. automethod:: pybricks.builtins::Motor.control.stall_tolerances
.. automethod:: pybricks.builtins::Motor.control.stalled
.. automethod:: pybricks.builtins::Motor.control.active
Motor Tips & Tricks
@@ -80,16 +90,7 @@ go further. This way, you don't need a touch or light sensor to detect this.
When is a motor stalled?
++++++++++++++++++++++++
When the motor is stalled, the :meth:`.stalled` will return ``True``.
Specifically, the motor is stalled when the duty cycle computed by the
PID controllers has reached the maximum (so ``duty`` = ``duty_limit``)
and still the motor cannot reach a minimal speed
(so ``speed`` < ``stall_speed``) for a period of at
least ``stall_time``.
You can change the ``duty_limit``, ``stall_speed``, and ``stall_time``
settings using and :meth:`.set_pid_settings`
in order to change the sensitivity to being stalled.
TODO
.. _gears:
+1 -1
View File
@@ -64,7 +64,7 @@ degrees per second, during one second (deg/s/s). This is also commonly written
as :math:`deg/s^2`.
For example, you can adjust the rotational acceleration setting of a
:meth:`Motor <.builtins.Motor.set_run_settings>` to change how smoothly or
:class:`Motor <.builtins.Motor>` to change how smoothly or
how quickly it reaches the constant speed set point.
+97 -6
View File
@@ -58,9 +58,104 @@ class DCMotor():
pass
class Control():
"""Class to interact with PID controller and settings."""
def __init__(self, scale=1):
"""Initialize the PID controller.
Arguments:
scale (float):
Number of integer counts per unit of output. For example, two
counts per degree of the motor.
"""
pass
def limits(self, speed, acceleration, actuation):
"""Configure the maximum speed, acceleration, and actuation.
If no arguments are given, this will return the current values.
Arguments:
speed (:ref:`speed` or :ref:`linspeed`):
Maximum speed. All speed commands will be capped to this value.
acceleration (:ref:`acceleration` or :ref:`linacceleration`):
Maximum acceleration.
actuation (:ref:`percentage`):
Maximum actuation as percentage of absolute maximum.
"""
pass
def pid(self, kp, ki, kd):
"""Get or set the PID values for position and speed control.
If no arguments are given, this will return the current values.
Arguments:
kp (int): Proportional position (or integral speed) control
constant.
ki (int): Integral position control constant.
kd (int): Derivative position (or proportional speed) control
constant.
"""
pass
def target_tolerances(self, speed, position):
"""Get or set the tolerances that say when a maneuver is done.
If no arguments are given, this will return the current values.
Arguments:
position (:ref:`angle` or :ref:`distance`): Allowed
deviation from the target before motion is considered
complete.
speed (:ref:`speed` or :ref:`linspeed`): Allowed deviation
from zero speed before motion is considered complete.
"""
pass
def stall_tolerances(self, speed, time):
"""Get or set stalling tolerances.
If no arguments are given, this will return the current values.
Arguments:
speed (:ref:`speed` or :ref:`linspeed`): If the controller
cannot reach this speed during at least ``stall_time``,
it is stalled.
time (:ref:`time`): See ``speed``.
"""
pass
def stalled(self):
"""Check whether the controller is currently stalled.
A controller is stalled when it cannot move even with the maximum
actuation signal.
Returns:
bool: ``True`` if the controller is stalled,``False`` if not.
"""
pass
def active(self):
"""Check whether the controller is currently active.
When active, it continuously adjusts the actuation to reach the control
objective. When it is passive, the control signal is zero or constant.
Returns:
bool: ``True`` if the controller is active,``False`` if not.
"""
pass
class Motor(DCMotor):
"""Generic class to control motors with built-in rotation sensors."""
control = Control()
def __init__(self, port,
positive_direction=Direction.CLOCKWISE,
gears=None):
@@ -239,12 +334,8 @@ class Motor(DCMotor):
stop_type (Stop): Whether to coast, brake, or hold after coming to
a standstill (*Default*:
:class:`Stop.COAST <.parameters.Stop>`).
duty_limit (:ref:`percentage`): Relative torque limit. This limit
works just like
:meth:`.set_dc_settings`, but in
this case the limit is temporary:
it returns to its previous value
after completing this command.
duty_limit (:ref:`percentage`): Relative torque limit during this
command.
"""
pass