Skip to main content

Common Python libraries used by parts of Bell AVR

Project description

AVR-Python-Libraries

Install

To install the base package, run:

pip install bell-avr-libraries

Additionally, the mqtt and serial extras are available if you want to use the MQTT or PCC functionality.

pip install bell-avr-libraries[mqtt,serial]

Usage

MQTT

from bell.avr import mqtt

These are MQTT utilities that are used to have a consistent messaging protocol throughout all the AVR software modules.

The first part of this are the payloads for the MQTT messages themselves. As AVR exclusively uses JSON, these are all TypedDicts that have all of the required fields for a message.

Example:

from bell.avr.mqtt.payloads import AvrPcmSetBaseColorPayload

payload = AvrPcmSetBaseColorPayload((128, 232, 142, 0))

The second part of the MQTT libraries, is the MQTTModule class. This is a boilerplate module for AVR that makes it very easy to send and recieve MQTT messages and do something with them.

Example:

from bell.avr.mqtt.client import MQTTModule
from bell.avr.mqtt.payloads import AvrFcmVelocityPayload, AvrPcmSetServoOpenClosePayload


class Sandbox(MQTTModule):
    def __init__(self) -> None:
        super().__init__()
        self.topic_map = {"avr/fcm/velocity": self.show_velocity}

    def show_velocity(self, payload: AvrFcmVelocityPayload) -> None:
        vx = payload["vX"]
        vy = payload["vY"]
        vz = payload["vZ"]
        v_ms = (vx, vy, vz)
        print(f"Velocity information: {v_ms} m/s")

    def open_servo(self) -> None:
        payload = AvrPcmSetServoOpenClosePayload(servo=0, action="open")
        self.send_message("avr/pcm/set_servo_open_close", payload)


if __name__ == "__main__":
    box = Sandbox()
    box.run()

The topic_map dictionary is a class attribute that maps topics to subscribe to and a function that will handle an incoming payload. The payload argument should match the appropriate Payload class for that topic.

Additionally, the message_cache attribute is a dictionary that holds a copy of the last payload sent by that module on a given topic. The keys are the topic strings, and the values are the topic payloads.

Utils

from bell.avr import utils

These are general purpose utilities.

Decorators

from bell.avr.utils import decorators

There are 3 different function decorators available, which are helpful for MQTT message callbacks. First is the try_except decorator, which wraps the function in a try: except: statement and will log any exceptions to the console:

    @decorators.try_except
    def assemble_hil_gps_message(self) -> None:
        ...

Additionally, there is the reraise argument, which can be set to True to raise any exceptions that are encountered. This is helpful if you still want exceptions to propagate up, but log them.

There is an async version of this decorator as well with an async_ prefix.

    @decorators.async_try_except()
    async def connected_status_telemetry(self) -> None:
        ...

The last decorator is run_forever which will run the wrapped function forever, with a given period or frequency.

    @decorators.run_forever(frequency=5)
    def read_data(self) -> None:
        ...

Timing

from bell.avr.utils import timing

Here is a rate_limit function which take a callable and a period or frequency, and only run the callable at that given rate.

for _ in range(10):
    # add() will only run twice
    timing.rate_limit(add, period=5)
    time.sleep(1)

This works tracking calls to the rate_limit function from a line number within a file, so multiple calls to rate_limit say within a loop with the same callable and period will be treated seperately. This allows for dynamic frequency manipulation.

Serial

from bell.avr import serial

These are serial utilities that help facilitate finding and communicating with the AVR peripherial control computer.

Client

from bell.avr.serial import client

The SerialLoop class is a small wrapper around the pyserial serial.Serial class which adds a run method that will try to read data from the serial device as fast as possible.

ser = client.SerialLoop()

PCC

from bell.avr.serial import client

The PeripheralControlComputer class sends serial messages to the AVR peripherial control computer, via easy-to-use class methods.

import bell.avr.serial.client
import bell.avr.serial.pcc
import threading

client = bell.avr.serial.client.SerialLoop()
client.port = port
client.baudrate = baudrate
client.open()

pcc = bell.avr.serial.pcc.PeripheralControlComputer(client)

client_thread = threading.Thread(target=client.run)
client_thread.start()

pcc.set_servo_max(0, 100)

Ports

from bell.avr.serial import ports

Here is a list_serial_ports function which returns a list of detected serial ports connected to the system.

serial_ports = ports.list_serial_ports()
# ["COM1", "COM5", ...]

Development

Install poetry and run poetry install --extras mqtt --extras serial to install of the dependencies inside a virtual environment.

Build the auto-generated code with poetry run python build.py. From here, you can now produce a package with poetry build.

To add new message definitions, add entries to the bell/avr/mqtt/messages.jsonc file. The 3 parts of a new message are as follows:

  1. "topic": This is the full topic path for the message. This must be all lower case and start with "avr/".
  2. "payload": These are the keys of the payload for the message. This is a list of key entries (see below).
  3. "docs": This is an optional list of Markdown strings that explains what this message does. Each list item is a new line.

The key entries for a message have the following elements:

  1. "key": This is the name of the key. Must be a valid Python variable name.
  2. "type": This is the data type of the key such as Tuple[int, int, int, int]. Must be a valid Python type hint. Otherwise, this can be a list of more key entries, effectively creating a nested dictionary.
  3. "docs": This is an optional list of Markdown strings that explains what the key is. Each list item is a new line.

The bell/avr/mqtt/schema.json file will help ensure the correct schema is maintained, assuming you are using VS Code.

MQTT Documentation

Data Types

AvrApriltagsRawTags

  • "id" (int): The ID of the AprilTag
  • "pos" (AvrApriltagsRawTagsPos)
  • "rotation" (Tuple[Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float]]): The 3x3 rotation matrix

AvrApriltagsRawTagsPos

  • "x" (float): The position in meters of the camera relative to the AprilTag's X frame
  • "y" (float): The position in meters of the camera relative to the AprilTag's Y frame
  • "z" (float): The position in meters of the camera relative to the AprilTag's Z frame

AvrApriltagsSelectedPos

The position of the vehicle in world frame in centimeters

  • "n" (float): The +north position of the vehicle relative to the world origin in world frame
  • "e" (float): The +east position of the vehicle relative to the world origin in world frame
  • "d" (float): The +down position of the vehicle relative to the world origin in world frame

AvrApriltagsVisibleTags

  • "id" (int): The ID of the AprilTag
  • "horizontal_dist" (float): The horizontal scalar distance from vehicle to AprilTag, in centimeters
  • "vertical_dist" (float): The vertical scalar distance from vehicle to AprilTag, in centimeters
  • "angle_to_tag" (float): The angle formed by the vector pointing from the vehicles body to the AprilTag in world frame relative to world-north
  • "heading" (float): The heading of the vehicle in world frame
  • "pos_rel" (AvrApriltagsVisibleTagsPosRel): The relative position of the vehicle to the tag in world frame in centimeters
  • "pos_world" (AvrApriltagsVisibleTagsPosWorld): The position of the vehicle in world frame in centimeters (if the tag has no truth data, this will not be present in the output)

AvrApriltagsVisibleTagsPosRel

The relative position of the vehicle to the tag in world frame in centimeters

  • "x" (float): The x (+north/-south) position of the vehicle relative to the AprilTag in world frame
  • "y" (float): The y (+east/-west) position of the vehicle relative to the AprilTag in world frame
  • "z" (float): The z (+down/-up) position of the vehicle relative to the AprilTag in world frame

AvrApriltagsVisibleTagsPosWorld

The position of the vehicle in world frame in centimeters (if the tag has no truth data, this will not be present in the output)

  • "x" (Optional[float]): The x position of the vehicle relative to the world origin (this is the ship) in world frame (for reference the mountain is north of the beach)
  • "y" (Optional[float]): The y position of the vehicle relative to the world origin in world frame
  • "z" (Optional[float]): The z position of the vehicle relative to the world origin in world frame

Message Payloads

AvrApriltagsFpsPayload

Topic: avr/apriltags/fps

This reports the framerate of AprilTag processing

  • "fps" (int): Number of frames of video data processed in the last second

AvrApriltagsRawPayload

Topic: avr/apriltags/raw

This topic publishes the raw AprilTag data

  • "tags" (List[AvrApriltagsRawTags])

AvrApriltagsSelectedPayload

Topic: avr/apriltags/selected

This topic publishes its best candidate for position feedback

  • "tag_id" (int): The id of the tag
  • "pos" (AvrApriltagsSelectedPos): The position of the vehicle in world frame in centimeters
  • "heading" (float)

AvrApriltagsVisiblePayload

Topic: avr/apriltags/visible

This topic publishes the transformed AprilTag data

  • "tags" (List[AvrApriltagsVisibleTags])

AvrAutonomousBuildingDropPayload

Topic: avr/autonomous/building/drop

