Skip to content

AmrFawzy-NavEng/GNSS-Precise-Point-Positioning-PPP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GNSS-Precise-Point-Positioning-PPP

Python 3.10+ License: MIT

Python implementation of a Precise Point Positioning (PPP) engine — integrating code and carrier-phase GNSS observations with a full Least Squares estimator supporting both Batch Adjustment and Schur Complement (Pre-elimination) solvers.

Mathematical Architecture

Observation Equations

The GNSS non-linear observation equations for Code ($P$) and Phase ($\Phi$) are linearized as:

  • $P_r^s = \rho_r^s + c(dt_r - dt^s) + T_r^s + I_r^s + \epsilon_P$
  • $\Phi_r^s = \rho_r^s + c(dt_r - dt^s) + T_r^s - I_r^s + \lambda N_r^s + \epsilon_\Phi$

Estimated Parameters

The PPPSolver estimates the following state vector $\hat{x}$:

  1. Receiver Coordinates $(X_r, Y_r, Z_r)$ — 3 parameters
  2. Receiver Clock Error $(dt_r)$ — 1 per epoch
  3. Zenith Wet Delay $(ZWD)$ — piece-wise constant (1 per hour)
  4. Phase Ambiguities $(N_r^s)$ — 1 float parameter per continuous satellite tracking arc

Solvers

Two solver strategies for the normal equations $N\hat{x} = n$:

1. Standard Batch Adjustment: $$\hat{x} = (A^T P A)^{-1} A^T P l$$

2. Schur Complement (Pre-elimination): Partitions into global parameters (Coordinates, Troposphere, Ambiguities) and local epoch-specific parameters (Clocks), dramatically reducing computational complexity:

  • $N' = N_{gg} - N_{gl}N_{ll}^{-1}N_{lg}$
  • $n' = n_g - N_{gl}N_{ll}^{-1}n_l$
  • $\hat{x}_g = (N')^{-1}n'$

Installation

git clone https://github.com/AmrFawzy-NavEng/GNSS-Precise-Point-Positioning-PPP.git
cd GNSS-Precise-Point-Positioning-PPP
pip install -r requirements.txt

Quick Start

from gnss_ppp import PPPDataLoader, DOPCalculator, PPPSolver
from gnss_ppp.utils import get_rotation_matrix, transform_to_neu

# Load observation data
loader = PPPDataLoader(filepath="observations.mat", approx_xyz=(X0, Y0, Z0))
window = loader.get_processing_window(start_epoch_idx=0, duration_hours=4.0)
arc_map, total_arcs = PPPDataLoader.identify_continuous_arcs(window)

# Solve static PPP
solver = PPPSolver(window, arc_map, total_arcs)
solver.build_system(mode='static')
x_hat, Q_xx = solver.solve_batch()

# Transform to local NEU coordinates
R = get_rotation_matrix(X0, Y0, Z0)
delta_neu, Q_neu = transform_to_neu(x_hat[:3], Q_xx[:3, :3], R)

Example Output

Run python examples/ex03_ppp_positioning.py to process GNSS observations and compare Batch vs Pre-elimination solvers:

DOP Analysis

Kinematic vs Static Scatter

Project Structure

GNSS-Precise-Point-Positioning-PPP/
├── gnss_ppp/
│   ├── __init__.py    # Package exports
│   ├── data.py        # PPPDataLoader (HDF5 ingestion, arc identification)
│   ├── dops.py        # DOPCalculator (GDOP, HDOP, VDOP)
│   ├── solver.py      # PPPSolver (Batch LSQ + Schur Complement)
│   └── utils.py       # ECEF↔NEU rotation and coordinate transforms
├── examples/
│   └── ex03_ppp_positioning.py
├── requirements.txt
└── LICENSE

License

MIT — see LICENSE for details.

About

Python PPP engine: Batch Least Squares and Schur Complement solvers for estimating receiver coordinates, clocks, tropospheric delays, and carrier-phase ambiguities from GNSS observations.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages