From 5dba8ab9c839e99fab9b04822b9dbfb1dcad2ace Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Aug 2020 12:54:53 +1000 Subject: [PATCH] AP_MSP: convert more MSP msg parsing to new system --- libraries/AP_MSP/Tools/msposd.py | 5 +- libraries/AP_MSP/Tools/pymsp.py | 147 +++++++++++++------------------ 2 files changed, 65 insertions(+), 87 deletions(-) diff --git a/libraries/AP_MSP/Tools/msposd.py b/libraries/AP_MSP/Tools/msposd.py index d7d34922bd..1a85e47216 100755 --- a/libraries/AP_MSP/Tools/msposd.py +++ b/libraries/AP_MSP/Tools/msposd.py @@ -69,9 +69,9 @@ pygame.display.set_caption('MSP Display') def item_to_pos(item): '''map MSP item to a X,Y tuple or None''' - if item is None or item >= msp.msp_osd_config.get('osd_item_count',0): + if item is None or item >= msp.get('OSD_CONFIG.osd_item_count'): return None - pos = msp.msp_osd_config['osd_items'][item] + pos = msp.get("OSD_CONFIG.osd_items")[item] if pos < 2048: return None pos_y = (pos-2048) // 32 @@ -103,6 +103,7 @@ def display_all(): display_text(msp.OSD_CURRENT_DRAW, "%.2fA" % (msp.get('BATTERY_STATE.current')*0.01)) display_text(msp.OSD_MAIN_BATT_VOLTAGE, "%.2fV" % (msp.get('BATTERY_STATE.voltage')*0.1)) display_text(msp.OSD_ALTITUDE, "%.1fm" % (msp.get("ALTITUDE.alt")*0.01)) + display_text(msp.OSD_MAIN_BATT_USAGE, "%umAh" % (msp.get('ANALOG.consumed_mah'))) display_text(msp.OSD_CRAFT_NAME, "%s" % (msp.msp_name['name'])) def receive_data(): diff --git a/libraries/AP_MSP/Tools/pymsp.py b/libraries/AP_MSP/Tools/pymsp.py index b61cbb7226..5983212b85 100755 --- a/libraries/AP_MSP/Tools/pymsp.py +++ b/libraries/AP_MSP/Tools/pymsp.py @@ -9,22 +9,49 @@ import struct import time import sys +import re class MSPItem: def __init__(self, name, fmt, fields): self.name = name self.format = fmt - self.fields = fields.split(',') + self.fields = fields + if not isinstance(self.format, list): + self.format = [self.format] + self.fields = [self.fields] self.values = {} - self.fmt_size = struct.calcsize(self.format) def parse(self, msp, dataSize): '''parse data''' - if dataSize < self.fmt_size: - raise Exception("Format %s needs %u bytes got %u" % (self.name, self.fmt_size, dataSize)) - values = list(struct.unpack(self.format, msp.inBuf[msp.p:msp.p+self.fmt_size])) - for i in range(len(self.fields)): - self.values[self.fields[i]] = values[i] + ofs = msp.p + for i in range(len(self.format)): + fmt = self.format[i] + fields = self.fields[i].split(',') + if fmt[0] == '{': + # we have a repeat count from an earlier variable + right = fmt.find('}') + vname = fmt[1:right] + count = self.values[vname] + fmt = "%u%s" % (count, fmt[right+1:]) + if fmt[0].isdigit(): + repeat = int(re.search(r'\d+', fmt).group()) + else: + repeat = None + fmt = "<" + fmt + fmt_size = struct.calcsize(fmt) + if dataSize < fmt_size: + raise Exception("Format %s needs %u bytes got %u for %s" % (self.name, fmt_size, dataSize, fmt)) + values = list(struct.unpack(fmt, msp.inBuf[ofs:ofs+fmt_size])) + if repeat is not None: + for i in range(len(fields)): + self.values[fields[i]] = [] + for j in range(repeat): + self.values[fields[i]].append(values[j*len(fields)]) + else: + for i in range(len(fields)): + self.values[fields[i]] = values[i] + dataSize -= fmt_size + ofs += fmt_size msp.by_name[self.name] = self #print("Got %s" % self.name) @@ -179,19 +206,34 @@ class PyMSP: PIDITEMS = 10 MESSAGES = { - MSP_RAW_GPS: MSPItem('RAW_GPS', "