ais

package
v0.331.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 21, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package ais decodes AIS (Automatic Identification System) NMEA 0183 sentences carried over the standard AIS VHF channels (161.975 / 162.025 MHz) — the maritime counterpart of ADS-B, mandatory on commercial vessels >300 GT and on most passenger ships under SOLAS Chapter V.

Wrap-vs-native judgement

Native. AIS is defined by the public ITU-R M.1371-5 standard (with the NMEA 0183 wire envelope per IEC 61162-1). Every payload is 6-bit ASCII-packed binary with well-documented per-message-type field layouts. Pasting a sentence from rtl_ais / AIS-catcher / NMEA-feed dump is enough — no vendor SDK, no handshake, no cryptography.

What this package covers

  • NMEA 0183 envelope: !AIVDM / !AIVDO talker IDs, fragment count + index + sequence ID + AIS channel (A/B), payload field, padding bits, and XOR checksum. Multi-fragment messages (Type 5 is always 2 fragments) are reassembled when newline-separated sentences are passed together.
  • 6-bit ASCII payload unpack: the canonical AIS bit-soup decode (char - 48; if >40 subtract another 8) followed by 6-bit-at-a-time packing into a bit string with the trailing padding bits stripped.
  • Type-1, Type-2, Type-3 Position Report Class A: MMSI, Navigation Status (16-state table — Under Way Using Engine, At Anchor, Not Under Command, Restricted Manoeuvrability, etc.), Rate Of Turn, Speed Over Ground, Position Accuracy, Longitude / Latitude (signed 28/27 bits at 1/10000 minute), Course Over Ground, True Heading, Timestamp, Manoeuvre Indicator, RAIM flag.
  • Type-4 Base Station Report: MMSI, UTC year / month / day / hour / minute / second + position.
  • Type-5 Static & Voyage: MMSI, AIS version, IMO number, callsign, vessel name, ship type (full 100- entry table), dimensions to bow / stern / port / starboard, EPFD type, ETA (month / day / hour / minute), draught, destination. Reassembled from the 2 fragments that this type always uses.
  • Type-18 Standard Class B Position Report: the smaller-vessel position broadcast with MMSI, Speed, Position Accuracy, Longitude / Latitude, Course, True Heading, Timestamp, RAIM.
  • Type-24 Static Data Class B: Part A (vessel name) or Part B (ship type + vendor ID + callsign + dimensions or mother-ship MMSI).

What this package does NOT cover (deliberately out of scope)

  • Type 6 / 8 Binary Addressed/Broadcast Message — the application-specific payloads are vendor-defined and would each need their own decoder; the type label and destination MMSI / DAC / FI fields are surfaced but the body is exposed as a raw hex string.
  • Type 9 SAR Aircraft Position, Type 11 UTC/Date Response, Type 14 Safety Related Broadcast, Type 15 Interrogation, Type 16 Assigned-Mode Command, Type 17 DGNSS Broadcast, Type 19 Extended Class B Position, Type 20 Data Link Management, Type 21 Aid-to-Navigation, Type 22 Channel Management, Type 23 Group Assignment, Type 25 / 26 / 27 Long-Range Application — recognised by name but body decode deferred.
  • Live demodulation from raw I/Q samples — sentences must be pre-decoded to NMEA text by an upstream receiver (rtl_ais / AIS-catcher / AISHub).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BaseStationReport

type BaseStationReport struct {
	Year             int      `json:"year"`
	Month            int      `json:"month"`
	Day              int      `json:"day"`
	Hour             int      `json:"hour"`
	Minute           int      `json:"minute"`
	Second           int      `json:"second"`
	PositionAccuracy bool     `json:"position_accuracy"`
	LongitudeDeg     *float64 `json:"longitude_deg,omitempty"`
	LatitudeDeg      *float64 `json:"latitude_deg,omitempty"`
	EPFDType         int      `json:"epfd_type"`
	EPFDName         string   `json:"epfd_name"`
	RAIM             bool     `json:"raim"`
}

BaseStationReport is Type-4 — UTC time + position of a shore-side AIS base station.

type Message

type Message struct {
	Sentences       []string                `json:"sentences"`
	Channel         string                  `json:"channel"`
	MessageType     int                     `json:"message_type"`
	TypeName        string                  `json:"type_name"`
	Repeat          int                     `json:"repeat_indicator"`
	MMSI            int                     `json:"mmsi"`
	PositionClassA  *PositionReportClassA   `json:"position_class_a,omitempty"`
	BaseStation     *BaseStationReport      `json:"base_station,omitempty"`
	StaticAndVoyage *StaticAndVoyageData    `json:"static_and_voyage,omitempty"`
	PositionClassB  *PositionReportClassB   `json:"position_class_b,omitempty"`
	StaticClassB    *StaticDataReportClassB `json:"static_class_b,omitempty"`
}

Message is one decoded AIS message.

Exactly one of the typed sub-pointers is set per call (the one matching MessageType). For unsupported types the body stays nil but TypeName labels what was seen.

func Decode

func Decode(input string) (*Message, error)

Decode parses one or more AIS NMEA sentences (newline- separated) into a single Message. Multi-fragment payloads are reassembled in input order — pass all fragments in one call.

type PositionReportClassA

type PositionReportClassA struct {
	NavStatus           int      `json:"nav_status"`
	NavStatusName       string   `json:"nav_status_name"`
	RateOfTurnDegPerMin *int     `json:"rate_of_turn_deg_per_min,omitempty"`
	SpeedOverGroundKts  *float64 `json:"speed_over_ground_kts,omitempty"`
	PositionAccuracy    bool     `json:"position_accuracy"`
	LongitudeDeg        *float64 `json:"longitude_deg,omitempty"`
	LatitudeDeg         *float64 `json:"latitude_deg,omitempty"`
	CourseOverGroundDeg *float64 `json:"course_over_ground_deg,omitempty"`
	TrueHeadingDeg      *int     `json:"true_heading_deg,omitempty"`
	Timestamp           int      `json:"timestamp_sec"`
	ManeuverIndicator   int      `json:"maneuver_indicator"`
	RAIM                bool     `json:"raim"`
}

PositionReportClassA is the Type-1/2/3 body — the high- frequency position broadcast from SOLAS-class vessels.

type PositionReportClassB

type PositionReportClassB struct {
	SpeedOverGroundKts  *float64 `json:"speed_over_ground_kts,omitempty"`
	PositionAccuracy    bool     `json:"position_accuracy"`
	LongitudeDeg        *float64 `json:"longitude_deg,omitempty"`
	LatitudeDeg         *float64 `json:"latitude_deg,omitempty"`
	CourseOverGroundDeg *float64 `json:"course_over_ground_deg,omitempty"`
	TrueHeadingDeg      *int     `json:"true_heading_deg,omitempty"`
	Timestamp           int      `json:"timestamp_sec"`
	CSUnit              bool     `json:"cs_unit"`
	DisplayFlag         bool     `json:"display_flag"`
	DSCFlag             bool     `json:"dsc_flag"`
	BandFlag            bool     `json:"band_flag"`
	Msg22Flag           bool     `json:"msg22_flag"`
	Assigned            bool     `json:"assigned"`
	RAIM                bool     `json:"raim"`
}

PositionReportClassB is Type-18 — the lighter, more frequent position broadcast from Class-B (small-vessel) transponders.

type Sentence

type Sentence struct {
	Talker        string
	FragmentCount int
	FragmentIndex int
	SequenceID    string
	Channel       string
	Payload       string
	PaddingBits   int
}

Sentence is a parsed !AIVDM / !AIVDO line.

type StaticAndVoyageData

type StaticAndVoyageData struct {
	AISVersion     int     `json:"ais_version"`
	IMONumber      int     `json:"imo_number"`
	CallSign       string  `json:"call_sign"`
	VesselName     string  `json:"vessel_name"`
	ShipType       int     `json:"ship_type"`
	ShipTypeName   string  `json:"ship_type_name"`
	DimensionBow   int     `json:"dimension_to_bow_m"`
	DimensionStern int     `json:"dimension_to_stern_m"`
	DimensionPort  int     `json:"dimension_to_port_m"`
	DimensionStbd  int     `json:"dimension_to_starboard_m"`
	EPFDType       int     `json:"epfd_type"`
	EPFDName       string  `json:"epfd_name"`
	ETAMonth       int     `json:"eta_month"`
	ETADay         int     `json:"eta_day"`
	ETAHour        int     `json:"eta_hour"`
	ETAMinute      int     `json:"eta_minute"`
	DraughtM       float64 `json:"draught_m"`
	Destination    string  `json:"destination"`
	DTE            int     `json:"dte"`
}

StaticAndVoyageData is Type-5 — assembled from the two fragments this type always uses.

type StaticDataReportClassB

type StaticDataReportClassB struct {
	PartNumber     int    `json:"part_number"`
	VesselName     string `json:"vessel_name,omitempty"`
	ShipType       int    `json:"ship_type,omitempty"`
	ShipTypeName   string `json:"ship_type_name,omitempty"`
	VendorID       string `json:"vendor_id,omitempty"`
	CallSign       string `json:"call_sign,omitempty"`
	DimensionBow   int    `json:"dimension_to_bow_m,omitempty"`
	DimensionStern int    `json:"dimension_to_stern_m,omitempty"`
	DimensionPort  int    `json:"dimension_to_port_m,omitempty"`
	DimensionStbd  int    `json:"dimension_to_starboard_m,omitempty"`
	MothershipMMSI int    `json:"mothership_mmsi,omitempty"`
}

StaticDataReportClassB is Type-24 — Part A (vessel name) or Part B (ship type + dimensions). PartA / PartB are mutually exclusive in a single sentence.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL