Skip to content
sedlak477Public

About

A python module providing high-level control for the OWL platform

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

21 Commits

Folders and files

Repository files navigation

pyowl

This module provides high-level control for the OWL platform via serial communication.

Installation

To install the package, we recommend using uv:

uv add git+https://github.com/sedlak477/pyowl.git

Alternatively, you can use standard pip:

pip install git+https://github.com/sedlak477/pyowl.git

Usage

The 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}°")

Basic Example

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()

API

OWL Class

Constructor: OWL(port: str, baudrate: int = 115200, timeout: float = 10.0, **kwargs)

  • port: The serial port (e.g., /dev/ttyUSB0 on Linux, COM3 on Windows).
  • baudrate: Serial baud rate (default: 115200).
  • timeout: Read timeout in seconds (default: 10.0).
  • **kwargs: Additional arguments passed to serial.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.

Motor settings

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 snapshot

Related resources

owl-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.

AI Disclosure

Large parts of the project were created with the help of AI tooling.

About

A python module providing high-level control for the OWL platform

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages