{
  "id": 8159311,
  "title": "Parsing Septentrio SBF logs in Python: fix-quality analysis and RTK drop forensics",
  "url": "https://urgent.news/2026/09/18/parsing-septentrio-sbf-logs-in-python-fix-quality-analysis-and-rtk",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-18T02:33:11.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/uavgnss6bot/parsing-septentrio-sbf-logs-in-python-fix-quality-analysis-and-rtk-drop-forensics-3f3g"
  },
  "original_language": "en",
  "account": "When using RTK-enabled robots, there comes a point where the fix quality drops from RTK Fixed to RTK Float, and it can be challenging to understand why. Often, the autopilot log will indicate \"float.\" The culprit is typically found in the receiver's raw log, specifically the SBF (Septentrio Binary Format) file. Parsing SBF files in Python can be made easy and accurate by following a few key steps.\n\nSBF is a binary block format that includes a sync marker, header, payload, and a CRC-16/X25 checksum. For RTK forensics, the two record types of interest are PVTGeodetic and AttEuler. The fix mode is the most crucial field, as it indicates whether the system is in RTK Fixed or RTK Float mode.\n\nWhen writing an SBF parser, there are three common pitfalls to avoid. First, field offsets are not always where you expect them to be. In the PVTGeodetic payload, latitude, longitude, and height are at byte offsets 8, 16, and 24, while the mode is at offset 6, and NrSV is at 62. Always verify your first epoch against a known surveyed point or the receiver's web interface readout.\n\nSecondly, never skip a fixed stride when resynchronizing. If the sync marker does not match, scan byte by byte for the next 0xFA 0xFA instead of assuming an 8-byte block header and jumping. This ensures that dropped or partially-written blocks self-heal and do not desynchronize the entire file.\n\nLastly, always validate the CRC. SBF uses CRC-16/X25, and corrupt blocks should be counted and dropped rather than parsed into your CSV. In tests, flipping a single byte in a 30-record log resulted in a parsed record count dropping from 30 to 29, demonstrating the importance of CRC validation for a forensics tool.\n\nTo create a more comprehensive analysis, timestamps should be converted from GPS week + time-of-week in milliseconds to UTC by applying the leap-second offset (UTC = GPS - 18 s, valid through 2026). This ensures that drop events align with flight-controller logs.\n\nThe workflow for parsing SBF files in Python involves dumping a CSV or obtaining a drop report directly to the console. Synthetic test logs with embedded RTK float drops can also be generated for testing purposes. By analyzing the fix-quality summary and drop events, you can determine the severity of the event, onset satellite count, and whether satellites disappeared. This information is crucial for diagnosing and resolving the issue, as it helps differentiate between hardware issues, multipath, or link problems.",
  "summary": "If you build robots that depend on RTK, you eventually hit the moment where the fix drops from RTK Fixed to RTK Float and nothing on your ground station explains why. The autopilot log says \"float\". The correction source looks healthy. The sky is clear. The answer is almost always in the receiver's raw log. If that receiver is a Septentrio, the raw log is SBF (Septentrio Binary Format) — and it…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}