Skip to content

Commit

Permalink
Replay: add example script for converting from cm to m in RRNI and RR…
Browse files Browse the repository at this point in the history
…NH messages
  • Loading branch information
peterbarker committed Jan 1, 2025
1 parent a5ff89e commit f657c9b
Showing 1 changed file with 132 additions and 0 deletions.
132 changes: 132 additions & 0 deletions Tools/Replay/examples/rewrite-RFND-values-to-floats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#!/usr/bin/env python
'''In ArduPilot 4.7 the distance values were moved to float to
facilitate supporting rangefinders with more than 327m of range.
The dataflash Replay log messages changes to support this.
This script will take an older log and convert those messages such
that older logs can be replayed with newer code.
AP_FLAKE8_CLEAN
'''

from argparse import ArgumentParser

import struct

from pymavlink import DFReader
from pymavlink import mavutil

new_RRNH_format = "ffB"
new_RRNI_format = "ffffBBB"


class Rewrite():
def __init__(self, rewrite_fmt, rewrite_fmtu, rewrite_instance):
self.rewrite_fmt = rewrite_fmt
self.rewrite_fmtu = rewrite_fmtu
self.rewrite_instance = rewrite_instance

def format_to_struct(fmt):
ret = bytes("<", 'ascii')
for c in fmt:
(s, mul, type) = DFReader.FORMAT_TO_STRUCT[c]
ret += bytes(s, 'ascii')
return bytes(ret)


rewrites = {
# convert RRNI.distance_cm > RRNI.distance
"RRNH": Rewrite(
rewrite_fmt=lambda buf, m : buf[:3] + struct.pack(
Rewrite.format_to_struct("BBnNZ"),
m.Type,
struct.calcsize(Rewrite.format_to_struct(new_RRNH_format)) + 3, # m.Length
bytes(m.Name, 'ascii'),
bytes(new_RRNH_format, 'ascii'),
bytes(m.Columns, 'ascii')
),
rewrite_fmtu=lambda buf, m : buf[:3] + struct.pack(
Rewrite.format_to_struct("QBNN"),
m.TimeUS,
m.FmtType,
bytes("mm-", 'ascii'), # new units
bytes("00-", 'ascii') # new mults
),
rewrite_instance=lambda buf, m : buf[:3] + struct.pack(
Rewrite.format_to_struct(new_RRNH_format),
m.GCl * 0.01,
m.MaxD * 0.01,
m.NumSensors
),
),
"RRNI": Rewrite(
rewrite_fmt=lambda buf, m : buf[:3] + struct.pack(
Rewrite.format_to_struct("BBnNZ"),
m.Type,
struct.calcsize(Rewrite.format_to_struct(new_RRNI_format)) + 3, # m.Length
bytes(m.Name, 'ascii'),
bytes(new_RRNI_format, 'ascii'),
bytes(m.Columns, 'ascii')
),
rewrite_fmtu=lambda buf, m : buf[:3] + struct.pack(
Rewrite.format_to_struct("QBNN"),
m.TimeUS,
m.FmtType,
bytes("???m--#", 'ascii'), # new units
bytes("???0---", 'ascii') # new mults
),
rewrite_instance=lambda buf, m : buf[:3] + struct.pack(
Rewrite.format_to_struct(new_RRNI_format),
m.PX,
m.PY,
m.PZ,
m.Dist * 0.01,
m.Orient,
m.Status,
m.I
),
),
}


parser = ArgumentParser(description=__doc__)

parser.add_argument("login")
parser.add_argument("logout")

args = parser.parse_args()

login = mavutil.mavlink_connection(args.login)
output = open(args.logout, mode='wb')

type_name_map = {}


def rewrite_message(m):
buf = bytearray(m.get_msgbuf())

mtype = m.get_type()
if mtype == 'FMT':
type_name_map[m.Type] = m.Name
if m.Name in rewrites:
return rewrites[m.Name].rewrite_fmt(buf, m)

if mtype == 'FMTU':
if m.FmtType not in type_name_map:
raise ValueError(f"Have not seen format for ID {m.FmtType}")
name = type_name_map[m.FmtType]
if name in rewrites:
return rewrites[name].rewrite_fmtu(buf, m)

if mtype in rewrites:
return rewrites[mtype].rewrite_instance(buf, m)

return buf


while True:
m = login.recv_msg()
if m is None:
break
output.write(rewrite_message(m))

0 comments on commit f657c9b

Please sign in to comment.