This enables or disables a building payload drop. This is not used by any Bell code, but available to students to listen to.

  • "id" (int): 0-index ID of the relevant building
  • "enabled" (bool): Boolean of whether the building should have drop enabled

AvrAutonomousEnablePayload

Topic: avr/autonomous/enable

This enables or disables autonomous mode. This is not used by any Bell code, but available to students to.

  • "enabled" (bool)

AvrFcmAttitudeEulerPayload

Topic: avr/fcm/attitude/euler

This reports the current attitude of the drone from the flight controller.

  • "roll" (float): Roll in degrees
  • "pitch" (float): Pitch in degrees
  • "yaw" (float): Yaw in degrees

AvrFcmBatteryPayload

Topic: avr/fcm/battery

This reports battery information from the flight controller.

  • "voltage" (float): Battery voltage
  • "soc" (float): State of charge (0 - 100)

AvrFcmEventsPayload

Topic: avr/fcm/events

This reports events from the flight controller such as flight mode changes.

  • "name" (str): The name of the event.
  • "payload" (str): The payload of the event.

AvrFcmGpsInfoPayload

Topic: avr/fcm/gps_info

This reports the current status of the flight controller's GPS connection.

  • "num_satellites" (int): Number of visible satellites in use. HIL GPS will appear as 13.
  • "fix_type" (str): GPS fix type

AvrFcmHilGpsStatsPayload

Topic: avr/fcm/hil_gps_stats

This reports statistics on the HIL GPS data that is fed into the flight controller.

  • "num_frames" (int): This is the number of messages that have been sent to the flight controller since the software has started.

AvrFcmLocationGlobalPayload

Topic: avr/fcm/location/global

This reports the current position of the drone in global coordinates from the flight controller.

  • "lat" (float): Latitude in degrees
  • "lon" (float): Longitude in degrees
  • "alt" (float): Altitude relative to takeoff altitude in meters
  • "hdg" (float): Heading in degrees.

AvrFcmLocationHomePayload

Topic: avr/fcm/location/home

This reports the current position of the drone's home position in global coordinates.

  • "lat" (float): Latitude in degrees of the home position
  • "lon" (float): Longitude in degrees of the home position
  • "alt" (float): Altitude relative to the home position in meters

AvrFcmLocationLocalPayload

Topic: avr/fcm/location/local

This reports the current position of the drone in local coordinates from the flight controller.

  • "dX" (float): X position in a local North/East/Down coordinate system in meters
  • "dY" (float): Y position in a local North/East/Down coordinate system in meters
  • "dZ" (float): Z position in a local North/East/Down coordinate system in meters

AvrFcmStatusPayload

Topic: avr/fcm/status

This reports general status of the flight controller.

  • "armed" (bool): Boolean of if the drone is currently armed
  • "mode" (str): Current flight mode, which is one of the following:
    • 'UNKNOWN'
    • 'READY'
    • 'TAKEOFF'
    • 'HOLD'
    • 'MISSION'
    • 'RETURN_TO_LAUNCH'
    • 'LAND'
    • 'OFFBOARD'
    • 'FOLLOW_ME'
    • 'MANUAL'
    • 'ALTCTL'
    • 'POSCTL'
    • 'ACRO'
    • 'STABILIZED'
    • 'RATTITUDE'

AvrFcmVelocityPayload

Topic: avr/fcm/velocity

This reports the current velocity vectors of the drone from the flight controller.

  • "vX" (float): X velocity in a local North/East/Down coordinate system in meters per second
  • "vY" (float): Y velocity in a local North/East/Down coordinate system in meters per second
  • "vZ" (float): Z velocity in a local North/East/Down coordinate system in meters per second

AvrFusionAttitudeEulerPayload

Topic: avr/fusion/attitude/euler

This reports the computed attitude of the drone from our sensor fusion.

  • "psi" (float): Roll in radians
  • "theta" (float): Pitch in radians
  • "phi" (float): Yaw in radians

AvrFusionAttitudeHeadingPayload

Topic: avr/fusion/attitude/heading

This reports the computed heading of the drone from our sensor fusion.

  • "heading" (float): Heading in degrees

AvrFusionAttitudeQuatPayload

Topic: avr/fusion/attitude/quat

This reports the computed attitude of the drone from our sensor fusion.

  • "w" (float): Quaternion w value
  • "x" (float): Quaternion x value
  • "y" (float): Quaternion y value
  • "z" (float): Quaternion z value

AvrFusionClimbratePayload

Topic: avr/fusion/climbrate

This reports the computed rate of climb of the drone from our sensor fusion.

  • "climb_rate_fps" (float): Rate of climb in feet per second

AvrFusionCoursePayload

Topic: avr/fusion/course

This reports the computed course of the drone from our sensor fusion.

  • "course" (float): Course in degrees

AvrFusionGeoPayload

Topic: avr/fusion/geo

This reports the computed position of the drone in global coordinates from our sensor fusion.

  • "lat" (float): Latitude in degrees
  • "lon" (float): Longitude in degrees
  • "alt" (float): Altitude relative to takeoff altitude in meters

AvrFusionGroundspeedPayload

Topic: avr/fusion/groundspeed

This reports the computed groundspeed of the drone from our sensor fusion.

  • "groundspeed" (float): Groundspeed of the drone in meters per second. This is a normal vector of the N and E velocities.

AvrFusionHilGpsPayload

Topic: avr/fusion/hil_gps

This is the raw data that will get converted to a MAVLink message and sent to the flight controller for HIL GPS. https://mavlink.io/en/messages/common.html#HIL_GPS

  • "time_usec" (int): UNIX epoch timestamp in microseconds
  • "fix_type" (int): 0-1: no fix, 2: 2D fix, 3: 3D fix.
  • "lat" (int): WGS84 Latitude * 10000000
  • "lon" (int): WGS84 Longitude * 10000000
  • "alt" (int): Altitude from sea level in mm. Positive for up.
  • "eph" (int): GPS HDOP horizontal dilution of position
  • "epv" (int): GPS VDOP vertical dilution of position
  • "vel" (int): GPS ground speed in centimeters per second
  • "vn" (int): GPS velocity in north direction in centimeters per second
  • "ve" (int): GPS velocity in east direction in centimeters per second
  • "vd" (int): GPS velocity in down direction in centimeters per second
  • "cog" (int): Course over ground in degrees
  • "satellites_visible" (int): Number of satellites visible. This is hardcoded to 13 for our HIL GPS.
  • "heading" (int): Custom heading field. This is the heading in degrees * 100.

AvrFusionPositionNedPayload

Topic: avr/fusion/position/ned

This reports the computed position of the drone in local coordinates from our sensor fusion.

  • "n" (float): X position in a local North/East/Down coordinate system in meters
  • "e" (float): Y position in a local North/East/Down coordinate system in meters
  • "d" (float): Z position in a local North/East/Down coordinate system in meters

AvrFusionVelocityNedPayload

Topic: avr/fusion/velocity/ned

This reports the computed velocity vectors of the drone from our sensor fusion.

  • "Vn" (float): X velocity in a local North/East/Down coordinate system in meters per second
  • "Ve" (float): Y velocity in a local North/East/Down coordinate system in meters per second
  • "Vd" (float): Z velocity in a local North/East/Down coordinate system in meters per second

AvrPcmFireLaserPayload

Topic: avr/pcm/fire_laser

Fires the laser for a 0.25 sec pulse. Has a cooldown of 0.5 sec.

There is no content for this class

AvrPcmSetBaseColorPayload

Topic: avr/pcm/set_base_color

This sets the color of the LED strip on the PCC

  • "wrgb" (Tuple[int, int, int, int]): A list of 4 ints between 0 and 255 to set the base color of the LEDs. This is in order of White, Red, Green, Blue. Example: [0, 0, 255, 0] would be Green.

AvrPcmSetLaserOffPayload

Topic: avr/pcm/set_laser_off

