rtcm

package
v0.0.0-...-5e985e4 Latest Latest
Warning

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

Go to latest
Published: Jun 5, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package rtcm provides parsing of RTCM 10403.x (RTCM3) binary frames used for GNSS correction data.

Index

Constants

View Source
const (
	// Preamble is the sync byte that starts every RTCM3 frame.
	Preamble byte = 0xD3
	// HeaderSize is the size of the frame header (preamble + 2 bytes).
	HeaderSize = 3
	// CRCSize is the size of the CRC-24Q checksum.
	CRCSize = 3
	// FrameOverhead is the total overhead per frame (header + CRC).
	FrameOverhead = HeaderSize + CRCSize
	// MaxPayloadLen is the maximum RTCM3 payload length (10-bit field).
	MaxPayloadLen = 1023
	// MaxFrameSize is the maximum total frame size.
	MaxFrameSize = MaxPayloadLen + FrameOverhead
)
View Source
const (
	TypeStationARP    uint16 = 1005 // Stationary RTK reference station ARP
	TypeGPSMSM7       uint16 = 1077 // GPS MSM7
	TypeGLONASSMSM7   uint16 = 1087 // GLONASS MSM7
	TypeGalileoMSM7   uint16 = 1097 // Galileo MSM7
	TypeBeiDouMSM7    uint16 = 1127 // BeiDou MSM7
	TypeGLONASSBiases uint16 = 1230 // GLONASS code-phase biases
)

Well-known RTCM3 message types for GNSS corrections.

View Source
const (
	UBXSync1 byte = 0xB5
	UBXSync2 byte = 0x62

	UBXClassRXM byte = 0x02
	UBXMsgRAWX  byte = 0x15
	UBXMsgSFRBX byte = 0x13

	UBXHeaderSize  = 6 // sync(2) + class(1) + id(1) + len(2)
	UBXChecksumLen = 2
)

UBX frame constants.

View Source
const (
	GnssGPS     uint8 = 0
	GnssSBAS    uint8 = 1
	GnssGalileo uint8 = 2
	GnssBeiDou  uint8 = 3
	GnssQZSS    uint8 = 5
	GnssGLONASS uint8 = 6
)

GNSS system identifiers from UBX protocol.

Variables

View Source
var (
	ErrInvalidPreamble = errors.New("invalid preamble")
	ErrPayloadTooLarge = errors.New("payload length exceeds maximum")
	ErrFrameTooShort   = errors.New("frame data too short")
	ErrCRCMismatch     = errors.New("CRC-24Q mismatch")
)
View Source
var ErrNoObservations = errors.New("no usable observations for constellation")

ErrNoObservations indicates a constellation had no usable observations to encode for the requested epoch. It is an expected outcome (e.g. a constellation not currently in view), not a programming error.

Functions

func CRC24Q

func CRC24Q(data []byte) uint32

CRC24Q computes the CRC-24Q checksum used in RTCM3 frames.

func Encode1033

func Encode1033(desc AntennaDescriptor) []byte

Encode1033 generates a complete RTCM 1033 frame (header + payload + CRC).

func EncodeMSM7

func EncodeMSM7(stationID uint16, gnssID uint8, epochMs uint32, obs []RawxObservation) ([]byte, error)

EncodeMSM7 generates an RTCM MSM7 frame for one constellation from RAWX observations. Only observations matching gnssID are included. stationID and epochMs are encoded into the MSM header. It returns ErrNoObservations if the constellation has no usable observations this epoch, or an error if gnssID is not a supported MSM constellation.

func MessageTypeFromPayload

func MessageTypeFromPayload(payload []byte) uint16

MessageTypeFromPayload extracts the 12-bit message type from the first two bytes of an RTCM3 payload.

func ParseUBXFrame

func ParseUBXFrame(data []byte) (payload []byte, frameLen int, err error)

ParseUBXFrame validates a UBX frame starting at data[0] and returns the payload and total frame length consumed. Returns an error if the frame is incomplete or checksum fails.

func Patch1005RefStation

func Patch1005RefStation(frame []byte) []byte

Patch1005RefStation sets the Reference Station Indicator (DF141) to 1 in an RTCM 1005 frame and recomputes the CRC. DF141 is bit 33 of the payload (0-indexed), which is byte 7 bit 6 of the raw frame.

func PatchStationID

func PatchStationID(frame []byte, id uint16) []byte

PatchStationID sets the 12-bit Reference Station ID (DF003, bits 12-23 of the payload) in any RTCM3 frame and recomputes the CRC.

func PayloadLen

func PayloadLen(header []byte) int

PayloadLen extracts the 10-bit payload length from a 3-byte RTCM3 header.

Types

type AntennaDescriptor

type AntennaDescriptor struct {
	AntennaType    string
	AntennaSerial  string
	ReceiverType   string
	ReceiverFW     string
	ReceiverSerial string
	StationID      uint16
	AntennaSetupID uint8
}

AntennaDescriptor holds parameters for generating RTCM 1033 (Receiver and Antenna Descriptor) messages.

type BitReader

type BitReader struct {
	// contains filtered or unexported fields
}

BitReader reads arbitrary numbers of bits from a byte slice.

func NewBitReader

func NewBitReader(data []byte) *BitReader

NewBitReader creates a BitReader over the given byte slice.

func (*BitReader) Pos

func (r *BitReader) Pos() int

Pos returns the current bit position.

func (*BitReader) ReadBits

func (r *BitReader) ReadBits(n int) uint32

ReadBits reads n bits (1-32) as an unsigned value.

func (*BitReader) ReadSignedBits

func (r *BitReader) ReadSignedBits(n int) int32

ReadSignedBits reads n bits as a signed two's complement value.

func (*BitReader) Skip

func (r *BitReader) Skip(n int)

Skip advances the position by n bits.

type BitWriter

type BitWriter struct {
	// contains filtered or unexported fields
}

BitWriter writes arbitrary numbers of bits to a byte slice.

func NewBitWriter

func NewBitWriter(capacity int) *BitWriter

NewBitWriter creates a BitWriter with the given initial capacity in bytes.

func (*BitWriter) Bytes

func (w *BitWriter) Bytes() []byte

Bytes returns the written data, trimmed to the byte boundary.

func (*BitWriter) Pos

func (w *BitWriter) Pos() int

Pos returns the current bit position.

func (*BitWriter) WriteBits

func (w *BitWriter) WriteBits(val uint32, n int)

WriteBits writes n bits (1-32) from the least significant bits of val.

func (*BitWriter) WriteSignedBits

func (w *BitWriter) WriteSignedBits(val int32, n int)

WriteSignedBits writes n bits of a signed value in two's complement.

type EphCollector

type EphCollector struct {
	// contains filtered or unexported fields
}

EphCollector assembles GPS broadcast ephemeris from UBX-RXM-SFRBX navigation subframes and emits RTCM 1019 (GPS ephemeris) messages. Casters need ephemeris to position the satellites referenced by the MSM observations; without it they report "lack usable measurements".

func NewEphCollector

func NewEphCollector() *EphCollector

NewEphCollector creates an empty GPS ephemeris collector.

func (*EphCollector) AddSFRBX

func (c *EphCollector) AddSFRBX(payload []byte) []byte

AddSFRBX consumes a UBX-RXM-SFRBX payload (the UBX message payload, without the UBX header/checksum). When a payload completes GPS LNAV subframes 1-3 for a satellite with a consistent IODE/IODC, it returns the encoded RTCM 1019 frame. Otherwise it returns nil.

func (*EphCollector) All

func (c *EphCollector) All() [][]byte

All returns the latest cached RTCM 1019 frame for every satellite with a complete ephemeris, for sending on (re)connect and periodically.

type Frame

type Frame struct {
	// Payload is the frame payload (without header and CRC).
	Payload []byte
	// Raw is the complete frame bytes including header, payload, and CRC.
	Raw []byte
	// MessageType is the 12-bit RTCM3 message type ID.
	MessageType uint16
}

Frame represents a parsed RTCM3 frame.

func ParseFrame

func ParseFrame(data []byte) (Frame, error)

ParseFrame validates and parses a complete RTCM3 frame from raw bytes. The input must contain the full frame including preamble, header, payload, and CRC.

