sparkfun / SparkFun_Ublox_Arduino_Library

Library to control UBX binary protocol and NMEA over I2C on Ublox GPS modules
Other
144 stars 85 forks source link

Feature Request: Please add support for UBX-HNR-PVT and UBX-HNR-INS (NEO-M8U) #156

Closed shecker closed 3 years ago

shecker commented 3 years ago

Subject of the issue

Unable to get GPS and/or deadreckoning updates from Sparkfun M8U with an update rate of 30Hz. Instead publishing rate is max. around 4Hz. How do we increase to 30Hz as written in the documentation (30 High Navigation Rate (HNR))? We are aware that "UBX-HNR-PVT" will be the HNR message but we do not understand how to use this with the Sparkfun library.

Your workbench

We are setting:

myGPS.setI2COutput(COM_TYPE_UBX);  
myGPS.setNavigationFrequency(30);
PaulZC commented 3 years ago

Hi Simon (@shecker ), To reach 30Hz, you will probably need to use only the GPS constellation and disable GLONASS, BeiDou and Galileo. I will need to check which commands you need to use on the M8 to do this. Until later, Paul

PaulZC commented 3 years ago

Hi Simon (@shecker ),

To explain the earlier comment, modules like the ZED-F9P can achieve a PVT navigation rate of 25Hz. but it depends on which constellations are being tracked:

image

The datasheet for the NEO-M8U doesn't say if it can achieve 30Hz while tracking all constellations. But let's ignore that for now.

The SparkFun u-blox GNSS library does not currently support the HNR messages. So we need to add those. This will take us some time as we will need to:

So, I'm going to change the name of this issue to "Feature Request: Please add support for UBX-HNR-PVT and UBX-HNR-INS (NEO-M8U).

For now, if you want to access the HNR information, so can do that by creating a custom command. Please see Example20 and Example21 for details. You will need to use:

customCfg.cls = UBX_CLASS_HNR; // This is the message Class
customCfg.id = 0x00;    // This is the message ID for UBX-HNR-PVT

and then refer to section 32.12 of the M8 Protocol Description to see which fields to extract.

Best wishes, Paul

shecker commented 3 years ago

Hi Paul (@PaulZC) Thanks a lot for your reply! You are right, I don't think the M8U can track constellations at 30Hz but it does use the deadreckoning ability (UDR) to provide up to 30Hz of vehicle position, attitude and speed (extrapolated via the IMU) and that is what we are looking for. I believe this is what's also mentioned on the Sparkfun product page and one of the reasons we bought it ;-)

"The combination of GNSS and integrated 3D sensor measurements on the NEO-M8U provide accurate, real-time positioning rates of up to 30Hz."

If I understand this correctly, then the 30Hz is only provided via the UBX-HNR-PVT and UBX-HNR-INS messages and these are not included in the current version of the Sparkfun library, thus disabling GLOSNASS, Galileo and BaiDou probably won't help us here? (I'm also unsure how to disable them using the library)

Would you happen to have a minimal working example of how to access the information at 30Hz we are using this unit as part of a Master thesis and the student is finishing soon (thus we are a bit under time pressure). Our core competency is unfortunately not with programming Arduinos but rather we are using them as a tool within our system. Thus it would probably take us quite some time to write this code from scratch that is able to poll the data at 30Hz.

Thanks a lot and best wishes Simon

PaulZC commented 3 years ago

Hi Simon (@shecker ), Correct, the main issue for you is that the HNR messages are not currently supported by the library - except through a custom command. The M8U is a recent product and the library has not yet been updated to fully support it. Disabling GLONASS, Galileo and BeiDou may help with reading the standard NAV-PVT messages at a higher rate, but it is not a complete fix for you. It will take us approximately one to two weeks to implement and test the new functions... We are happy to add them as I am sure other users will find them useful too - but it will be on a best-effort basis, other projects permitting. The library has examples for the standard NAV-PVT messages, but nothing yet for HNR-PVT. Very best wishes, Paul

shecker commented 3 years ago

Hi Paul (@PaulZC) Okay great thanks a lot for the offer and I agree that other users are probably interested in this functionality so it's definitely worth including. We will wait for your implementation then, 1-2 weeks should be fine for the students to still finish the master thesis within the deadline, thanks a lot!

