-
Hello, first of all, thanks for your job. In the last weeks I began implementing a python client to retrieve GNSS RTK positioning data from U-Blox F9P based board (ArduSimple RTK2B). I have a fully stable and working C++ clients for both the RTK corrections as well as to retrieve the GNSS data from the board, which is connected through a USB cable. I implemented a very simple python client to just retrieve the GNSS data from the board using yours library, it works but it is unstable, where with unstable I mean that after some time it raise an error saying the serial connection to the device is already in use. It can work for some minutes of even an hour. Now, I analysed the C++ clients, and the only difference with the Python-based example is that in the two C++ clients (one to provide the board the corrections and one to get the fused GNSS data) is that in these client, both connected to the board using he same USB serial interface, the internal ports are specified, more in detail UART2 is used by the client that provides the corrections, while USB by the client that get the fused position data. It works flawlessly. Therefore, I was wondering how do I specify on the PyUBX2 python-based client how to use the specific port (in this case USB) on the serial interface, and if it is possible to do it. My guess is that once I specify the exact port, the client will work stable like the C++ one. I read the documentation but I didn’t find anything specific to this. Thanks to anyone! |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 2 replies
-
Hi @palia95 So, if I understand your use case correctly, you want to use a Python client to simultaneously send RTK (RTCM3) correction data (presumably from an NTRIP or SPARTN source) to the receiver, and receive GNSS output from the receiver. Note that the pyubx2 library does not implement internal serial connectivity - it assumes the user will employ a standard Python library e.g. The ArduSimple RTK2B board uses the u-blox ZED-F9P module which supports RTCM3 via either the USB, UART1, UART2 or I2C ports (I'm assuming you don't want to use I2C). So you could, for example, send the RTCM corrections to the UART1 port while simultaneously monitoring output on the USB port, but you don't have to do it this way. You could, for example, use USB for both input and output provided your client is capable of 'multi-tasking' the relevant send and receive processes. If you have separate send and receive processes both accessing the same serial port, you will get contention issues. If your computing platform has a GUI, you might want to check out the PyGPSClient graphical utility, which implements both NTRIP and SPARTN clients. If you don't want to use a GUI client, you could use the pygnssutils library (which is what PyGPSClient uses under the covers, and which employs the pyubx2 and pyspartn libraries) as the basis for your own client. See, for example, this example NTRIP client implementation: https://github.com/semuconsulting/pygnssutils/blob/main/examples/rtk_example.py Suggest take a look at this example and get back to me with any further queries. NB: make sure you don't have any other daemon processes running on your platform accessing the same serial ports e.g. 'gpsd'. Shut down all your C++ clients before running any Python clients. If this is part of a PhD project, I would be grateful if you could cite the pyubx2 or pygnssutils libraries in your work. |
Beta Was this translation helpful? Give feedback.
-
If you can share the code for your "PyUBX2-based client" I may be able to advise further. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
I'd recommend a few minor tweaks... from serial import Serial
from pyubx2 import UBXReader
from datetime import datetime, timedelta
with Serial('/dev/ttyACM0', 115200, timeout=3) as stream:
print("Port is open? -> ", stream.is_open)
ubr = UBXReader(stream, protfilter=2, quitonerror=0)
for (raw_data, parsed_data) in ubr:
try:
if parsed_data.identity:
# Get all fields dynamically
if parsed_data.identity == 'NAV-PVT':
iTOW_seconds = parsed_data.iTOW / 1000 # Convert milliseconds to seconds
iTOW_datetime = datetime.utcfromtimestamp(iTOW_seconds).replace(microsecond=(parsed_data.iTOW % 1000) * 1000)
print(f"Time: {iTOW_datetime.strftime('%H:%M:%S.%f')}")
print(f"Latitude and Longitude: {parsed_data.lat}, {parsed_data.lon}")
print(f"Altitude above sea level (m): {parsed_data.hMSL / 10**3}")
print(f"2D Heading (°): {parsed_data.headMot}")
print(f"Ground Speed (m/s): {parsed_data.gSpeed / 10**3}")
print(f"Horizontal Accuracy (cm): {parsed_data.hAcc / 10}")
print(f"Vertical Accurancy (cm): {parsed_data.vAcc / 10}")
print(f"Position Dilution of Precision (pDOP): {parsed_data.pDOP}")
print(f"Number of Satellites: {parsed_data.numSV}")
print(f"Fix Type: {parsed_data.fixType}")
#print(f"Fix Ok? {parsed_data.gnssFixOk}")
print(f"Differential Correction applied? {parsed_data.difSoln}")
print(f"Carrier Phase Range Solution (0 none, 1 RTK float, 2 RTK fixed): {parsed_data.carrSoln}")
#print(f"Power Save Mode State: {parsed_data.psmState}")
if parsed_data.identity == 'NAV-DOP':
iTOW_seconds = parsed_data.iTOW / 1000 # Convert milliseconds to seconds
iTOW_datetime = datetime.utcfromtimestamp(iTOW_seconds).replace(microsecond=(parsed_data.iTOW % 1000) * 1000)
print(f"Time: {iTOW_datetime.strftime('%H:%M:%S.%f')}")
print(f"Horizontal Dilution of Precision (hDOP): {parsed_data.hDOP}")
print(f"Vertical Dilution of Precision (vDOP): {parsed_data.vDOP}")
print(f"Geometrical Dilution of Precision (gDOP): {parsed_data.gDOP}")
except:
print('Unknown message') Note there are helper methods available in pyubx2 which may simplify things e.g. |
Beta Was this translation helpful? Give feedback.
Thanks, if I'll manage to achieve what I want, I'll come back with the possible solution