Path: blob/master/Tools/Replay/examples/rewrite-RFND-values-to-floats.py
6351 views
#!/usr/bin/env python312'''In ArduPilot 4.7 the distance values were moved to float to3facilitate supporting rangefinders with more than 327m of range.45The dataflash Replay log messages changes to support this.67This script will take an older log and convert those messages such8that older logs can be replayed with newer code.910AP_FLAKE8_CLEAN11'''1213from argparse import ArgumentParser1415import struct1617from pymavlink import DFReader18from pymavlink import mavutil1920new_RRNH_format = "ffB"21new_RRNI_format = "ffffBBB"222324class Rewrite():25def __init__(self, rewrite_fmt, rewrite_fmtu, rewrite_instance):26self.rewrite_fmt = rewrite_fmt27self.rewrite_fmtu = rewrite_fmtu28self.rewrite_instance = rewrite_instance2930@staticmethod31def format_to_struct(fmt):32ret = bytes("<", 'ascii')33for c in fmt:34(s, _mul, _type) = DFReader.FORMAT_TO_STRUCT[c]35ret += bytes(s, 'ascii')36return bytes(ret)373839rewrites = {40# convert RRNI.distance_cm > RRNI.distance41"RRNH": Rewrite(42rewrite_fmt=lambda buf, m : buf[:3] + struct.pack(43Rewrite.format_to_struct("BBnNZ"),44m.Type,45struct.calcsize(Rewrite.format_to_struct(new_RRNH_format)) + 3, # m.Length46bytes(m.Name, 'ascii'),47bytes(new_RRNH_format, 'ascii'),48bytes(m.Columns, 'ascii')49),50rewrite_fmtu=lambda buf, m : buf[:3] + struct.pack(51Rewrite.format_to_struct("QBNN"),52m.TimeUS,53m.FmtType,54bytes("mm-", 'ascii'), # new units55bytes("00-", 'ascii') # new mults56),57rewrite_instance=lambda buf, m : buf[:3] + struct.pack(58Rewrite.format_to_struct(new_RRNH_format),59m.GCl * 0.01,60m.MaxD * 0.01,61m.NumSensors62),63),64"RRNI": Rewrite(65rewrite_fmt=lambda buf, m : buf[:3] + struct.pack(66Rewrite.format_to_struct("BBnNZ"),67m.Type,68struct.calcsize(Rewrite.format_to_struct(new_RRNI_format)) + 3, # m.Length69bytes(m.Name, 'ascii'),70bytes(new_RRNI_format, 'ascii'),71bytes(m.Columns, 'ascii')72),73rewrite_fmtu=lambda buf, m : buf[:3] + struct.pack(74Rewrite.format_to_struct("QBNN"),75m.TimeUS,76m.FmtType,77bytes("???m--#", 'ascii'), # new units78bytes("???0---", 'ascii') # new mults79),80rewrite_instance=lambda buf, m : buf[:3] + struct.pack(81Rewrite.format_to_struct(new_RRNI_format),82m.PX,83m.PY,84m.PZ,85m.Dist * 0.01,86m.Orient,87m.Status,88m.I89),90),91}929394parser = ArgumentParser(description=__doc__)9596parser.add_argument("login")97parser.add_argument("logout")9899args = parser.parse_args()100101login = mavutil.mavlink_connection(args.login)102output = open(args.logout, mode='wb')103104type_name_map = {}105106107def rewrite_message(m):108buf = bytearray(m.get_msgbuf())109110mtype = m.get_type()111if mtype == 'FMT':112type_name_map[m.Type] = m.Name113if m.Name in rewrites:114return rewrites[m.Name].rewrite_fmt(buf, m)115116if mtype == 'FMTU':117if m.FmtType not in type_name_map:118raise ValueError(f"Have not seen format for ID {m.FmtType}")119name = type_name_map[m.FmtType]120if name in rewrites:121return rewrites[name].rewrite_fmtu(buf, m)122123if mtype in rewrites:124return rewrites[mtype].rewrite_instance(buf, m)125126return buf127128129while True:130m = login.recv_msg()131if m is None:132break133output.write(rewrite_message(m))134135136