Repository URL to install this package:
Version:
0.5.3 ▾
|
"""
MAVLink protocol implementation (auto-generated by mavgen.py)
Generated from: ('loweheiser.xml,minimal.xml',)
Note: this file has been auto-generated. DO NOT EDIT
"""
import hashlib
import json
import logging
import os
import struct
import sys
import time
from builtins import object, range
from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple, Type, Union
WIRE_PROTOCOL_VERSION = "1.0"
DIALECT = "loweheiser"
PROTOCOL_MARKER_V1 = 0xFE
PROTOCOL_MARKER_V2 = 0xFD
HEADER_LEN_V1 = 6
HEADER_LEN_V2 = 10
MAVLINK_SIGNATURE_BLOCK_LEN = 13
MAVLINK_IFLAG_SIGNED = 0x01
logger = logging.getLogger(__name__)
# allow MAV_IGNORE_CRC=1 to ignore CRC, allowing some
# corrupted msgs to be seen
MAVLINK_IGNORE_CRC = os.environ.get("MAV_IGNORE_CRC", 0)
# some base types from mavlink_types.h
MAVLINK_TYPE_CHAR = 0
MAVLINK_TYPE_UINT8_T = 1
MAVLINK_TYPE_INT8_T = 2
MAVLINK_TYPE_UINT16_T = 3
MAVLINK_TYPE_INT16_T = 4
MAVLINK_TYPE_UINT32_T = 5
MAVLINK_TYPE_INT32_T = 6
MAVLINK_TYPE_UINT64_T = 7
MAVLINK_TYPE_INT64_T = 8
MAVLINK_TYPE_FLOAT = 9
MAVLINK_TYPE_DOUBLE = 10
# CRC calculation using fastcrc, falling back to a pure Python implementation
# if fastcrc is not available
try:
import fastcrc
mcrf4xx = fastcrc.crc16.mcrf4xx
except Exception:
mcrf4xx = None # type: ignore
BytesLike = Union[List[int], Tuple[int], bytes, bytearray, str]
class _x25crc_slow(object):
"""CRC-16/MCRF4XX - based on checksum.h from mavlink library"""
crc: int
def __init__(self, buf: Optional[BytesLike] = None):
self.crc = 0xFFFF
if buf is not None:
self.accumulate(buf)
def accumulate(self, buf: BytesLike) -> None:
"""add in some more bytes (it also accepts strings)"""
if isinstance(buf, str):
buf = buf.encode()
accum = self.crc
for b in buf:
tmp = b ^ (accum & 0xFF)
tmp = (tmp ^ (tmp << 4)) & 0xFF
accum = (accum >> 8) ^ (tmp << 8) ^ (tmp << 3) ^ (tmp >> 4)
self.crc = accum
class _x25crc_fast(object):
"""CRC-16/MCRF4XX - based on checksum.h from mavlink library"""
def __init__(self, buf: Optional[BytesLike] = None):
self.crc = 0xFFFF
if buf is not None:
self.accumulate(buf)
def accumulate(self, buf: BytesLike) -> None:
"""add in some more bytes (it also accepts strings)"""
if isinstance(buf, str):
buf_as_bytes = bytes(buf.encode())
elif isinstance(buf, (list, tuple, bytearray)):
buf_as_bytes = bytes(buf)
else:
buf_as_bytes = buf
self.crc = mcrf4xx(buf_as_bytes, self.crc)
x25crc = _x25crc_fast if mcrf4xx is not None else _x25crc_slow
class MAVLink_header(object):
"""MAVLink message header"""
def __init__(self, msgId: int, incompat_flags: int = 0, compat_flags: int = 0, mlen: int = 0, seq: int = 0, srcSystem: int = 0, srcComponent: int = 0) -> None:
self.mlen = mlen
self.seq = seq
self.srcSystem = srcSystem
self.srcComponent = srcComponent
self.msgId = msgId
self.incompat_flags = incompat_flags
self.compat_flags = compat_flags
def pack(self, force_mavlink1: bool = False) -> bytes:
if float(WIRE_PROTOCOL_VERSION) == 2.0 and not force_mavlink1:
return struct.pack(
"<BBBBBBBHB",
254,
self.mlen,
self.incompat_flags,
self.compat_flags,
self.seq,
self.srcSystem,
self.srcComponent,
self.msgId & 0xFFFF,
self.msgId >> 16,
)
return struct.pack(
"<BBBBBB",
PROTOCOL_MARKER_V1,
self.mlen,
self.seq,
self.srcSystem,
self.srcComponent,
self.msgId,
)
class MAVLink_message(object):
"""base MAVLink message class"""
id = 0
msgname = ""
fieldnames: List[str] = []
ordered_fieldnames: List[str] = []
fieldtypes: List[str] = []
fielddisplays_by_name: Dict[str, str] = {}
fieldenums_by_name: Dict[str, str] = {}
fieldunits_by_name: Dict[str, str] = {}
native_format = bytearray(b"")
orders: List[int] = []
lengths: List[int] = []
array_lengths: List[int] = []
crc_extra = 0
unpacker = struct.Struct("")
instance_field: Optional[str] = None
instance_offset = -1
def __init__(self, msgId: int, name: str) -> None:
self._header = MAVLink_header(msgId)
self._payload: Optional[bytes] = None
self._msgbuf = bytearray(b"")
self._crc: Optional[int] = None
self._fieldnames: List[str] = []
self._type = name
self._signed = False
self._link_id: Optional[int] = None
self._instances: Optional[Dict[str, str]] = None
self._instance_field: Optional[str] = None
def format_attr(self, field: str) -> Union[str, float, int]:
"""override field getter"""
raw_attr: Union[bytes, float, int] = getattr(self, field)
if isinstance(raw_attr, bytes):
return raw_attr.decode(errors="backslashreplace").rstrip("\x00")
return raw_attr
def get_msgbuf(self) -> bytearray:
return self._msgbuf
def get_header(self) -> MAVLink_header:
return self._header
def get_payload(self) -> Optional[bytes]:
return self._payload
def get_crc(self) -> Optional[int]:
return self._crc
def get_fieldnames(self) -> List[str]:
return self._fieldnames
def get_type(self) -> str:
return self._type
def get_msgId(self) -> int:
return self._header.msgId
def get_srcSystem(self) -> int:
return self._header.srcSystem
def get_srcComponent(self) -> int:
return self._header.srcComponent
def get_seq(self) -> int:
return self._header.seq
def get_signed(self) -> bool:
return self._signed
def get_link_id(self) -> Optional[int]:
return self._link_id
def __str__(self) -> str:
ret = "%s {" % self._type
for a in self._fieldnames:
v = self.format_attr(a)
ret += "%s : %s, " % (a, v)
ret = ret[0:-2] + "}"
return ret
def __ne__(self, other: object) -> bool:
return not self.__eq__(other)
def __eq__(self, other: object) -> bool:
if other is None:
return False
if not isinstance(other, MAVLink_message):
return False
if self.get_type() != other.get_type():
return False
if self.get_crc() != other.get_crc():
return False
if self.get_seq() != other.get_seq():
return False
if self.get_srcSystem() != other.get_srcSystem():
return False
if self.get_srcComponent() != other.get_srcComponent():
return False
for a in self._fieldnames:
if self.format_attr(a) != other.format_attr(a):
return False
return True
def to_dict(self) -> Dict[str, Union[str, float, int]]:
d: Dict[str, Union[str, float, int]] = {}
d["mavpackettype"] = self._type
for a in self._fieldnames:
d[a] = self.format_attr(a)
return d
def to_json(self) -> str:
return json.dumps(self.to_dict())
def sign_packet(self, mav: "MAVLink") -> None:
assert mav.signing.secret_key is not None
h = hashlib.new("sha256")
self._msgbuf += struct.pack("<BQ", mav.signing.link_id, mav.signing.timestamp)[:7]
h.update(mav.signing.secret_key)
h.update(self._msgbuf)
sig = h.digest()[:6]
self._msgbuf += sig
mav.signing.timestamp += 1
def _pack(self, mav: "MAVLink", crc_extra: int, payload: bytes, force_mavlink1: bool = False) -> bytes:
plen = len(payload)
if float(WIRE_PROTOCOL_VERSION) == 2.0 and not force_mavlink1:
# in MAVLink2 we can strip trailing zeros off payloads. This allows for simple
# variable length arrays and smaller packets
nullbyte = 0
while plen > 1 and payload[plen - 1] == nullbyte:
plen -= 1
self._payload = payload[:plen]
incompat_flags = 0
if mav.signing.sign_outgoing:
incompat_flags |= MAVLINK_IFLAG_SIGNED
self._header = MAVLink_header(
self._header.msgId,
incompat_flags=incompat_flags,
compat_flags=0,
mlen=len(self._payload),
seq=mav.seq,
srcSystem=mav.srcSystem,
srcComponent=mav.srcComponent,
)
self._msgbuf = bytearray(self._header.pack(force_mavlink1=force_mavlink1))
self._msgbuf += self._payload
crc = x25crc(self._msgbuf[1:])
if True:
# we are using CRC extra
crc.accumulate(struct.pack("B", crc_extra))
self._crc = crc.crc
self._msgbuf += struct.pack("<H", self._crc)
if mav.signing.sign_outgoing and not force_mavlink1:
self.sign_packet(mav)
return bytes(self._msgbuf)
def pack(self, mav: "MAVLink", force_mavlink1: bool = False) -> bytes:
raise NotImplementedError("MAVLink_message cannot be serialized directly")
def __getitem__(self, key: str) -> str:
"""support indexing, allowing for multi-instance sensors in one message"""
if self._instances is None:
raise IndexError()
if key not in self._instances:
raise IndexError()
return self._instances[key]
class mavlink_msg_deprecated_name_property(object):
"""
This handles the class variable name change from name to msgname for
subclasses of MAVLink_message during a transition period.
This is used by setting the class variable to
`mavlink_msg_deprecated_name_property()`.
"""
def __get__(self, instance: Optional[MAVLink_message], owner: Type[MAVLink_message]) -> str:
if instance is not None:
logger.error("Using .name on a MAVLink_message is not supported, use .get_type() instead.")
raise AttributeError("Class {} has no attribute 'name'".format(owner.__name__))
logger.warning(
"""Using .name on a MAVLink_message class is deprecated, consider using .msgname instead.
Note that if compatibility with pymavlink 2.4.30 and earlier is desired, use something like this:
msg_name = msg.msgname if hasattr(msg, "msgname") else msg.name"""
)
return owner.msgname
# enums
class EnumEntry(object):
def __init__(self, name: str, description: str) -> None:
self.name = name
self.description = description
self.param: Dict[int, str] = {}
self.has_location = False
class Enum(Dict[int, EnumEntry]):
def __init__(self) -> None:
self.bitmask = False
enums: Dict[str, Enum] = {}
# MAV_CMD
enums["MAV_CMD"] = Enum()
enums["MAV_CMD"].bitmask = False
MAV_CMD_LOWEHEISER_SET_STATE = 10151
enums["MAV_CMD"][10151] = EnumEntry("MAV_CMD_LOWEHEISER_SET_STATE", """Set Loweheiser desired states""")
enums["MAV_CMD"][10151].param[1] = """EFI Index"""
enums["MAV_CMD"][10151].param[2] = """Desired Engine/EFI State (0: Power Off, 1:Running)"""
enums["MAV_CMD"][10151].param[3] = """Desired Governor State (0:manual throttle, 1:Governed throttle)"""
enums["MAV_CMD"][10151].param[4] = """Manual throttle level, 0% - 100%"""
enums["MAV_CMD"][10151].param[5] = """Electronic Start up (0:Off, 1:On)"""
enums["MAV_CMD"][10151].param[6] = """Empty"""
enums["MAV_CMD"][10151].param[7] = """Empty"""
MAV_CMD_ENUM_END = 10152
enums["MAV_CMD"][10152] = EnumEntry("MAV_CMD_ENUM_END", """""")
# MAV_AUTOPILOT
enums["MAV_AUTOPILOT"] = Enum()
enums["MAV_AUTOPILOT"].bitmask = False
MAV_AUTOPILOT_GENERIC = 0
enums["MAV_AUTOPILOT"][0] = EnumEntry("MAV_AUTOPILOT_GENERIC", """Generic autopilot, full support for everything""")
MAV_AUTOPILOT_RESERVED = 1
enums["MAV_AUTOPILOT"][1] = EnumEntry("MAV_AUTOPILOT_RESERVED", """Reserved for future use.""")
MAV_AUTOPILOT_SLUGS = 2
enums["MAV_AUTOPILOT"][2] = EnumEntry("MAV_AUTOPILOT_SLUGS", """SLUGS autopilot, http://slugsuav.soe.ucsc.edu""")
MAV_AUTOPILOT_ARDUPILOTMEGA = 3
enums["MAV_AUTOPILOT"][3] = EnumEntry("MAV_AUTOPILOT_ARDUPILOTMEGA", """ArduPilot - Plane/Copter/Rover/Sub/Tracker, https://ardupilot.org""")
MAV_AUTOPILOT_OPENPILOT = 4
enums["MAV_AUTOPILOT"][4] = EnumEntry("MAV_AUTOPILOT_OPENPILOT", """OpenPilot, http://openpilot.org""")
MAV_AUTOPILOT_GENERIC_WAYPOINTS_ONLY = 5
enums["MAV_AUTOPILOT"][5] = EnumEntry("MAV_AUTOPILOT_GENERIC_WAYPOINTS_ONLY", """Generic autopilot only supporting simple waypoints""")
MAV_AUTOPILOT_GENERIC_WAYPOINTS_AND_SIMPLE_NAVIGATION_ONLY = 6
enums["MAV_AUTOPILOT"][6] = EnumEntry("MAV_AUTOPILOT_GENERIC_WAYPOINTS_AND_SIMPLE_NAVIGATION_ONLY", """Generic autopilot supporting waypoints and other simple navigation commands""")
MAV_AUTOPILOT_GENERIC_MISSION_FULL = 7
enums["MAV_AUTOPILOT"][7] = EnumEntry("MAV_AUTOPILOT_GENERIC_MISSION_FULL", """Generic autopilot supporting the full mission command set""")
MAV_AUTOPILOT_INVALID = 8
enums["MAV_AUTOPILOT"][8] = EnumEntry("MAV_AUTOPILOT_INVALID", """No valid autopilot, e.g. a GCS or other MAVLink component""")
MAV_AUTOPILOT_PPZ = 9
enums["MAV_AUTOPILOT"][9] = EnumEntry("MAV_AUTOPILOT_PPZ", """PPZ UAV - http://nongnu.org/paparazzi""")
MAV_AUTOPILOT_UDB = 10
enums["MAV_AUTOPILOT"][10] = EnumEntry("MAV_AUTOPILOT_UDB", """UAV Dev Board""")
MAV_AUTOPILOT_FP = 11
enums["MAV_AUTOPILOT"][11] = EnumEntry("MAV_AUTOPILOT_FP", """FlexiPilot""")
MAV_AUTOPILOT_PX4 = 12
enums["MAV_AUTOPILOT"][12] = EnumEntry("MAV_AUTOPILOT_PX4", """PX4 Autopilot - http://px4.io/""")
MAV_AUTOPILOT_SMACCMPILOT = 13
enums["MAV_AUTOPILOT"][13] = EnumEntry("MAV_AUTOPILOT_SMACCMPILOT", """SMACCMPilot - http://smaccmpilot.org""")
MAV_AUTOPILOT_AUTOQUAD = 14
enums["MAV_AUTOPILOT"][14] = EnumEntry("MAV_AUTOPILOT_AUTOQUAD", """AutoQuad -- http://autoquad.org""")
MAV_AUTOPILOT_ARMAZILA = 15
enums["MAV_AUTOPILOT"][15] = EnumEntry("MAV_AUTOPILOT_ARMAZILA", """Armazila -- http://armazila.com""")
MAV_AUTOPILOT_AEROB = 16
enums["MAV_AUTOPILOT"][16] = EnumEntry("MAV_AUTOPILOT_AEROB", """Aerob -- http://aerob.ru""")
MAV_AUTOPILOT_ASLUAV = 17
enums["MAV_AUTOPILOT"][17] = EnumEntry("MAV_AUTOPILOT_ASLUAV", """ASLUAV autopilot -- http://www.asl.ethz.ch""")
MAV_AUTOPILOT_SMARTAP = 18
enums["MAV_AUTOPILOT"][18] = EnumEntry("MAV_AUTOPILOT_SMARTAP", """SmartAP Autopilot - http://sky-drones.com""")
MAV_AUTOPILOT_AIRRAILS = 19
enums["MAV_AUTOPILOT"][19] = EnumEntry("MAV_AUTOPILOT_AIRRAILS", """AirRails - http://uaventure.com""")
MAV_AUTOPILOT_REFLEX = 20
enums["MAV_AUTOPILOT"][20] = EnumEntry("MAV_AUTOPILOT_REFLEX", """Fusion Reflex - https://fusion.engineering""")
MAV_AUTOPILOT_ENUM_END = 21
enums["MAV_AUTOPILOT"][21] = EnumEntry("MAV_AUTOPILOT_ENUM_END", """""")
# MAV_TYPE
enums["MAV_TYPE"] = Enum()
enums["MAV_TYPE"].bitmask = False
MAV_TYPE_GENERIC = 0
enums["MAV_TYPE"][0] = EnumEntry("MAV_TYPE_GENERIC", """Generic micro air vehicle""")
MAV_TYPE_FIXED_WING = 1
enums["MAV_TYPE"][1] = EnumEntry("MAV_TYPE_FIXED_WING", """Fixed wing aircraft.""")
MAV_TYPE_QUADROTOR = 2
enums["MAV_TYPE"][2] = EnumEntry("MAV_TYPE_QUADROTOR", """Quadrotor""")
MAV_TYPE_COAXIAL = 3
enums["MAV_TYPE"][3] = EnumEntry("MAV_TYPE_COAXIAL", """Coaxial helicopter""")
MAV_TYPE_HELICOPTER = 4
enums["MAV_TYPE"][4] = EnumEntry("MAV_TYPE_HELICOPTER", """Normal helicopter with tail rotor.""")
MAV_TYPE_ANTENNA_TRACKER = 5
enums["MAV_TYPE"][5] = EnumEntry("MAV_TYPE_ANTENNA_TRACKER", """Ground installation""")
MAV_TYPE_GCS = 6
enums["MAV_TYPE"][6] = EnumEntry("MAV_TYPE_GCS", """Operator control unit / ground control station""")
MAV_TYPE_AIRSHIP = 7
enums["MAV_TYPE"][7] = EnumEntry("MAV_TYPE_AIRSHIP", """Airship, controlled""")
MAV_TYPE_FREE_BALLOON = 8
enums["MAV_TYPE"][8] = EnumEntry("MAV_TYPE_FREE_BALLOON", """Free balloon, uncontrolled""")
MAV_TYPE_ROCKET = 9
enums["MAV_TYPE"][9] = EnumEntry("MAV_TYPE_ROCKET", """Rocket""")
MAV_TYPE_GROUND_ROVER = 10
enums["MAV_TYPE"][10] = EnumEntry("MAV_TYPE_GROUND_ROVER", """Ground rover""")
MAV_TYPE_SURFACE_BOAT = 11
enums["MAV_TYPE"][11] = EnumEntry("MAV_TYPE_SURFACE_BOAT", """Surface vessel, boat, ship""")
MAV_TYPE_SUBMARINE = 12
enums["MAV_TYPE"][12] = EnumEntry("MAV_TYPE_SUBMARINE", """Submarine""")
MAV_TYPE_HEXAROTOR = 13
enums["MAV_TYPE"][13] = EnumEntry("MAV_TYPE_HEXAROTOR", """Hexarotor""")
MAV_TYPE_OCTOROTOR = 14
enums["MAV_TYPE"][14] = EnumEntry("MAV_TYPE_OCTOROTOR", """Octorotor""")
MAV_TYPE_TRICOPTER = 15
enums["MAV_TYPE"][15] = EnumEntry("MAV_TYPE_TRICOPTER", """Tricopter""")
MAV_TYPE_FLAPPING_WING = 16
enums["MAV_TYPE"][16] = EnumEntry("MAV_TYPE_FLAPPING_WING", """Flapping wing""")
MAV_TYPE_KITE = 17
enums["MAV_TYPE"][17] = EnumEntry("MAV_TYPE_KITE", """Kite""")
MAV_TYPE_ONBOARD_CONTROLLER = 18
enums["MAV_TYPE"][18] = EnumEntry("MAV_TYPE_ONBOARD_CONTROLLER", """Onboard companion controller""")
MAV_TYPE_VTOL_DUOROTOR = 19
enums["MAV_TYPE"][19] = EnumEntry("MAV_TYPE_VTOL_DUOROTOR", """Two-rotor VTOL using control surfaces in vertical operation in addition. Tailsitter.""")
MAV_TYPE_VTOL_QUADROTOR = 20
enums["MAV_TYPE"][20] = EnumEntry("MAV_TYPE_VTOL_QUADROTOR", """Quad-rotor VTOL using a V-shaped quad config in vertical operation. Tailsitter.""")
MAV_TYPE_VTOL_TILTROTOR = 21
enums["MAV_TYPE"][21] = EnumEntry("MAV_TYPE_VTOL_TILTROTOR", """Tiltrotor VTOL""")
MAV_TYPE_VTOL_RESERVED2 = 22
enums["MAV_TYPE"][22] = EnumEntry("MAV_TYPE_VTOL_RESERVED2", """VTOL reserved 2""")
MAV_TYPE_VTOL_RESERVED3 = 23
enums["MAV_TYPE"][23] = EnumEntry("MAV_TYPE_VTOL_RESERVED3", """VTOL reserved 3""")
MAV_TYPE_VTOL_RESERVED4 = 24
enums["MAV_TYPE"][24] = EnumEntry("MAV_TYPE_VTOL_RESERVED4", """VTOL reserved 4""")
MAV_TYPE_VTOL_RESERVED5 = 25
enums["MAV_TYPE"][25] = EnumEntry("MAV_TYPE_VTOL_RESERVED5", """VTOL reserved 5""")
MAV_TYPE_GIMBAL = 26
enums["MAV_TYPE"][26] = EnumEntry("MAV_TYPE_GIMBAL", """Gimbal""")
MAV_TYPE_ADSB = 27
enums["MAV_TYPE"][27] = EnumEntry("MAV_TYPE_ADSB", """ADSB system""")
MAV_TYPE_PARAFOIL = 28
enums["MAV_TYPE"][28] = EnumEntry("MAV_TYPE_PARAFOIL", """Steerable, nonrigid airfoil""")
MAV_TYPE_DODECAROTOR = 29
enums["MAV_TYPE"][29] = EnumEntry("MAV_TYPE_DODECAROTOR", """Dodecarotor""")
MAV_TYPE_CAMERA = 30
enums["MAV_TYPE"][30] = EnumEntry("MAV_TYPE_CAMERA", """Camera""")
MAV_TYPE_CHARGING_STATION = 31
enums["MAV_TYPE"][31] = EnumEntry("MAV_TYPE_CHARGING_STATION", """Charging station""")
MAV_TYPE_FLARM = 32
enums["MAV_TYPE"][32] = EnumEntry("MAV_TYPE_FLARM", """FLARM collision avoidance system""")
MAV_TYPE_SERVO = 33
enums["MAV_TYPE"][33] = EnumEntry("MAV_TYPE_SERVO", """Servo""")
MAV_TYPE_ODID = 34
enums["MAV_TYPE"][34] = EnumEntry("MAV_TYPE_ODID", """Open Drone ID. See https://mavlink.io/en/services/opendroneid.html.""")
MAV_TYPE_DECAROTOR = 35
enums["MAV_TYPE"][35] = EnumEntry("MAV_TYPE_DECAROTOR", """Decarotor""")
MAV_TYPE_BATTERY = 36
enums["MAV_TYPE"][36] = EnumEntry("MAV_TYPE_BATTERY", """Battery""")
MAV_TYPE_PARACHUTE = 37
enums["MAV_TYPE"][37] = EnumEntry("MAV_TYPE_PARACHUTE", """Parachute""")
MAV_TYPE_LOG = 38
enums["MAV_TYPE"][38] = EnumEntry("MAV_TYPE_LOG", """Log""")
MAV_TYPE_OSD = 39
enums["MAV_TYPE"][39] = EnumEntry("MAV_TYPE_OSD", """OSD""")
MAV_TYPE_IMU = 40
enums["MAV_TYPE"][40] = EnumEntry("MAV_TYPE_IMU", """IMU""")
MAV_TYPE_GPS = 41
enums["MAV_TYPE"][41] = EnumEntry("MAV_TYPE_GPS", """GPS""")
MAV_TYPE_WINCH = 42
enums["MAV_TYPE"][42] = EnumEntry("MAV_TYPE_WINCH", """Winch""")
MAV_TYPE_ENUM_END = 43
enums["MAV_TYPE"][43] = EnumEntry("MAV_TYPE_ENUM_END", """""")
# MAV_MODE_FLAG
enums["MAV_MODE_FLAG"] = Enum()
enums["MAV_MODE_FLAG"].bitmask = True
MAV_MODE_FLAG_CUSTOM_MODE_ENABLED = 1
enums["MAV_MODE_FLAG"][1] = EnumEntry("MAV_MODE_FLAG_CUSTOM_MODE_ENABLED", """0b00000001 Reserved for future use.""")
MAV_MODE_FLAG_TEST_ENABLED = 2
enums["MAV_MODE_FLAG"][2] = EnumEntry("MAV_MODE_FLAG_TEST_ENABLED", """0b00000010 system has a test mode enabled. This flag is intended for temporary system tests and should not be used for stable implementations.""")
MAV_MODE_FLAG_AUTO_ENABLED = 4
enums["MAV_MODE_FLAG"][4] = EnumEntry("MAV_MODE_FLAG_AUTO_ENABLED", """0b00000100 autonomous mode enabled, system finds its own goal positions. Guided flag can be set or not, depends on the actual implementation.""")
MAV_MODE_FLAG_GUIDED_ENABLED = 8
enums["MAV_MODE_FLAG"][8] = EnumEntry("MAV_MODE_FLAG_GUIDED_ENABLED", """0b00001000 guided mode enabled, system flies waypoints / mission items.""")
MAV_MODE_FLAG_STABILIZE_ENABLED = 16
enums["MAV_MODE_FLAG"][16] = EnumEntry("MAV_MODE_FLAG_STABILIZE_ENABLED", """0b00010000 system stabilizes electronically its attitude (and optionally position). It needs however further control inputs to move around.""")
MAV_MODE_FLAG_HIL_ENABLED = 32
enums["MAV_MODE_FLAG"][32] = EnumEntry("MAV_MODE_FLAG_HIL_ENABLED", """0b00100000 hardware in the loop simulation. All motors / actuators are blocked, but internal software is full operational.""")
MAV_MODE_FLAG_MANUAL_INPUT_ENABLED = 64
enums["MAV_MODE_FLAG"][64] = EnumEntry("MAV_MODE_FLAG_MANUAL_INPUT_ENABLED", """0b01000000 remote control input is enabled.""")
MAV_MODE_FLAG_SAFETY_ARMED = 128
enums["MAV_MODE_FLAG"][128] = EnumEntry("MAV_MODE_FLAG_SAFETY_ARMED", """0b10000000 MAV safety set to armed. Motors are enabled / running / can start. Ready to fly. Additional note: this flag is to be ignore when sent in the command MAV_CMD_DO_SET_MODE and MAV_CMD_COMPONENT_ARM_DISARM shall be used instead. The flag can still be used to report the armed state.""")
MAV_MODE_FLAG_ENUM_END = 129
enums["MAV_MODE_FLAG"][129] = EnumEntry("MAV_MODE_FLAG_ENUM_END", """""")
# MAV_MODE_FLAG_DECODE_POSITION
enums["MAV_MODE_FLAG_DECODE_POSITION"] = Enum()
enums["MAV_MODE_FLAG_DECODE_POSITION"].bitmask = True
MAV_MODE_FLAG_DECODE_POSITION_CUSTOM_MODE = 1
enums["MAV_MODE_FLAG_DECODE_POSITION"][1] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_CUSTOM_MODE", """Eighth bit: 00000001""")
MAV_MODE_FLAG_DECODE_POSITION_TEST = 2
enums["MAV_MODE_FLAG_DECODE_POSITION"][2] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_TEST", """Seventh bit: 00000010""")
MAV_MODE_FLAG_DECODE_POSITION_AUTO = 4
enums["MAV_MODE_FLAG_DECODE_POSITION"][4] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_AUTO", """Sixth bit: 00000100""")
MAV_MODE_FLAG_DECODE_POSITION_GUIDED = 8
enums["MAV_MODE_FLAG_DECODE_POSITION"][8] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_GUIDED", """Fifth bit: 00001000""")
MAV_MODE_FLAG_DECODE_POSITION_STABILIZE = 16
enums["MAV_MODE_FLAG_DECODE_POSITION"][16] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_STABILIZE", """Fourth bit: 00010000""")
MAV_MODE_FLAG_DECODE_POSITION_HIL = 32
enums["MAV_MODE_FLAG_DECODE_POSITION"][32] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_HIL", """Third bit: 00100000""")
MAV_MODE_FLAG_DECODE_POSITION_MANUAL = 64
enums["MAV_MODE_FLAG_DECODE_POSITION"][64] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_MANUAL", """Second bit: 01000000""")
MAV_MODE_FLAG_DECODE_POSITION_SAFETY = 128
enums["MAV_MODE_FLAG_DECODE_POSITION"][128] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_SAFETY", """First bit: 10000000""")
MAV_MODE_FLAG_DECODE_POSITION_ENUM_END = 129
enums["MAV_MODE_FLAG_DECODE_POSITION"][129] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_ENUM_END", """""")
# MAV_STATE
enums["MAV_STATE"] = Enum()
enums["MAV_STATE"].bitmask = False
MAV_STATE_UNINIT = 0
enums["MAV_STATE"][0] = EnumEntry("MAV_STATE_UNINIT", """Uninitialized system, state is unknown.""")
MAV_STATE_BOOT = 1
enums["MAV_STATE"][1] = EnumEntry("MAV_STATE_BOOT", """System is booting up.""")
MAV_STATE_CALIBRATING = 2
enums["MAV_STATE"][2] = EnumEntry("MAV_STATE_CALIBRATING", """System is calibrating and not flight-ready.""")
MAV_STATE_STANDBY = 3
enums["MAV_STATE"][3] = EnumEntry("MAV_STATE_STANDBY", """System is grounded and on standby. It can be launched any time.""")
MAV_STATE_ACTIVE = 4
enums["MAV_STATE"][4] = EnumEntry("MAV_STATE_ACTIVE", """System is active and might be already airborne. Motors are engaged.""")
MAV_STATE_CRITICAL = 5
enums["MAV_STATE"][5] = EnumEntry("MAV_STATE_CRITICAL", """System is in a non-normal flight mode. It can however still navigate.""")
MAV_STATE_EMERGENCY = 6
enums["MAV_STATE"][6] = EnumEntry("MAV_STATE_EMERGENCY", """System is in a non-normal flight mode. It lost control over parts or over the whole airframe. It is in mayday and going down.""")
MAV_STATE_POWEROFF = 7
enums["MAV_STATE"][7] = EnumEntry("MAV_STATE_POWEROFF", """System just initialized its power-down sequence, will shut down now.""")
MAV_STATE_FLIGHT_TERMINATION = 8
enums["MAV_STATE"][8] = EnumEntry("MAV_STATE_FLIGHT_TERMINATION", """System is terminating itself.""")
MAV_STATE_ENUM_END = 9
enums["MAV_STATE"][9] = EnumEntry("MAV_STATE_ENUM_END", """""")
# MAV_COMPONENT
enums["MAV_COMPONENT"] = Enum()
enums["MAV_COMPONENT"].bitmask = False
MAV_COMP_ID_ALL = 0
enums["MAV_COMPONENT"][0] = EnumEntry("MAV_COMP_ID_ALL", """Target id (target_component) used to broadcast messages to all components of the receiving system. Components should attempt to process messages with this component ID and forward to components on any other interfaces. Note: This is not a valid *source* component id for a message.""")
MAV_COMP_ID_AUTOPILOT1 = 1
enums["MAV_COMPONENT"][1] = EnumEntry("MAV_COMP_ID_AUTOPILOT1", """System flight controller component ("autopilot"). Only one autopilot is expected in a particular system.""")
MAV_COMP_ID_USER1 = 25
enums["MAV_COMPONENT"][25] = EnumEntry("MAV_COMP_ID_USER1", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER2 = 26
enums["MAV_COMPONENT"][26] = EnumEntry("MAV_COMP_ID_USER2", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER3 = 27
enums["MAV_COMPONENT"][27] = EnumEntry("MAV_COMP_ID_USER3", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER4 = 28
enums["MAV_COMPONENT"][28] = EnumEntry("MAV_COMP_ID_USER4", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER5 = 29
enums["MAV_COMPONENT"][29] = EnumEntry("MAV_COMP_ID_USER5", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER6 = 30
enums["MAV_COMPONENT"][30] = EnumEntry("MAV_COMP_ID_USER6", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER7 = 31
enums["MAV_COMPONENT"][31] = EnumEntry("MAV_COMP_ID_USER7", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER8 = 32
enums["MAV_COMPONENT"][32] = EnumEntry("MAV_COMP_ID_USER8", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER9 = 33
enums["MAV_COMPONENT"][33] = EnumEntry("MAV_COMP_ID_USER9", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER10 = 34
enums["MAV_COMPONENT"][34] = EnumEntry("MAV_COMP_ID_USER10", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER11 = 35
enums["MAV_COMPONENT"][35] = EnumEntry("MAV_COMP_ID_USER11", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER12 = 36
enums["MAV_COMPONENT"][36] = EnumEntry("MAV_COMP_ID_USER12", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER13 = 37
enums["MAV_COMPONENT"][37] = EnumEntry("MAV_COMP_ID_USER13", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER14 = 38
enums["MAV_COMPONENT"][38] = EnumEntry("MAV_COMP_ID_USER14", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER15 = 39
enums["MAV_COMPONENT"][39] = EnumEntry("MAV_COMP_ID_USER15", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER16 = 40
enums["MAV_COMPONENT"][40] = EnumEntry("MAV_COMP_ID_USER16", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER17 = 41
enums["MAV_COMPONENT"][41] = EnumEntry("MAV_COMP_ID_USER17", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER18 = 42
enums["MAV_COMPONENT"][42] = EnumEntry("MAV_COMP_ID_USER18", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER19 = 43
enums["MAV_COMPONENT"][43] = EnumEntry("MAV_COMP_ID_USER19", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER20 = 44
enums["MAV_COMPONENT"][44] = EnumEntry("MAV_COMP_ID_USER20", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER21 = 45
enums["MAV_COMPONENT"][45] = EnumEntry("MAV_COMP_ID_USER21", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER22 = 46
enums["MAV_COMPONENT"][46] = EnumEntry("MAV_COMP_ID_USER22", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER23 = 47
enums["MAV_COMPONENT"][47] = EnumEntry("MAV_COMP_ID_USER23", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER24 = 48
enums["MAV_COMPONENT"][48] = EnumEntry("MAV_COMP_ID_USER24", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER25 = 49
enums["MAV_COMPONENT"][49] = EnumEntry("MAV_COMP_ID_USER25", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER26 = 50
enums["MAV_COMPONENT"][50] = EnumEntry("MAV_COMP_ID_USER26", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER27 = 51
enums["MAV_COMPONENT"][51] = EnumEntry("MAV_COMP_ID_USER27", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER28 = 52
enums["MAV_COMPONENT"][52] = EnumEntry("MAV_COMP_ID_USER28", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER29 = 53
enums["MAV_COMPONENT"][53] = EnumEntry("MAV_COMP_ID_USER29", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER30 = 54
enums["MAV_COMPONENT"][54] = EnumEntry("MAV_COMP_ID_USER30", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER31 = 55
enums["MAV_COMPONENT"][55] = EnumEntry("MAV_COMP_ID_USER31", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER32 = 56
enums["MAV_COMPONENT"][56] = EnumEntry("MAV_COMP_ID_USER32", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER33 = 57
enums["MAV_COMPONENT"][57] = EnumEntry("MAV_COMP_ID_USER33", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER34 = 58
enums["MAV_COMPONENT"][58] = EnumEntry("MAV_COMP_ID_USER34", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER35 = 59
enums["MAV_COMPONENT"][59] = EnumEntry("MAV_COMP_ID_USER35", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER36 = 60
enums["MAV_COMPONENT"][60] = EnumEntry("MAV_COMP_ID_USER36", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER37 = 61
enums["MAV_COMPONENT"][61] = EnumEntry("MAV_COMP_ID_USER37", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER38 = 62
enums["MAV_COMPONENT"][62] = EnumEntry("MAV_COMP_ID_USER38", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER39 = 63
enums["MAV_COMPONENT"][63] = EnumEntry("MAV_COMP_ID_USER39", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER40 = 64
enums["MAV_COMPONENT"][64] = EnumEntry("MAV_COMP_ID_USER40", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER41 = 65
enums["MAV_COMPONENT"][65] = EnumEntry("MAV_COMP_ID_USER41", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER42 = 66
enums["MAV_COMPONENT"][66] = EnumEntry("MAV_COMP_ID_USER42", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER43 = 67
enums["MAV_COMPONENT"][67] = EnumEntry("MAV_COMP_ID_USER43", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_TELEMETRY_RADIO = 68
enums["MAV_COMPONENT"][68] = EnumEntry("MAV_COMP_ID_TELEMETRY_RADIO", """Telemetry radio (e.g. SiK radio, or other component that emits RADIO_STATUS messages).""")
MAV_COMP_ID_USER45 = 69
enums["MAV_COMPONENT"][69] = EnumEntry("MAV_COMP_ID_USER45", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER46 = 70
enums["MAV_COMPONENT"][70] = EnumEntry("MAV_COMP_ID_USER46", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER47 = 71
enums["MAV_COMPONENT"][71] = EnumEntry("MAV_COMP_ID_USER47", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER48 = 72
enums["MAV_COMPONENT"][72] = EnumEntry("MAV_COMP_ID_USER48", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER49 = 73
enums["MAV_COMPONENT"][73] = EnumEntry("MAV_COMP_ID_USER49", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER50 = 74
enums["MAV_COMPONENT"][74] = EnumEntry("MAV_COMP_ID_USER50", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER51 = 75
enums["MAV_COMPONENT"][75] = EnumEntry("MAV_COMP_ID_USER51", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER52 = 76
enums["MAV_COMPONENT"][76] = EnumEntry("MAV_COMP_ID_USER52", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER53 = 77
enums["MAV_COMPONENT"][77] = EnumEntry("MAV_COMP_ID_USER53", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER54 = 78
enums["MAV_COMPONENT"][78] = EnumEntry("MAV_COMP_ID_USER54", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER55 = 79
enums["MAV_COMPONENT"][79] = EnumEntry("MAV_COMP_ID_USER55", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER56 = 80
enums["MAV_COMPONENT"][80] = EnumEntry("MAV_COMP_ID_USER56", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER57 = 81
enums["MAV_COMPONENT"][81] = EnumEntry("MAV_COMP_ID_USER57", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER58 = 82
enums["MAV_COMPONENT"][82] = EnumEntry("MAV_COMP_ID_USER58", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER59 = 83
enums["MAV_COMPONENT"][83] = EnumEntry("MAV_COMP_ID_USER59", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER60 = 84
enums["MAV_COMPONENT"][84] = EnumEntry("MAV_COMP_ID_USER60", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER61 = 85
enums["MAV_COMPONENT"][85] = EnumEntry("MAV_COMP_ID_USER61", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER62 = 86
enums["MAV_COMPONENT"][86] = EnumEntry("MAV_COMP_ID_USER62", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER63 = 87
enums["MAV_COMPONENT"][87] = EnumEntry("MAV_COMP_ID_USER63", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER64 = 88
enums["MAV_COMPONENT"][88] = EnumEntry("MAV_COMP_ID_USER64", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER65 = 89
enums["MAV_COMPONENT"][89] = EnumEntry("MAV_COMP_ID_USER65", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER66 = 90
enums["MAV_COMPONENT"][90] = EnumEntry("MAV_COMP_ID_USER66", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER67 = 91
enums["MAV_COMPONENT"][91] = EnumEntry("MAV_COMP_ID_USER67", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER68 = 92
enums["MAV_COMPONENT"][92] = EnumEntry("MAV_COMP_ID_USER68", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER69 = 93
enums["MAV_COMPONENT"][93] = EnumEntry("MAV_COMP_ID_USER69", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER70 = 94
enums["MAV_COMPONENT"][94] = EnumEntry("MAV_COMP_ID_USER70", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER71 = 95
enums["MAV_COMPONENT"][95] = EnumEntry("MAV_COMP_ID_USER71", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER72 = 96
enums["MAV_COMPONENT"][96] = EnumEntry("MAV_COMP_ID_USER72", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER73 = 97
enums["MAV_COMPONENT"][97] = EnumEntry("MAV_COMP_ID_USER73", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER74 = 98
enums["MAV_COMPONENT"][98] = EnumEntry("MAV_COMP_ID_USER74", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER75 = 99
enums["MAV_COMPONENT"][99] = EnumEntry("MAV_COMP_ID_USER75", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_CAMERA = 100
enums["MAV_COMPONENT"][100] = EnumEntry("MAV_COMP_ID_CAMERA", """Camera #1.""")
MAV_COMP_ID_CAMERA2 = 101
enums["MAV_COMPONENT"][101] = EnumEntry("MAV_COMP_ID_CAMERA2", """Camera #2.""")
MAV_COMP_ID_CAMERA3 = 102
enums["MAV_COMPONENT"][102] = EnumEntry("MAV_COMP_ID_CAMERA3", """Camera #3.""")
MAV_COMP_ID_CAMERA4 = 103
enums["MAV_COMPONENT"][103] = EnumEntry("MAV_COMP_ID_CAMERA4", """Camera #4.""")
MAV_COMP_ID_CAMERA5 = 104
enums["MAV_COMPONENT"][104] = EnumEntry("MAV_COMP_ID_CAMERA5", """Camera #5.""")
MAV_COMP_ID_CAMERA6 = 105
enums["MAV_COMPONENT"][105] = EnumEntry("MAV_COMP_ID_CAMERA6", """Camera #6.""")
MAV_COMP_ID_SERVO1 = 140
enums["MAV_COMPONENT"][140] = EnumEntry("MAV_COMP_ID_SERVO1", """Servo #1.""")
MAV_COMP_ID_SERVO2 = 141
enums["MAV_COMPONENT"][141] = EnumEntry("MAV_COMP_ID_SERVO2", """Servo #2.""")
MAV_COMP_ID_SERVO3 = 142
enums["MAV_COMPONENT"][142] = EnumEntry("MAV_COMP_ID_SERVO3", """Servo #3.""")
MAV_COMP_ID_SERVO4 = 143
enums["MAV_COMPONENT"][143] = EnumEntry("MAV_COMP_ID_SERVO4", """Servo #4.""")
MAV_COMP_ID_SERVO5 = 144
enums["MAV_COMPONENT"][144] = EnumEntry("MAV_COMP_ID_SERVO5", """Servo #5.""")
MAV_COMP_ID_SERVO6 = 145
enums["MAV_COMPONENT"][145] = EnumEntry("MAV_COMP_ID_SERVO6", """Servo #6.""")
MAV_COMP_ID_SERVO7 = 146
enums["MAV_COMPONENT"][146] = EnumEntry("MAV_COMP_ID_SERVO7", """Servo #7.""")
MAV_COMP_ID_SERVO8 = 147
enums["MAV_COMPONENT"][147] = EnumEntry("MAV_COMP_ID_SERVO8", """Servo #8.""")
MAV_COMP_ID_SERVO9 = 148
enums["MAV_COMPONENT"][148] = EnumEntry("MAV_COMP_ID_SERVO9", """Servo #9.""")
MAV_COMP_ID_SERVO10 = 149
enums["MAV_COMPONENT"][149] = EnumEntry("MAV_COMP_ID_SERVO10", """Servo #10.""")
MAV_COMP_ID_SERVO11 = 150
enums["MAV_COMPONENT"][150] = EnumEntry("MAV_COMP_ID_SERVO11", """Servo #11.""")
MAV_COMP_ID_SERVO12 = 151
enums["MAV_COMPONENT"][151] = EnumEntry("MAV_COMP_ID_SERVO12", """Servo #12.""")
MAV_COMP_ID_SERVO13 = 152
enums["MAV_COMPONENT"][152] = EnumEntry("MAV_COMP_ID_SERVO13", """Servo #13.""")
MAV_COMP_ID_SERVO14 = 153
enums["MAV_COMPONENT"][153] = EnumEntry("MAV_COMP_ID_SERVO14", """Servo #14.""")
MAV_COMP_ID_GIMBAL = 154
enums["MAV_COMPONENT"][154] = EnumEntry("MAV_COMP_ID_GIMBAL", """Gimbal #1.""")
MAV_COMP_ID_LOG = 155
enums["MAV_COMPONENT"][155] = EnumEntry("MAV_COMP_ID_LOG", """Logging component.""")
MAV_COMP_ID_ADSB = 156
enums["MAV_COMPONENT"][156] = EnumEntry("MAV_COMP_ID_ADSB", """Automatic Dependent Surveillance-Broadcast (ADS-B) component.""")
MAV_COMP_ID_OSD = 157
enums["MAV_COMPONENT"][157] = EnumEntry("MAV_COMP_ID_OSD", """On Screen Display (OSD) devices for video links.""")
MAV_COMP_ID_PERIPHERAL = 158
enums["MAV_COMPONENT"][158] = EnumEntry("MAV_COMP_ID_PERIPHERAL", """Generic autopilot peripheral component ID. Meant for devices that do not implement the parameter microservice.""")
MAV_COMP_ID_QX1_GIMBAL = 159
enums["MAV_COMPONENT"][159] = EnumEntry("MAV_COMP_ID_QX1_GIMBAL", """Gimbal ID for QX1.""")
MAV_COMP_ID_FLARM = 160
enums["MAV_COMPONENT"][160] = EnumEntry("MAV_COMP_ID_FLARM", """FLARM collision alert component.""")
MAV_COMP_ID_PARACHUTE = 161
enums["MAV_COMPONENT"][161] = EnumEntry("MAV_COMP_ID_PARACHUTE", """Parachute component.""")
MAV_COMP_ID_GIMBAL2 = 171
enums["MAV_COMPONENT"][171] = EnumEntry("MAV_COMP_ID_GIMBAL2", """Gimbal #2.""")
MAV_COMP_ID_GIMBAL3 = 172
enums["MAV_COMPONENT"][172] = EnumEntry("MAV_COMP_ID_GIMBAL3", """Gimbal #3.""")
MAV_COMP_ID_GIMBAL4 = 173
enums["MAV_COMPONENT"][173] = EnumEntry("MAV_COMP_ID_GIMBAL4", """Gimbal #4""")
MAV_COMP_ID_GIMBAL5 = 174
enums["MAV_COMPONENT"][174] = EnumEntry("MAV_COMP_ID_GIMBAL5", """Gimbal #5.""")
MAV_COMP_ID_GIMBAL6 = 175
enums["MAV_COMPONENT"][175] = EnumEntry("MAV_COMP_ID_GIMBAL6", """Gimbal #6.""")
MAV_COMP_ID_BATTERY = 180
enums["MAV_COMPONENT"][180] = EnumEntry("MAV_COMP_ID_BATTERY", """Battery #1.""")
MAV_COMP_ID_BATTERY2 = 181
enums["MAV_COMPONENT"][181] = EnumEntry("MAV_COMP_ID_BATTERY2", """Battery #2.""")
MAV_COMP_ID_MAVCAN = 189
enums["MAV_COMPONENT"][189] = EnumEntry("MAV_COMP_ID_MAVCAN", """CAN over MAVLink client.""")
MAV_COMP_ID_MISSIONPLANNER = 190
enums["MAV_COMPONENT"][190] = EnumEntry("MAV_COMP_ID_MISSIONPLANNER", """Component that can generate/supply a mission flight plan (e.g. GCS or developer API).""")
MAV_COMP_ID_ONBOARD_COMPUTER = 191
enums["MAV_COMPONENT"][191] = EnumEntry("MAV_COMP_ID_ONBOARD_COMPUTER", """Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.""")
MAV_COMP_ID_ONBOARD_COMPUTER2 = 192
enums["MAV_COMPONENT"][192] = EnumEntry("MAV_COMP_ID_ONBOARD_COMPUTER2", """Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.""")
MAV_COMP_ID_ONBOARD_COMPUTER3 = 193
enums["MAV_COMPONENT"][193] = EnumEntry("MAV_COMP_ID_ONBOARD_COMPUTER3", """Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.""")
MAV_COMP_ID_ONBOARD_COMPUTER4 = 194
enums["MAV_COMPONENT"][194] = EnumEntry("MAV_COMP_ID_ONBOARD_COMPUTER4", """Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.""")
MAV_COMP_ID_PATHPLANNER = 195
enums["MAV_COMPONENT"][195] = EnumEntry("MAV_COMP_ID_PATHPLANNER", """Component that finds an optimal path between points based on a certain constraint (e.g. minimum snap, shortest path, cost, etc.).""")
MAV_COMP_ID_OBSTACLE_AVOIDANCE = 196
enums["MAV_COMPONENT"][196] = EnumEntry("MAV_COMP_ID_OBSTACLE_AVOIDANCE", """Component that plans a collision free path between two points.""")
MAV_COMP_ID_VISUAL_INERTIAL_ODOMETRY = 197
enums["MAV_COMPONENT"][197] = EnumEntry("MAV_COMP_ID_VISUAL_INERTIAL_ODOMETRY", """Component that provides position estimates using VIO techniques.""")
MAV_COMP_ID_PAIRING_MANAGER = 198
enums["MAV_COMPONENT"][198] = EnumEntry("MAV_COMP_ID_PAIRING_MANAGER", """Component that manages pairing of vehicle and GCS.""")
MAV_COMP_ID_IMU = 200
enums["MAV_COMPONENT"][200] = EnumEntry("MAV_COMP_ID_IMU", """Inertial Measurement Unit (IMU) #1.""")
MAV_COMP_ID_IMU_2 = 201
enums["MAV_COMPONENT"][201] = EnumEntry("MAV_COMP_ID_IMU_2", """Inertial Measurement Unit (IMU) #2.""")
MAV_COMP_ID_IMU_3 = 202
enums["MAV_COMPONENT"][202] = EnumEntry("MAV_COMP_ID_IMU_3", """Inertial Measurement Unit (IMU) #3.""")
MAV_COMP_ID_GPS = 220
enums["MAV_COMPONENT"][220] = EnumEntry("MAV_COMP_ID_GPS", """GPS #1.""")
MAV_COMP_ID_GPS2 = 221
enums["MAV_COMPONENT"][221] = EnumEntry("MAV_COMP_ID_GPS2", """GPS #2.""")
MAV_COMP_ID_ODID_TXRX_1 = 236
enums["MAV_COMPONENT"][236] = EnumEntry("MAV_COMP_ID_ODID_TXRX_1", """Open Drone ID transmitter/receiver (Bluetooth/WiFi/Internet).""")
MAV_COMP_ID_ODID_TXRX_2 = 237
enums["MAV_COMPONENT"][237] = EnumEntry("MAV_COMP_ID_ODID_TXRX_2", """Open Drone ID transmitter/receiver (Bluetooth/WiFi/Internet).""")
MAV_COMP_ID_ODID_TXRX_3 = 238
enums["MAV_COMPONENT"][238] = EnumEntry("MAV_COMP_ID_ODID_TXRX_3", """Open Drone ID transmitter/receiver (Bluetooth/WiFi/Internet).""")
MAV_COMP_ID_UDP_BRIDGE = 240
enums["MAV_COMPONENT"][240] = EnumEntry("MAV_COMP_ID_UDP_BRIDGE", """Component to bridge MAVLink to UDP (i.e. from a UART).""")
MAV_COMP_ID_UART_BRIDGE = 241
enums["MAV_COMPONENT"][241] = EnumEntry("MAV_COMP_ID_UART_BRIDGE", """Component to bridge to UART (i.e. from UDP).""")
MAV_COMP_ID_TUNNEL_NODE = 242
enums["MAV_COMPONENT"][242] = EnumEntry("MAV_COMP_ID_TUNNEL_NODE", """Component handling TUNNEL messages (e.g. vendor specific GUI of a component).""")
MAV_COMP_ID_SYSTEM_CONTROL = 250
enums["MAV_COMPONENT"][250] = EnumEntry("MAV_COMP_ID_SYSTEM_CONTROL", """Component for handling system messages (e.g. to ARM, takeoff, etc.).""")
MAV_COMPONENT_ENUM_END = 251
enums["MAV_COMPONENT"][251] = EnumEntry("MAV_COMPONENT_ENUM_END", """""")
# message IDs
MAVLINK_MSG_ID_BAD_DATA = -1
MAVLINK_MSG_ID_UNKNOWN = -2
MAVLINK_MSG_ID_HEARTBEAT = 0
class MAVLink_heartbeat_message(MAVLink_message):
"""
The heartbeat message shows that a system or component is present
and responding. The type and autopilot fields (along with the
message component id), allow the receiving system to treat further
messages from this system appropriately (e.g. by laying out the
user interface based on the autopilot). This microservice is
documented at https://mavlink.io/en/services/heartbeat.html
"""
id = MAVLINK_MSG_ID_HEARTBEAT
msgname = "HEARTBEAT"
fieldnames = ["type", "autopilot", "base_mode", "custom_mode", "system_status", "mavlink_version"]
ordered_fieldnames = ["custom_mode", "type", "autopilot", "base_mode", "system_status", "mavlink_version"]
fieldtypes = ["uint8_t", "uint8_t", "uint8_t", "uint32_t", "uint8_t", "uint8_t"]
has_bytes = False
fielddisplays_by_name: Dict[str, str] = {"base_mode": "bitmask"}
fieldenums_by_name: Dict[str, str] = {"type": "MAV_TYPE", "autopilot": "MAV_AUTOPILOT", "base_mode": "MAV_MODE_FLAG", "system_status": "MAV_STATE"}
fieldunits_by_name: Dict[str, str] = {}
native_format = bytearray(b"<IBBBBB")
orders = [1, 2, 3, 0, 4, 5]
lengths = [1, 1, 1, 1, 1, 1]
has_array = False
cumulative_lengths = [0, 1, 2, 3, 4, 5]
array_lengths = [0, 0, 0, 0, 0, 0]
crc_extra = 50
unpacker = struct.Struct("<IBBBBB")
instance_field = None
instance_offset = -1
def __init__(self, type: int, autopilot: int, base_mode: int, custom_mode: int, system_status: int, mavlink_version: int):
MAVLink_message.__init__(self, MAVLink_heartbeat_message.id, MAVLink_heartbeat_message.msgname)
self._fieldnames = MAVLink_heartbeat_message.fieldnames
self._instance_field = MAVLink_heartbeat_message.instance_field
self._instance_offset = MAVLink_heartbeat_message.instance_offset
self.type = type
self.autopilot = autopilot
self.base_mode = base_mode
self.custom_mode = custom_mode
self.system_status = system_status
self.mavlink_version = mavlink_version
def pack(self, mav: "MAVLink", force_mavlink1: bool = False) -> bytes:
return self._pack(mav, self.crc_extra, self.unpacker.pack(self.custom_mode, self.type, self.autopilot, self.base_mode, self.system_status, self.mavlink_version), force_mavlink1=force_mavlink1)
# Define name on the class for backwards compatibility (it is now msgname).
# Done with setattr to hide the class variable from mypy.
setattr(MAVLink_heartbeat_message, "name", mavlink_msg_deprecated_name_property())
mavlink_map: Dict[int, Type[MAVLink_message]] = {
MAVLINK_MSG_ID_HEARTBEAT: MAVLink_heartbeat_message,
}
class MAVError(Exception):
"""MAVLink error class"""
def __init__(self, msg: str) -> None:
Exception.__init__(self, msg)
self.message = msg
class MAVLink_bad_data(MAVLink_message):
"""
a piece of bad data in a mavlink stream
"""
def __init__(self, data: bytes, reason: str) -> None:
MAVLink_message.__init__(self, MAVLINK_MSG_ID_BAD_DATA, "BAD_DATA")
self._fieldnames = ["data", "reason"]
self.data = data
self.reason = reason
self._msgbuf = bytearray(data)
self._instance_field = None
def __str__(self) -> str:
"""Override the __str__ function from MAVLink_messages because non-printable characters are common in to be the reason for this message to exist."""
hexstr = ["{:x}".format(i) for i in self.data]
return "%s {%s, data:%s}" % (self._type, self.reason, hexstr)
class MAVLink_unknown(MAVLink_message):
"""
a message that we don't have in the XML used when built
"""
def __init__(self, msgid: int, data: bytes) -> None:
MAVLink_message.__init__(self, MAVLINK_MSG_ID_UNKNOWN, "UNKNOWN_%u" % msgid)
self._fieldnames = ["data"]
self.data = data
self._msgbuf = bytearray(data)
self._instance_field = None
def __str__(self) -> str:
"""Override the __str__ function from MAVLink_messages because non-printable characters are common."""
hexstr = ["{:x}".format(i) for i in self.data]
return "%s {data:%s}" % (self._type, hexstr)
class MAVLinkSigning(object):
"""MAVLink signing state class"""
def __init__(self) -> None:
self.secret_key: Optional[bytes] = None
self.timestamp = 0
self.link_id = 0
self.sign_outgoing = False
self.allow_unsigned_callback: Optional[Callable[["MAVLink", int], bool]] = None
self.stream_timestamps: Dict[Tuple[int, int, int], int] = {}
self.sig_count = 0
self.badsig_count = 0
self.goodsig_count = 0
self.unsigned_count = 0
self.reject_count = 0
MAVLinkV1Header = Tuple[bytes, int, int, int, int, int]
MAVLinkV2Header = Tuple[bytes, int, int, int, int, int, int, int, int]
class MAVLink(object):
"""MAVLink protocol handling class"""
def __init__(self, file: Any, srcSystem: int = 0, srcComponent: int = 0, use_native: bool = False) -> None:
self.seq = 0
self.file = file
self.srcSystem = srcSystem
self.srcComponent = srcComponent
self.callback: Optional[Callable[..., None]] = None
self.callback_args: Optional[Iterable[Any]] = None
self.callback_kwargs: Optional[Mapping[str, Any]] = None
self.send_callback: Optional[Callable[..., None]] = None
self.send_callback_args: Optional[Iterable[Any]] = None
self.send_callback_kwargs: Optional[Mapping[str, Any]] = None
self.buf = bytearray()
self.buf_index = 0
self.expected_length = HEADER_LEN_V1 + 2
self.have_prefix_error = False
self.robust_parsing = False
self.protocol_marker = 254
self.little_endian = True
self.crc_extra = True
self.sort_fields = True
self.total_packets_sent = 0
self.total_bytes_sent = 0
self.total_packets_received = 0
self.total_bytes_received = 0
self.total_receive_errors = 0
self.startup_time = time.time()
self.signing = MAVLinkSigning()
self.mav20_unpacker = struct.Struct("<cBBBBBBHB")
self.mav10_unpacker = struct.Struct("<cBBBBB")
self.mav20_h3_unpacker = struct.Struct("BBB")
self.mav_csum_unpacker = struct.Struct("<H")
self.mav_sign_unpacker = struct.Struct("<IH")
def set_callback(self, callback: Callable[..., None], *args: Any, **kwargs: Any) -> None:
self.callback = callback
self.callback_args = args
self.callback_kwargs = kwargs
def set_send_callback(self, callback: Callable[..., None], *args: Any, **kwargs: Any) -> None:
self.send_callback = callback
self.send_callback_args = args
self.send_callback_kwargs = kwargs
def send(self, mavmsg: MAVLink_message, force_mavlink1: bool = False) -> None:
"""send a MAVLink message"""
buf = mavmsg.pack(self, force_mavlink1=force_mavlink1)
self.file.write(buf)
self.seq = (self.seq + 1) % 256
self.total_packets_sent += 1
self.total_bytes_sent += len(buf)
if self.send_callback is not None and self.send_callback_args is not None and self.send_callback_kwargs is not None:
self.send_callback(mavmsg, *self.send_callback_args, **self.send_callback_kwargs)
def buf_len(self) -> int:
return len(self.buf) - self.buf_index
def bytes_needed(self) -> int:
"""return number of bytes needed for next parsing stage"""
ret = self.expected_length - self.buf_len()
if ret <= 0:
return 1
return ret
def __callbacks(self, msg: MAVLink_message) -> None:
"""this method exists only to make profiling results easier to read"""
if self.callback is not None and self.callback_args is not None and self.callback_kwargs is not None:
self.callback(msg, *self.callback_args, **self.callback_kwargs)
def parse_char(self, c: Sequence[int]) -> Optional[MAVLink_message]:
"""input some data bytes, possibly returning a new message"""
self.buf.extend(c)
self.total_bytes_received += len(c)
m = self.__parse_char_legacy()
if m is not None:
self.total_packets_received += 1
self.__callbacks(m)
else:
# XXX The idea here is if we've read something and there's nothing left in
# the buffer, reset it to 0 which frees the memory
if self.buf_len() == 0 and self.buf_index != 0:
self.buf = bytearray()
self.buf_index = 0
return m
def __parse_char_legacy(self) -> Optional[MAVLink_message]:
"""input some data bytes, possibly returning a new message"""
header_len = HEADER_LEN_V1
if self.buf_len() >= 1 and self.buf[self.buf_index] == PROTOCOL_MARKER_V2:
header_len = HEADER_LEN_V2
m: Optional[MAVLink_message] = None
if self.buf_len() >= 1 and self.buf[self.buf_index] != PROTOCOL_MARKER_V1 and self.buf[self.buf_index] != PROTOCOL_MARKER_V2:
magic = self.buf[self.buf_index]
self.buf_index += 1
if self.robust_parsing:
invalid_prefix_start = self.buf_index - 1
while self.buf_len() >= 1 and self.buf[self.buf_index] != PROTOCOL_MARKER_V1 and self.buf[self.buf_index] != PROTOCOL_MARKER_V2:
self.buf_index += 1
m = MAVLink_bad_data(self.buf[invalid_prefix_start : self.buf_index], "Bad prefix")
self.expected_length = header_len + 2
self.total_receive_errors += 1
return m
if self.have_prefix_error:
return None
self.have_prefix_error = True
self.total_receive_errors += 1
raise MAVError("invalid MAVLink prefix '%s'" % magic)
self.have_prefix_error = False
if self.buf_len() >= 3:
sbuf = self.buf[self.buf_index : 3 + self.buf_index]
unpacked_h3: Tuple[int, int, int] = self.mav20_h3_unpacker.unpack(sbuf)
magic, self.expected_length, incompat_flags = unpacked_h3
if magic == PROTOCOL_MARKER_V2 and (incompat_flags & MAVLINK_IFLAG_SIGNED):
self.expected_length += MAVLINK_SIGNATURE_BLOCK_LEN
self.expected_length += header_len + 2
if self.expected_length >= (header_len + 2) and self.buf_len() >= self.expected_length:
mbuf = self.buf[self.buf_index : self.buf_index + self.expected_length]
self.buf_index += self.expected_length
self.expected_length = header_len + 2
if self.robust_parsing:
try:
if magic == PROTOCOL_MARKER_V2 and (incompat_flags & ~MAVLINK_IFLAG_SIGNED) != 0:
raise MAVError("invalid incompat_flags 0x%x 0x%x %u" % (incompat_flags, magic, self.expected_length))
m = self.decode(mbuf)
except MAVError as reason:
m = MAVLink_bad_data(mbuf, reason.message)
self.total_receive_errors += 1
else:
if magic == PROTOCOL_MARKER_V2 and (incompat_flags & ~MAVLINK_IFLAG_SIGNED) != 0:
raise MAVError("invalid incompat_flags 0x%x 0x%x %u" % (incompat_flags, magic, self.expected_length))
m = self.decode(mbuf)
return m
return None
def parse_buffer(self, s: Sequence[int]) -> Optional[List[MAVLink_message]]:
"""input some data bytes, possibly returning a list of new messages"""
m = self.parse_char(s)
if m is None:
return None
ret = [m]
while True:
m = self.parse_char(b"")
if m is None:
return ret
ret.append(m)
def check_signature(self, msgbuf: bytearray, srcSystem: int, srcComponent: int) -> bool:
"""check signature on incoming message"""
assert self.signing.secret_key is not None
timestamp_buf = msgbuf[-12:-6]
link_id = msgbuf[-13]
tbytes: Tuple[int, int] = self.mav_sign_unpacker.unpack(timestamp_buf)
tlow, thigh = tbytes
timestamp = tlow + (thigh << 32)
# see if the timestamp is acceptable
stream_key = (link_id, srcSystem, srcComponent)
if stream_key in self.signing.stream_timestamps:
if timestamp <= self.signing.stream_timestamps[stream_key]:
# reject old timestamp
logger.info("old timestamp")
return False
else:
# a new stream has appeared. Accept the timestamp if it is at most
# one minute behind our current timestamp
if timestamp + 6000 * 1000 < self.signing.timestamp:
logger.info("bad new stream %s %s", timestamp / (100.0 * 1000 * 60 * 60 * 24 * 365), self.signing.timestamp / (100.0 * 1000 * 60 * 60 * 24 * 365))
return False
# set the streams timestamp so we reject timestamps that go backwards
self.signing.stream_timestamps[stream_key] = timestamp
h = hashlib.new("sha256")
h.update(self.signing.secret_key)
h.update(msgbuf[:-6])
sig1 = h.digest()[:6]
sig2 = msgbuf[-6:]
if sig1 != sig2:
logger.info("sig mismatch")
return False
# the timestamp we next send with is the max of the received timestamp and
# our current timestamp
self.signing.timestamp = max(self.signing.timestamp, timestamp)
return True
def decode(self, msgbuf: bytearray) -> MAVLink_message:
"""decode a buffer as a MAVLink message"""
# decode the header
if msgbuf[0] != PROTOCOL_MARKER_V1:
headerlen = 10
try:
header_v2: MAVLinkV2Header = self.mav20_unpacker.unpack(msgbuf[:headerlen])
except struct.error as emsg:
raise MAVError("Unable to unpack MAVLink header: %s" % emsg)
magic, mlen, incompat_flags, compat_flags, seq, srcSystem, srcComponent, msgIdlow, msgIdhigh = header_v2
msgId = msgIdlow | (msgIdhigh << 16)
else:
headerlen = 6
try:
header_v1: MAVLinkV1Header = self.mav10_unpacker.unpack(msgbuf[:headerlen])
except struct.error as emsg:
raise MAVError("Unable to unpack MAVLink header: %s" % emsg)
magic, mlen, seq, srcSystem, srcComponent, msgId = header_v1
incompat_flags = 0
compat_flags = 0
mapkey = msgId
if (incompat_flags & MAVLINK_IFLAG_SIGNED) != 0:
signature_len = MAVLINK_SIGNATURE_BLOCK_LEN
else:
signature_len = 0
if ord(magic) != PROTOCOL_MARKER_V1 and ord(magic) != PROTOCOL_MARKER_V2:
raise MAVError("invalid MAVLink prefix '{}'".format(hex(ord(magic))))
if mlen != len(msgbuf) - (headerlen + 2 + signature_len):
raise MAVError("invalid MAVLink message length. Got %u expected %u, msgId=%u headerlen=%u" % (len(msgbuf) - (headerlen + 2 + signature_len), mlen, msgId, headerlen))
if mapkey not in mavlink_map:
return MAVLink_unknown(msgId, msgbuf)
# decode the payload
msgtype = mavlink_map[mapkey]
order_map = msgtype.orders
len_map = msgtype.lengths
has_array = msgtype.has_array
has_bytes = msgtype.has_bytes
clen_map = msgtype.cumulative_lengths
crc_extra = msgtype.crc_extra
# decode the checksum
try:
crc: int = self.mav_csum_unpacker.unpack(msgbuf[-(2 + signature_len) :][:2])[0]
except struct.error as emsg:
raise MAVError("Unable to unpack MAVLink CRC: %s" % emsg)
crcbuf = msgbuf[1 : -(2 + signature_len)]
if True:
# using CRC extra
crcbuf.append(crc_extra)
crc2 = x25crc(crcbuf)
if crc != crc2.crc and not MAVLINK_IGNORE_CRC:
raise MAVError("invalid MAVLink CRC in msgID %u 0x%04x should be 0x%04x" % (msgId, crc, crc2.crc))
sig_ok = False
if signature_len == MAVLINK_SIGNATURE_BLOCK_LEN:
self.signing.sig_count += 1
if self.signing.secret_key is not None:
accept_signature = False
if signature_len == MAVLINK_SIGNATURE_BLOCK_LEN:
sig_ok = self.check_signature(msgbuf, srcSystem, srcComponent)
accept_signature = sig_ok
if sig_ok:
self.signing.goodsig_count += 1
else:
self.signing.badsig_count += 1
if not accept_signature and self.signing.allow_unsigned_callback is not None:
accept_signature = self.signing.allow_unsigned_callback(self, msgId)
if accept_signature:
self.signing.unsigned_count += 1
else:
self.signing.reject_count += 1
elif self.signing.allow_unsigned_callback is not None:
accept_signature = self.signing.allow_unsigned_callback(self, msgId)
if accept_signature:
self.signing.unsigned_count += 1
else:
self.signing.reject_count += 1
if not accept_signature:
raise MAVError("Invalid signature")
csize = msgtype.unpacker.size
mbuf = msgbuf[headerlen : -(2 + signature_len)]
if len(mbuf) < csize:
# zero pad to give right size
mbuf.extend([0] * (csize - len(mbuf)))
if len(mbuf) < csize:
raise MAVError("Bad message of type %s length %u needs %s" % (msgtype, len(mbuf), csize))
mbuf = mbuf[:csize]
try:
t: Tuple[Union[bytes, int, float], ...] = msgtype.unpacker.unpack(mbuf)
except struct.error as emsg:
raise MAVError("Unable to unpack MAVLink payload type=%s payloadLength=%u: %s" % (msgtype, len(mbuf), emsg))
tlist: List[Union[bytes, float, int, Sequence[Union[bytes, float, int]]]] = list(t)
# handle sorted fields
if True:
if not has_array:
# message has no arrays in it
for i in range(0, len(tlist)):
tlist[i] = t[order_map[i]]
else:
# message has some arrays
tlist = []
for i in range(0, len(order_map)):
order = order_map[i]
L = len_map[order]
tip = clen_map[order]
field = t[tip]
if L == 1 or isinstance(field, bytes):
tlist.append(field)
else:
tlist.append(list(t[tip : (tip + L)]))
# terminate any strings
for i, elem in (enumerate(tlist) if has_bytes else ()):
if isinstance(elem, bytes):
tlist[i] = elem.rstrip(b"\x00")
# construct the message object
try:
# Note that initializers don't follow the Liskov Substitution Principle
# therefore it can't be typechecked
m = msgtype(*tlist) # type: ignore
except Exception as emsg:
raise MAVError("Unable to instantiate MAVLink message of type %s : %s" % (msgtype, emsg))
m._signed = sig_ok
if m._signed:
m._link_id = msgbuf[-13]
m._msgbuf = msgbuf
m._payload = msgbuf[6 : -(2 + signature_len)]
m._crc = crc
m._header = MAVLink_header(msgId, incompat_flags, compat_flags, mlen, seq, srcSystem, srcComponent)
return m
def heartbeat_encode(self, type: int, autopilot: int, base_mode: int, custom_mode: int, system_status: int, mavlink_version: int = 3) -> MAVLink_heartbeat_message:
"""
The heartbeat message shows that a system or component is present and
responding. The type and autopilot fields (along with the
message component id), allow the receiving system to treat
further messages from this system appropriately (e.g. by
laying out the user interface based on the autopilot). This
microservice is documented at
https://mavlink.io/en/services/heartbeat.html
type : Vehicle or component type. For a flight controller component the vehicle type (quadrotor, helicopter, etc.). For other components the component type (e.g. camera, gimbal, etc.). This should be used in preference to component id for identifying the component type. (type:uint8_t, values:MAV_TYPE)
autopilot : Autopilot type / class. Use MAV_AUTOPILOT_INVALID for components that are not flight controllers. (type:uint8_t, values:MAV_AUTOPILOT)
base_mode : System mode bitmap. (type:uint8_t, values:MAV_MODE_FLAG)
custom_mode : A bitfield for use for autopilot-specific flags (type:uint32_t)
system_status : System status flag. (type:uint8_t, values:MAV_STATE)
mavlink_version : MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version (type:uint8_t)
"""
return MAVLink_heartbeat_message(type, autopilot, base_mode, custom_mode, system_status, mavlink_version)
def heartbeat_send(self, type: int, autopilot: int, base_mode: int, custom_mode: int, system_status: int, mavlink_version: int = 3, force_mavlink1: bool = False) -> None:
"""
The heartbeat message shows that a system or component is present and
responding. The type and autopilot fields (along with the
message component id), allow the receiving system to treat
further messages from this system appropriately (e.g. by
laying out the user interface based on the autopilot). This
microservice is documented at
https://mavlink.io/en/services/heartbeat.html
type : Vehicle or component type. For a flight controller component the vehicle type (quadrotor, helicopter, etc.). For other components the component type (e.g. camera, gimbal, etc.). This should be used in preference to component id for identifying the component type. (type:uint8_t, values:MAV_TYPE)
autopilot : Autopilot type / class. Use MAV_AUTOPILOT_INVALID for components that are not flight controllers. (type:uint8_t, values:MAV_AUTOPILOT)
base_mode : System mode bitmap. (type:uint8_t, values:MAV_MODE_FLAG)
custom_mode : A bitfield for use for autopilot-specific flags (type:uint32_t)
system_status : System status flag. (type:uint8_t, values:MAV_STATE)
mavlink_version : MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version (type:uint8_t)
"""
self.send(self.heartbeat_encode(type, autopilot, base_mode, custom_mode, system_status, mavlink_version), force_mavlink1=force_mavlink1)