Code Monkey home page Code Monkey logo

ais's Introduction

AIS parser

This is the beginning of a parser for AIS messages, written in Rust.

Documentation

API documentation is available at https://docs.rs/ais

Try it out

If you just want to take a bunch of AIS NMEA sentences and see what they mean, you can try running this as a (very rough) command-line utility.

If your NMEA source is sending UDP packets to port 4722, for example:

nc -u -l 4722 | cargo run

You should start seeing messages stream in:

AidToNavigationReport(AidToNavigationReport { message_type: 21, repeat_indicator: 1, mmsi: 993692016, aid_type: Some(ReferencePoint), name: "6W", accuracy: Unaugmented, longitude: Some(-122.80445), latitude: Some(37.705833), dimension_to_bow: 0, dimension_to_stern: 0, dimension_to_port: 0, dimension_to_starboard: 0, epfd_type: Some(Surveyed), utc_second: 61, off_position: false, regional_reserved: 0, raim: false, virtual_aid: false, assigned_mode: false })
BaseStationReport(BaseStationReport { message_type: 4, repeat_indicator: 0, mmsi: 3669710, year: Some(2020), month: Some(4), day: Some(18), hour: Some(8), minute: Some(46), second: Some(40), fix_quality: DGPS, longitude: Some(-122.42347), latitude: Some(37.96206), epfd_type: None, raim: true, radio_status: Sotdma(SotdmaMessage { sync_state: UtcDirect, slot_timeout: 0, sub_message: SlotOffset(2250) }) })
PositionReport(PositionReport { message_type: 1, repeat_indicator: 0, mmsi: 367625810, navigation_status: Some(UnderWayUsingEngine), rate_of_turn: Some(RateOfTurn { raw: 0 }), speed_over_ground: Some(0.1), position_accuracy: DGPS, longitude: Some(-122.398), latitude: Some(37.80256), course_over_ground: Some(343.8), true_heading: Some(55), timestamp: 41, maneuver_indicator: None, raim: false, radio_status: Sotdma(SotdmaMessage { sync_state: UtcDirect, slot_timeout: 2, sub_message: SlotNumber(1524) }) })
BaseStationReport(BaseStationReport { message_type: 4, repeat_indicator: 0, mmsi: 3669145, year: Some(2020), month: Some(4), day: Some(18), hour: Some(8), minute: Some(46), second: Some(41), fix_quality: DGPS, longitude: Some(-122.46484), latitude: Some(37.794273), epfd_type: None, raim: true, radio_status: Sotdma(SotdmaMessage { sync_state: UtcDirect, slot_timeout: 3, sub_message: ReceivedStations(187) }) })

Use it as a library

Here's an example that parses a single NMEA sentence. In this case, it contains an Aid to Navigation Report:

use ais::{AisFragments, AisParser};
use ais::messages::AisMessage;

// The line below is an NMEA sentence, much as you'd see coming out of an AIS decoder.
let line = b"!AIVDM,1,1,,B,E>kb9O9aS@7PUh10dh19@;0Tah2cWrfP:l?M`00003vP100,0*01";

let mut parser = AisParser::new();
if let AisFragments::Complete(sentence) = parser.parse(line, true)? {
   // This sentence is complete, ie unfragmented
   assert_eq!(sentence.num_fragments, 1);
   // The data was transmitted on AIS channel B
   assert_eq!(sentence.channel, Some('B'));

   if let Some(message) = sentence.message {
       match message {
           AisMessage::AidToNavigationReport(report) => {
               assert_eq!(report.mmsi, 993692028);
               assert_eq!(report.name, "SF OAK BAY BR VAIS E");
               // There are a ton more fields available here
           },
           _ => panic!("Unexpected message type"),
       }
   }
}
# Ok::<(), ais::errors::Error>(())

Supported message types

Right now, only a few common types are supported. They are:

  • Position Report (types 1-3)
  • Base Station Report (type 4)
  • Static and Voyage Related Data (type 5)
  • Binary Broadcast Message (type 8)
  • UTC/Date Response (type 11)
  • Interrogation (type 15)
  • DGNSS Broadcast Binary Message (type 17)
  • Static Class B Position Report (type 18)
  • Extended Class B Position Report (type 19)
  • Data Link Management Message (type 20)
  • Aid to Navigation Report (type 21)
  • Static Data Report (type 24)

Others to come soon, I hope!

no_std support

This library has experimental support for no_std; add the library like this to your Cargo.toml:

ais = { version = "0.9", default-features = false }

Some AIS messages have variable length fields; this is accomplished using heapless Vec and String types, allocating the maximum possible data size on the stack.

If you have access to an allocator, opting into the alloc feature may be more space efficient, as observed messages sizes are often much smaller than the maximum possible.

The std feature is the default, and it is more or less identical to the alloc version; it's required to build the binary CLI tool.

ais's People

Contributors

ebuckley avatar jkr78 avatar keesverruijt avatar manevillef avatar squidpickles avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ais's Issues

Crate integration in NMEA.

Hello @squidpickles ๐Ÿ‘‹,
I'm the community lead of the AeroRust community and one of the co-founders.
I've recently landed your crate for parsing AIS messages and I wanted to let you know that we are making efforts to develop an NMEA 0183 crate that is feature rich for Rust.
I think AIS messages can be very beneficial to the overall messages that the crate can parse.

Would you be interested to take the AIS parsing and integrate it to the NMEA crate?

https://github.com/AeroRust/nmea

Also, you can come join the community in Discord if you're interested in robotics and aerospace or you want to discuss this idea.

Regards,
Lachezar

Ps: I see there is binary data field that uses a Vec, do you know if there is a limit to it, as we support no_std and this is one aspect we should alter to fit NMEA.

Parse NMEA tag blocks

An example NMEA message with tag block might be

\s:2573435,c:1699169531*03\!BSVDM,1,1,,B,13md`u0P00PoLB4V`C8=;wvF24r0,0*0F

It would be nice to parse these, rather than just ignoring them (or worse, erroring)

Update to Nom 5

Nice to get away from big scary macros, and keep our dependencies modern

#![no_std] compatibility

Some thought will need to go into optimal buffer sizes given multi-part messages, and I would want to look at a better way of building up character data, but this seems doable given demand.

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.