chutsu / ubx

u-blox protocol parser and RTK GPS server client
MIT License
2 stars 3 forks source link

Running on NEO M8P #2

Closed dizcza closed 6 months ago

dizcza commented 7 months ago

Hello,

the first question is where did you take all these ubx_* functions? It looks like you ported some library but I cannot find it elsewhere.

I tried to run your code on a NEO M8P capable of a base station setup. However, neither example-gps nor example-base works:

$ ./example-base 
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ublox_base_station_config] Failed to configure Ublox into BASE_STATION mode!
[ERROR] [ublox_base_run] Failed to configure Ublox into BASE_STATION mode!
[FATAL] Failed to run ublox in base mode!

$ ./test_ublox 
-> test_ubx_msg_init 
TEST PASSED!

-> test_ubx_msg_checksum 
TEST PASSED!

-> test_ubx_msg_is_valid 
TEST PASSED!

-> test_ubx_msg_build 
TEST PASSED!

-> test_ubx_msg_parse_and_serialize 
TEST PASSED!

-> test_ubx_msg_print 
msg_class: 0x01
msg_id: 0x22
payload_length: 0x00
ck_a: 0x23
ck_b: 0x6a
TEST PASSED!

-> test_ubx_parser_init 
TEST PASSED!

-> test_ubx_parser_reset 
TEST PASSED!

-> test_ubx_parser_update 
TEST PASSED!

-> test_ublox_init 
TEST PASSED!

-> test_ublox_version 
SW VERSION: EXT CORE 3.05 (ff96ba)
HW VERSION: 00080000
ROM BASE 3.01 (107888)
TEST PASSED!

-> test_ubx_set_and_get 
[ERROR] [ubx_set] Failed to set configuration!
ERROR! [test_ubx_set_and_get:233] value == val FAILED!
TEST FAILED!

-> test_ublox_parse_rtcm3 
[DEBUG] ublox_parse_rtcm3:1460: [RTCM3] msg type: 1005  msg length: 25
[DEBUG] ublox_parse_rtcm3:1460: [RTCM3] msg type: 1074  msg length: 129
[DEBUG] ublox_parse_rtcm3:1460: [RTCM3] msg type: 1077  msg length: 201
[DEBUG] ublox_parse_rtcm3:1460: [RTCM3] msg type: 1097  msg length: 176
[DEBUG] ublox_parse_rtcm3:1460: [RTCM3] msg type: 1230  msg length: 14
TEST PASSED!

-> test_ublox_run 
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ubx_set] Failed to set configuration!
[ERROR] [ublox_run] Failed to configure Ublox into GPS mode!
TEST PASSED!

14 tests, 13 passed, 1 failed

Setting the configuration shouldn't be module-specific and I used SparkFun lib to change the module configuration in flash with success.

chutsu commented 6 months ago

Hi,

the first question is where did you take all these ubx_* functions? It looks like you ported some library but I cannot find it elsewhere.

These ubx_* functions are written by myself. They aren't ported from any library at all.

I tried to run your code on a NEO M8P capable of a base station setup. However, neither example-gps nor example-base works:

I wouldn't presume it would, since this library was created specifically for the UBlox ZED-F9P (as stated in the README) which came after the NEO M8P. I don't have that hardware at hand so I'd presume there will be minor startup sequences.

Setting the configuration shouldn't be module-specific and I used SparkFun lib to change the module configuration in flash with success.

I think this is a minor engineering decision. For my use-case I configure the devices every time I run the above examples. There are alternative ways to configure them.

Thanks Chris

chutsu commented 6 months ago

For the GPS mode, you can see which line in ublox_gps_config() (here) fails to configure the device. The function basically tells the GPS device which messages you would like the device to report and at what rate (default 10Hz).

dizcza commented 6 months ago

These ubx_* functions are written by myself. They aren't ported from any library at all.

Impressive.

All right, I happen to have a rover-only ZED-F9P module, and when I run the code (for example, test), I see endless messages

[DEBUG] ublox_parse_ubx:1356: [UBX] msg_class: 1    msg_id: 97

until I hit the CRTC+C and get a notification of 14/14 tests passed. Anyway, seems to work fine.

Can you share the script for the server part? I'd like to test the rover example.

Thanks.

chutsu commented 6 months ago

Hi @dizcza,

Both example-rover.c and example-base.c should work out of the box, it is a matter of running the correct executable on the respective computers. The configuration I had in mind is you have a rover and a base-station. Both are in the same TCP/IP network, for example:

Computer1 --- (UART)---> ZED-F9P  [ROVER]
        ^
        |
    (Wifi Network)
        |
        V
Computer2 --- (UART)---> ZED-F9P  [BASE STATION]

The way RTK-GPS works is that the base-station would send a RTK time correction signal to the Rover. In my setup, its over wifi, but another possible setup is via some long range radio where you would have to relay that information to the ROVER gps.

If you read ublox_base_run() (here) which runs the base-station loop, you'll see it creates a TCP/IP socket to transmit the RTK correction signal to its client. Conversely, the rover in ublox_rover_run() (here) connects to the base station (server), and whenever it receives the RTK correction signal it relays that to the GPS module via UART.

Let me know if you're confused about the code base. I could have documented this a little better.

Hope this helps

dizcza commented 6 months ago

I see. I read the rover connect code but overlooked the base setup. It makes sense now, thanks for the explanation.

I'd say your code is well written with just enough comments put at critical lines. It'd make more sense to separate the networking logic from the ubx uart interaction to have a standalone cpp-header library just for ubx uart communication - not for me, I won't be using Linux code anyway: I'm doing everything on an ESP32 board. Maybe I'll strip some functionality of yours - I'm interested in setting up a uart communication to receive both RTK corrections and NMEA messages or at least switching between these two regimes - such code is missing elsewhere.

I'm working on a project where one ESP board is a base and several others are rovers. The RTK corrections will be streamed with LoRa modules. I ain't there yet.

Have you worked with other GPS RTK manufacturers? For example, SIMCOM and/or SkyTraq? ZED-F9P is significantly expensive compared to SIM66MD and even more, ublox modules can be easily spoofed or jammed because they operate on L1 & L2 bands while the one I mentioned can work on L5.

chutsu commented 6 months ago

Hey, I'm afraid I haven't really explored other manufacturers. When I first came across the UBlox ZED-F9P RTK GPS board, I was amazed at how small and fast it converged to a RTK solution (~30 seconds). Prior to that chip, the RTK GPS I encoutered in research / academia we had to work with a thick text-book size circuit. And it often took ~30 minutes for the RTK solution to converge to mm-scale accuracy. While the ZED-F9P does not go all the way down to mm accuracy, the size and cm - level accuracy is a good trade off.

I personally found the UBlox documentation to be excellent, I have quite a bit of experience interfacing with hardware from IMUs, gimbal controllers to GPS, and I can tell you UBlox documentation is very comprehensive. There weren't that many questions I couldn't find in their manuals. I don't know whether SIMCOM or SkyTraq have the same level of quality. I would also consider future supply chain issues considering the current geo-political climate, which countries the chips are developed / made from SIMCOM (China), SkyTraq (Taiwan). I personally would choose chips I know are going to be available long term / well documented.

While there is a UBlox ZED-F9P-15B (new version), that works with the L5 band, the documentation suggests it is still spotty. (source) 1712769894_screenshot

Maybe you can achieve high-accuracy through other sensors, e.g. cameras, Lidars?

dizcza commented 6 months ago

Maybe you can achieve high-accuracy through other sensors, e.g. cameras, Lidars?

No, the devices will be deployed in the field.

I didn't know about the L5 support of a new ublox ZED-F9P module, thanks. Well, it's x10 more expensive than the SIMCOM chip I mentioned. Another annoying feature of ublox/sparkfun is signing that you'll be a good boy and will use it only in limited ways, otherwise, they won't sell it.

You're right, ublox features extensive documentation, examples, and overall user support while SIMCOM isn't at that level at all, and SkyTraq users are fighting to set it up on adrupilot forums with little and no success.

Wow, the mm accuracy sounds like too much. I wasn't even able to achieve less than 2m with NEO M8P and the ANN-MB-00 RTK antenna, however, the antenna was put close to the window surrounded by many other buildings in Kyiv, so only half of the sky was visible. It shouldn't be a problem in an open field.

I put the ublox module on a metal plate (I milled a 15cm circle of a one-sided copper PCB) but I've been told that it isn't enough and I need to connect the metal plate and the antenna GND electrically - have you also done it?

dizcza commented 6 months ago

I put the ublox module on a metal plate (I milled a 15cm circle of a one-sided copper PCB) but I've been told that it isn't enough and I need to connect the metal plate and the antenna GND electrically - have you also done it?

The ANN-MB-00 RTK antenna doesn't expose the GND so I wired the metal plate to the ESP board instead (and the board GND is connected to the antenna GND, of course). In my tests, it didn't yield any difference.

chutsu commented 6 months ago

If you haven't already, UBlox has a really good article on antenna considerations: GNSS antennas RF design considerations for u-blox GNSS receivers (Application Note)

Afraid reducing EMF noise to me is voodoo magic. I did have some experience dealing with GPS signal loss, it turns out it is particularly sensitive to USB 3 data transmission (when I used USB 3 cameras on a drone). I suspect if you're using LoRa modules that could also be a potential source of noise where its signals are colliding with your GPS signals. I did not major in EE so I don't have good solutions other than try to separate everything out and try and compartmentalize via proper copper shielding, and distance the antenna away from everything.

I personally never had to solder GND from the antenna to a metal plate from sparkfun (here). A quick hack a friend and I did was to use tin foil to form a dish. No idea how effective this was in reality, but it did resolve the USB 3 interfering with GPS problem for us. 53365758_2194130550901477_1774613614066401280_n 54435979_663962224060009_1964925629291823104_n

dizcza commented 6 months ago

Interesting. I haven't seen anyone wrapping the drone GPS antenna with foil, including the cable. And also, it's a one-time solution.

I wonder if a dish-plate form was really needed or you could go ahead with just a flat plate. I'm not quite sure if I understand correctly the purpose of shielding a GPS receiver with a metal plate: is it just ordinary shielding or rather concentrating the reflected satellite signals back to the antenna placed on top of such a shield?

I've seen their "paper", there isn't much physics and no mentions of connecting the GNDs electrically either.

chutsu commented 6 months ago

I believe it to shield the antenna by making sure there's no "multi-path" signals to interfere with the antennas. A small radio signal bubble just focusing on GPS signal. I have no idea if the dish shape actually helps, would just go for a flat plane.

If you just try and google "GPS cooper shielding drones", there are multiple hits where people have had to solve this issue by wrapping tin foil or copper tape around wires and including USB ports: https://github.com/IntelRealSense/realsense-ros/issues/319

But yes, I can't seem to find resources that can list down actual maths / physics equations so one can calculate the best configration. That is why in my previous message I said this is voodoo magic to me xD If you have a good resource I am all ears :P

dizcza commented 6 months ago

Yeah, voodo magic. Anyway, my devices won't fly - they will be lying still on the ground.

Thanks for the insights though.