Closed dizcza closed 6 months ago
Hi Danylo (@dizcza ),
Please see pushRawData
: https://github.com/search?q=repo%3Asparkfun%2FSparkFun_u-blox_GNSS_Arduino_Library%20pushrawdata&type=code
Best, Paul
I've been doing my first RTK base-rover pairing and spent the entire day figuring out why I get empty RELPOS messages in the rover. After the survey is completed, calling
response &= myGNSS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through I2C port, message every second
response &= myGNSS.enableRTCMmessage(UBX_RTCM_1077, COM_PORT_I2C, 1);
response &= myGNSS.enableRTCMmessage(UBX_RTCM_1087, COM_PORT_I2C, 1);
response &= myGNSS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_I2C, 10); //Enable message every 10 seconds
as suggested in your examples is not enough. It turns out, in order to output 1005 (or 4072 in case of a moving base) messages, the user has to set the base station in a fixed mode with the UBX-CFG-TMODE3 message:
// ECEF X, Y, and Z values are easily extracted from the SurveyIn packets
bool SFE_UBLOX_GPS_ADD::setRTKFixedMode(int32_t ecefX, int32_t ecefY, int32_t ecefZ) {
UBX_CFG_TMODE3_data_t data;
ubxPacket packetCfg = {0, 0, 0, 0, 0, (uint8_t*) &data, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
if (getSurveyMode(&data) == false)
{
return (false);
}
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_TMODE3;
packetCfg.len = 40;
packetCfg.startingSpot = 0;
data.flags.bits.mode = 2; // Fixed Mode
data.ecefXOrLat = ecefX;
data.ecefYOrLon = ecefY;
data.ecefZOrAlt = ecefZ;
bool response = sendCommand(&packetCfg) == SFE_UBLOX_STATUS_DATA_SENT;
return response;
}
Correct me if I'm wrong but without explicitly setting the base station coordinates, I was getting empty RELPOS packets on the rover side. As soon as I fixed the base station coordinates, I immediately got non-zero relative positions on both NEO-M8P-00 and ZED-F9P rovers. I'm using ESP-NOW to send binary RTCM3 data between the base and the rover and then push raw data via I2C.
Another question is how to confirm the successful parsing of input RTCM messages in the rover. For this, I utilize UBX_RXM_RTCM messages:
typedef struct
{
uint8_t version;
union
{
uint8_t all;
struct
{
uint8_t crcFailed : 1; // 0 when RTCM message received and passed CRC check, 1 when failed
uint8_t msgUsed : 2; // 2 = RTCM message used successfully by the receiver, 1 = not used, 0 = do not know
} bits;
} flags;
uint16_t subType; // not available on NEO-M8P
uint16_t refStation;
uint16_t msgType;
} UBX_RXM_RTCM_data_t;
bool SFE_UBLOX_GPS_ADD::getRTCMInfo(UBX_RXM_RTCM_data_t* data) {
uint8_t customPayload[MAX_PAYLOAD_SIZE]{};
ubxPacket packetCfg = {0, 0, 0, 0, 0, customPayload, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
// Query the module
packetCfg.cls = UBX_CLASS_RXM;
packetCfg.id = UBX_RXM_RTCM;
packetCfg.len = 0;
packetCfg.startingSpot = 0;
if (sendCommand(&packetCfg) != SFE_UBLOX_STATUS_DATA_RECEIVED) {
return false;
}
data->version = extractLong(&packetCfg, 0);
data->flags.all = extractByte(&packetCfg, 1);
data->subType = extractSignedInt(&packetCfg, 2);
data->refStation = extractSignedInt(&packetCfg, 4);
data->msgType = extractSignedInt(&packetCfg, 6);
ESP_LOGI(TAG, "getRTCMInfo:");
ESP_LOGI(TAG, " flags:");
ESP_LOGI(TAG, " crcFailed: %u", data->flags.bits.crcFailed);
ESP_LOGI(TAG, " msgUsed: %u", data->flags.bits.msgUsed);
ESP_LOGI(TAG, " refStation %u", data->refStation);
ESP_LOGI(TAG, " msgType %u", data->msgType);
return true;
}
Usage:
bool response = myGNSS.pushRawData(incomingData, len);
if (!response)
{
log_w("RTCM message wasn't accepted");
}
UBX_RXM_RTCM_data_t data;
myGNSS.getRTCMInfo(&data);
But I'm always getting msgUsed=0
(I expect msgUsed=2
) even if the packet seems to be processed correctly
[5943973][I][SparkFun_myGNSS.cpp:275] getRTCMInfo(): [ublox] getRTCMInfo:
[5943973][I][SparkFun_myGNSS.cpp:277] getRTCMInfo(): [ublox] flags:
[5943975][I][SparkFun_myGNSS.cpp:278] getRTCMInfo(): [ublox] crcFailed: 0
[5943981][I][SparkFun_myGNSS.cpp:279] getRTCMInfo(): [ublox] msgUsed: 0
[5943988][I][SparkFun_myGNSS.cpp:280] getRTCMInfo(): [ublox] refStation 0
[5943995][I][SparkFun_myGNSS.cpp:281] getRTCMInfo(): [ublox] msgType 1077
Also, the doc says these messages are output immediately upon an RTCM message parsing. If I send several RTCM binary messages, I get only one confirmation.
Have you assessed the correctness of RTCM input data in rovers?
Hi Danylo (@dizcza ),
Please see the NEO-M8P examples, specifically the two Moving Base examples. For a Moving Base Base this line is essential. See also setStaticPosition.
For corrections monitoring, the library includes support for UBX-RXM-COR. It provides feedback on RTCM3, L-Band (PMP) and SPARTN corrections.
For the ZED-F9P, I'd recommend switching to v3 of the library.
Best, Paul
For corrections monitoring, the library includes support for UBX-RXM-COR. It provides feedback on RTCM3, L-Band (PMP) and SPARTN corrections.
Thanks, I overlooked this one. Looks like this is exactly what I was looking for. And I didn't know about the setStaticPosition
as well - the API is quite huge to digest all functions.
For the NEO-M8P and ZED-F9P, I'd recommend switching to v3 of the library.
I'd switch if the readme states otherwise:
If you are using an older module, like the M8, you will need to use version 2 of this library.
So I'm puzzled whether I can use v3.
For a Moving Base Base this line is essential.
Yes, I borrowed this line in my code as well (I should have mentioned this in my previous reply), so adding this line wasn't enough - only setting the fixed position helped. I wonder if you didn't set the fixed position and yet were able to get non-empty RELPOS packets on the rover side...
In my setup, all stations - base and rovers - lie still on the ground, I just need to know their exact position (relative to the base). If my base station doesn't move, can I decrease the rate of 1005 RTCM messages, f.i. to output each 10 seconds only? The docs don't mention this.
Oh, yes, my bad. Keep using v2 of the library with the NEO-M8P - it doesn't support the configuration interface.
Re. the rate of 1005: I don't know... I suspect it needs to be 1Hz...
You might find this discussion useful:
https://forum.sparkfun.com/viewtopic.php?p=239720#p239720 https://forum.sparkfun.com/viewtopic.php?p=239779#p239779
Unfortunately, UBX-RXM-COR are not supported on M8 - they are not even described in the docs.
I'll proceed as is. Thanks for your help.
Hi Paul, I finally got an RTK FIX for my base-rover setup, and I'm very happy about it!
Since my base is stationary (I'm using setStaticPosition
), I noticed that it always sends the same 1005 and even 1230 RTCM corrections. My Lora bandwidth is narrow and I want to squeeze the information as much as possible. Therefore, I'll transmit 1005 and 1230 only once, and of course, on the rover side, I'll be pushing them to the ublox module alongside with always updating 1074 and 1084 messages. The only problem is that I don't know whether
Can you confirm it? Does ublox website provide information about RTCM message lengths? I cannot find this info. On various other sources, I find different numbers of bytes of 1005 compared to my discovery. I've been experimenting for a while and my discovery seems to be valid. But I'm unsure if this is a feature of the coordinates I tried (Ukraine) or this is true in any part of the globe.
Hi Danylo (@dizcza ),
RTCM 10403 defines the message format:
RTCM1005 is always 3+19+3 bytes. RTCM1230 is variable length: 3+4+2*N+3, where N = Number of Code-Phase Biases (max 4).
These links may help:
Best wishes, Paul
RTCM1005 is always 3+19+3 bytes. RTCM1230 is variable length: 3+4+2*N+3, where N = Number of Code-Phase Biases (max 4).
Thank you for this valuable information. I couldn't find such a simple answer elsewhere.
And thanks for the parsing links. I tried to find such a parser but the ones I saw were never complete.
Cheers, Danylo
Sorry for opening an issue for a question but I don't see other means asking you...
I need to send RTCM bytes available at the
void SFE_UBLOX_GNSS::processRTCM(uint8_t incoming)
function from base (NEO M8P) to rover (also M8P) via I2C. How to do this? I don't see such an API for the rover module to be able to accept RTCM raw bytes from base.I mean, RTCM bytes will be broadcasted with LoRa radio but the communication between the NEO M8P module and ESP32 is done via I2C.
My setup:
NEO M8P base -- (I2C) --> ESP32 --> LoRa --> ... --> LoRa --> ESP32 -- (I2C) --> NEO M8P rover
I don't mind extending the API if it doesn't exist, but I don't know where to start.