ais

package
v0.783.0 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 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-9 SAR Aircraft Position Report: altitude (in place of nav status), whole-knot speed, position, course, timestamp and the DTE / assigned / RAIM flags — the broadcast from a search-and-rescue aircraft.
  • Type-19 Extended Class B Position Report: Type-18's position fields plus the vessel name, ship type and dimensions, so a single 312-bit message carries both dynamic and static data for the craft.
  • Type-21 Aid-to-Navigation Report: aid type (32-entry table — buoys, lighthouses, RACONs, beacons), name (with the 0-88-bit extension field), position, dimensions, EPFD, timestamp, and the off-position / virtual-aid / assigned flags that distinguish a real mark from a transmitted "virtual" AtoN.
  • Type-24 Static Data Class B: Part A (vessel name) or Part B (ship type + vendor ID + callsign + dimensions or mother-ship MMSI).
  • Type-27 Long-Range Position Report: the compressed position broadcast for satellite reception — nav status, coarse 1/10-minute position, whole-knot speed, whole-degree course, RAIM and the GNSS position-latency flag.

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 11 UTC/Date Response, Type 14 Safety Related Broadcast, Type 15 Interrogation, Type 16 Assigned- Mode Command, Type 17 DGNSS Broadcast, Type 20 Data Link Management, Type 22 Channel Management, Type 23 Group Assignment, Type 25 / 26 Binary Message — 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 AidToNavigationReport added in v0.543.0

type AidToNavigationReport struct {
	AidType          int      `json:"aid_type"`
	AidTypeName      string   `json:"aid_type_name"`
	Name             string   `json:"name"`
	NameExtension    string   `json:"name_extension,omitempty"`
	PositionAccuracy bool     `json:"position_accuracy"`
	LongitudeDeg     *float64 `json:"longitude_deg,omitempty"`
	LatitudeDeg      *float64 `json:"latitude_deg,omitempty"`
	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"`
	Timestamp        int      `json:"timestamp_sec"`
	OffPosition      bool     `json:"off_position"`
	RAIM             bool     `json:"raim"`
	VirtualAid       bool     `json:"virtual_aid"`
	Assigned         bool     `json:"assigned"`
}

AidToNavigationReport is Type-21 — broadcast by (or on behalf of) a navigation aid: a buoy, lighthouse, RACON, beacon or a "virtual" AtoN that exists only as a transmitted mark. The name can overflow into a 0-88-bit extension field.

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 ExtendedPositionClassB added in v0.543.0

type ExtendedPositionClassB 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"`
	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"`
	RAIM                bool     `json:"raim"`
	DTE                 int      `json:"dte"`
	Assigned            bool     `json:"assigned"`
}

ExtendedPositionClassB is Type-19 — the richer Class-B position broadcast that, unlike Type-18, also carries the vessel name, ship type and dimensions in a single 312-bit message (so it doubles as static data for small craft).

type LongRangePosition added in v0.544.0

type LongRangePosition struct {
	PositionAccuracy    bool     `json:"position_accuracy"`
	RAIM                bool     `json:"raim"`
	NavStatus           int      `json:"nav_status"`
	NavStatusName       string   `json:"nav_status_name"`
	LongitudeDeg        *float64 `json:"longitude_deg,omitempty"`
	LatitudeDeg         *float64 `json:"latitude_deg,omitempty"`
	SpeedOverGroundKts  *float64 `json:"speed_over_ground_kts,omitempty"`
	CourseOverGroundDeg *float64 `json:"course_over_ground_deg,omitempty"`
	// GNSSPositionLatency is the Type-27 GNSS flag: false = the
	// position is a current GNSS fix (latency < 5 s); true = the
	// position is older / not a current GNSS fix.
	GNSSPositionLatency bool `json:"gnss_position_latency"`
}

LongRangePosition is Type-27 — the heavily-compressed position report intended for long-range (satellite) reception. Position is at the coarser 1/10-minute resolution and speed/course are whole knots / whole degrees.

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"`
	ExtendedClassB  *ExtendedPositionClassB `json:"extended_class_b,omitempty"`
	StaticClassB    *StaticDataReportClassB `json:"static_class_b,omitempty"`
	AidToNavigation *AidToNavigationReport  `json:"aid_to_navigation,omitempty"`
	SARAircraft     *SARAircraftPosition    `json:"sar_aircraft,omitempty"`
	LongRange       *LongRangePosition      `json:"long_range,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 SARAircraftPosition added in v0.544.0

type SARAircraftPosition struct {
	AltitudeM           *int     `json:"altitude_m,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"`
	Timestamp           int      `json:"timestamp_sec"`
	DTE                 int      `json:"dte"`
	Assigned            bool     `json:"assigned"`
	RAIM                bool     `json:"raim"`
}

SARAircraftPosition is Type-9 — the position broadcast from a Search-And-Rescue aircraft (helicopter / fixed-wing). Unlike the vessel position reports it carries an altitude instead of a navigation status, and its speed is in whole knots.

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