type MixedScanner

type MixedScanner struct {
	// contains filtered or unexported fields
}

MixedScanner reads both RTCM3 frames and UBX frames from a byte stream. It detects the frame type by preamble (0xD3 for RTCM3, 0xB5 for UBX).

func NewMixedScanner

func NewMixedScanner(r io.Reader) *MixedScanner

NewMixedScanner creates a scanner that reads both RTCM3 and UBX frames.

func (*MixedScanner) Err

func (s *MixedScanner) Err() error

Err returns the first non-EOF error.

func (*MixedScanner) Frame

func (s *MixedScanner) Frame() Frame

Frame returns the RTCM3 frame (valid only when Type() == MsgRTCM3).

func (*MixedScanner) Scan

func (s *MixedScanner) Scan() bool

Scan reads the next frame from the stream (either RTCM3 or UBX).

func (*MixedScanner) Type

func (s *MixedScanner) Type() MsgType

Type returns the type of the last scanned message.

func (*MixedScanner) UBXClass

func (s *MixedScanner) UBXClass() byte

UBXClass returns the UBX message class.

func (*MixedScanner) UBXMsgID

func (s *MixedScanner) UBXMsgID() byte

UBXMsgID returns the UBX message ID.

func (*MixedScanner) UBXPayload

func (s *MixedScanner) UBXPayload() []byte

UBXPayload returns the UBX payload (valid only when Type() == MsgUBX).

type MsgType

type MsgType int

MsgType indicates the type of message returned by MixedScanner.

const (
	MsgRTCM3 MsgType = iota
	MsgUBX
)

type RawxEpoch

type RawxEpoch struct {
	Observations []RawxObservation // Per-satellite measurements
	RcvTow       float64           // Receiver time of week [s]
	Week         uint16            // GPS week number
	LeapS        int8              // GPS-UTC leap seconds
}

RawxEpoch holds all observations from one UBX-RXM-RAWX message.

func ParseRawx

func ParseRawx(payload []byte) (RawxEpoch, error)

ParseRawx decodes a UBX-RXM-RAWX payload into an epoch with observations.

type RawxObservation

type RawxObservation struct {
	PrMes    float64 // Pseudorange measurement [m]
	CpMes    float64 // Carrier phase measurement [cycles]
	DoMes    float32 // Doppler measurement [Hz]
	GnssID   uint8   // GNSS identifier
	SvID     uint8   // Satellite identifier
	SigID    uint8   // Signal identifier
	FreqID   uint8   // GLONASS frequency slot
	Locktime uint16  // Carrier phase lock time [ms]
	CNO      uint8   // Carrier-to-noise ratio [dB-Hz]
	PrValid  bool    // Pseudorange valid
	CpValid  bool    // Carrier phase valid
	HalfCyc  bool    // Half cycle resolved
}

RawxObservation holds one satellite/signal measurement from UBX-RXM-RAWX.

type Scanner

type Scanner struct {
	// contains filtered or unexported fields
}

Scanner reads RTCM3 frames from a byte stream. It handles byte-level synchronization by scanning for the 0xD3 preamble, validating reserved bits and CRC-24Q checksums, and automatically resyncing after corrupted or non-RTCM data.

Usage:

scanner := rtcm.NewScanner(reader)
for scanner.Scan() {
    frame := scanner.Frame()
    // process frame
}
if err := scanner.Err(); err != nil {
    // handle error
}

func NewScanner

func NewScanner(r io.Reader) *Scanner

NewScanner creates a new Scanner that reads RTCM3 frames from r.

func (*Scanner) Err

func (s *Scanner) Err() error

Err returns the first non-EOF error encountered by the Scanner.

func (*Scanner) Frame

func (s *Scanner) Frame() Frame

Frame returns the most recently scanned frame. It is only valid after Scan returns true.

func (*Scanner) Scan

func (s *Scanner) Scan() bool

Scan reads the next RTCM3 frame from the stream. It returns true if a frame was successfully read, or false on error or EOF. After Scan returns false, the Err method returns any error that occurred (nil on clean EOF).

Jump to

Keyboard shortcuts

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