dacabdi / xhoundpi

RaspberryPi-based high precision GPS point surveyor
Other
0 stars 0 forks source link

Write/Read long & lat in decimal degrees from UBX and NMEA with optional high precision #28

Closed dacabdi closed 3 years ago

dacabdi commented 3 years ago

Read NMEA longitude and latitude with high precision

The library supports high precision and provides mixins to read in decimal degrees. ⚠️ The frame reader has to relax the 82 max frame length restriction to allow reading high precision values. Investigate heuristics for max message length.

Write NMEA longitude and latitude with high precision

Write converter from decimal degrees (floating point value) to (d*)ddmm.mmmmm(mm**). Setter must set lat_dir and lon_dir depending on sign of decimal degrees value. ⚠️ Investigate if NMEA writes 0 to the left.

lon = converter(decimal_degress_lon, length=len(original_len))
lon_dir = 'E' if decimal_degrees_lon > 0 else 'W'
lat = converter(decimal_degrees_lat, length=len(original_lat))
lat_dir = 'N' if decimal_degrees_lat > 0 else 'S'

(*) the extra degree digit depends on latitude (2 digits) or longitude (3 digits). (**) the extra resolution for minutes is used in high precision mode (5 vs 7 digits)

Read UBX long/lat low/high precision (pending) :

lathp = msg.latHp if hasattr(msg, 'latHp') else 0
lonhp = msg.lonHp if hasattr(msg, 'lonHp') else 0
lat = msg.lat * 10^-7 + lathp * 10^-9
lon = msg.lon * 10^-7 + lonhp * 10^-9

Write UBX long/lat low/high precision (pending) :

lat = decimal_degress * 10^7
if hasattr(msg, 'latHp'):
    latHp = two first digits after floating point in lat
(same for lon)

Misc

Use this tool to generate the UBX numerical fields: https://www.scadacore.com/tools/programming-calculators/online-hex-converter/


Tasks

dacabdi commented 3 years ago

@eloyja2004 guidance for test cases

def test_get_fields_modify_and_rebuild(self):
        frame = bytes.fromhex(
            'B5 62 01 14 24 00 00 00 00 00'
            'F8 0D B9 1D' # iToW
            '14 4E E3 CE' # lon
            '09 07 AB 11' # lat
            '7F 45 00 00 E6 BB 00 00 23 29'
            'FE FC 38 99 01 00 59 69 02 00 34 63            ')
        # lon == -823964140
        msg = pyubx2.UBXReader.parse(frame)
        data = msg.__dict__
        data['lon'] = -923964140
        msg = pyubx2.UBXMessage(msg.msg_cls, msg.msg_id, msg._mode, **data)
        self.assertEqual(msg.lon, -923964140) # pylint: disable=no-member
        # for the conversions use https://www.scadacore.com/tools/programming-calculators/online-hex-converter/
        self.assertEqual(msg.serialize(), bytes.fromhex(
            'B5 62 01 14 24 00' # header + class + id + length
            '00 00 00 00'
            'F8 0D B9 1D'
            '14 6D ED C8' # lon == -923964140
            '09 07 AB 11' # lat
            '7F 45 00 00' # height
            'E6 BB 00 00' # height sea level
            '23 29'       # hp lon,lat
            'FE FC 38 99 01 00 59 69 02 00'
            '57 16')) # checksum also changed
dacabdi commented 3 years ago

test cases: