GithubHelp home page GithubHelp logo

aerorust / nmea Goto Github PK

View Code? Open in Web Editor NEW
49.0 7.0 40.0 775 KB

NMEA 0183 - for communication between marine electronics such as echo sounder, sonars, anemometer, gyrocompass, autopilot, GNSS receivers and many other types of instruments. Defined and controlled by the National Marine Electronics Association (NMEA)

Home Page: https://crates.io/crates/nmea

License: Other

Rust 100.00%
rust nmea gps glonass galileo marine-robotics protocol rustlang embedded no-std

nmea's Introduction

Version Build Status License Apache-2

Complete documentation can be found on www.docs.rs/nmea

NMEA 0183 sentence parser for Rust.

Supported sentences:

NMEA Standard Sentences

  • AAM
  • ALM
  • APA
  • BOD
  • BWC
  • BWW
  • DBK
  • GBS
  • GGA *
  • GLL *
  • GNS *
  • GSA *
  • GST
  • GSV *
  • HDT
  • MDA
  • MTW
  • MWV
  • RMC *
  • VHW
  • VTG *
  • WNC
  • ZDA
  • ZFO
  • ZTG

Other Sentences

  • TXT *

Vendor Extensions

  • PGRMZ

* Nmea::parse() supported sentences

How to contribute

We have an ongoing effort to support as many sentences from NMEA 0183 as possible, starting with the most well-known. If you'd like to contribute by writing a parser for a given message, check out the Supporting additional sentences (AeroRust/nmea#54) issue and contribute in 3 easy steps:

  1. Write a comment - Please write a comment in the issue for the sentence(s) you'd like to implement, you will be mentioned on the task to avoid duplicate implementations.
  2. Implement each sentence alongside at least 1 test in its own module under the ./src/sentences directory using the nom crate.
  3. Open a PR ๐ŸŽ‰

What is NMEA 0183?

NMEA 0183 is a combined electrical and data specification for communication between marine electronics such as echo sounder, sonars, anemometer, gyrocompass, autopilot, GPS receivers and many other types of instruments.

Usage

Add the nmea dependency in your Cargo.toml:

[dependencies]
nmea = "0.6"

For no_std

This crate support no_std without the use of an allocator ( alloc ), just add the nmea crate without the default features:

[dependencies]
nmea = { version = "0.6", default-features = false }

Parse

To use the NMEA parser create a Nmea struct and feed it with NMEA sentences (only supports GNSS messages, otherwise use the parse_str() and parse_bytes()):

use nmea::Nmea;

fn main() {
    let mut nmea = Nmea::default();
    let gga = "$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76";

    // feature `GGA` should be enabled to parse this sentence.
    #[cfg(feature = "GGA")]
    {
        nmea.parse(gga).unwrap();
        println!("{}", nmea);
    }
}

Supported Rust Versions

The Minimum supported Rust version (or MSRV) is 1.65.

Unsafe-free crate

We use #![deny(unsafe_code)] for a fully unsafe-free crate.

License

This project is licensed under the Apache-2.0.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the project by you, shall be licensed as Apache-2.0, without any additional terms or conditions.

nmea's People

Contributors

0xf4lc0n avatar afonso360 avatar andrewlipscomb avatar ang13t avatar bahelms avatar clemarescx avatar dushistov avatar dylan-dpc avatar ekuinox avatar elpiel avatar flxo avatar fparat avatar gflow33 avatar hargonix avatar jarrod817 avatar jasminfragnaud avatar patrickoppel avatar sknsean avatar taavit avatar turbo87 avatar yjh0502 avatar zeroerrors avatar zhrbrk 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

nmea's Issues

Support defmt

defmt is a high performance logging framework extensively used in embedded rust. It would be great if we can add a feature flag to implement defmt::Format for the Error struct and the Nmea struct.

Increase test coverage.

The code should have as many test / as high test coverage as possible, maybe even fuzzing.

Configurable GSA fix_stas_prn size

Testing with the Quectel LC76G GNSS receiver which supports the GNSS providers:GPS, GLONASS, Galileo, BDS, QZSS was causing an error for GSA.

Try to avoid alloc

During the no_std rewrite we should try to avoid alloc, maybe some embedded users don't wanna have an allocator or can't use one even.

xxGNS parsing issue

Hi. Hope all is well.

I've encountered a parsing problem while trying to parse a GNS message from my u-blox SAM-M10Q module. I think I've narrowed it down, but some help will be appreciated.
The message received from the module (no gps fix): $GNGNS,,,,,,NNNNNN,00,99.99,,,,,V*07
The error I got while trying to parse the message:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParsingError(Failure(Error { input: "NNNN", code: Fail }))', src\main.rs:6:35
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\gpsdecoder.exe` (exit code: 101)

Now from what I can gather, the NNNNNN is fix flags for each of the satellite constellations supported and being used by the u-blox module, parsed with the parse_faa_modes function.

However, the parse_faa_modes function checks the next character to parse (in this case the first GNSS's flag), parses it and builds a FaaModes struct, and since there is still characters to parse (the rest of the GNSS's flags), it adds a second system state to the same FaaModes struct it just created for the first one. Thereafter, the rest of the GNSS's flags are still there, the parse_faa_modes function doesn't know what to do and returns an error.

Now I think this can be solved by running the parse_faa_modes function on each character in this group and not on the group as a whole.

I am willing to create a PR for this, but I need some help.

Thanks for your assistance,
Stefan

no_std

The crate should become no_std as things that use NMEA directly are often gonna be embedded devices. #13

When I import the struct nmea::Nmea the program crashes on ESP32

steps to reproduce:

1- Create the project with cargo generate esp-rs/esp-idf-template cargo
2- Follow the instructions and select esp32 architecture
3- Add the following code the main.rs:

use nmea::Nmea;

fn main() {
    // It is necessary to call this function once. Otherwise some patches to the runtime
    // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
    esp_idf_svc::sys::link_patches();

    // Bind the log crate to the ESP Logging facilities
    esp_idf_svc::log::EspLogger::initialize_default();

    Nmea::default();

    log::info!("Hello, world!");
}

4- Flash the code using cargo run

The error dump

I (31) boot: ESP-IDF v5.1-beta1-378-gea5e0ff298-dirt 2nd stage bootloader I (31) boot: compile time Jun 7 2023 07:48:23 I (33) boot: Multicore bootloader I (37) boot: chip revision: v3.1 I (41) boot.esp32: SPI Speed : 40MHz I (46) boot.esp32: SPI Mode : DIO I (50) boot.esp32: SPI Flash Size : 4MB I (55) boot: Enabling RNG early entropy source... I (60) boot: Partition Table: I (64) boot: ## Label Usage Type ST Offset Length I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (79) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (86) boot: 2 factory factory app 00 00 00010000 003f0000 I (94) boot: End of partition table I (98) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=1dec8h (122568) map I (151) esp_image: segment 1: paddr=0002def0 vaddr=3ffb0000 size=0200ch ( 8204) load I (154) esp_image: segment 2: paddr=0002ff04 vaddr=40080000 size=00114h ( 276) load I (157) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=46230h (287280) map I (269) esp_image: segment 4: paddr=00076258 vaddr=40080114 size=0b2a8h ( 45736) load I (293) boot: Loaded app from partition at offset 0x10000 I (294) boot: Disabling RNG early entropy source... I (305) cpu_start: Multicore app I (305) cpu_start: Pro cpu up. I (305) cpu_start: Starting app cpu, entry point is 0x40081914 0x40081914 - call_start_cpu1 at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/esp_system/port/cpu_start.c:159 I (293) cpu_start: App cpu up. I (323) cpu_start: Pro cpu start user code I (324) cpu_start: cpu freq: 160000000 Hz I (324) cpu_start: Application information: I (328) cpu_start: Project name: libespidf I (333) cpu_start: App version: 1 I (338) cpu_start: Compile time: Mar 25 2024 21:45:10 I (344) cpu_start: ELF file SHA256: 0000000000000000... I (350) cpu_start: ESP-IDF: v5.1.3 I (355) cpu_start: Min chip rev: v0.0 I (359) cpu_start: Max chip rev: v3.99 I (364) cpu_start: Chip rev: v3.1 I (369) heap_init: Initializing. RAM available for dynamic allocation: I (376) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM I (382) heap_init: At 3FFB2900 len 0002D700 (181 KiB): DRAM I (389) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM I (395) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM I (401) heap_init: At 4008B3BC len 00014C44 (83 KiB): IRAM I (409) spi_flash: detected chip: generic I (412) spi_flash: flash io: dio W (416) timer_group: legacy driver is deprecated, please migrate todriver/gptimer.h`
I (425) app_start: Starting scheduler on CPU0
I (430) app_start: Starting scheduler on CPU1
I (430) main_task: Started on CPU0
I (440) main_task: Calling app_main()
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.

Core 0 register dump:
PC : 0x40089059 PS : 0x00060233 A0 : 0x800893a4 A1 : 0x3ffb28b0
0x40089059 - tlsf_block_size_max
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/heap/tlsf/tlsf.c:841
0x3ffb28b0 - s_mmu_ctx
at ??:??
A2 : 0x00000004 A3 : 0x00060220 A4 : 0x00000000 A5 : 0x00060223
A6 : 0xb33fffff A7 : 0xb33fffff A8 : 0x800873d1 A9 : 0x3ffb2880
0x3ffb2880 - s_mmu_ctx
at ??:??
A10 : 0x00000001 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x3ffb5be8
A14 : 0x00000084 A15 : 0x400d6670 SAR : 0x0000001f EXCCAUSE: 0x0000001c
0x400d6670 - heapless::vec::Vec<T,_>::as_mut_slice
at /home/hu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/heapless-0.7.17/src/vec.rs:178
EXCVADDR: 0x00000014 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0x00000000

Backtrace: 0x40089056:0x3ffb28b0 0x400893a1:0x3ffb28d0 0x40088f85:0x3ffb28f0 0x400827ce:0x3ffb2910 0x400827e1:0x3ffb2940 0x4008280d:0x3ffb2960 0x4008a221:0x3ffb2980 0x400e7c60:0x3ffb29a0 0x400e7bb8:0x3ffb29c0 0x400d4a26:0x3ffb29e0 0x400feeef:0x3ffb2a00 0x400fef04:0x3ffb2a20 0x400febf7:0x3ffb2a40 0x400fe9d7:0x3ffb2a60 0x400dd3f8:0x3ffb2aa0 0x400d6391:0x3ffb2ac0 0x400d4cd9:0x3ffb2b00 0x400d651c:0x3ffb2bb0 0x400d63e4:0x3ffb2c40 0x400d4992:0x3ffb2c60 0x40114ee7:0x3ffb5c80 0x400d4a04:0x3ffb5ca0 0x400dccee:0x3ffb5cc0 0x400d49f4:0x3ffb5cf0 0x400d49a7:0x3ffb5d20 0x400d641b:0x3ffb5d40 0x40115b27:0x3ffb5d60
0x40089056 - tlsf_block_size_max
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/heap/tlsf/tlsf.c:835
0x3ffb28b0 - s_mmu_ctx
at ??:??
0x400893a1 - adjust_request_size
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/heap/tlsf/tlsf.c:250
0x3ffb28d0 - s_mmu_ctx
at ??:??
0x40088f85 - multi_heap_malloc_impl
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/heap/multi_heap.c:207
0x3ffb28f0 - _GLOBAL__N_1::emergency_pool
at ??:??
0x400827ce - heap_caps_malloc_base
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/heap/heap_caps.c:176
0x400827e1 - heap_caps_malloc
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/heap/heap_caps.c:197
0x4008280d - heap_caps_malloc_default
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/heap/heap_caps.c:223
0x4008a221 - malloc
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/newlib/heap.c:24
0x400e7c60 - std::sys::unix::alloc::::alloc
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/sys/unix/alloc.rs:14
0x400e7bb8 - __rdl_alloc
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/alloc.rs:394
0x400d4a26 - __rust_alloc
at ??:??
0x400feeef - alloc::alloc::Global::alloc_impl
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/alloc/src/alloc.rs:181
0x400fef04 - <alloc::alloc::Global as core::alloc::Allocator>::allocate
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/alloc/src/alloc.rs:241
0x400febf7 - alloc::raw_vec::RawVec<T,A>::allocate_in
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/alloc/src/raw_vec.rs:199
0x400fe9d7 - alloc::raw_vec::RawVec<T,A>::with_capacity_in
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/alloc/src/raw_vec.rs:145
0x400dd3f8 - alloc::ffi::c_str::CString::new
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/alloc/src/ffi/c_str.rs:316
0x400d6391 - esp_idf_svc::private::cstr::to_cstring_arg
at /home/hu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/esp-idf-svc-0.48.1/src/private/cstr.rs:90
0x400d4cd9 - esp_idf_svc::log::EspLogger::should_log
at /home/hu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/esp-idf-svc-0.48.1/src/log.rs:203
0x400d651c - log::__private_api::log_impl
at /home/hu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.21/src/__private_api.rs:61
0x400d63e4 - log::__private_api::log
at /home/hu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.21/src/__private_api.rs:73
0x400d4992 - test_nmea_crate2::main
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/src/main.rs:14
0x40114ee7 - core::ops::function::FnOnce::call_once
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/core/src/ops/function.rs:250
0x400d4a04 - std::rt::lang_start::{{closure}}
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/rt.rs:166
0x400dccee - core::ops::function::impls::<impl core::ops::function::FnOnce for &F>::call_once
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/core/src/ops/function.rs:284
0x400d49f4 - std::rt::lang_start
at /home/hu/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/rt.rs:165
0x400d49a7 - main
at ??:??
0x400d641b - app_main
at /home/hu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/esp-idf-sys-0.34.1/src/start.rs:46
0x40115b27 - main_task
at /home/hu/DataProjects/RustyESP32/test_nmea_crate2/test-nmea-crate2/.embuild/espressif/esp-idf/v5.1.3/components/freertos/app_startup.c:208

ELF file SHA256: 0000000000000000

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7104
load:0x40078000,len:15576
load:0x40080400,len:4
0x40080400 - _invalid_pc_placeholder
at ??:??
ho 8 tail 4 room 4
load:0x40080404,len:3876
entry 0x4008064c
`

Some more info

rustup -V
rustup 1.27.0 (bbb9276d2 2024-03-08)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active rustc version is rustc 1.76.0-nightly (88269fa9e 2024-02-09) (1.76.0.1)

cargo -V
cargo 1.76.0-nightly (c84b36747 2024-01-18)

rust-toolchain.toml

[toolchain]
channel = "esp"
components = ["rustfmt", "rustc-dev"]
targets = ["xtensa-esp32-none-elf"]

Formatting/serialization support

Other formats we could support (share your thoughts below):

  • serde #102

  • bincode

  • ufmt

  • All of these formats should be optionally configured with a feature of the crate

Additional message types support

yanp supported message types

@hargoniX has created the yanp crate which supports much more message types currently missing from nmea.
We should move the message types parsing form yanp which are not supported by nmea:

  • BOD
  • BWC (check support)
  • GBS
  • GGA (check support)
  • GLL (check support)
  • GSA
  • GNS (check support)
  • GSV (check support)
  • HDT
  • RMA
  • RMB
  • RMC (check support)
  • STN
  • VBW
  • VTG (check support)
  • WPL

Other tasks:

  • Dual license with yanp MIT adding the copyright to Apache too!!!

  • AIS message types #46

Not all parts of a RMC sentence are parsed

After the fix in the documentation of RMC sentences #57 we've realized there are missing parts of the parsing of those sentences.

In particular the parsing of parts after the date is missing, i.e.:

Parsing that is missing

  1. Magnetic Variation, degrees
  2. E or W
  3. FAA mode indicator (NMEA 2.3 and later)
  4. Nav Status (NMEA 4.1 and later)
    A = autonomous, D = differential, E = Estimated,
    M = Manual input mode, N = not valid, S = Simulator, V = Valid

Testing

Make sure to test for all fields variations, more specifically 3 different versions of the sentence:

  • Pre- NMEA 2.3
  • NMEA 2.3 (with FAA mode)
  • NMEA 4.1 (with Nav status)

Stack overflow

Hi,
nmea 0.0.7 chokes with Stack Overflow on this data dumped from the GPS integrated into the Algiz tablet:

$GNVTG,,,,,,,,,N*2E
$GNGNS,181604.00,,,,,NN,00,99.99,,,,*59
$GNGGA,181604.00,,,,,0,00,99.99,,,,,,*72
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GPGSV,4,1,13,02,35,291,,03,09,129,,05,14,305,,06,38,226,*7D
$GPGSV,4,2,13,07,56,177,,09,70,067,,16,20,055,,23,41,076,*77
$GPGSV,4,3,13,26,10,030,,29,05,341,,30,26,199,,36,30,158,*7E
$GPGSV,4,4,13,49,32,192,*4D
$GLGSV,3,1,10,66,45,091,,67,67,334,,68,17,297,,75,13,025,*68
$GLGSV,3,2,10,76,49,059,,77,40,156,,78,00,183,,82,15,246,*68
$GLGSV,3,3,10,83,28,298,,84,10,352,*6F
$GNGLL,,,,,181604.00,V,N*5E
$GNGRS,181604.00,1,,,,,,,,,,,,*5A
$GNGRS,181604.00,1,,,,,,,,,,,,*5A
$GNGST,181604.00,0.0000,,,,5773795,5773795,5773794*4F
$GNZDA,181604.00,12,09,2018,00,00*73
$GNGBS,181604.00,,,,,,,*7B
$GNTXT,01,01,02,u-blox AG - www.u-blox.com*4E
$GNTXT,01,01,02,HW UBX-M8030 00080000*60
$GNTXT,01,01,02,EXT CORE 3.01 (107900)*33
$GNTXT,01,01,02,ROM BASE 3.01 (107888)*25
$GNTXT,01,01,02,FWVER=SPG 3.01*46
$GNTXT,01,01,02,PROTVER=18.00*11
$GNTXT,01,01,02,MOD=NEO-M8N-0*67
$GNTXT,01,01,02,FIS=0xC22536 (100111)*28
$GNTXT,01,01,02,GPS;GLO;GAL;BDS*77
$GNTXT,01,01,02,SBAS;IMES;QZSS*49
$GNTXT,01,01,02,GNSS OTP=GPS;GLO*37
$GNTXT,01,01,02,LLC=FFFFFFFF-FFFFFFED-FFFFFFFF-FFFFFFFF-FFFFFF69*23
$GNTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*3E
$GNTXT,01,01,02,ANTSTATUS=OK*25
$GNTXT,01,01,02,PF=3FF*4B
$GNVTG,,,,,,,,,N*2E
$GNGNS,181605.00,,,,,NN,00,99.99,,,,*58
$GNGGA,181605.00,,,,,0,00,99.99,,,,,,*73

Tests for sentences/utils.rs

As per #11 we wanna ensure max test coverage, as of now sentences/utils.rs is not at all tested but shared across all sentence parsers and thus a source for very common bugs.

Should be quite easy to do and might be an easy way for an individual to look into tests and make a small open source commit unless someone really wants this in the crate quickly.

AIS NMEA messages

AIS messages

We're missing support for AIS messages and thankfully there's a crate build for them already!

I've already opened an issue regarding the integration in the NMEA crate (squidpickles/ais#8) and the maintainer is looking into no_std support for the crate (squidpickles/ais#9)

We should integrate the ais crate or use it as a dependency inside nmea.

As @squidpickles mentioned in a comment (squidpickles/ais#8 (comment)):

Probably do want to keep this existing on its own, too, as some folks (myself included) only have real use for the AIS portion at the moment.
However, we can look into another solution, instead of keeping the crates separate - enabling message parsing by features gates.

Features proposal

Here's a WIP list of features we can use to separate the different message parsing of the crate and allow people to only use a certain message(s):

  • ais
  • bwc
  • gga
  • gll
  • gns
  • gsa
  • gsv
  • rmc
  • txt
  • vtg

Enable sentences with features

We should have all sentences enabled with a feature, e.g. "all-sentences", however, it should be possible to parse only a subset of sentences by enabling only their own feature, e.g. gll or gsv, etc.

This will ensure that the size of the crate is optimised for highly constraint targets which require some subset of the sentences.

This is related to #54

What is the MSRV?

What is the MSRV of the NMEA crate?

Right now we can use:

[package]
# ...
rust-version = "1.56"

Which requires a minimum version of 1.56 for this cargo feature.

README update - Contributing & dual license

  • We need dual-license the nmea code with MIT due to the code integration from the yanp crate (yanp integration is no longer needed due to the amount of work to refactor the code without the added benefit of having additional tests) #52

  • Add Contributing section to README with suggestions on how people can contribute to this crate and be made available in crates.io as well (suggested by @zeenix https://twitter.com/zeenix/status/1567582371297345539, thanks for the suggestions!) fc93169

use `f64` (double) over `f32` precision in the Parser

Research whether:

  • We need f64 accuracy for any of the fields? - Yes, complexity will be lower by just using double precision.
  • If it's really needed, then how we can allow both f32 and f64 in the parser (a choice that will be given to the user of the crate)? - No, it is not needed

TODOs:

Replace all places to use f64 (double) precision rather than complicating the source code.

Iterator-based parser

This idea was mentioned in #9 and will greatly improve the usability of the crate by providing an iterator-based parser that will parse new messages from e.g. streamed/received bytes when \r\n ending is present.

  • Extend with bytes (similar to Iterator::chain)
  • Extend with a single byte (optional)
  • try_next() try to parse the currently collected bytes (by searching for an ending - \r\n)

Enhancements:

  • Track both the ending \r\n but also the start of a message ! (for AIS messages) or $ (for all other) in the iterator.

C API

It would be nice if we could expose a C API and compile into a static lib so the crate could be linked into already exisitng C programs in order to be used in already existing C applications. This could be especially interesting for once AVR supports lands in rustc, then it could be used in Arduino applications as a safe building stone.

Update README/docs for a new release

With #54 we've already added multiple new sentences, however, we should also update the README.md and lib.rs docs accordingly to show the newly supported messages.

  • Make a list of all new messages and order all sentences alphabetically and in groups the same way they are now in #54
  • Update README
  • Update lib.rs

Supporting additional sentences

There are multiple sentences that are still not implemented in the crate and this is a list of the remaining sentences that we can implement.

Some work has gone into supporting additional sentences - #51

Contributing

  1. Write a comment - Please write a comment for the sentence(s) you'd like to implement and to be mentioned on the task to avoid duplicate implementations.
  2. Implement each sentence alongside at least 1 test in its own module using the nom crate.
  3. Open a PR ๐ŸŽ‰

Tips for contributing

  • We suggest you start with a single sentence per PR and get a sense of the NMEA 0183 crate and protocol
  • If you have any questions, just open a Draft PR, so that we can provide you with feedback or answer your questions
  • Checkout the GPSD project page for an example to use in your test (https://gpsd.gitlab.io/gpsd/NMEA.html) and any additional information for the given sentences
  • Follow the information for the different versions of NMEA 0183 standard given in the GPSD project and implement the parsing for them

Sources

Sentences

In this curated list you'll find sentence types that have yet to be implemented and tested.
The standard sentences have priority over the rest of the types and less-known sentences.

NMEA Standard Sentences

Other sentences (low priority)

  • TODO: Find information on the internet for those additional messages if possible
  • TXT (u-blox)
  • ACK - Alarm Acknowledgement
  • ADS - Automatic Device Status
  • AKD - Acknowledge Detail Alarm Condition
  • ALA - Set Detail Alarm Condition
  • ASD - Autopilot System Data
  • BEC - Bearing & Distance to Waypoint - Dead Reckoning
  • CEK - Configure Encryption Key Command
  • COP - Configure the Operational Period, Command
  • CUR - Water Current Layer
  • DCR - Device Capability Report
  • DDC - Display Dimming Control
  • DOR - Door Status Detection
  • DSC - Digital Selective Calling Information
  • DSE - Extended DSC
  • DSI - DSC Transponder Initiate
  • DSR - DSC Transponder Response
  • ETL - Engine Telegraph Operation Status
  • EVE - General Event Message
  • FIR - Fire Detection
  • MWD - Wind Direction & Speed
  • WDR - Distance to Waypoint - Rhumb Line
  • WDC - Distance to Waypoint - Great Circle
  • ZDL - Time and Distance to Variable Point

Vendor extensions (low priority)

Refactoring this into *the* rust nmea parser

It would be nice if rust finally had a go to nmea parser that is used by as many people as possible. Considering NMEA is a kinda easy data format to parse / handle usually this shouldn't be too hard to unify reasonably for everyone either. As of now there are 7 nmea related crates on crates.io.

  1. This one which with 4583 downloads seems to be the most popular one as of now
  2. https://github.com/nicolas-goudry/nmea-0183 by a member of this working group which has tests for each sentence as its most notable attribute.
  3. https://github.com/nsforth/nmea0183 this has no dependencies at all as well as no_std support as its most notable attributes.
  4. https://github.com/hargoniX/yanp (mine) which has the combination of support for lots of sentences + no_std support as its most notable attribute
  5. https://github.com/49nord/titanic-rs which can only parse GGA sentences, whether it has something special about it that might be interesting for us I don't know
  6. https://github.com/frafra/frakegps which emulates a GPS receiver that emits NMEA codes, however as it appears only for GGA code as well but maybe the ideas there could be useful for fuzzing related things.
  7. https://github.com/dndx/pitot which as far as I can see from isn't exactly useful for us? Feel free to correct me on this or any of the other statements though.

I believe that the core requirements for our NMEA parser should be that:

  • It should be no_std as things that use NMEA directly are often gonna be embedded devices. (see 3. and 4.) #10
  • Should have as many tests as possible (see 2. and fuzzing 6.) #11
  • Should have as little requirements as possible, considering the size constraints on embedded devices (see 3.)
  • Should under no circumstances ever panic but always return an error, again in an embedded device there is nobody to look at your panic with their eyes. #12
  • Should maintain API compatibility with the current crate so it is no hassle to upgrade for already existing users. @elpiel : We can break the API following semantic version and in the name of usability and idiomatic APIs
  • Shouldn't make use of alloc as for some embedded devices you either don't have or don't want to use an allocator for various reasons. #13 #10
  • Another cool and optional feature could be to expose our library functions and structs via the C FFI so they could be easily integrated as a piece of safe and fast Software into already existing C code bases or other code bases that can call into C. #14

It seems to me like especially the point with no dependencies seems kinda hard to adopt, especially when looking at timestamp data because it might be nice to have a well known data structure the user can use in his program. Parsing could be done without dependencies as 3. shows, however I don't think this should be our first target to tackle as it seems like a quite huge effort, would definitely be nice to have in a final version though.

Don't panic

We should never panic, instead always return Result's and try not to unwrap unless we can be absolutely sure it is safe.

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.