UNPKG

@jbroll/nmea-simple

Version:

NMEA 0183 sentence parser and encoder

98 lines (88 loc) 3.1 kB
/* * === GSV - Satellites in view === * * ------------------------------------------------------------------------------ * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 * | | | | | | | | | | | | | | | | | | | | | | * $--GSV,x,x,xx,xx,xx,xx,xxx,xx,xx,xx,xxx,xx,xx,xx,xxx,xx,xx,xx,xxx,xx,s*hh<CR><LF> * ------------------------------------------------------------------------------ * * Field Number: * * 1. Number of sentences for full data * 2. Sentence number out of total * 3. Number of satellites in view * 4. PRN of satellite used for fix (may be blank) * * 5. Satellite PRN number \ * 6. Elevation, degrees +- Satellite 1 * 7. Azimuth, degrees | * 8. Signal to noise ratio / * * 9. Satellite PRN number \ * 10. Elevation, degrees +- Satellite 2 * 11. Azimuth, degrees | * 12. Signal to noise ratio / * * 13. Satellite PRN number \ * 14. Elevation, degrees +- Satellite 3 * 15. Azimuth, degrees | * 16. Signal to noise ratio / * * 17. Satellite PRN number \ * 18. Elevation, degrees +- Satellite 4 * 19. Azimuth, degrees | * 20. Signal to noise ratio / * * 21. Signal ID (u-blox specific field, optional): * For GPS (GP): * 0: All signals (default if field not present) * 1: L1 C/A * 6: L2 CL * 22. Checksum */ import { parseIntSafe } from "../helpers"; import { adjustPRN, getTalkerSystemId } from "../prn-utils"; import { initStubFields, PacketStub } from "./PacketStub"; export const sentenceId: "GSV" = "GSV"; export const sentenceName = "Satellites in view"; export interface Satellite { prnNumber: number; elevationDegrees: number; azimuthTrue: number; SNRdB: number; } export interface GSVPacket extends PacketStub<typeof sentenceId> { numberOfMessages: number; messageNumber: number; satellitesInView: number; satellites: Satellite[]; } export function decodeSentence(stub: PacketStub, fields: string[]): GSVPacket { // Each satellite uses 4 fields const numRecords = Math.floor((fields.length - 4) / 4); const sats: Satellite[] = []; const systemId = getTalkerSystemId(stub.talkerId || ""); // Process satellite records for (let i = 0; i < numRecords; i++) { const offset = i * 4 + 4; // Only add satellites with valid PRN numbers const rawPrn = parseIntSafe(fields[offset]); if (rawPrn > 0) { const adjustedPrn = adjustPRN(rawPrn, systemId); sats.push({ prnNumber: adjustedPrn, elevationDegrees: parseIntSafe(fields[offset + 1]), azimuthTrue: parseIntSafe(fields[offset + 2]), SNRdB: parseIntSafe(fields[offset + 3]) }); } } return { ...initStubFields(stub, sentenceId, sentenceName), numberOfMessages: parseIntSafe(fields[1]), messageNumber: parseIntSafe(fields[2]), satellitesInView: parseIntSafe(fields[3]), satellites: sats }; }