Best wishes Simon

PaulZC commented 3 years ago

Some notes on this:

Messages to support:

"If a high navigation rate has been configured with UBX-CFG-HNR then the number of enabled output messages must be adjusted to keep within the maximum throughput of the interface used."

Questions / Things To Test:

UBX-HNR-ATT is 32+6 bytes UBX-HNR-INS is 26+6 bytes UBX-HNR-PVT is 72+6 bytes

(38+32+78) 9 bits per byte (8 bits plus ACK) 30Hz = ~40 kilobits per second (without overheads).

It may be feasible...

shecker commented 3 years ago

Hi Paul (@PaulZC) I've actually been working with your info and I think I got something running! I modified the library so that I can set UBX-CFG-HNR with the correct rate and have added parsing of UBX-HNR-PVT as well. It seems to be running at around 30Hz as promised and GPS time/noise from position is also showing up at this rate. I will try driving around tomorrow to see if this also works when the GPS is actually moving and has more satellites available. Then I will also include UBX-HNR-INS and UBX-HNR-ATT, those should be quite straight forward after the PVT is done.

Regarding your questions: Does UBX-CFG-HNR cause the HNR messages to be generated? Or do we also need to use UBX-CFG-MSG to enable each message? I believe you need to also enable CFG-MSG, at least that is what I am doing with a new "setHNRAutoPVT" which is basically the same as for regular NAV_PVT just with HNR class id etc. Will I2C support all three HNR messages at 30Hz? Will we hit throughput issues? (Does the M8U core assume 100kHz is being used?) Unsure about this yet, we are running the I2C at 400kHz with the M8U and it seems to be fine, will let you know once I have the other 2 messages implemented.

If you want I can make a branch or something once I finish this and you can decide to use some parts.

Thanks Simon

PaulZC commented 3 years ago

Hi Simon (@shecker ), I'm really pleased you've got this up and running! Yes, please send us a Pull Request when you are done. Please target it at the release_candidate branch. Details are here. Thank you. The u-blox modules are really very clever and won't let you overload the interface you are communicating on. If the message rate you have just requested is going to overload the interface, it seems to get (politely) ignored or NACK-nowledged. A question at the back of my mind has always been "how does the module know what I2C clock rate we intend to use"? For UART, this is easy as you have to tell the module what Baud rate to use. But for I2C, this is very different. Your controller/master code determines what the clock rate will be, and the module has no prior knowledge of this. So, my assumption is that the module probably assumes you intend to use 100kHz. If you find any of your CFG-MSG messages being NACK-nowledged, that may be the reason. Best wishes, Paul

PaulZC commented 3 years ago

Hi Simon (@shecker),

I have added the HNR functionality you wanted to the release_candidate branch.

Can you please test it? I have tested it on the NEO-M8U and it all appears to run correctly, but I have not yet tried to calibrate the IMU. (Basically, I don't have the time to take this out to my car and drive around with it!)

You will find two new examples in the Dead Reckoning section which show how to get the data with and without "autoHNR". You will find the data structures defined in the header file.

Please let me know how your tests go.

Best wishes, Paul

shecker commented 3 years ago

Hi Paul (@PaulZC) Sorry for the late reply, we have been quite busy testing our system. Your code is very similar to the one I had written, although yours is definitely more complete and mine is more tailored to our use case. For example, I removed the polling option in getHNRPVT as I found that sometimes the autoreporting flag was not set correctly for INS or ATT so it continued to poll those even though all three HNR messages should have been on auto report, causing traffic and bus overload.

I am able to run the GPS at 28Hz with all three messages being reported. I turn off everything else (regular PVT, etc.) One issue we had is that the dynamic model re-calibrated itself quite often during driving. This then temporarily resulted in a low 1-2Hz reporting rate. We solved this with a factory reset of the IMU. This was probably due to a faulty calibration maybe caused by internal gyro temperature tables...?

Thanks again for your help and all the best Simon

PaulZC commented 3 years ago

Thanks Simon, If you are happy with the code, I will merge it into the master branch and release it. I'm going to close this issue, but please re-open if we have missed anything. (@balamuruganky has just submitted a useful PR #159 - I'll include that too before releasing.) All the best, Paul