SkillAgentSearch skills...

matlab-compute-gnss-position

Computes multi-constellation Global Positioning System (GPS) or Global Navigation Satellite System (GNSS) positions from RINEX v3 data using rinexread, gnssmeasurements, receiverposition, and gnssoptions. Filters by constellation, elevation mask, C/N0, and observation code.

Install / Use

npx skills add matlab/matlab-agentic-toolkit --skill matlab-compute-gnss-position

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

93/100

Supported Platforms

Universal

Tags

Our assessment of matlab-compute-gnss-position

matlab-compute-gnss-position scores 93/100 on our quality scale, 813th of 4,646 Development & Engineering skills we index (top 18%).

Its SKILL.md is 19 KB long, well organised into 23 sections with 10 code examples: a thorough specification that gives an agent plenty to work with.

With 1,098 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
13/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 18 days ago, so matlab-compute-gnss-position is actively maintained.
  • No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
  • Its trust signals score 88/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

matlab-compute-gnss-position compared with similar skills

All 4 of these similar skills score higher than matlab-compute-gnss-position; compare them before choosing.

SkillScoreStarsUpdatedFormat
matlab-compute-gnss-position (this skill)by matlab931.1k18d agoSKILL.md
ai-job-searchby MadsLorentzen10044.9ktodayCLAUDE.md
claude-howtoby luongnv8910041.7k3d agoCLAUDE.md
algorithmic-artby anthropics100177.9k11d agoSKILL.md
pptxby anthropics100177.9k11d agoSKILL.md

Frequently asked questions

How do I install matlab-compute-gnss-position?
Run npx skills add matlab/matlab-agentic-toolkit --skill matlab-compute-gnss-position. The install tabs above show the steps for each supported agent.
Which AI agents does matlab-compute-gnss-position work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is matlab-compute-gnss-position safe to use?
It declares no license and scores 88/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is matlab-compute-gnss-position still maintained?
The repository was last updated 18 days ago, so matlab-compute-gnss-position is actively maintained.

name: matlab-compute-gnss-position description: > Computes multi-constellation Global Positioning System (GPS) or Global Navigation Satellite System (GNSS) positions from RINEX v3 data using rinexread, gnssmeasurements, receiverposition, and gnssoptions. Filters by constellation, elevation mask, C/N0, and observation code. Reports DOP, scatter RMS, and satellite count. Use when processing GNSS data, computing positions from RINEX files, analyzing accuracy, comparing constellations, or evaluating satellite geometry. Do NOT use for carrier-phase RTK/PPP, IMU fusion, orbit propagation, NMEA streaming, or RINEX v4. metadata: author: MathWorks version: "1.0" license: https://www.mathworks.com/content/dam/mathworks/license/pmrl/license.md

Multi-Constellation GNSS Positioning

Pseudorange-based single-point positioning (SPP) from RINEX v3 data. Supports GPS, GLONASS, Galileo, BeiDou, QZSS, NavIC/IRNSS, and SBAS.

Requires: Navigation Toolbox R2026a or later.

When to Use

  • Processing RINEX observation/navigation files into position solutions
  • Computing multi-constellation receiver positions
  • Analyzing positioning accuracy, DOP, and satellite geometry
  • Comparing single-constellation vs multi-constellation performance
  • Evaluating the effect of processing options (elevation mask, C/N0, corrections)
  • Teaching or demonstrating GNSS positioning concepts

When NOT to Use

  • Carrier-phase positioning (RTK, PPP, ambiguity resolution)
  • Sensor fusion with IMU — use matlab-system-identification or INS filters
  • Satellite orbit propagation or scenario simulation — use Aerospace Toolbox
  • Real-time NMEA stream processing — use nmeaParser directly
  • RINEX v4 files — nested struct format requires different handling

Must-Follow Rules

  • Always use rinexinfo first to confirm RINEX v3 and inspect available constellations/observation codes before reading
  • Use the correct observation code per constellation — wrong code produces empty measurements (see default codes table)
  • Pre-filter satellites with missing navigation data before calling gnssmeasurements — it errors on any satellite without matching nav data
  • Always apply atmospheric corrections via gnssoptions — uncorrected SPP has >20 m vertical error
  • Use tiledlayout/nexttile for multi-panel figures (never subplot)
  • Label all axes with units and include titles on every plot
  • Report DOP quality — HDOP > 6 is degraded, HDOP > 20 is unusable
  • Skyplot requires a full-size figure — never place skyplot inside a tile of a compact tiledlayout. Use a dedicated figure for the skyplot, or if it must share a layout, size the figure so the skyplot tile is at least 560×560 pixels. Skyplots in small tiles produce unreadable, overlapping satellite markers.

Workflow

  1. Inspect RINEX files — call rinexinfo on each file to confirm v3, identify constellations, and list available observation codes. Use SatelliteSystem and Descriptors to iterate over ObservationTypes:
    info = rinexinfo('rover.obs');
    for i = 1:numel(info.ObservationTypes)
        fprintf('%s: %s\n', info.ObservationTypes(i).SatelliteSystem, ...
            strjoin(info.ObservationTypes(i).Descriptors, ', '));
    end
    
  2. Resolve observation codes — confirm default codes exist in the RINEX data; if not, suggest alternatives from the header
  3. Gather processing options — constellation selection, elevation mask (degrees, default 10), C/N0 threshold (dB-Hz, default 0), observation code overrides
  4. Read data — call rinexread for observation and navigation files
  5. Extract measurements — call gnssmeasurements per constellation with the confirmed observation code; pre-filter observation data to remove satellites without matching nav data
  6. Filter by C/N0 — remove rows from observation timetable where signal strength column falls below threshold before calling gnssmeasurements
  7. Validate constellations — solve each constellation independently first; if any produces wildly wrong positions (>1 km error, extreme altitudes), exclude it from the combination
  8. Combine constellations — vertically concatenate validated measurement timetables: combinedMeas = [gpsMeas; galMeas; ...]
  9. Apply elevation mask — compute initial position from one epoch, use lookangles to get satellite elevations, remove satellites below mask
  10. Solve position — call receiverposition with gnssoptions for atmospheric corrections
  11. Report metrics — per-epoch (HDOP, VDOP, satellite count) and aggregate (scatter RMS, mean DOP)
  12. Visualize — skyplot, position time series, DOP and satellite count panels
  13. (Optional) Ground truth — if user provides LLA, compute ENU error via lla2enu

Default Observation Codes (Band 1 Preferred)

Prefer frequency band 1 codes across all constellations. Consistent band-1 codes produce more robust multi-constellation solutions by avoiding inter-frequency bias.

| Constellation | RINEX Field | Default Code | C/N0 Column | Notes | |---------------|-------------|-------------|-------------|-------| | GPS | .GPS | "C1C" | S1C | L1 C/A (band 1) | | GLONASS | .GLONASS | "C1C" | S1C | L1 C/A (band 1) | | Galileo | .Galileo | "C1C" | S1C | E1; use "C1X" if C1C unavailable | | BeiDou | .BeiDou | "C1P" or "C1X" | S1P or S1X | Band 1 preferred (C1P, C1X, or any C1*) | | QZSS | .QZSS | "C1C" | S1C | L1 C/A (band 1) | | NavIC/IRNSS | .NavIC | "C5A" | S5A | L5 SPS (only band available) | | SBAS | .SBAS | "C1C" | S1C | L1 C/A (band 1) |

C/N0 column pattern: Replace the C prefix in the observation code with S (e.g., C1C → S1C, C1P → S1P).

Band-1 codes may have higher NaN rates than higher-band alternatives but produce more robust positions in multi-constellation solutions. Always check code availability with rinexinfo and prefer band 1.

Processing Defaults

| Parameter | Default | Units | Valid Range | |-----------|---------|-------|-------------| | Constellation selection | All available | — | Any subset of supported systems | | Elevation mask | 10 | degrees | 0–90 | | C/N0 threshold | 0 (no filtering) | dB-Hz | 0–60 | | Observation code | Per-constellation default | — | Must exist in RINEX observation fields |

Elevation mask and C/N0 filtering are not independent in urban environments. C/N0 filtering typically removes the same low-elevation, multipath-affected satellites. Applying both rarely improves results beyond C/N0 filtering alone. Elevation mask is most effective when the receiver does not report signal strength.

Key Functions

| Function | Purpose | |----------|---------| | rinexinfo | Inspect RINEX file metadata (version, systems, obs types) without reading | | rinexread | Read RINEX v3 observation and navigation files | | gnssmeasurements | Extract pseudorange, satellite position, clock bias from obs+nav data | | gnssoptions | Configure atmospheric corrections and bias accuracy | | gnssIonosphere | Klobuchar ionospheric delay model | | gnssTroposphere | Saastamoinen tropospheric delay model | | receiverposition | Weighted least-squares position solution; returns [pos, vel, hdop, vdop, info] | | lookangles | Satellite azimuth, elevation, visibility from receiver position | | skyplot | Polar plot of satellite positions with constellation grouping | | lla2enu | Geodetic to local ENU coordinate conversion (for ground truth error) |

Patterns

GPS-Only Positioning

dataDir = fullfile(matlabroot, 'toolbox', 'nav', 'positioning', ...
    'core', 'positioningdata');

obsData = rinexread(fullfile(dataDir, ...
    'GODS00USA_R_20211750000_01H_30S_MO.rnx'));
gpsNav = rinexread(fullfile(dataDir, ...
    'GODS00USA_R_20211750000_01D_GN.rnx'));

gpsMeas = gnssmeasurements(obsData.GPS, gpsNav.GPS);
opts = gnssoptions( ...
    Ionosphere=gnssIonosphere("klobuchar"), ...
    Troposphere=gnssTroposphere("saastamoinen"));

