libstp.step.motor.steps ======================= .. py:module:: libstp.step.motor.steps Classes ------- .. autoapisummary:: libstp.step.motor.steps.StopMode libstp.step.motor.steps.SetMotorPower libstp.step.motor.steps.SetMotorVelocity libstp.step.motor.steps.SetMotorDps libstp.step.motor.steps.MoveMotorTo libstp.step.motor.steps.MoveMotorRelative libstp.step.motor.steps.StopMotor Functions --------- .. autoapisummary:: libstp.step.motor.steps.motor_power libstp.step.motor.steps.motor_velocity libstp.step.motor.steps.motor_move_to libstp.step.motor.steps.motor_move_relative libstp.step.motor.steps.motor_dps libstp.step.motor.steps.motor_off libstp.step.motor.steps.motor_passive_brake libstp.step.motor.steps.motor_brake Module Contents --------------- .. py:class:: StopMode(*args, **kwds) Bases: :py:obj:`enum.Enum` Enumeration of motor stopping behaviours. OFF -- Remove power and let the motor coast (free-spin). PASSIVE_BRAKE -- Command zero power; H-bridge shorts the leads for electrical braking, but no active position hold. ACTIVE_BRAKE -- Engage the firmware stop latch to actively resist external forces and hold the current shaft position. .. py:attribute:: OFF :value: 'off' .. py:attribute:: PASSIVE_BRAKE :value: 'passive_brake' .. py:attribute:: ACTIVE_BRAKE :value: 'active_brake' .. py:class:: SetMotorPower(motor: libstp.hal.IMotor, percent: int) Bases: :py:obj:`libstp.step.Step` Set a motor to open-loop percent power (-100..100). .. py:class:: SetMotorVelocity(motor: libstp.hal.IMotor, velocity: int) Bases: :py:obj:`libstp.step.Step` Set a motor to closed-loop velocity (firmware BEMF units). .. py:class:: SetMotorDps(motor: libstp.hal.IMotor, dps: float) Bases: :py:obj:`libstp.step.Step` Set a motor to closed-loop velocity specified in degrees per second. .. py:class:: MoveMotorTo(motor: libstp.hal.IMotor, position: int, velocity: int = 1000, timeout: Optional[float] = None) Bases: :py:obj:`libstp.step.Step` Move a motor to an absolute encoder position, waiting for completion. .. py:class:: MoveMotorRelative(motor: libstp.hal.IMotor, delta: int, velocity: int = 1000, timeout: Optional[float] = None) Bases: :py:obj:`libstp.step.Step` Move a motor by a relative encoder delta, waiting for completion. .. py:class:: StopMotor(motor: libstp.hal.IMotor, mode: StopMode = StopMode.ACTIVE_BRAKE) Bases: :py:obj:`libstp.step.Step` Stop a motor using the specified mode. .. py:function:: motor_power(motor: libstp.hal.IMotor, percent: int) -> SetMotorPower Set a motor to open-loop percent power. Commands the motor at a raw duty-cycle percentage without any feedback control. The command is applied immediately and the step completes without waiting -- the motor keeps spinning until another command (or a stop step) is issued. :param motor: The motor to control, obtained from the robot hardware map (e.g. ``robot.motor(0)``). :param percent: Duty-cycle power from -100 (full reverse) to 100 (full forward). Values outside this range raise ``ValueError``. :returns: A ``SetMotorPower`` step ready to be scheduled in a step sequence. Example:: from libstp.step.motor import motor_power, motor_off # Spin the claw motor forward at half power for 2 seconds sequence( motor_power(robot.motor(1), 50), wait(2.0), motor_off(robot.motor(1)), ) .. py:function:: motor_velocity(motor: libstp.hal.IMotor, velocity: int) -> SetMotorVelocity Set a motor to closed-loop velocity in firmware BEMF units. Commands the motor's firmware PID controller to maintain a target velocity expressed in raw BEMF tick units. The step completes immediately; the motor continues at the requested speed until changed. For a human-friendly velocity interface, prefer ``motor_dps`` which accepts degrees per second. :param motor: The motor to control, obtained from the robot hardware map (e.g. ``robot.motor(0)``). :param velocity: Target velocity in firmware BEMF units (ticks per BEMF sample period). Positive values drive forward; negative values drive in reverse. :returns: A ``SetMotorVelocity`` step ready to be scheduled in a step sequence. Example:: from libstp.step.motor import motor_velocity, motor_brake # Drive the left wheel at 800 BEMF units, then brake sequence( motor_velocity(robot.motor(0), 800), wait(3.0), motor_brake(robot.motor(0)), ) .. py:function:: motor_move_to(motor: libstp.hal.IMotor, position: int, velocity: int = 1000, timeout: float | None = None) -> MoveMotorTo Move a motor to an absolute encoder position and wait for completion. Commands the motor's firmware position controller to drive to the given absolute encoder tick count. The step blocks (yielding to the async loop) until the firmware reports the move is complete, or until the optional timeout expires. :param motor: The motor to control, obtained from the robot hardware map (e.g. ``robot.motor(2)``). :param position: Target position in absolute encoder ticks. :param velocity: Movement speed in firmware ticks/s. Must be positive. Defaults to 1000. :param timeout: Maximum seconds to wait for the move to finish. ``None`` (the default) means wait indefinitely. If the timeout fires a warning is logged and the step returns without stopping the motor. :returns: A ``MoveMotorTo`` step ready to be scheduled in a step sequence. Example:: from libstp.step.motor import motor_move_to # Raise the arm to encoder position 500 at speed 800, with a 3s safety timeout motor_move_to(robot.motor(2), position=500, velocity=800, timeout=3.0) .. py:function:: motor_move_relative(motor: libstp.hal.IMotor, delta: int, velocity: int = 1000, timeout: float | None = None) -> MoveMotorRelative Move a motor by a relative encoder delta and wait for completion. Commands the motor's firmware position controller to move by the given number of encoder ticks relative to its current position. The step blocks until the firmware reports the move is complete, or until the optional timeout expires. :param motor: The motor to control, obtained from the robot hardware map (e.g. ``robot.motor(2)``). :param delta: Number of encoder ticks to move. Positive values move forward; negative values move in reverse. :param velocity: Movement speed in firmware ticks/s. Must be positive. Defaults to 1000. :param timeout: Maximum seconds to wait for the move to finish. ``None`` (the default) means wait indefinitely. If the timeout fires a warning is logged and the step returns without stopping the motor. :returns: A ``MoveMotorRelative`` step ready to be scheduled in a step sequence. Example:: from libstp.step.motor import motor_move_relative, motor_brake # Rotate the arm motor 200 ticks forward, then brake sequence( motor_move_relative(robot.motor(2), delta=200, velocity=600), motor_brake(robot.motor(2)), ) .. py:function:: motor_dps(motor: libstp.hal.IMotor, dps: float) -> SetMotorDps Set a motor to closed-loop velocity in degrees per second. Converts the requested angular velocity from degrees per second into firmware BEMF units using the motor's calibration data, then engages the firmware's closed-loop velocity controller. The step completes immediately; the motor continues at the requested speed until changed. Prerequisites: The motor must have valid calibration data (``ticks_to_rad``) so the deg/s to BEMF conversion is accurate. Run the motor calibration step first if calibration has not been performed. :param motor: The motor to control, obtained from the robot hardware map (e.g. ``robot.motor(0)``). :param dps: Target angular velocity in degrees per second. Positive values drive forward; negative values drive in reverse. :returns: A ``SetMotorDps`` step ready to be scheduled in a step sequence. Example:: from libstp.step.motor import motor_dps, motor_brake # Spin the left wheel at 180 deg/s for 2 seconds sequence( motor_dps(robot.motor(0), 180.0), wait(2.0), motor_brake(robot.motor(0)), ) .. py:function:: motor_off(motor: libstp.hal.IMotor) -> StopMotor Turn a motor off, allowing it to coast freely. Removes all power from the motor so it spins down under friction alone. The motor shaft is not held in place and can be back-driven. Use this when you want the mechanism to move freely (e.g. letting an arm fall under gravity). :param motor: The motor to turn off, obtained from the robot hardware map (e.g. ``robot.motor(0)``). :returns: A ``StopMotor`` step configured for coast / free-spin mode. Example:: from libstp.step.motor import motor_power, motor_off # Run a motor briefly, then let it coast to a stop sequence( motor_power(robot.motor(3), 80), wait(1.5), motor_off(robot.motor(3)), ) .. py:function:: motor_passive_brake(motor: libstp.hal.IMotor) -> StopMotor Passively brake a motor by commanding zero power. Sets the motor power to zero, which causes the H-bridge to short the motor leads. This provides electrical braking that decelerates the motor faster than coasting (``motor_off``), but does not actively hold position once the motor stops. :param motor: The motor to brake, obtained from the robot hardware map (e.g. ``robot.motor(0)``). :returns: A ``StopMotor`` step configured for passive braking mode. Example:: from libstp.step.motor import motor_velocity, motor_passive_brake # Drive forward then passively brake sequence( motor_velocity(robot.motor(0), 600), wait(2.0), motor_passive_brake(robot.motor(0)), ) .. py:function:: motor_brake(motor: libstp.hal.IMotor) -> StopMotor Actively brake a motor and hold its current position. Engages the firmware's active brake (stop latch), which commands the motor controller to resist any external force and maintain the current shaft position. This is the strongest stop mode and is appropriate when the mechanism must not move (e.g. holding an arm up against gravity). :param motor: The motor to brake, obtained from the robot hardware map (e.g. ``robot.motor(2)``). :returns: A ``StopMotor`` step configured for active braking mode. Example:: from libstp.step.motor import motor_move_to, motor_brake # Move the arm to a target, then lock it in place sequence( motor_move_to(robot.motor(2), position=400), motor_brake(robot.motor(2)), )