This module provides high-level control for the OWL platform via serial communication.
To install the package, we recommend using uv:
uv add git+https://github.com/sedlak477/pyowl.gitAlternatively, you can use standard pip:
pip install git+https://github.com/sedlak477/pyowl.gitThe recommended way to use pyowl is with a context manager, which handles cleanup automatically:
from pyowl import OWL
with OWL(port='/dev/ttyUSB0') as owl:
# Set target position (in radians)
owl.set_target(3.14159) # Set target to π radians
owl.set_target(180, unit="deg") # Set target to 180°
# Get current target position
target = owl.get_target()
print(f"Target: {target} rad")
# Get current absolute angle in radians
absolute_angle = owl.get_absolute_angle()
print(f"Absolute angle: {absolute_angle} rad")
# Get current mechanical angle (within current revolution) in degrees
mechanical_angle = owl.get_mechanical_angle(unit="deg")
print(f"Mechanical angle: {mechanical_angle}°")When not using the context manager, you must manually ensure the connection is opened and closed:
from pyowl import OWL
owl = OWL(port='/dev/ttyUSB0')
owl.open()
try:
# Set target position
owl.set_target(1.5708) # Set target to π/2 radians
# Get position information
target = owl.get_target()
absolute = owl.get_absolute_angle()
mechanical = owl.get_mechanical_angle()
print(f"Target: {target} rad")
print(f"Absolute: {absolute} rad")
print(f"Mechanical: {mechanical} rad")
finally:
owl.close()Constructor:
OWL(port: str, baudrate: int = 115200, timeout: float = 10.0, **kwargs)
port: The serial port (e.g.,/dev/ttyUSB0on Linux,COM3on Windows).baudrate: Serial baud rate (default: 115200).timeout: Read timeout in seconds (default: 10.0).**kwargs: Additional arguments passed toserial.Serial.
Methods:
open(): Opens the serial connection.close(): Closes the serial connection.write(data: bytes) -> int: Writes raw bytes to the device. Returns the number of bytes written.read(size: int = 1) -> bytes: Reads raw bytes from the device.read_line(num_lines: int = 1) -> str: Reads one or more lines of text, decoded as UTF-8.raw_command(command: str, num_lines: int = 1) -> str: Sends a raw text command and reads the response. It is recommended to use the higher-level functions instead.set_target(target: float, unit: Literal["rad", "deg"] = "rad") -> None: Sets the target position.get_target(unit: Literal["rad", "deg"] = "rad") -> float: Gets the current target position.get_absolute_angle(unit: Literal["rad", "deg"] = "rad") -> float: Gets the current absolute angle (since last reset).get_mechanical_angle(unit: Literal["rad", "deg"] = "rad") -> float: Gets the current mechanical angle (within current revolution).get_motor_voltage() -> float: Gets the motor voltage in volts.set_LED(on: bool) -> None: Sets the user LED state.buzz(duration: int) -> None: Buzzes the buzzer for a specified duration in milliseconds.goto(target: float, unit: Literal["rad", "deg"] = "rad") -> None: Moves the OWL to a target position. Blocks until the target is reached.get_setting(name: str | Iterable[str] | None = None) -> float | dict[str, float]: Gets a motor setting (see below), or a dict of several. Defaults to the angle and velocity PID settings and the limits (DEFAULT_SNAPSHOT).set_setting(name: str | dict[str, float], value: float | None = None) -> float | dict[str, float]: Sets a motor setting, or several in order from a dict, and returns the value(s) read back from the OWL.
The firmware exposes SimpleFOC's motor commands under M. Settings are named by their command code without the M, e.g. VP (velocity PID P gain), AP (angle PID P gain) or LV (velocity limit in rad/s). MOTOR_SETTINGS lists all supported codes; unknown codes raise a ValueError. Settings are kept in RAM only and reset when the OWL restarts, and values are read back with 3 decimal places.
with OWL(port='/dev/ttyUSB0') as owl:
owl.set_setting("LV", 3.14)
owl.set_setting({"VP": 0.5, "VI": 10, "AP": 20})
print(owl.get_setting("VP"))
print(owl.get_setting()) # default snapshotowl-firmware: The firmware for the OWL platform.
owl-ranger: A script for stepping through some orientations and recording measurements.
owl-hardware: Hardware design files for the OWL platform.
Dataset: Orientation-diverse BLE Channel Sounding and UWB ranging measurements recorded with the OWL.
Large parts of the project were created with the help of AI tooling.