Turns off laser (laser off from blip mode - but doesn't prevent fire_laser)

There is no content for this class

AvrPcmSetLaserOnPayload

Topic: avr/pcm/set_laser_on

Turns on laser (in blip mode - 0.1 second on every 0.5. sec)

There is no content for this class

AvrPcmSetServoAbsPayload

Topic: avr/pcm/set_servo_abs

This sets the absolute position of a specific servo. SERVOMIN 150 is closed, and SERVOMAX 425 is open. We need to send a High and Low byte due to limitations of the API

  • "servo" (int): ID of the servo to set the percent as an int. This is 0-indexed.
  • "absolute" (int): Absolute position between SERVOMIN 150 and SERVOMAX 425

AvrPcmSetServoMaxPayload

Topic: avr/pcm/set_servo_max

This sets the maximum pulse width of a specific servo.

  • "servo" (int): ID of the servo to set the maximum pulse width as an int. This is 0-indexed.
  • "max_pulse" (int): A int between 0 and 1000.

AvrPcmSetServoMinPayload

Topic: avr/pcm/set_servo_min

This sets the minimum pulse width of a specific servo.

  • "servo" (int): ID of the servo to set the minimum pulse width as an int. This is 0-indexed.
  • "min_pulse" (int): A int between 0 and 1000.

AvrPcmSetServoOpenClosePayload

Topic: avr/pcm/set_servo_open_close

This opens or closes a specific servo.

  • "servo" (int): ID of the servo to open or close as an int. This is 0-indexed.
  • "action" (Literal["open", "close"]): Either the literal string "open" or "close".

AvrPcmSetServoPctPayload

Topic: avr/pcm/set_servo_pct

This sets the percentage of a specific servo. 0 is closed, and 100 is open.

  • "servo" (int): ID of the servo to set the percent as an int. This is 0-indexed.
  • "percent" (int): A int between 0 and 100.

AvrPcmSetTempColorPayload

Topic: avr/pcm/set_temp_color

This sets the color of the LED strip on the PCC temporarily

  • "wrgb" (Tuple[int, int, int, int]): A list of 4 ints between 0 and 255 to set the base color of the LEDs. This is in order of White, Red, Green, Blue. Example: [0, 0, 255, 0] would be Green.
  • "time" (float): Optional float for the number of seconds the color should be set for. Default is 0.5.

AvrStatusLightApriltagsPayload

Topic: avr/status/light/apriltags

There is no content for this class

AvrStatusLightFcmPayload

Topic: avr/status/light/fcm

There is no content for this class

AvrStatusLightPcmPayload

Topic: avr/status/light/pcm

There is no content for this class

AvrStatusLightThermalPayload

Topic: avr/status/light/thermal

There is no content for this class

AvrStatusLightVioPayload

Topic: avr/status/light/vio

There is no content for this class

AvrThermalReadingPayload

Topic: avr/thermal/reading

This publishes data from the thermal camera

  • "data" (str): The raw data from the thermal camera are integer values from an 8x8 grid of pixels. This data is then converted into a bytearray and base64 encoded. Any example of how to unpack this data:

    import base64
    import json
    
    data = json.loads(payload)["data"]
    base64_decoded = data.encode("utf-8")
    as_bytes = base64.b64decode(base64_decoded)
    pixel_ints = list(bytearray(as_bytes))
    

AvrVioConfidencePayload

Topic: avr/vio/confidence

This reports the tracking camera's confidence

  • "tracker" (float): Number between 0 and 100 of tracking confidence

AvrVioHeadingPayload

Topic: avr/vio/heading

This reports the measued heading of the drone from the tracking camera.

  • "degrees" (float): Heading in degrees

AvrVioOrientationEulPayload

Topic: avr/vio/orientation/eul

This reports the measued attitude of the drone from the tracking camera.

  • "psi" (float): Roll in radians
  • "theta" (float): Pitch in radians
  • "phi" (float): Yaw in radians

AvrVioOrientationQuatPayload

Topic: avr/vio/orientation/quat

This reports the measued attitude of the drone from the tracking camera.

  • "w" (float): Quaternion w value
  • "x" (float): Quaternion x value
  • "y" (float): Quaternion y value
  • "z" (float): Quaternion z value

AvrVioPositionNedPayload

Topic: avr/vio/position/ned

This reports the measured position of the drone in local coordinates from the tracking camera.

  • "n" (float): X position in a local North/East/Down coordinate system in meters
  • "e" (float): Y position in a local North/East/Down coordinate system in meters
  • "d" (float): Z position in a local North/East/Down coordinate system in meters

AvrVioResyncPayload

Topic: avr/vio/resync

This reports significant position differences from the tracking camera, and detected AprilTags at known positions.

  • "n" (float): X position difference in a local North/East/Down coordinate system in meters
  • "e" (float): Y position difference in a local North/East/Down coordinate system in meters
  • "d" (float): Z position difference in a local North/East/Down coordinate system in meters
  • "heading" (float): Heading difference in degrees

AvrVioVelocityNedPayload

Topic: avr/vio/velocity/ned

This reports the measued velocity vectors of the drone from the tracking camera.

  • "n" (float): X velocity in a local North/East/Down coordinate system in meters per second
  • "e" (float): Y velocity in a local North/East/Down coordinate system in meters per second
  • "d" (float): Z velocity in a local North/East/Down coordinate system in meters per second

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bell_avr_libraries-0.1.13.tar.gz (28.7 kB view hashes)

Uploaded Source

Built Distribution

bell_avr_libraries-0.1.13-py3-none-any.whl (23.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page