[recPos, recVel, hdop, vdop, info] = receiverposition(gpsMeas, opts);

Multi-Constellation (GPS + Galileo)

galNav = rinexread(fullfile(dataDir, ...
    'GODS00USA_R_20211750000_01D_EN.rnx'));

gpsMeas = gnssmeasurements(obsData.GPS, gpsNav.GPS);
galMeas = gnssmeasurements(obsData.Galileo, galNav.Galileo, "C1X");

combinedMeas = [gpsMeas; galMeas];
[recPos, recVel, hdop, vdop] = receiverposition(combinedMeas, opts);

Pre-Filter Satellites Missing Navigation Data

BeiDou and other constellations may have observed satellites without matching navigation messages. gnssmeasurements errors if any satellite lacks nav data.

bdsNav = rinexread(fullfile(dataDir, ...
    'GODS00USA_R_20211750000_01D_CN.rnx'));

% Find satellite IDs present in both obs and nav
obsIDs = unique(obsData.BeiDou.SatelliteID);
navIDs = unique(bdsNav.BeiDou.SatelliteID);
validIDs = intersect(obsIDs, navIDs);

% Filter observation data to valid satellites only
bdsObs = obsData.BeiDou(ismember(obsData.BeiDou.SatelliteID, validIDs), :);
bdsMeas = gnssmeasurements(bdsObs, bdsNav.BeiDou, "C1X");  % Use C1P or C1X or any C1* (band 1 preferred)

C/N0 Signal Strength Filtering

Filter weak signals before extracting measurements. The C/N0 column name follows the pattern: replace the C prefix of the observation code with S.

% Filter GPS observations with C/N0 < 30 dB-Hz
cn0Threshold = 30;
gpsObs = obsData.GPS;
gpsObs = gpsObs(gpsObs.S1C >= cn0Threshold, :);  % S1C corresponds to C1C

gpsMeas = gnssmeasurements(gpsObs, gpsNav.GPS);

Elevation Mask Filtering

Elevation filtering requires a position estimate. Use an initial fix from one epoch, then apply lookangles to filter low-elevation satellites.

% Remove rows with non-finite satellite positions (can occur in multi-GNSS data)
validRows = all(isfinite(combinedMeas.SatellitePosition), 2);
combinedMeas = combinedMeas(validRows, :);

% Get initial position from first epoch (unfiltered)
[initPos] = receiverposition(combinedMeas);
recLLA = initPos(1,:);  % [lat lon alt]

% Get unique epochs
epochs = unique(combinedMeas.Time);
filteredMeas = timetable();

for i = 1:numel(epochs)
    epochMeas = combinedMeas(combinedMeas.Time == epochs(i), :);
    satPos = epochMeas.SatellitePosition;
    [~, el, vis] = lookangles(recLLA, satPos, elevationMask);
    filteredMeas = [filteredMeas; epochMeas(vis, :)]; %#ok<AGROW>
end

Atmospheric Corrections

opts = gnssoptions( ...
    Ionosphere=gnssIonosphere("klobuchar"), ...
    Troposphere=gnssTroposphere("saastamoinen"));

[recPos, recVel, hdop, vdop, info] = receiverposition(combinedMeas, opts);
% info.ClockBias, info.ClockDrift, info.TDOP also available

Quality Metrics

% Per-epoch metrics from receiverposition outputs
nSats = arrayfun(@(t) sum(combinedMeas.Time == t), unique(combinedMeas.Time));

% Aggregate scatter RMS (no ground truth needed)
meanPos = mean(recPos, 1, 'omitnan');
enu = lla2enu(recPos, meanPos, 'ellipsoid');
hRMS = rms(vecnorm(enu(:,1:2), 2, 2));  % Horizontal scatter
vRMS = rms(enu(:,3));                     % Vertical scatter

fprintf('Horizontal scatter RMS: %.2f m\n', hRMS);
fprintf('Vertical scatter RMS:   %.2f m\n', vRMS);
fprintf('Mean HDOP: %.2f\n', mean(hdop, 'omitnan'));
fprintf('Mean VDOP: %.2f\n', mean(vdop, 'omitnan'));

Choosing a C/N0 threshold. Sweep a small set of thresholds (e.g., 25, 30, 35, 40 dB-Hz) and use the appropriate quality signal to select the best value:

| Scenario | Quality signal | Stop when | |---|---|---| | Ground truth available | H RMS and V RMS vs truth | Improvement plateaus or epoch loss is unacceptable | | No ground truth, static receiver | Position scatter RMS | Scatter plateaus or epoch loss is significant | | No ground truth, kinematic receiver | HDOP and valid epoch count | HDOP degrades or epoch loss is significant |

C/N0 filtering typical

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars1.1k
CategoryDevelopment
Updated18d ago
Forks134

Languages

MATLAB

Trust signals

88/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

1 medium