Code Monkey home page Code Monkey logo

pyubx2's Introduction

pyubx2

Current Status | Installation | Message Categories | Reading | Parsing | Generating | Serializing | Configuration Interface | Utilities | Examples | Extensibility | Troubleshooting | Command Line Utility | Graphical Client | Author & License

pyubx2 is an original Python 3 parser for the UBX ©, NMEA 0183 © and RTCM3 © protocols. UBX is a proprietary binary protocol implemented on u-blox ™ GNSS/GPS receiver modules.

The pyubx2 homepage is located at https://github.com/semuconsulting/pyubx2.

This is an independent project and we have no affiliation whatsoever with u-blox.

Status Release Build Codecov Release Date Last Commit Contributors Open Issues

The library implements a comprehensive set of inbound (SET/POLL) and outbound (GET) messages for u-blox GPS/GNSS devices from generation 6 through generation 10, but is readily extensible. Refer to UBX_MSGIDS in ubxtypes_core.py for the complete dictionary of messages currently supported. UBX protocol information sourced from public domain u-blox Interface Specifications © 2013-2021, u-blox AG.

Sphinx API Documentation in HTML format is available at https://www.semuconsulting.com/pyubx2.

Contributions welcome - please refer to CONTRIBUTING.MD. Feel free to discuss any proposed changes beforehand in the Discussion Channel.

Bug reports and Feature requests - please use the templates provided. For general queries and advice, post a message to one of the pyubx2 Discussions channels.


pyubx2 is compatible with Python >=3.8. In the following, python3 & pip refer to the Python 3 executables. You may need to type python or pip3, depending on your particular environment.

Python version PyPI version PyPI downloads

The recommended way to install the latest version of pyubx2 is with pip:

python3 -m pip install --upgrade pyubx2

If required, pyubx2 can also be installed into a virtual environment, e.g.:

python3 -m pip install --user --upgrade virtualenv
python3 -m virtualenv env
source env/bin/activate (or env\Scripts\activate on Windows)
(env) python3 -m pip install --upgrade pyubx2
...
deactivate

For Conda users, pyubx2 is also available from conda forge:

Anaconda-Server Badge Anaconda-Server Badge

conda install -c conda-forge pyubx2

pyubx2 divides UBX messages into three categories, signified by the mode or msgmode parameter.

mode description defined in
GET (0x00) output from the receiver (the default) ubxtypes_get.py
SET (0x01) command input to the receiver ubxtypes_set.py
POLL (0x02) query input to the receiver ubxtypes_poll.py

If you're simply streaming and/or parsing the output of a UBX receiver, the mode is implicitly GET. If you want to create or parse an input (command or query) message, you must set the mode parameter to SET or POLL. If the parser mode is set to 0x03 (SETPOLL), pyubx2 will automatically determine the applicable input mode (SET or POLL) based on the message payload.


class pyubx2.ubxreader.UBXReader(stream, *args, **kwargs)

You can create a UBXReader object by calling the constructor with an active stream object. The stream object can be any viable data stream which supports a read(n) -> bytes method (e.g. File or Serial, with or without a buffer wrapper). pyubx2 implements an internal SocketStream class to allow sockets to be read in the same way as other streams (see example below).

Individual input UBX, NMEA or RTCM3 messages can then be read using the UBXReader.read() function, which returns both the raw binary data (as bytes) and the parsed data (as a UBXMessage, NMEAMessage or RTCMMessage object, via the parse() method). The function is thread-safe in so far as the incoming data stream object is thread-safe. UBXReader also implements an iterator.

The constructor accepts the following optional keyword arguments:

  • protfilter: NMEA_PROTOCOL (1), UBX_PROTOCOL (2), RTCM3_PROTOCOL (4). Can be OR'd; default is NMEA_PROTOCOL | UBX_PROTOCOL | RTCM3_PROTOCOL (7)
  • quitonerror: ERR_IGNORE (0) = ignore errors, ERR_LOG (1) = log errors and continue (default), ERR_RAISE (2) = (re)raise errors and terminate
  • validate: VALCKSUM (0x01) = validate checksum (default), VALNONE (0x00) = ignore invalid checksum or length
  • parsebitfield: 1 = parse bitfields ('X' type properties) as individual bit flags, where defined (default), 0 = leave bitfields as byte sequences
  • msgmode: GET (0) (default), SET (1), POLL (2), SETPOLL (3) = automatically determine SET or POLL input mode

Example - Serial input. This example will output both UBX and NMEA messages but not RTCM3:

from serial import Serial
from pyubx2 import UBXReader, NMEA_PROTOCOL, UBX_PROTOCOL
with Serial('/dev/ttyACM0', 38400, timeout=3) as stream:
  ubr = UBXReader(stream, protfilter=NMEA_PROTOCOL | UBX_PROTOCOL)
  raw_data, parsed_data = ubr.read()
  if parsed_data is not None:
    print(parsed_data)

Example - File input (using iterator). This will only output UBX data:

from pyubx2 import UBXReader, UBX_PROTOCOL
with open('ubxdata.bin', 'rb') as stream:
  ubr = UBXReader(stream, protfilter=UBX_PROTOCOL)
  for raw_data, parsed_data in ubr:
    print(parsed_data)

Example - Socket input (using iterator). This will output UBX, NMEA and RTCM3 data:

import socket
from pyubx2 import UBXReader, NMEA_PROTOCOL, UBX_PROTOCOL, RTCM3_PROTOCOL
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as stream:
  stream.connect(("localhost", 50007))
  ubr = UBXReader(stream, protfilter=NMEA_PROTOCOL | UBX_PROTOCOL | RTCM3_PROTOCOL)
  for raw_data, parsed_data in ubr:
    print(parsed_data)

You can parse individual UBX messages using the static UBXReader.parse(data) function, which takes a bytes array containing a binary UBX message and returns a UBXMessage object.

NB: Once instantiated, a UBXMessage object is immutable.

The parse() method accepts the following optional keyword arguments:

  • validate: VALCKSUM (0x01) = validate checksum (default), VALNONE (0x00) = ignore invalid checksum or length
  • parsebitfield: 1 = parse bitfields as individual bit flags, where defined (default), 0 = leave bitfields as byte sequences
  • msgmode: GET (0) (default), SET (1), POLL (2), SETPOLL (3) = automatically determine SET or POLL input mode

Example - output (GET) message:

from pyubx2 import UBXReader
msg = UBXReader.parse(b'\xb5b\x05\x01\x02\x00\x06\x01\x0f\x38')
print(msg)
msg = UBXReader.parse(b'\xb5b\x01\x12$\x000D\n\x18\xfd\xff\xff\xff\xf1\xff\xff\xff\xfc\xff\xff\xff\x10\x00\x00\x00\x0f\x00\x00\x00\x83\xf5\x01\x00A\x00\x00\x00\xf0\xdfz\x00\xd0\xa6')
print(msg)
<UBX(ACK-ACK, clsID=CFG, msgID=CFG-MSG)>
<UBX(NAV-VELNED, iTOW=16:01:48, velN=-3, velE=-15, velD=-4, speed=16, gSpeed=15, heading=1.28387, sAcc=65, cAcc=80.5272)>

Example - input (SET) message:

from pyubx2 import UBXReader, SET
msg = UBXReader.parse(b"\xb5b\x13\x40\x14\x00\x01\x00\x01\x02\x01\x02\x03\x04\x01\x02\x03\x04\x01\x02\x03\x04\x01\x02\x03\x04\x93\xc8", msgmode=SET)
print(msg)
<UBX(MGA-INI-POS-LLH, type=1, version=0, reserved0=513, lat=6.7305985, lon=6.7305985, alt=67305985, posAcc=67305985)>

The UBXMessage object exposes different public attributes depending on its message type or 'identity', e.g. the NAV-POSLLH message has the following attributes:

print(msg)
print(msg.identity)
print(msg.lat, msg.lon)
print(msg.hMSL/10**3)
<UBX(NAV-POSLLH, iTOW=16:01:54, lon=-2.1601284, lat=52.6206345, height=86327, hMSL=37844, hAcc=38885, vAcc=16557)>
'NAV-POSLLH'
(52.6206345, -2.1601284)
37.844

The payload attribute always contains the raw payload as bytes. Attributes within repeating groups are parsed with a two-digit suffix (svid_01, svid_02, etc.).

Tip: To iterate through a repeating group of attributes (e.g. svid), the following construct can be used:

vals = [] # list of svid values from repeating group
for i in range(msg.numSV): # numSV = size of repeating group
    svid = getattr(msg, f"svid_{i+1:02d}")
    vals.append(svid)
print(vals)

If the input message class / id is unrecognised (i.e. not publicly documented by u-blox), pyubx2 will parse the message to a nominal payload definition and append the term 'NOMINAL' to the message identity.


(see below for special methods relating to the UBX configuration interface)

class pyubx2.ubxmessage.UBXMessage(ubxClass, ubxID, mode: int, **kwargs)

You can create a UBXMessage object by calling the constructor with the following parameters:

  1. message class (must be a valid class from pyubx2.UBX_CLASSES)
  2. message id (must be a valid id from pyubx2.UBX_MSGIDS)
  3. mode (0=GET, 1=SET, 2=POLL)
  4. (optional) a series of keyword parameters representing the message payload
  5. (optional) parsebitfield keyword - 1 = define bitfields as individual bits (default), 0 = define bitfields as byte sequences

The 'message class' and 'message id' parameters may be passed as lookup strings, integers or bytes.

The message payload can be defined via keyword arguments in one of three ways:

  1. A single keyword argument of payload containing the full payload as a sequence of bytes (any other keyword arguments will be ignored). NB the payload keyword argument must be used for message types which have a 'variable by size' repeating group.
  2. One or more keyword arguments corresponding to individual message attributes. Any attributes not explicitly provided as keyword arguments will be set to a nominal value according to their type.
  3. If no keyword arguments are passed, the payload is assumed to be null.

Example - to generate a CFG-MSG command (msgClass 0x06, msgID 0x01) which sets the NAV-STATUS (msgClass 0x01, msgID 0x03) outbound message rate to 1 on the UART1 port, any of the following constructor formats will work:

A. Pass entire payload as bytes:

from pyubx2 import UBXMessage, SET
msg1 = UBXMessage(b'\x06', b'\x01', SET, payload=b'\x01\x03\x00\x01\x00\x00\x00\x00')
print(msg1)
<UBX(CFG-MSG, msgClass=NAV, msgID=NAV-STATUS, rateDDC=0, rateUART1=1, rateUART2=0, rateUSB=0, rateSPI=0, reserved=0)>

B. Pass individual attributes as keyword arguments:

from pyubx2 import UBXMessage, SET
msg2 = UBXMessage(0x06, 0x01, SET, msgClass=0x01, msgID=0x03, rateDDC=0, rateUART1=1, rateUART2=0, rateUSB=0, rateSPI=0)
print(msg2)
<UBX(CFG-MSG, msgClass=NAV, msgID=NAV-STATUS, rateDDC=0, rateUART1=1, rateUART2=0, rateUSB=0, rateSPI=0, reserved=0)>

C. Pass selected attribute as keyword argument; the rest will be set to nominal values (in this case 0):

from pyubx2 import UBXMessage, SET
msg3 = UBXMessage('CFG','CFG-MSG', SET, msgClass=0x01, msgID=0x03, rateUART1=1)
print(msg3)
<UBX(CFG-MSG, msgClass=NAV, msgID=NAV-STATUS, rateDDC=0, rateUART1=1, rateUART2=0, rateUSB=0, rateSPI=0, reserved=0)>

