step.motion.set_speed_mode ========================== .. py:module:: step.motion.set_speed_mode .. autoapi-nested-parse:: Toggle the firmware's SpeedMode (BEMF on/off) and synchronize the library flag. SpeedMode disables the STM32's BEMF closed-loop control. The firmware no longer measures wheel velocity and integrates encoder ticks, so the robot gains roughly 10% top speed at the cost of cm-accurate distance and angle termination. While SpeedMode is on every motion primitive must terminate via an explicit ``until``-condition; using a distance- or angle-based goal raises ``std::logic_error`` from the C++ controller. This step is the only sanctioned way to flip the flag — it owns the LCM handshake with ``stm32-data-reader``: 1. Publish ``raccoon::scalar_i32_t(value=1|0)`` on ``raccoon/cmd/feature/bemf_enabled`` (1 = BEMF on / normal mode, 0 = BEMF off / SpeedMode). 2. Wait for the retained ACK on ``raccoon/feature/bemf_enabled``. 3. On ACK, update ``raccoon.foundation.set_speed_mode_enabled`` so the motion runtime sees the new state. 4. On timeout, raise ``RuntimeError`` — the firmware did not confirm the change and the library state must not diverge from the hardware state. Classes ------- .. autoapisummary:: step.motion.set_speed_mode.SetSpeedMode Module Contents --------------- .. py:class:: SetSpeedMode(enabled: bool, timeout_s: float = _DEFAULT_ACK_TIMEOUT_S) Bases: :py:obj:`step.Step` Enable or disable SpeedMode (BEMF off / on) via an LCM handshake. SpeedMode disables the firmware's BEMF closed-loop measurements, granting ~10% additional top speed in exchange for cm precision. Once SpeedMode is active, every motion that has a distance- or angle-based goal will refuse to start — use ``until``-conditions (sensors, timeouts, light gates, ...) to terminate motions instead. Returning to normal mode restores BEMF and cm accuracy. The step publishes the command, waits for the firmware's ACK on the retained ``raccoon/feature/bemf_enabled`` channel, and only then updates the library's ``SpeedModeContext`` flag. If no ACK arrives within the timeout it raises so the program does not proceed with library / firmware state out of sync. :param enabled: ``True`` to engage SpeedMode (BEMF off, 10% faster, no cm precision); ``False`` to return to normal closed-loop BEMF control. :param timeout_s: Maximum time in seconds to wait for the firmware ACK before raising ``RuntimeError``. Defaults to 0.5 s. :raises RuntimeError: If the firmware does not acknowledge the command within ``timeout_s``. Example:: from raccoon.step.motion import set_speed_mode, drive_forward from raccoon.step.sensor import on_black set_speed_mode(True) drive_forward(speed=1.0).until(on_black(line_sensor)) set_speed_mode(False)