The UBXMessage class implements a serialize() method to convert a UBXMessage object to a bytes array suitable for writing to an output stream.

e.g. to create and send a CFG-MSG command which sets the NMEA GLL (msgClass 0xf0, msgID 0x01) message rate to 1 on the receiver's UART1 and USB ports:

from serial import Serial
from pyubx2 import UBXMessage, SET
serialOut = Serial('COM7', 38400, timeout=5)
msg = UBXMessage('CFG','CFG-MSG', SET, msgClass=0xf0, msgID=0x01, rateUART1=1, rateUSB=1)
print(msg)
output = msg.serialize()
print(output)
serialOut.write(output)
<UBX(CFG-MSG, msgClass=NMEA-Standard, msgID=GLL, rateDDC=0, rateUART1=1, rateUART2=0, rateUSB=1, rateSPI=0, reserved=0)>
b'\xb5b\x06\x01\x08\x00\xf0\x01\x00\x01\x00\x01\x00\x00\x022'

CFG-VALSET, CFG-VALDEL and CFG-VALGET message types

Generation 9 of the UBX protocol (23.01 or greater, e.g. NEO-M9N, ZED-F9P) introduced the concept of a device configuration interface with configurable parameters being set or unset (del) in the designated memory layer(s) via the CFG-VALSET and CFG-VALDEL message types, or queried via the CFG-VALGET message type. Legacy CFG configuration message types continue to be supported but are now deprecated on Generation 9+ devices.

Optionally, batches of CFG-VALSET and CFG-VALDEL messages can be applied transactionally, with the combined configuration only being committed at the end of the transaction.

Individual configuration parameters are designated by keys, which may be in string (keyname) or hexadecimal integer (keyID) format. Keynames and their corresponding hexadecimal keyIDs and data types are defined in ubxtypes_configdb.py as UBX_CONFIG_DATABASE. Two helper methods are available to convert keyname to keyID and vice versa - cfgname2key() and cfgkey2name().

Dedicated static methods are provided to create these message types - UBXMessage.config_set(), UBXMessage.config_del() and UBXMessage.config_poll(). The following examples assume an output serial stream has been created as serialOut.

UBXMessage.config_set() (CFG-VALSET)

Sets up to 64 parameters in the designated memory layer(s).

Parameters:

  1. layers - SET_LAYER_RAM (1) = Volatile RAM, SET_LAYER_BBR (2) = Battery-Backed RAM (BBR), SET_LAYER_FLASH (4) = External Flash (may be OR'd)
  2. transaction - TXN_NONE (0) = None, TXN_START (1) = Start, TXN_ONGOING (2) = Ongoing, TXN_COMMIT (3) = Commit
  3. cfgData - an array of up to 64 (key, value) tuples. Keys can be in either keyID (int) or keyname (str) format
from pyubx2 import UBXMessage, SET_LAYER_RAM, TXN_NONE
layers = SET_LAYER_RAM
transaction = TXN_NONE
cfgData = [("CFG_UART1_BAUDRATE", 9600), (0x40520001, 115200)]
msg = UBXMessage.config_set(layers, transaction, cfgData)
print(msg)
serialOut.write(msg.serialize())
<UBX(CFG-VALSET, version=0, ram=1, bbr=0, flash=0, action=0, reserved0=0, cfgData_01=1, cfgData_02=0 ...)>

UBXMessage.config_del() (CFG-VALDEL)

Unsets (deletes) up to 64 parameter settings in the designated non-volatile memory layer(s).

Parameters:

  1. layers - SET_LAYER_BBR (2) = Battery-Backed RAM (BBR), SET_LAYER_FLASH (4) = External Flash (may be OR'd)
  2. transaction - TXN_NONE (0) = None, TXN_START (1) = Start, TXN_ONGOING (2) = Ongoing, TXN_COMMIT (3) = Commit
  3. keys - an array of up to 64 keys in either keyID (int) or keyname (str) format
from pyubx2 import UBXMessage, SET_LAYER_FLASH, TXN_NONE
layers = SET_LAYER_FLASH
transaction = TXN_NONE
keys = ["CFG_UART1_BAUDRATE", 0x40520001]
msg = UBXMessage.config_del(layers, transaction, keys)
print(msg)
serialOut.write(msg.serialize())
<UBX(CFG-VALDEL, version=0, bbr=0, flash=1, action=0, reserved0=0, keys_01=1079115777, keys_02=1079181313)>

UBXMessage.config_poll() (CFG-VALGET)

Polls up to 64 parameters from the designated memory layer.

Parameters:

  1. layer - POLL_LAYER_RAM (0) = Volatile RAM, POLL_LAYER_BBR (1) = Battery-Backed RAM (BBR), POLL_LAYER_FLASH (2) = External Flash, POLL_LAYER_DEFAULT (7) = Default (readonly)
  2. position - unsigned integer representing number of items to be skipped before returning result (used when number of matches for an individual query exceeds 64)
  3. keys - an array of up to 64 keys in either keyID (int) or keyname (str) format. keyIDs can use wildcards - see example below and UBX device interface specification for details.
from pyubx2 import UBXMessage,  POLL_LAYER_BBR
layer = POLL_LAYER_BBR
position = 0
keys = ["CFG_UART1_BAUDRATE", 0x40520001]
msg = UBXMessage.config_poll(layer, position, keys)
print(msg)
serialOut.write(msg.serialize())
<UBX(CFG-VALGET, version=0, layer=1, position=0, keys_01=1079115777, keys_02=1079181313)>

Wild card queries can be performed by setting bits 0..15 of the keyID to 0xffff e.g. to retrieve all CFG_MSGOUT parameters (keyID 0x2091*) :

from pyubx2 import UBXMessage, POLL_LAYER_BBR
layer = POLL_LAYER_BBR
position = 0 # retrieve first 64 results
keys = [0x2091ffff]
msg1of3 = UBXMessage.config_poll(layer, position, keys)
print(msg1of3)
serialOut.write(msg1of3.serialize())
position = 64 # retrieve next 64 results
msg2of3 = UBXMessage.config_poll(layer, position, keys)
print(msg2of3)
serialOut.write(msg2of3.serialize())
position = 128 # retrieve next 64 results
msg3of3 = UBXMessage.config_poll(layer, position, keys)
print(msg3of3)
serialOut.write(msg3of3.serialize())
<UBX(CFG-VALGET, version=0, layer=1, position=0, keys_01=546439167)>
<UBX(CFG-VALGET, version=0, layer=1, position=64, keys_01=546439167)>
<UBX(CFG-VALGET, version=0, layer=1, position=128, keys_01=546439167)>

pyubx2 provides the following utility methods (via the pynmeagps library):

  • latlon2dms - converts decimal lat/lon to degrees, minutes, decimal seconds format e.g. "53°20′45.6″N", "2°32′46.68″W"
  • latlon2dmm - converts decimal lat/lon to degrees, decimal minutes format e.g. "53°20.76′N", "2°32.778′W"
  • ecef2llh - converts ECEF (X, Y, Z) coordinates to geodetic (lat, lon, ellipsoidal height) coordinates
  • llh2ecef - converts geodetic (lat, lon, ellipsoidal height) coordinates to ECEF (X, Y, Z) coordinates
  • haversine - finds spherical distance in km between two sets of (lat, lon) coordinates
  • bearing - finds bearing in degrees between two sets of (lat, lon) coordinates
  • cel2cart - converts celestial coordinates (elevation, azimuth) to cartesian coordinations (X,Y)

See Sphinx documentation for details.


The following command line examples can be found in the \examples folder:

  1. ubxoptions.py illustrates the various options available for parsing and constructing UBX messages.
  2. ubxpoller.py illustrates how to read, write and display UBX messages 'concurrently' using threads and queues. This represents a useful generic pattern for many end user applications.
  3. ubxsetrates.py illustrates how to use legacy configuration messages (CFG-MSG) to set navigation message rates.
  4. ubxconfigdb.py illustrates how to invoke the Generation 9 configuration database interface via CFG-VALSET, CF-VALDEL and CFG-VALGET messages.
  5. ubxfactoryreset.py illustrates how to send a factory reset (CFG-CFG) command.
  6. ubxfile.py illustrates how to implement a binary file reader for UBX messages using UBXReader iterator functionality.
  7. ubxsocket.py illustrates how to implement a TCP Socket reader for UBX messages using UBXReader iterator functionality. Can be used in conjunction with the tcpserver_threaded.py socket server test harness.
  8. gpxtracker.py illustrates a simple tool to convert a binary UBX data dump to a *.gpx track file.
  9. ubxserver.py in the \examples\webserver folder illustrates a simple HTTP web server wrapper around pyubx2.UBXreader; it presents data from selected UBX messages as a web page http://localhost:8080 or a RESTful API http://localhost:8080/gps.
  10. mon_span_spectrum.py illustrates how to use pyubx2 and matplotlib to plot a spectrum analysis graph from a UBX MON-SPAN message.
  11. utilities.py illustrates how to use various pyubx2 utility methods.
  12. benchmark.py provides a simple performance benchmarking tool for the pyubx2 parser.

The UBX protocol is principally defined in the modules ubxtypes_*.py as a series of dictionaries. Message payload definitions must conform to the following rules:

1. attribute names must be unique within each message class
2. attribute types must be one of the valid types (I1, U2, X4, etc.)
3. if the attribute is scaled, attribute type is list of [attribute type as string (I1, U2, etc.), scaling factor as float] e.g. {"lat": [I4, 1e-7]}
4. repeating or bitfield groups must be defined as a tuple ('numr', {dict}), where:
   'numr' is either:
     a. an integer representing a fixed number of repeats e.g. 32
     b. a string representing the name of a preceding attribute containing the number of repeats e.g. 'numCh'
     c. an 'X' attribute type ('X1', 'X2', 'X4', etc) representing a group of individual bit flags
     d. 'None' for a 'variable by size' repeating group. Only one such group is permitted per payload and it must be at the end.
   {dict} is the nested dictionary of repeating items or bitfield group

Repeating attribute names are parsed with a two-digit suffix (svid_01, svid_02, etc.). Nested repeating groups are supported. See CFG-VALGET, MON-SPAN, NAV-PVT, NAV-SAT and RXM-RLM by way of examples.

In most cases, a UBX message's content (payload) is uniquely defined by its class, id and mode; accommodating the message simply requires the addition of an appropriate dictionary entry to the relevant ubxtypes_*.py module(s). However, there are a handful of message types which have multiple possible payload variants for the same class, id and mode. These exceptional message types are handled in ubxvariants.py, to which any additional variants should be added.


1. Unknown Protocol errors.

These are usually due to corruption of the serial data stream, either because the serial port configuration is incorrect (baud rate, parity, etc.) or because another process is attempting to use the same data stream.

  • Check that your UBX receiver UART1 or UART2 ports are configured for the desired baud rate - remember the factory default is 38400 (not 9600).
  • Check that no other process is attempting to use the same serial port, including daemon processes like gpsd.

2. Serial Permission errors.

These are usually caused by inadequate user privileges or contention with another process.

  • On Linux platforms, check that the user is a member of the tty and/or dialout groups.
  • Check that no other process is attempting to use the same serial port, including daemon processes like gpsd.

3. UnicodeDecode errors.

  • If reading UBX data from a log file, check that the file.open() procedure is using the rb (read binary) setting e.g. stream = open('ubxdatalog.log', 'rb').

4. Spurious CFG-VALGET, DBG, TRK, TUN and SEC data in *.ubx files recorded in u-center.

By default, u-center 21.09 records a series of configuration messages (CFG-VALGET) containing undocumented configuration database keys. In addition, clicking the 'debug' option results in a large number of undocumented DBG, TRK, TUN and SEC message classes. As of version v1.2.15, pyubx2 is capable of parsing these undocumented message classes (to a nominal payload definition), but they are really only of relevance to u-blox technical support. If you are not intending to send the recordings to u-blox;

  • When recording GNSS output data in u-center, select 'No' when prompted to 'Add Receiver Configuration' to the recording, and avoid the 'debug' option.

A command line utility gnssdump is available via the pygnssutils package. This is capable of reading and parsing NMEA, UBX and RTCM3 data from a variety of input sources (e.g. serial, socket and file) and outputting to a variety of media in a variety of formats. See https://github.com/semuconsulting/pygnssutils for further details.

To install pygnssutils:

python3 -m pip install --upgrade pygnssutils

For help with the gnssdump utility, type:

gnssdump -h

A python/tkinter graphical GPS client which supports NMEA, UBX and RTCM3 protocols (via pynmeagps, pyubx2 and pyrtcm respectively) is available at:

https://github.com/semuconsulting/PyGPSClient


[email protected]

License

pyubx2 is maintained entirely by unpaid volunteers. It receives no funding from advertising or corporate sponsorship. If you find the library useful, a small donation would be greatly appreciated!

Donations

pyubx2's People

Contributors

agagniere avatar alinsavix avatar alkeldi avatar arressjay avatar cturvey avatar gabrielecoppi avatar hadatko avatar horace1024 avatar lyngklip avatar nerolf05 avatar phsommer avatar semuadmin avatar semudev2 avatar ts-ahmed avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyubx2's Issues

Getting time in ms format

Something I trying to accomplish for some time now is to be able to get timestamp with ms precision, as for when I send a NAV-PVT message the response is up to seconds. I do get the nano field but oddly this is a 6 digit number so it doesn't contain any milliseconds info... I've tried to configure the time pulse thinking maybe it'll change the resolution but am yet to have it working for this.

I'm asking the question here just thought maybe I could get help here, since I've been going through the datasheet lately but I feel like I'm missing something 🤔.

Help would be very appreciated!

Parsing bitfields, UBX-ESF-MEAS

I am getting errors parsing the UBX stream. The UBX-ESF-MEAS (0x10 0x02) is not supported on the NEO-M8U-0-10
The message is not supported and the field requires getting the length from a bit field.

I'm not sure how to extract repeated fields from a bit field.

It's easy to add new messages where the length is full sized,

    "numOsc": U1,
    "reserved1": U2,
    "group": (
        "numOsc",
        {  # repeating group * numOsc
            "oscId": U1,

but I' not sure valid syntax for bit slicing the fields. What's the best way to modify ubxtypes_get.py?

It does change over time so using a fixed value isn't working.

numMea is the 5MSBs at offset 6.

19:13:02 0000 B5 62 10 02 18 00 72 D8 07 00 18 18 00 00 4B FD µb....rØ......Ký
0010 FF 10 40 02 00 11 23 28 00 12 72 D8 07 00 03 9C ÿ.@...#(..rØ.....

19:13:02 0000 B5 62 10 02 1C 00 6D D8 07 00 18 20 00 00 CD 06 µb....mØ... ..Í.
0010 00 0E E4 FE FF 0D 03 FA FF 05 09 0B 00 0C 6D D8 ..äþÿ..úÿ.....mØ
0020 07 00 EE 51 ..îQ.

19:13:02 0000 B5 62 10 02 18 00 D5 D8 07 00 18 18 00 00 4D FD µb....ÕØ......Mý
0010 FF 10 45 02 00 11 1F 28 00 12 D5 D8 07 00 CC AC ÿ.E....(..ÕØ..̬.

19:13:02 0000 B5 62 10 02 1C 00 D0 D8 07 00 18 20 00 00 7C 06 µb....ÐØ... ..|.
0010 00 0E CB FE FF 0D AC F9 FF 05 09 0B 00 0C D0 D8 ..Ëþÿ.¬ùÿ.....ÐØ
0020 07 00 F2 AE ..ò®.

19:13:02 0000 B5 62 10 02 18 00 38 D9 07 00 18 18 00 00 4A FD µb....8Ù......Jý
0010 FF 10 41 02 00 11 27 28 00 12 38 D9 07 00 95 7A ÿ.A...'(..8Ù...z.

19:13:02 0000 B5 62 10 02 1C 00 33 D9 07 00 18 20 00 00 0F 06 µb....3Ù... ....
0010 00 0E 16 FE FF 0D 5B FA FF 05 0A 0B 00 0C 33 D9 ...þÿ.[úÿ.....3Ù
0020 07 00 49 9F ..I..

19:13:02 0000 B5 62 10 02 18 00 9C D9 07 00 18 18 00 00 4E FD µb.....Ù......Ný
0010 FF 10 4E 02 00 11 20 28 00 12 9C D9 07 00 67 0E ÿ.N... (...Ù..g..

19:13:02 0000 B5 62 10 02 1C 00 97 D9 07 00 18 20 00 00 85 06 µb.....Ù... ....
0010 00 0E 77 FE FF 0D E1 F9 FF 05 0A 0B 00 0C 97 D9 ..wþÿ.áùÿ......Ù
0020 07 00 6D A4 ..m¤.

19:13:02 0000 B5 62 10 02 18 00 FF D9 07 00 18 18 00 00 4C FD µb....ÿÙ......Lý
0010 FF 10 3E 02 00 11 24 28 00 12 FF D9 07 00 1F 22 ÿ.>...$(..ÿÙ...".

19:13:02 0000 B5 62 10 02 1C 00 FA D9 07 00 18 20 00 00 92 06 µb....úÙ... ....
0010 00 0E 61 FE FF 0D 9F F9 FF 05 0A 0B 00 0C FA D9 ..aþÿ..ùÿ.....úÙ
0020 07 00 E8 90 ..è..

19:13:02 0000 B5 62 10 02 18 00 63 DA 07 00 18 18 00 00 47 FD µb....cÚ......Gý
0010 FF 10 44 02 00 11 1C 28 00 12 63 DA 07 00 E2 E4 ÿ.D....(..cÚ..âä.

19:13:02 0000 B5 62 10 02 1C 00 5E DA 07 00 18 20 00 00 EF 06 µb....^Ú... ..ï.
0010 00 0E B8 FE FF 0D C8 F9 FF 05 0A 0B 00 0C 5E DA ..¸þÿ.Èùÿ.....^Ú
0020 07 00 8F CE ...Î.

19:13:02 0000 B5 62 10 02 18 00 C6 DA 07 00 18 18 00 00 4A FD µb....ÆÚ......Jý
0010 FF 10 4E 02 00 11 21 28 00 12 C6 DA 07 00 BA 88 ÿ.N...!(..ÆÚ..º..

19:13:02 0000 B5 62 10 02 1C 00 C1 DA 07 00 18 20 00 00 82 06 µb....ÁÚ... ....
0010 00 0E 5B FE FF 0D C8 F9 FF 05 09 0B 00 0C C1 DA ..[þÿ.Èùÿ.....ÁÚ
0020 07 00 8A D2 ...Ò.

19:13:02 0000 B5 62 10 02 18 00 2A DB 07 00 18 18 00 00 48 FD µb....*Û......Hý
0010 FF 10 47 02 00 11 27 28 00 12 2A DB 07 00 81 4E ÿ.G...'(..*Û...N.

19:13:02 0000 B5 62 10 02 1C 00 25 DB 07 00 18 20 00 00 1B 07 µb....%Û... ....
0010 00 0E ED FE FF 0D FA F9 FF 05 09 0B 00 0C 25 DB ..íþÿ.úùÿ.....%Û
0020 07 00 B2 EF

19:05:43 0000 B5 62 10 02 1C 00 DB 25 01 00 18 20 00 00 76 02 µb....Û%... ..v.
0010 00 0E 06 F8 FF 0D DE F7 FF 05 54 0A 00 0C DB 25 ...øÿ.Þ÷ÿ.T...Û%
0020 01 00 3B 91

19:05:42 0000 B5 62 10 02 18 00 EE 23 01 00 18 18 00 00 E8 11 µb....î#......è.
0010 00 10 FA 07 00 11 A1 22 00 12 EE 23 01 00 6E F9 ..ú...¡"..î#..nù.

19:05:42 0000 B5 62 10 02 1C 00 94 21 01 00 18 20 00 00 FF 05 µb.....!... ..ÿ.
0010 00 0E F3 FE FF 0D 4D 0B 00 05 51 0A 00 0C 94 21 ..óþÿ.M...Q....!
0020 01 00 A5 52

CFG-DAT / Set Standard Datum

Using pyubx2 1.2.6

I try to build a UBXMessage from "CFG-DAT - 06 06 02 00 00 00" (this message comes from uCenter feature Tools/Receiver configuration/Transfer GNSS -> File, with a M8N PROTVER 18.0 & FWVER=SPG 3.01)

I have the following exception :

Traceback (most recent call last):
  File "d:\atp_holybro\env\lib\site-packages\pyubx2\ubxmessage.py", line 106, in _do_attributes
    (offset, index) = self._set_attribute(
  File "d:\atp_holybro\env\lib\site-packages\pyubx2\ubxmessage.py", line 168, in _set_attribute
    offset = self._set_attribute_single(att, offset, key, index, **kwargs)
  File "d:\atp_holybro\env\lib\site-packages\pyubx2\ubxmessage.py", line 266, in _set_attribute_single
    val = bytes2val(valb, att)
  File "d:\atp_holybro\env\lib\site-packages\pyubx2\ubxhelpers.py", line 296, in bytes2val
    val = struct.unpack("<d", valb)[0]
struct.error: unpack requires a buffer of 8 bytes

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "d:\atp_holybro\atp_holybro\ubx_config_parser.py", line 26, in <module>
    p.build_msg()
  File "d:\atp_holybro\atp_holybro\ubx_config_parser.py", line 16, in build_msg
    msg = UBXMessage(bytes[0], bytes[1], GET, payload=bytes[2:-1])
  File "d:\atp_holybro\env\lib\site-packages\pyubx2\ubxmessage.py", line 81, in __init__
    self._do_attributes(**kwargs)
  File "d:\atp_holybro\env\lib\site-packages\pyubx2\ubxmessage.py", line 117, in _do_attributes
    raise ube.UBXTypeError(
pyubx2.exceptions.UBXTypeError: Incorrect type for attribute 'majA' in GET message class CFG-DAT

It seems that this message is not well understood ; in older version of protocol specification §31.3.2, a "Set Standard Datum" message is defined, with just a enumerate of Geodetic Datum.

It should be good to add the support of this CFG-DAT / Set Standard Datum message.

I would be happy to help you for developping & testing this feature.

Navigation-message decoder

Is your feature request related to a problem? Please describe.
I would like to suggest/contribute a new additional feature. During my time as a working student, I developed a gnss-navigation message parser for the ubx-rxm-sfrbx-message, based on this amazing library.
In detail, the following messages are currently supported:

  • GPS - C/NAV
  • GPS - L/NAV
  • GLON - NAV
  • GAL - I/NAV
  • BDS - D1
  • BDS - D2 (not completely)

The proposed decoder/parser parses the raw binary-navigation message, which is available through the ubx-rxm-sfrbx-message, into a readable format. So one would be able to present/store/visualize the transmitted navigation data like:

  • Ephemeris
  • Almancs
  • Clock-parameters
  • and some more.

An additional feature might be a nav-rinex exporter

A clear and concise description of what you want to happen.

  1. Would the proposed feature be interesting for pyubx2 (if not interesting: skip 2-4)
  2. One could discuss my existing code and design, if something should be changed or restructured (Feedback and suggestions for improvement would be appreciated)
  3. Develop tests
  4. Add the feature

Would you be willing to assist with testing?

Yes, I would like to help and develop tests to secure a correct decoding of the navigation messages.
Additionally, I would suggest, that it might be useful to add some ublox-recordings in the *.ubx-format and navigation reference data for testing the navigation message decoder.

If the request relates to a specific u-blox device that is not currently supported, would you be
willing to assist with testing e.g. by contributing a test device to the project, providing real data dumps, or writing unittest scripts?

Unfortunately, I don't have access to an ublox-gnss receiver supporting the ubx-rxm-sfrbx message at the moment. But yes, I would be willing to assist with defining tests.

Best regards

HNR-PVT Values seem incorrect, in relation to NAV-PVT and HNR-PVT in UCenter

Describe the bug
Some of the values in the HNR-PVT message have completely different values after reading from UART, in comparison to the Ucenter data. (I believe all the values with number format 'I4').

The iTOW, and date values come in correctly. But the Lon, Lat, gSpeed, height, mslHeight, heading, heading accuracy etc are all incorrect values (before and after adding the supplied scaling).

I checked the number formats in ubxtypes_core.py and ubxtypes_get,py. These seem to correspond with the types given in the UBlox receiver description 8 (https://www.u-blox.com/sites/default/files/products/documents/u-blox8-M8_ReceiverDescrProtSpec_UBX-13003221.pdf)

pyUBX2 version: 1.0.7

Relevant files (also uploaded in this issues attachments, as ZIP File):

  1. UBX binary file (sorry if there are hickups in the fix, I had really bad reception): https://drive.google.com/open?id=1dmmSrNeFPoTk5itSg5kI3zCpjPnxG8dg

  2. Expected values (screenshot from messages view in Ucenter): https://drive.google.com/open?id=1P1b93eRtnUc4yQ40uS_6S3ELEN3YvUrK

  3. Gotten values (log output of my Python program, no scaling applied, so units might be incorrect): https://drive.google.com/open?id=1pg5W18EeQw2wr1PnIPVsajNYzoxljmHV

  4. Used script to read serial stream and print log messages: https://drive.google.com/file/d/13RdHPz3kWPeIEFOuqWazbgHFCM1JJbjY/view?usp=sharing

HNR-PVT-Problem.zip

To Reproduce

in UBX-CFG-PRT: Enable UART as target, prot in: UBX, prot out: UBX, Baudrate: 921600, databits: 8, stopbits: 1, parity: None, BitORder: LSB First

in UBX-CFG-HNR: NavRate: 20 Hz

I ran the script on a Raspberry Pi 4, 4GB with python 3.7.3 and pyUBX2 1.0.7

Expected Behavior

I expected the HNR-PVT values parsed with pyUBX2 parser (see appendix file 3 and 4), to be identical to the UCenter values (see appendix file 2). I expected that maybe some factor difference would be noticeable, but the whole values is completely different. So only scaling would not work.

Desktop (please complete the following information):

  • Raspberry Pi 4, 4GB, Raspberry Pi OS version 10 (buster)
  • Kernel: Linux raspberrypi 5.10.17-v7l+ #1403 SMP Mon Feb 22 11:33:35 GMT 2021 armv7l GNU
  • Python 3.7.3 and pyUBX2 1.0.7
  • Windows10 for the uCenter screenshot
  • UART on the raspberry Pi to retrieve data
  • USB on Windows 10 to double check UART data
  • Ucenter v 20.10

GNSS/GPS Device (please complete the following information as best you can):

  • Device: U-Blox NEO-M8U
  • firmware version: UDR 1.5 (latest)
  • protocol: 19.20

Additional context

The data received by NAV-PVT, does parse correctly and correspond to the values in U-Center. I checked the source code of PyUBX2 to see if the unpacking of bytes might have been wrong, but it seems to be identical for HNR-PVT and NAV-PVT. Although the values of HNR-PVT do not correspond to U-center.

I also wanted to add that the accelerometer and gyro are not calibrated at the moment, since I don't have access to a vehicle. Although, I would think that if U center can display sensible data, that I should be able to get the same data in Python.

If you need any more information or clarification, you can always ask me.

P.S. Great work on this library! It is a great tool (the best for Python IMO) to parse the data. Keep it up! :)

Serialization of messages into bytes sometimes gives non-hex values

Describe the bug
I do not know if this is a bug, improper procedure on my part, or improper understanding of the results. The issue is that the serialized message generated by UBXMessage sometimes includes characters that are not in hex format. The message does work when sent to the receiver, and generates an ACK, so this is about representation, I think.

For example the following message for CFG-TP5 generated by UBXMessage:

<UBX(CFG-TP5, tpIdx=0, version=1, reserved0=0, antCableDelay=50, rfGroupDelay=0, freqPeriod=1, freqPeriodLock=4687500, pulseLenRatio=0, pulseLenRatioLock=50, userConfigDelay=0, active=1, lockGnssFreq=1, lockedOtherSet=1, isFreq=1, isLength=0, alignToTow=1, polarity=1, gridUtcGnss=1, syncMode=0)>

when run through serialize() returns this:

b'\xb5b\x061 \x00\x00\x01\x00\x002\x00\x00\x00\x01\x00\x00\x00\x8c\x86G\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x00\x00\xef\x00\x00\x00\x05n'

Note the "\x86G" in the middle and the "\x05n" at the end. I believe that in those cases the letters represent the ASCII representation rather the the hex of the byte.

Again, this message works so it is not a pyubx2 bug, but maybe unexpected behavior that the printed output is mainly hex but includes occasional non-hex representations?

I am trying to generate a byte stream that can be used by another program to send the command, and this quirk is throwing me off. Is there a different way to generate a stream of bytes purely in hex form from the output of UBXMessage?

This is on pyubx2 version 1.2.19 running with Python v3.10.6 on a Linux mint system.

Thanks!

Wrong cfg-tmode key ids

Describe the bug

Some of the key IDs in ubxtypes_configdb.py are different from ZED-F9P InterfaceDescription (UBX-18010854). Since the keys IDs are different when I am trying to send UBX-CFG-VALSET message I receive NAK messages. The keys I have found so far (might be more affected):

  • CFG-TMODE-ECEF_X
  • CFG-TMODE-ECEF_Y
  • CFG-TMODE-ECEF_Z
  • CFG-TMODE-LAT
  • CFG-TMODE-LON
  • CFG-TMODE-HEIGHT
  • CFG-TMODE-FIXED_POS_ACC
  • CFG-TMODE-SVIN_MIN_DUR
  • CFG-TMODE-SVIN_ACC_LIMIT

pyubx2 version: 1.0.6

To Reproduce

  1. Create CFG-VALSET message with one of the keys above
  2. Sent it to UBlox device

Expected Behavior

Receive ACK message and changed device configuration according to the keys.

Desktop (please complete the following information):

  • The operating system you're using: Ubuntu Focal Fossa
  • The type of serial connection: UART1

GNSS/GPS Device (please complete the following information as best you can):

  • Device Model/Generation: u-blox ZED-F9P
  • Firmware Version: HPG 1.12
  • Protocol: 27.11

Additional context

Same with current version (1.0.8).
Values a different by a single digit, e.g. "CFG_TMODE_ECEF_X" is 0x40030003 while "CFG_TMODE_ECEF_X_HP" is 0x20030006. Currently all of tmode keys in pyubx have key ids like 0x2*, while in ubx docs some are 0x2* while others are 0x4* for some weird reason.

Meta-data for "MON-RF.group.flags.jammingState" is incorrect. It is specified as U1 when it should be U2.

Describe the bug

The meta-data for "MON-RF.group.flags.jammingState" is incorrect. It is specified as U1 when it should be U2.

This can be seen in the code here:
https://github.com/semuconsulting/pyubx2/blob/master/src/pyubx2/ubxtypes_get.py#L1812C44-L1812C44

It affects release v1.2.29

Here is the relevant extract from the UBX interface description:
image

To Reproduce

Expected Behaviour

Desktop (please complete the following information):

N/A

GNSS/GPS Device (please complete the following information as best you can):

N/A

Additional context

Add any other context about the problem here.

streamer exemple using asyncio. Or maybe UBXReader.read() alternative

Is your feature request related to a problem? Please describe.

Hello, when we started to use this module we got inspire with your examples. For reading data we looked into stremear example. This solution was eating 100% cpu when we were not waiting any data (most of the time => period 5min).

Describe the solution you'd like

So we decided to do solution with asyncio. We have solution for our case. SO we were thinking that we can share example. Maybe it can get into core of module but i think it is not that quality currently.

Additional context

We were curious if you would accept such an example.

rinex output

Dear Developers,
Is there or is there a plan to make a u-bloc to rinex (Receiver Independent Exchange Format) converter?
Terveisin, Markus

Wrong LOG-FINDTIME packet format due to error in UBX protocol documentation

Describe the bug

LOG-FINDTIME Documentation from UBlox is incorrect. The payload should in fact be 10 bytes long
It will always return NAK in any case with the current implementation.

Running Ublox U-Center, the bytes stream (working with the ZOE-M8B devkit) for the LOG-FINDTIME command is shorter with only 10 bytes payload instead of 12

2 U1[2] - reserved1 - Reserved Field in the documentation is in fact non-existant

To Reproduce

Identical ticket opened for gpsd ubxtool with a working fix already applied there:
https://gitlab.com/gpsd/gpsd/-/issues/68
https://gitlab.com/gpsd/gpsd/-/commit/b0e89557be1e9a5cf95d4e189e960b9de2794a1c

Steps to reproduce the behaviour:

Call the command when hooked to a ZOE-M8B devkit

Expected Behavior

LOG-FINDTIME returns ACK and a properly formatted answer

Desktop (please complete the following information):

  • Linux Alpine docker container with pyserial on ARM-A7 NXP platform
  • UART mapped to /dev/ttyLP2

GNSS/GPS Device (please complete the following information as best you can):

  • Hardware: ZOE-M8B with external QSPI flash for use with Logging features
  • Protocol: 23.01

Additional context

Changing this:

    "LOG-FINDTIME": {
        "version": U1,
        "type": U1,
        "reserved0": U2,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "minute": U1,
        "second": U1,
        "reserved1": U1,
    },

to this:

    "LOG-FINDTIME": {
        "version": U1,
        "type": U1,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "minute": U1,
        "second": U1,
        "reserved1": U1,
    },

under ubxtypes_set.py should fix the issue. If required I will be glad to forward you our email exchange with steliau technology (support providr for ublox).

CircleCI automation

Is your feature request related to a problem? Please describe.

Hi, you may consider using circleci auto free run test with every PR. They will be executed automaticly on PR creation and change and you may be sure that code is properly tested.

Describe the solution you'd like

Describe alternatives you've considered

Any other automation system

Would you be willing to assist with testing?

Sure no problem :D I did same for eRPC. You can see it e.g. here EmbeddedRPC/erpc#254 at bottom (all checks passed).

Additional context

How to read ubx flags

I have a problem how to understand and read ubx flags.
I.e. I want to read NAV-STATUS message:

raw data:
b'\xb5b\x01\x03\x10\x00\xe0\xc8a\x18\x03\xdf\x02\x08D\x02\x00\x004S\x1e\x00\x0c\xf3'

parsed data:
<UBX(NAV-STATUS, iTOW=17:37:25.600000, gpsFix=3, flags=b'\xdf', fixStat=b'\x02', flags2=b'\x08', ttff=580, msss=1987380)>

Precisely - I want to get carrSoln value, which is under flags2 (page 141 in ZEDF9P Interface Description: https://www.u-blox.com/en/docs/UBX-18010854)

How to read b'\x08' and extract from it the carrSoln?

Thank you so much for help! :D

CFG-DAT message generation fails

Hi, I can't figure out what exactly is going wrong here. Hope you have an idea?

I would expect the below lines to assemble a valid UBX message:

import pyubx2
pyubx2.UBXMessage("CFG", "CFG-DAT", 1, payload=bytes.fromhex("00" * 44))

However it's somehow running out of bytes to unpack in

val = struct.unpack("<f", valb)[0]

I'm on pyubx2 1.0.12

Traceback:

Python 3.6.13 (default, May  3 2021, 02:51:47)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pyubx2
   ...: pyubx2.UBXMessage("CFG", "CFG-DAT", 1, payload=bytes.fromhex("00" * 44))
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
~/.local/lib/python3.6/site-packages/pyubx2/ubxmessage.py in _do_attributes(self, **kwargs)
     97                     (offset, index) = self._set_attribute(
---> 98                         offset, pdict, key, index, **kwargs
     99                     )

~/.local/lib/python3.6/site-packages/pyubx2/ubxmessage.py in _set_attribute(self, offset, pdict, key, index, **kwargs)
    136         else:  # single attribute
--> 137             offset = self._set_attribute_single(att, offset, key, index, **kwargs)
    138

~/.local/lib/python3.6/site-packages/pyubx2/ubxmessage.py in _set_attribute_single(self, att, offset, key, index, **kwargs)
    221             valb = self._payload[offset : offset + atts]
--> 222             val = self.bytes2val(valb, att)
    223         else:

~/.local/lib/python3.6/site-packages/pyubx2/ubxmessage.py in bytes2val(valb, att)
    782         elif att == ubt.R4:  # single precision floating point
--> 783             val = struct.unpack("<f", valb)[0]
    784         elif att == ubt.R8:  # double precision floating point

error: unpack requires a buffer of 4 bytes

The above exception was the direct cause of the following exception:

UBXTypeError                              Traceback (most recent call last)
<ipython-input-1-863373d112f6> in <module>
      1 import pyubx2
----> 2 pyubx2.UBXMessage("CFG", "CFG-DAT", 1, payload=bytes.fromhex("00" * 44))

~/.local/lib/python3.6/site-packages/pyubx2/ubxmessage.py in __init__(self, ubxClass, ubxID, msgmode, **kwargs)
     71             self._ubxID = ubxID
     72
---> 73         self._do_attributes(**kwargs)
     74         self._immutable = True  # once initialised, object is immutable
     75

~/.local/lib/python3.6/site-packages/pyubx2/ubxmessage.py in _do_attributes(self, **kwargs)
    113                     f"class {self.identity}"
    114                 )
--> 115             ) from err
    116
    117     def _set_attribute(

UBXTypeError: Incorrect type for attribute 'rotZ' in SET message class CFG-DAT

On the other hand,

len(pyubx2.UBXMessage("CFG", "CFG-DAT", 1, majA=0, flat=0, dX=0, dY=0, dZ=0, rotX=0, rotY=0, rotZ=0, scale=0).payload)

is 52, while my datasheet says the payload length should be 44?


Looking at the protocol description again, it seems this is the difference between GET and SET of CFG_DAT. (https://www.u-blox.com/sites/default/files/products/documents/u-blox8-M8_ReceiverDescrProtSpec_UBX-13003221.pdf page 196/197)

MGA messages cannot be parsed

Describe the bug

Hello. I have issue to parse MGA messages.
In your comments is mentioned:

***************************************************************

# Multiple GNSS Assistance messages
# These need special handling as MSGIDs alone are not unique;
# message identity is determined by 'type' attribute in payload
# ***************************************************************

Are you planing to support this somehow? I can help but i wan't do PR before small talk.

My current idea:
Change UBX_MSGIDS from:
UBX_MSGIDS={key:value} to UBX_MSGIDS={key:{key2:value}}
for unique messages it would looks like UBX_MSGIDS={key:{"":value}}
key2 would be type in MGA messages. What would you say about that?

Please specify the pyubx2 version (>>> pyubx2.version) and, where possible, include:
current version
image

To Reproduce

Steps to reproduce the behaviour:
pyubx2.UBXReader.parse(b'\xb5\x62\x13\x40\x18\x00\x10\x00\x00\x12\xe5\x07\x0b\x16\x09\x3A\x3b\x00\x80\x73\x3b\x0D\x0f\x00\x00\x00\x00\x00\x00\x00\x62\x3f')

Expected Behavior

Parse message successfuly.

tcp input instead of serial

Hello,

Is it possible to use pyubx2 with a tcp input instead of serial?

My applications already use the serial port as input str2str -in serial://ttyACM0:115200:8:n:1#ubx -out tcpsvr://:5015 and I would like to connect pyubx2 on the localhost:5015

thanks!

How to extract GPS time or higher number of digits in the iTOW field instead of UTC time?

I am using ublox ZED-F9K receiver for serial communication. While recording the measurements, I noticed that the time shows up as iTOW instead of GPS time probably because, in the codebase, there is a conversion happening between GPS time and UTC time.
For my application, I would like to get a higher precision time from the iTOW and ideally the GPS time directly instead of the UTC time. Is there a way to extract it?

It should be possible to *read* CFG-VALSET packets

Is your feature request related to a problem? Please describe.

When reading a stream of ubx data, pyubx2 is currently unable to parse CFG-VALSET packets. To some degree this makes sense, because a device will never send those packets... but being able to take a saved ubx file on disk that contains a bunch of CFG-VALSET packets, and being able to read it to see what config values are actually getting set, would be an extremely useful thing.

At the moment, trying to parse a file with CFG-VALSET commands gives the following traceback:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/pyubx2/ubxreader.py", line 379, in parse
    return UBXMessage(
  File "/usr/local/lib/python3.10/site-packages/pyubx2/ubxmessage.py", line 81, in __init__
    self._do_attributes(**kwargs)
  File "/usr/local/lib/python3.10/site-packages/pyubx2/ubxmessage.py", line 104, in _do_attributes
    pdict = self._get_dict(**kwargs)  # get appropriate payload dict
  File "/usr/local/lib/python3.10/site-packages/pyubx2/ubxmessage.py", line 525, in _get_dict
    pdict = ubg.UBX_PAYLOADS_GET[self.identity]
KeyError: 'CFG-VALSET'

(which makes sense, as ubxtypes_get.py has no knowledge of CFG-VALSET packets)

Describe the solution you'd like

Make the above work! These are completely valid packets, it seems like loading and parsing them like any other packets should be a valid behavior.

(Unless there's already a way to do so, but one wasn't obvious from looking at the docs)

Would you be willing to assist with testing?

More than happy to help test in any way I can (though I doubt my help will be needed, though I'm happy to provide example ubx files)

UBXMessage throws UBXTypeError for headMot parameter

Describe the bug

UBXTypeError is thrown when providing headMot parameter to UBXMessage constructor. According to the documentation this field is I4 with scaling 10^-5, thus I pass there value in range 0...359 multiplied by pow(10,5):

pvt = UBXMessage(0x01, 0x07, GET, headMot=int(self.hom*pow(10,5)), month=6, fixType=3, gSpeed=3000, flags=b"\x01", parsebitfield=0)

where self.hom is in range 1...359.

pyubx2 version: 1.2.16

Traceback:

Traceback (most recent call last):
  File "~/.local/lib/python3.8/site-packages/pyubx2/ubxmessage.py", line 106, in _do_attributes
    (offset, index) = self._set_attribute(
  File "~/.local/lib/python3.8/site-packages/pyubx2/ubxmessage.py", line 168, in _set_attribute
    offset = self._set_attribute_single(att, offset, key, index, **kwargs)
  File "~/.local/lib/python3.8/site-packages/pyubx2/ubxmessage.py", line 284, in _set_attribute_single
    valb = val2bytes(int(val / scale), att)
  File "~/.local/lib/python3.8/site-packages/pyubx2/ubxhelpers.py", line 232, in val2bytes
    valb = val.to_bytes(atts, byteorder="little", signed=True)
OverflowError: int too big to convert

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "~/test.py", line 78, in onTimerTimeout
    pvt = UBXMessage(0x01, 0x07, GET, headMot=int(self.hom*pow(10,5)), month=6, fixType=3, gSpeed=3000, flags=b"\x01", parsebitfield=0)
  File "~/.local/lib/python3.8/site-packages/pyubx2/ubxmessage.py", line 81, in __init__
    self._do_attributes(**kwargs)
  File "~/.local/lib/python3.8/site-packages/pyubx2/ubxmessage.py", line 125, in _do_attributes
    raise ube.UBXTypeError(
pyubx2.exceptions.UBXTypeError: Overflow error for attribute 'headMot' in GET message class NAV-PVT

To Reproduce

UBXMessage(0x01, 0x07, GET, headMot=int(20*pow(10,5)), month=6, fixType=3, gSpeed=3000, flags=b"\x01", parsebitfield=0)

Expected Behaviour

A UBXMessage is created without throwing exception.

Desktop (please complete the following information):

OS: Ubuntu 20.04
Python 3.8.10

GNSS/GPS Device (please complete the following information as best you can):

  • Device Model/Generation: u-blox ZED-F9P
  • Iface: 27.31 LINK

Additional context

NONE

Program stuck on ubr.read()

Environment MACOS Catalina, Anaconda, Spyder:
Python version 3.8.1
Code:

import serial
from pyubx2 import UBXReader

stream = serial.Serial('/dev/tty.usbmodem142301',38400)  # open serial port
ubr = UBXReader(stream)
print(ubr.read())
stream.close()

Program hangs on ubr.read().
Attempted to change baudrate etc.

Can confirm that the standard stream.read() and stream.readline() functions output the data correctly

RXM-PMREQ

Looking at the interface description for ZED-F9P I see that the message structure for RXM-PMREQ differs from pyubx2 - in the file ubxtypes_set.py, instead of

 "RXM-PMREQ": {"duration": U4, "flags": X4},

I would need

"RXM-PMREQ": {"version": U1, "reserved0": U3, "duration": U4, "flags": X4, "wakeupSources": X4},

This is probably a version issue. Do you have a policy regarding different versions of interface descriptions?

Load config

Hi,
I made this request to you in order to know if it was possible to load a ublox configuration on an f9p with your library.
For this I have a file generated by u-center.
My goal would be to be able to load a ublox configuration through a python script without a user interface.

Thank you in advance for your answers, cordially, Vincent LAMBERT.

pyubx2 stop processing when there is a broken data in the ubx file.

May I ask for your assistance with regard to an issue I am encountering?
It appears that when there is broken data in the UBX file, the program Pyubx2 raises an exception and stops processing.
The error message associated with this exception is "'str' object has no attribute 'dict'".
I have noticed that this issue persists even with the latest version 1.2.23.

I kindly request your help in addressing this issue.
Would it be possible to continue the procedure despite the error data by simply displaying some messages?
For your information, my operating system is Windows 10 and I am recording logs via U-center v22.05.
The device model I am using is the u-blox NEO-9M, and the protocol in use is UBX_PROTOCOL.

Thank you for your attention to this matter. I sincerely appreciate any response or assistance you can provide.

ESF-MEAS message cannot input dataField and dataType

I used the following code and try to send a ESF-MEAS message to F9R module.
Sending messages to F9R is successful, but I failed to generate a correct message using the generator.
When I used the following code, I cannot make dataField and dataType into the generated message.

msg = UBXMessage("ESF", "ESF-MEAS", SET , timeTag=int((round((time.time()-starttime) * 1000))), timeMarkSent=0, timeMarkEdge=0, calibTtagValid=0, numMeas=1, dataField_01=188, dataType_01=11 ) print("msg generated:") print(msg) output = msg.serialize() print ("Parsed:") parsed = UBXReader.parse(output) print(parsed)

The printed results are:
msg:
<UBX(ESF-MEAS, timeTag=6082, timeMarkSent=0, timeMarkEdge=0, calibTtagValid=0, numMeas=1, id=0)>
Parsed:
<UBX(ESF-MEAS, timeTag=6082, timeMarkSent=0, timeMarkEdge=0, calibTtagValid=0, numMeas=1, id=0)>

There is no dataField_01 or dataType_01.
Am I using a wrong syntax or is it a bug of the library?
Thanks in advance for this great library.

quitonerror option doesn't work for nmeamessage.py _do_attributes errors

I am using bluetooth with my GPS receiver, and I believe that is why I am getting some parsing errors. I don't get any when hard wired. When nmeamessage.py _do_attributes raises an error, I can't figure out any way to continue operation and just ignoring the corrupt message without modifying the library. It seems like there should be a graceful way to just drop the bad data and continue.

Value of "dyn" field in CFG-NAV5

I'm not sure if this is a bug or my misinterpretation of the output. The "dyn" field from the parsed CFG-NAV5 POLL message is reported as "1" which is not listed as a valid dynamic model in the HPG 1.32 interface spec. I think the receiver is actually in dynamic model 2 (stationary). The field is a U1, not a flag byte. I don't know if that might be the reason for the discrepancy.

Getting CFG-PRT to change UART speed

Hi --

I'm trying to change the baud rate of a NEO-6M and finding that no matter what I do the baud rate change doesn't take -- it ACKs the command, but still talks at the old speed, and if I poll CFG-PRT afterwards it still reports the old speed. I've also tried this on a NEO-M8 where I'm communicating by USB but commanded to change the UART1 speed, and had the same result -- an ACK but no speed change reported.

I originally tried creating a CFG-PRT message with only the portID and baudRate fields set: cmd = UBXMessage('CFG','CFG-PRT',SET,portID=1,baudRate=setbaud). When that didn't work, I polled CFG-PRT with parsebitfield=False, then copied the resulting fields into a new SET message with only the baudRate field changed. That did not change the speed, either.

I'd like to avoid cut-pasting a byte object as ultimately I'd like to have flexibility in changing the port params. I'd appreciate any suggestions about what I might be doing wrong.

Thanks!

UnicodeDecodeError when opening ubx file

I downloaded an UBX file for Assisted GPS as described here. Since I did not receive any acknowledgement from the receiver when writing it to serial, I wanted to check the content of the file. I used this code:

from pyubx2 import UBXReader
stream = open('mgaonline.ubx', 'rb')
UBXReader(stream, protfilter=2)
for (raw_data, parsed_data) in ubr: print(parsed_data)

and I got this error:
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python3.6/dist-packages/pyubx2/ubxreader.py", line 79, in next
(raw_data, parsed_data) = self.read()
File "/usr/local/lib/python3.6/dist-packages/pyubx2/ubxreader.py", line 103, in read
byte1 = self._read_bytes(1) # read the first byte
File "/usr/local/lib/python3.6/dist-packages/pyubx2/ubxreader.py", line 242, in _read_bytes
data = self._stream.read(size)
File "/usr/lib/python3.6/codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb5 in position 0: invalid start byte

UNKNOWN PROTOCOL(header=b'$4')

Hi

I'm trying to use the Reading example script to get te parsed data of the gnss:

from serial import Serial
from pyubx2 import UBXReader
stream = Serial('/dev/ttyUSB0', 9600, timeout=None)
ubr = UBXReader(stream, portfilter=2)
(raw_data, parsed_data) = ubr.read()
print(parsed_data)

You can see in bold text, what I've changed.

Instead of the parsed_data I get:
<Unkown protocol(header=b'$4')>

I know that the header of my outputs is b'\x01' and it should be b'\xb5b'

I'm using the gnss 7 click neo M9N with a serial basic adapter on a jetson nano

Is there a parameter I can change?
Thanks!

NAV-PVT via I2C?

Is there an example on how to poll the NAV-PVT message via I2C ?

Unable to increase the rate of navposecef stream from 1Hz to 4 Hz

I am trying to read messages from the u-blox ZED-F9K receiver via serial communication using pyubx2. However, currently, the measurement update rate for various streams such as the navposecef stream is set to 1 Hz. Since my application involves high dynamics, I would like to increase the streaming rate to ideally 4 Hz or 20 Hz (the highest rate possible). I was able to do this in ucenter-2 but I would like to do it via serial communication. I tried setting higher rates than 1 Hz but the iTOW in messages still shows that we receive these measurements at 1 Hz.

Configuring receiver -> then UBXReader stops reading after several succesful readings (F9P)

Firstly I want to thank you for the effort you put into creating this library - it's AWESOME and you are GREAT! :D

My config:

u-blox C099-F9P // FWVER = HPG 1.13 // PROTVER = 27.12
navigation frequency: 10Hz
connection via USB cable (UART1)
windows 10 x64
python 3.7.9
pyubx2 ver. 1.0.2

My problem:

I want to start GNSS (via CFG-RST message), then read UBX messages for some time (in my case these are MON-RF, NAV-DOP, NAV-EELL, NAV-HPPOSLLH, NAV-PVT, NAV-SIG, NAV-STATUS) and stop GNSS (again via CFG-RST). The reason why I want to stop and start GNSS is that I want to save battery while keeping GNSS parameters in memory (so then I may perform hotstart).

How my code below works:

#receiver is stopped
-Starting GNSS is succesfull
-Reading several first message is also succesful, but then it hangs up and wait for message from serial (but the receiver is still working, and the serial send messages)
-I terminate the script
#start again (now the receiver keeps working - we are not stopped it)
-"Starting" GNSS is succesful - it just sends the message, but of course receiver is already wroking
-Reading all messages is succesfull
-Stopping GNSS is succesful
#again receiver is stopped
-Starting GNSS is succesfull
-Reading several first message is also succesful, but then it hangs up...
...

I tried to set validate flag to True - it raise

UBXStreamError(f"Unknown data header {byte1}. {nmeawarn}")
pyubx2.exceptions.UBXStreamError: Unknown data header 

What I noticed - after several OK readings it starts to divide binary message to single bytes and this is why this error occurs.

To prevent this I need to close port after writing, sleep for 1 second (shorter values don't help), open serial port again and flush it. This way everything works OK. But the problem is that in the future I would like to configure receiver on the run and then 1 second break looks ugly :/

Code:

import time
import serial
from pyubx2 import UBXReader, UBXMessage, SET

print("hello")

ser = serial.Serial(port="COM9", baudrate=921600, timeout=1)
print("Port is open? -> ", ser.is_open)

if ser.is_open:
    # START GNSS
    msg = UBXMessage(6, 4, SET, resetMode=9)
    print(msg)
    ser.write(msg.serialize())
    print("STARTED!")

    """
    # CLOSE, SLEEP and OPEN AGAIN
    ser.close()
    time.sleep(1)
    ser = serial.Serial(port="COM9", baudrate=921600, timeout=1)

    # PORT FLUSH
    print("dummy read", ser.read())
    ser.flush()
    ser.flushInput()
    ser.flushOutput()
    """

    # READING UBX
    i = 0
    while i < 300:
        print("reading ", i, ":")
        ubr = UBXReader(ser)
        (raw_data, parsed_data) = ubr.read()
        print(raw_data)
        print(parsed_data)
        if parsed_data.identity == 'NAV-HPPOSLLH':
            print("LON = ", (parsed_data.lon + parsed_data.lonHp/100)*10**(-7))
        print("\n")
        i += 1

    # STOP GNSS
    msg1 = UBXMessage(6, 4, SET, resetMode=8)
    print(msg1)
    msg1 = msg1.serialize()
    ser.write(msg1)
    print("STOPPED!")

    ser.close()

else:
    print("Problem with serial port")

Possible to Brick GPS Module?

Dear Semu,

I was wondering if it is in some way possible to use this library in some way that could lead to bricking a drotek zed-f9p gps module?
I currently have 2 "dead" GPS modules that do not show up as /dev/ttyACM* devices anymore and on windows they show as "USB device not recognised".

The script that i'm running starts with running 3 threads, one thread pushes a config every 5 seconds, the second thread sends/polls the config every 2 seconds, and the third thread reads the serial buffer and confirms that the received config matches the sent config.

Once that is confirmed, these threads exit and a new serial read thread is started as a main thread, as the only thread.

Could I have bricked the GPS device with such a setup? Is there any other way I could have bricked the device through software/serial? Is the gps module truly bricked or could I somehow hard-reset it?

greetings.

UBX-ESF-STATUS messages seem incorrect

I have a NEO-M8U-0-10 module and want to monitor the status of the sensor fusion calibration process with a python script running on a Windows 10 desktop (with USB serial connection).

However, the parsed ESF-STATUS messages (shown below) differ from the UBX-ESF-STATUS messages shown in the documentation.

<UBX(ESF-STATUS, iTOW=17:20:34.350000, version=2, reserved1=36, reserved2=2, reserved3=0, status=0, reserved4=0, reserved5=0, numCh=6, type_01=5, used_01=0, ready_01=1, calibStatus_01=0, timeStatus_01=1, freq_01=0, badMeas_01=1, badTTag_01=0, missingMeas_01=1, noisyMeas_01=1, type_02=4, used_02=0, ready_02=0, calibStatus_02=2, timeStatus_02=2, freq_02=142, badMeas_02=0, badTTag_02=0, missingMeas_02=1, noisyMeas_02=0, type_03=10, used_03=0, ready_03=0, calibStatus_03=0, timeStatus_03=0, freq_03=4, badMeas_03=0, badTTag_03=1, missingMeas_03=0, noisyMeas_03=1, type_04=0, used_04=0, ready_04=0, calibStatus_04=1, timeStatus_04=0, freq_04=10, badMeas_04=0, badTTag_04=0, missingMeas_04=0, noisyMeas_04=0, type_05=18, used_05=0, ready_05=1, calibStatus_05=0, timeStatus_05=1, freq_05=0, badMeas_05=0, badTTag_05=0, missingMeas_05=0, noisyMeas_05=0, type_06=0, used_06=0, ready_06=0, calibStatus_06=0, timeStatus_06=0, freq_06=0, badMeas_06=0, badTTag_06=0, missingMeas_06=0, noisyMeas_06=0)>

In the message payload:

  • the fusionMode and numSens fields are missing
  • there are not only reserved1 and reserved2 fields (like in the docs) but reserved3, reserved4 and reserved5 fields as well
  • different from the doc, there is a status fileld and a numCh field as well
  • according to the docs and the U-Center application, the type (sensor data type) fields are supposed to be either 5 (z-axis gyroscope), 13 (y-axis gyroscope), 14 (x-axis gyroscope), 16 (x-axis accelerometer), 17 (y-axis accelerometer), 18 (z-axis accelerometer), but in the parsed messages type fields are mainly 0 (none, data field contains no data) or 4 (reserved)

To reproduce this behaviour use the following code snippet:

from serial import Serial
from pyubx2 import UBXReader

stream = Serial('COM5', 115200, timeout=3)
ubr = UBXReader(stream)

while True:
    (raw_data, parsed_data) = ubr.read()

    if parsed_data.identity == 'ESF-STATUS':
        print(parsed_data)

GPS-UTC Offset

Version: 1.2.0
File: pyubx2/pyubx2/ubxhelpers.py

I think the offset between iTOW and UTC is 2 seconds off? It should be 18 seconds and not 16 seconds.

From https://endruntechnologies.com/support/leap-seconds.

  • TAI-UTC = 37 seconds
  • GPS-UTC = 18 seconds
  • TAI-GPS = 19 seconds
def itow2utc(itow: int) -> datetime.time:
    """
    Convert GPS Time Of Week to UTC time.
    :param int itow: GPS Time Of Week
    :return: UTC time hh.mm.ss
    :rtype: datetime.time
    """

    utc = datetime(1980, 1, 6) + timedelta(seconds=(itow / 1000) - (35 - 19))   #Fix: 37 - 19 = 18
    return utc.time()

Getting ACK/NAK response from command

This may be a bug, or it may be my lack of knowledge. I want to send a command to the receiver and find out whether it was ACK'd or NAK'd. The application is getting HPPOSLLH where the receiver supports it, or POSLLH where it doesn't. I can't find a straightforward way to do this.

Here is an example trying to set HPPOSLLH on a neo-m8t receiver that doesn't support it, then setting POSLLH where that succeeded:

<UBX(ACK-NAK, clsID=CFG, msgID=CFG-MSG)>
{'_immutable': True, '_mode': 0, '_payload': b'\x06\x01', '_length': b'\x02\x00', '_checksum': b'\x0e3', '_parsebf': 1, '_scaling': 1, '_ubxClass': b'\x05', '_ubxID': b'\x00', 'clsID': 6, 'msgID': 1}

<UBX(ACK-ACK, clsID=CFG, msgID=CFG-MSG)>
{'_immutable': True, '_mode': 0, '_payload': b'\x06\x01', '_length': b'\x02\x00', '_checksum': b'\x0f8', '_parsebf': 1, '_scaling': 1, '_ubxClass': b'\x05', '_ubxID': b'\x01', 'clsID': 6, 'msgID': 1}

Note that the ubxID value changes but the clsID value does not. And both the clsID and msgID values are 1 higher than their _ubx equivalents -- a picket-fence error, or am I misunderstanding the intention?

Is there a bug in the values of clsID and msgID in this case? And is there a more elegant way of telling whether a command was ACK'd or NAK'd than looking for the object attributes?

The environment is Linux Mint 21 and Python 3.10, with pyuxb2 installed via pip3 today.

Thanks!

Add sigId to RXM-RAWX message in ubxtypes_get.py

At line 3218 of ubxtypes_get.py:

Byte 38+32*n of the RXM-RAWX message is identified as "reserved2". For protver 18+ with high precision or timesync firmware, version 0x01 of the message uses that field for sigId.

Changing line 3218 of ubxtypes_get.py from "reserved2" to "sigId" allows getting the signal frequency where available.

(It is also available from the NAV-SIG message, but I think there are a set of receivers that support RXM-RAWX v0x01 but not NAV-SIG.

Thanks!
John

UBXMessageError: Undefined configuration database key 0x10010001

Hi,
I have a ZED-F9T module with which I have made a measurement via U-Center and produced a binary output log file containing both NMEA and UBX messages(the data). I can read the NMEA messages with pyubx2 without any problems (i.e. when portfilter=1), but when I try to read the UBX messages I get the error message shown below.

Is there a solution?

In [10]: from pyubx2 import UBXReader

In [11]: stream = open('Messung_Galileo_GPS.ubx', 'rb')

In [12]: ubr = UBXReader(stream, protfilter=2)

In [13]: for (raw_data, parsed_data) in ubr:
...: print(parsed_data)
...:
<UBX(MON-VER)>
<UBX(MON-VER, swVersion=b'EXT CORE 1.00 (71b20c)\x00\x00\x00\x00\x00\x00\x00\x00', hwVersion=b'00190000\x00\x00', extension_01=b'ROM BASE 0x118B2060\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', extension_02=b'FWVER=TIM 2.01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', extension_03=b'PROTVER=29.00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', extension_04=b'MOD=ZED-F9T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', extension_05=b'GPS;GLO;GAL;BDS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', extension_06=b'SBAS;QZSS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')>
<UBX(CFG-VALGET, version=0, layer=0, position=0)>

UBXMessageError Traceback (most recent call last)
in
----> 1 for (raw_data, parsed_data) in ubr:
2 print(parsed_data)
3

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxreader.py in next(self)
86 """
87
---> 88 (raw_data, parsed_data) = self.read()
89 if raw_data is not None:
90 return (raw_data, parsed_data)

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxreader.py in read(self)
118 # if it's a UBX message (b'\xb5\x62')
119 if bytehdr == ubt.UBX_HDR:
--> 120 (raw_data, parsed_data) = self._parse_ubx(bytehdr)
121 # if protocol filter passes UBX, return message,
122 # otherwise discard and continue

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxreader.py in _parse_ubx(self, hdr)
178 # only parse if we need to (filter passes UBX)
179 if self._protfilter & ubt.UBX_PROTOCOL:
--> 180 parsed_data = self.parse(
181 raw_data,
182 validate=self._validate,

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxreader.py in parse(message, **kwargs)
377 if payload is None:
378 return UBXMessage(clsid, msgid, msgmode)
--> 379 return UBXMessage(
380 clsid,
381 msgid,

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxmessage.py in init(self, ubxClass, ubxID, msgmode, **kwargs)
79 self._ubxID = ubxID
80
---> 81 self._do_attributes(**kwargs)
82
83 self._immutable = True # once initialised, object is immutable

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxmessage.py in _do_attributes(self, **kwargs)
104 pdict = self._get_dict(**kwargs) # get appropriate payload dict
105 for key in pdict: # process each attribute in dict
--> 106 (offset, index) = self._set_attribute(
107 offset, pdict, key, index, **kwargs
108 )

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxmessage.py in _set_attribute(self, offset, pdict, key, index, **kwargs)
162 )
163 else: # repeating group of attributes
--> 164 (offset, index) = self._set_attribute_group(
165 att, offset, index, **kwargs
166 )

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxmessage.py in _set_attribute_group(self, att, offset, index, **kwargs)
194 and self._mode == ubt.GET
195 ):
--> 196 self._set_attribute_cfgval(offset, **kwargs)
197 else:
198 # derive or retrieve number of items in group

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxmessage.py in _set_attribute_cfgval(self, offset, **kwargs)
460 self._payload[offset : offset + KEYLEN], "little", signed=False
461 )
--> 462 (keyname, att) = cfgkey2name(key)
463 atts = attsiz(att)
464 valb = self._payload[offset + KEYLEN : offset + KEYLEN + atts]

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pyubx2/ubxhelpers.py in cfgkey2name(keyID)
374 if keyID == kid:
375 return (key, typ)
--> 376 raise ube.UBXMessageError(f"Undefined configuration database key {hex(keyID)}")
377
378

UBXMessageError: Undefined configuration database key 0x10010001

Enabling RTCM Corrections on the ZED-F9K receivers via serial communication

Our research group would like to use the ZED-F9K receivers with RTCM base station corrections enabled. This is because we are currently observing significant drifts (8-10 m) in the ECEF positions in the absence of these corrections. We have been able to enable the corrections via u-center but would like to enable them via serial communication.
Are there any starter codes or examples in the repository that we can use to setup the RTCM corrections?

Parse UBX-MGA-INI as SET

Hello, it's me again, your nuisance.

I'd like to parse not just UBX-MGA-INI but any UBX-MGA message as mode SET.

I'd like the parser to figure out that UBX-MGA messages are always input types (as specified in the interface description) - apart from UBX-MGA-ACK of course.

When I parse a UBX-MGA-INI file I'd like the parser to use the UBX_PAYLOADS_SET dictionary rather than UBX_PAYLOADS_GET (which doesn't contain the definition for UBX-MGA-INI).

The parser decides to use mode GET in ubxmessage.py line 705 (calling UBXMessage constructor with payload).

IMO the parser should determine from the message what type of message it is - if at all possible.

I would absolutely be willing to assist in testing...

I can provide a dump of UBX-MGA messages. I obtained said dump from a ublox AssistNow online server. My intention was to analyze the dump with the pyubx2 library of which I have become dependent ;-)

The dump is provided below. From this dump you will be able to determine exactly where I am - or at least where my ZED-FP9 was when I made the request to AssistNow Online.

assist.zip

gpxtracker.py not working

Describe the bug

VALCKSUM import error

Please specify the pyubx2 version (>>> pyubx2.version) and, where possible, include:

>>> pyubx2.version
'1.2.6'
 $ python gpxtracker.py 
Traceback (most recent call last):
  File "/home/sylvain/SIG/RTK/gpxtracker.py", line 21, in <module>
    from pyubx2.ubxreader import UBXReader, VALCKSUM
ImportError: cannot import name 'VALCKSUM' from 'pyubx2.ubxreader' (/home/sylvain/.local/lib/python3.10/site-packages/pyubx2/ubxreader.py)
**To Reproduce**

Steps to reproduce the behaviour:

Python 3.10.2 (main, Jan 15 2022, 19:56:27) [GCC 11.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyubx2.ubxreader import UBXReader, VALCKSUM
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'VALCKSUM' from 'pyubx2.ubxreader' (/home/sylvain/.local/lib/python3.10/site-packages/pyubx2/ubxreader.py)

Expected Behavior

import correct python module

Desktop (please complete the following information):

██████████████████  ████████   sylvain@T480s 
██████████████████  ████████   ------------- 
██████████████████  ████████   OS: Manjaro Linux x86_64 
██████████████████  ████████   Host: 20L7S0XM00 ThinkPad T480s 
████████            ████████   Kernel: 5.10.102-1-MANJARO 
████████  ████████  ████████   Uptime: 3 days, 16 hours, 11 mins 
████████  ████████  ████████   Packages: 2240 (pacman), 1 (pkg) 
████████  ████████  ████████   Shell: bash 5.1.16 
████████  ████████  ████████   Resolution: 1920x1080 
████████  ████████  ████████   DE: MATE 
████████  ████████  ████████   WM: Metacity (Marco) 
████████  ████████  ████████   WM Theme: Matcha-dark-sea 
████████  ████████  ████████   Theme: Matcha-dark-azul 
████████  ████████  ████████   Icons: Papirus-Dark 
                               Terminal: mate-terminal 
                               Terminal Font: Monospace 10 
                               CPU: Intel i7-8550U (8) @ 4.000GHz 
                               GPU: Intel UHD Graphics 620 
                               Memory: 6378MiB / 15769MiB 

GNSS/GPS Device (please complete the following information as best you can):

  • Device Model/Generation: u-blox F9P
  • Firmware Version: 1.13
  • Protocol: ubx file

I think this could become slightly more higher level.

I mean you went all the way to abstracting it with attributes out of the messages it receives and sends and it remains in need of checking the documentation on the protocols in most cases.
What I mean is methods like "just turn off the messages of class X and ID Y"; or "turn on messages if their port type is USB"; it's already great just mentioning it feels it can be more.

High precision message truncation

Description
I think there is an issue with the parsing of High precision messages in UBX protocol. According to documentation, the the high precision part is supposed to introduce 2 more digits of precision (1e-9) in comparison with normal precision messages (1e-7). However when I look at the high precision part of the data obtained from puubx2 reader, all of the values are truncated to one digit in 1e-8. I suspect there might be some rounding happening in here.

I am using python 3.9 with the latest 1.2.4.

To Reproduce
Steps to reproduce the behavior:
Happens always with NAV-HPPOSLLH message type.

Desktop (please complete the following information):

  • Ubuntu 20.04 LTS
  • USB connection

GNSS/GPS Device

  • Device Model/Generation: u-blox ZED F9P
  • Firmware Version: HPG 1.30

Is my ubx file compatible?

Describe the bug
Cannot run a simple import of my test.ubx file.
pyubx2.version: 1.2.14
uCenter software used to generate the test.ubx file: v21.09

Error message:
[some valid parsed data from (1)... to (114) with parsed string]
Traceback (most recent call last):
File "C:\Users\jgorisse\Documents_FFANT\SW\GNSS_analyzer\parser.py", line 9, in
print(f'({str(i)})\t{parsed_data}')
File "C:\Asulab\Python310\lib\site-packages\pyubx2\ubxmessage.py", line 848, in str
val = ubt.UBX_MSGIDS[clsid + msgid]
KeyError: b'\x13`'

python code:
from pyubx2 import UBXReader
stream = open('ubx_file.txt', 'rb')
ubr = UBXReader(stream, protfilter=2)
i = 0
for (raw_data, parsed_data) in ubr:
i += 1
print(f'({str(i)})\t{parsed_data}')

ubx file (ubx_file.ubx, extension simply changed to .txt):
ubx_file.txt

To Reproduce

  1. save the python code to parser.py
  2. run the parser.py python code

Expected Behaviour

A string with parsed data.

Desktop (please complete the following information):

  • OS: Windows 10
  • no u-blox devkit connected (but files saved from a u-blox M8 evaluation kit, usb-connected)

Additional context

uCenter has no problem to read back the above mentioned .ubx file.
What I really want to do is to directly read the *.ubx files (I have many of those files), parse the messages and build some numpy tables with C/N0, used of each satellites and then utc, lat, lon, alt, psm and fix that I can post-process with some already operational python codes. Now I have to extract those data from the table view of uCenter and save it in *.csv files which is very time-consuming; this is why I am interested in this library to process the data with minimal human interaction.

webserver example not working

Hello,

[pyubx2 v1.26] [F9P]

I can't get the webserver example to work...

I added a line print(parsed_data) on line 166 to better illustrate my problem
Here is what happens when I start the service

python3 ubxserver.py 
Connecting to serial port /dev/pts/2 at 115200 baud...

Starting serial read thread...

Starting HTTP Server on http://127.0.0.1:8123 ...
Press Ctrl-C to terminate.

<UBX(NAV-PVT, iTOW=14:37:23, year=2022, month=4, day=11, hour=14, min=37, second=23, validDate=1, validTime=1, fullyResolved=1, validMag=0, tAcc=21, nano=32824, fixType=3, gnssFixOk=1, difSoln=1, psmState=0, headVehValid=0, carrSoln=1, confirmedAvai=1, confirmedDate=1, confirmedTime=1, numSV=19, lon=-1.0281844, lat=45.9921417, height=55272, hMSL=7149, hAcc=14, vAcc=11, velN=5, velE=3, velD=-5, gSpeed=6, headMot=307.36934, sAcc=83, headAcc=180.0, pDOP=1.28, invalidLlh=0, lastCorrectionAge=0, reserved0=1044519020, headVeh=0.0, magDec=0.0, magAcc=0.0)>
Something went wrong Message checksum b'\x00\x00' invalid - should be b'\xab\t'
<UBX(RXM-SFRBX, gnssId=Galileo, svId=30, reserved0=1, freqId=0, numWords=9, chn=49, version=2, reserved1=208, dwrd_01=172157743, dwrd_02=3776755709, dwrd_03=3154092032, dwrd_04=2231468032, dwrd_05=3003596800, dwrd_06=42, dwrd_07=2863297454, dwrd_08=3112124416, dwrd_09=0)>
<UBX(RXM-SFRBX, gnssId=Galileo, svId=36, reserved0=1, freqId=0, numWords=9, chn=20, version=2, reserved1=216, dwrd_01=174254895, dwrd_02=3777549821, dwrd_03=3154092032, dwrd_04=2231468032, dwrd_05=3003605611, dwrd_06=2734180266, dwrd_07=2863292447, dwrd_08=1249853440, dwrd_09=0)>
Something went wrong Message checksum b'\x00\x00' invalid - should be b'J\x0b'
<UBX(RXM-SFRBX, gnssId=GPS, svId=23, reserved0=0, freqId=0, numWords=10, chn=1, version=2, reserved1=0, dwrd_01=583048449, dwrd_02=2337352243, dwrd_03=1006485321, dwrd_04=2347592695, dwrd_05=621987212, dwrd_06=1041481844, dwrd_07=47615079, dwrd_08=37660748, dwrd_09=57217316, dwrd_10=147464095)>
<UBX(RXM-SFRBX, gnssId=GPS, svId=29, reserved0=0, freqId=0, numWords=10, chn=3, version=2, reserved1=32, dwrd_01=583048449, dwrd_02=2337352243, dwrd_03=75589508, dwrd_04=176016204, dwrd_05=1022468931, dwrd_06=18268243, dwrd_07=42600581, dwrd_08=2229971034, dwrd_09=2205569994, dwrd_10=2294925823)>
<UBX(RXM-SFRBX, gnssId=GLONASS, svId=10, reserved0=0, freqId=0, numWords=4, chn=13, version=2, reserved1=32, dwrd_01=1707355723, dwrd_02=3329273952, dwrd_03=282068992, dwrd_04=65470469)>
<UBX(RXM-SFRBX, gnssId=GLONASS, svId=20, reserved0=0, freqId=9, numWords=4, chn=30, version=2, reserved1=32, dwrd_01=1707355723, dwrd_02=3329273952, dwrd_03=282068992, dwrd_04=65470469)>
<UBX(RXM-SFRBX, gnssId=GLONASS, svId=20, reserved0=2, freqId=9, numWords=4, chn=101, version=2, reserved1=64, dwrd_01=1707355723, dwrd_02=3329273952, dwrd_03=282068992, dwrd_04=65470469)>
<UBX(RXM-SFRBX, gnssId=GLONASS, svId=11, reserved0=0, freqId=7, numWords=4, chn=17, version=2, reserved1=32, dwrd_01=1707355723, dwrd_02=3329273952, dwrd_03=282068992, dwrd_04=65470469)>
<UBX(RXM-SFRBX, gnssId=GLONASS, svId=11, reserved0=2, freqId=7, numWords=4, chn=100, version=2, reserved1=64, dwrd_01=1707355723, dwrd_02=3329273952, dwrd_03=282068992, dwrd_04=65470469)>
<UBX(RXM-SFRBX, gnssId=Galileo, svId=36, reserved0=5, freqId=0, numWords=8, chn=64, version=2, reserved1=64, dwrd_01=9786709, dwrd_02=1431655765, dwrd_03=1431655765, dwrd_04=1383366656, dwrd_05=2278359040, dwrd_06=42, dwrd_07=2863309660, dwrd_08=1568620544)>
<UBX(RXM-SFRBX, gnssId=Galileo, svId=30, reserved0=5, freqId=0, numWords=8, chn=75, version=2, reserved1=64, dwrd_01=9786709, dwrd_02=1431655765, dwrd_03=1431655765, dwrd_04=1383366656, dwrd_05=2278359040, dwrd_06=42, dwrd_07=2863309660, dwrd_08=1568620544)>
<UNKNOWN PROTOCOL(header=b'$w')>
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/home/basegnss/pyubx2/examples/webserver/ubxserver.py", line 167, in set_data
    if parsed_data.identity == 'NAV-PVT':
AttributeError: 'str' object has no attribute 'identity'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/home/basegnss/pyubx2/examples/webserver/ubxserver.py", line 150, in _read_thread
    self.set_data(parsed_data)
  File "/home/basegnss/pyubx2/examples/webserver/ubxserver.py", line 192, in set_data
    except ube.UBXMessageError() as err:
TypeError: catching classes that do not inherit from BaseException is not allowed

F9P_rover_usb_uart1-RAWX_SFRBX_PVT.txt

pyubx2.exceptions.UBXParseError: Message checksum b'\xce\xe9' invalid - should be b'j\xf9'

Describe the bug

A clear and concise description of what the bug is.

Please specify the pyubx2 version (>>> pyubx2.version) and, where possible, include:

  • The error message and full traceback.
  • A binary / hexadecimal dump of the UBX data stream (e.g. from PuTTY, screen or u-center).

To Reproduce

Steps to reproduce the behaviour:

  1. Any relevant device configuration (if other than factory defaults).
  2. Any causal UBX command input(s).

Expected Behavior

A clear and concise description of what you expected to happen.

Desktop (please complete the following information):

  • The operating system you're using [e.g. Windows 10, MacOS Big Sur, Ubuntu Bionic]
  • The type of serial connection [e.g. USB, UART1, I2C]

GNSS/GPS Device (please complete the following information as best you can):

  • Device Model/Generation: [e.g. u-blox NEO-9M]
  • Firmware Version: [e.g. SPG 4.03]
  • Protocol: [e.g. 32.00]

This information is typically output by the device at startup via a series of NMEA TXT messages.
It can also be found by polling the device with a UBX MON-VER message. If you're using the
PyGPSClient GUI, a screenshot of the UBXConfig window should suffice.

Additional context

Add any other context about the problem here.

pynmeagps>=1.0.17 Not found

For some reason pynmeagps>=1.0.17 dependency can't be found when installing with:

python3 -m pip install --upgrade pyubx2

Wheel tick measurement support

Is your feature request related to a problem? Please describe.
Ublox has a number of chips that support wheel ticks like M9L, F9R and F9K. usually it is done via hardware put recently streaming wheels ticks via software is more important and easier since new wheel encoders are digital. this will eliminate the need to convert digital signal to analog signal. Also, using SW interface allow you to stream two wheels instead of one which improves performance.

I'd like to read wheel ticks data from serial interface and feed it to the receiver.

Describe the solution you'd like
being able to feed wheel ticks to F9R chip to improve performance. F9R should be able to calibrate wheel ticks and use it in DR in addition to built-in IMU

Describe alternatives you've considered

The alternative is to provide the wheel ticks via HW but an MCU needed to convert the digital msgs to analog.

Would you be willing to assist with testing?

I have ublox F9R dev kit that I can use for testing. I can help with testing your code. I'm an armature programmer I'm not sure if I can help with writing test code.

Additional context

Parsing .ubx files

I have created a .ubx file by using u-center with ZED-F9P and NEO-6M.
I just want to extract information like C/No values of the satellites or AGC count from .ubx file created by u-center.
Am I able to do that with this repo?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.