Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/Documenter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Documentation

on:
push:
branches:
- master
tags: ['*']
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: '1'
- uses: julia-actions/cache@v2
- name: Install dependencies
run: julia --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
- name: Build and deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: julia --project=docs docs/make.jl
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Manifest.toml
docs/build/
9 changes: 6 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ version = "0.2.0"
[deps]
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[compat]
Aqua = "0.8"
DocStringExtensions = "0.8, 0.9"
LinearAlgebra = "1"
Test = "1"
Unitful = "0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 1.0"
julia = "1"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[target]
test = ["Test"]
[targets]
test = ["Aqua", "Test"]
30 changes: 13 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
[![Build Status](https://travis-ci.org/JuliaGNSS/TrackingLoopFilters.jl.svg?branch=master)](https://travis-ci.org/JuliaGNSS/TrackingLoopFilters.jl)
[![Coverage Status](https://coveralls.io/repos/github/JuliaGNSS/TrackingLoopFilters.jl/badge.svg?branch=master)](https://coveralls.io/github/JuliaGNSS/TrackingLoopFilters.jl?branch=master)
# TrackingLoopFilters.jl

# TrackingLoopFilters
This implements multiple loop filters for GNSS tracking algorithms.
[![Build Status](https://github.com/JuliaGNSS/TrackingLoopFilters.jl/actions/workflows/ci.yml/badge.svg)](https://github.com/JuliaGNSS/TrackingLoopFilters.jl/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/JuliaGNSS/TrackingLoopFilters.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaGNSS/TrackingLoopFilters.jl)
[![Documentation](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliagnss.github.io/TrackingLoopFilters.jl/stable)
[![Documentation](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliagnss.github.io/TrackingLoopFilters.jl/dev)

## Features
Loop filters for GNSS tracking algorithms.

* First, second and third order loop filters
* Boxcar and bilinear loop filters
## Installation

## Getting started

Install:
```julia
julia> ]
pkg> add TrackingLoopFilters
```

## Usage
## Documentation

```julia
using TrackingLoopFilters
carrier_loop_filter = ThirdOrderBilinearLF()
output, next_carrier_loop_filter = filter_loop(carrier_loop_filter, discriminator_output, Δt, bandwidth)
```
See the [documentation](https://juliagnss.github.io/TrackingLoopFilters.jl/stable) for API reference.

## License

MIT
6 changes: 6 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
TrackingLoopFilters = "0814aff9-93cb-554c-9fff-9bf1cfdb5efa"

[compat]
Documenter = "1"
14 changes: 14 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Documenter
using TrackingLoopFilters

makedocs(
sitename = "TrackingLoopFilters.jl",
modules = [TrackingLoopFilters],
pages = [
"Home" => "index.md",
],
)

deploydocs(
repo = "github.com/JuliaGNSS/TrackingLoopFilters.jl.git",
)
28 changes: 28 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# TrackingLoopFilters.jl

Loop filters for GNSS tracking algorithms.

## Installation

```julia
pkg> add TrackingLoopFilters
```

## Quick Start

```julia
using TrackingLoopFilters
using Unitful: Hz, s

# Create a loop filter
lf = ThirdOrderBilinearLF()

# Process discriminator output
output, next_lf = filter_loop(lf, δθ, Δt, bandwidth)
```

## API Reference

```@autodocs
Modules = [TrackingLoopFilters]
```
45 changes: 43 additions & 2 deletions src/FirstOrderLF.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
"""
$(TYPEDEF)

Abstract base type for first order loop filters.
"""
abstract type AbstractFirstOrderLF <: AbstractLoopFilter end

"""
$(TYPEDEF)

First order loop filter (proportional only).

A stateless filter that provides proportional gain without integration.
The natural frequency scaling factor is 4.0.

# Example
```julia
lf = FirstOrderLF()
output, next_lf = filter_loop(lf, δθ, Δt, bandwidth)
```
"""
struct FirstOrderLF <: AbstractFirstOrderLF
end

"""
$(SIGNATURES)

Propagates the state of the loop filter.
Propagate the first order loop filter state.

Since the first order filter is stateless, this returns the input state unchanged.

# Arguments
- `state`: Current loop filter state
- `δθ`: Phase discriminator output
- `Δt`: Integration time
- `bandwidth`: Loop bandwidth

# Returns
The unchanged loop filter state.
"""
function propagate(state::FirstOrderLF, δθ, Δt, bandwidth)
state
Expand All @@ -15,7 +45,18 @@ end
"""
$(SIGNATURES)

Calculates the output of the loop filter.
Calculate the filtered output for the first order loop filter.

Computes `ω₀ * δθ` where `ω₀ = bandwidth * 4.0`.

# Arguments
- `state`: Current loop filter state
- `δθ`: Phase discriminator output
- `Δt`: Integration time
- `bandwidth`: Loop bandwidth

# Returns
Filtered frequency estimate.
"""
function get_filtered_output(state::FirstOrderLF, δθ, Δt, bandwidth)
ω₀ = bandwidth * 4.0
Expand Down
88 changes: 85 additions & 3 deletions src/SecondOrderLF.jl
Original file line number Diff line number Diff line change
@@ -1,25 +1,85 @@
"""
$(TYPEDEF)

Abstract base type for second order loop filters.
"""
abstract type AbstractSecondOrderLF <: AbstractLoopFilter end

"""
$(TYPEDEF)

Second order bilinear loop filter.

Uses bilinear transformation for improved frequency response.
The natural frequency scaling factor is 1.89.

$(TYPEDFIELDS)

# Example
```julia
lf = SecondOrderBilinearLF()
output, next_lf = filter_loop(lf, δθ, Δt, bandwidth)
```
"""
struct SecondOrderBilinearLF{T} <: AbstractSecondOrderLF
"Frequency state estimate"
x::T
end

"""
$(TYPEDEF)

Second order boxcar loop filter.

Uses boxcar (rectangular) integration for simpler implementation.
The natural frequency scaling factor is 1.89.

$(TYPEDFIELDS)

# Example
```julia
lf = SecondOrderBoxcarLF()
output, next_lf = filter_loop(lf, δθ, Δt, bandwidth)
```
"""
struct SecondOrderBoxcarLF{T} <: AbstractSecondOrderLF
"Frequency state estimate"
x::T
end

"""
SecondOrderBilinearLF()

Construct a second order bilinear loop filter with zero initial state.
"""
function SecondOrderBilinearLF()
SecondOrderBilinearLF(0.0Hz)
end

"""
SecondOrderBoxcarLF()

Construct a second order boxcar loop filter with zero initial state.
"""
function SecondOrderBoxcarLF()
SecondOrderBoxcarLF(0.0Hz)
end

"""
$(SIGNATURES)

Propagates the state of the loop filter.
Propagate the second order loop filter state.

Updates the frequency state estimate using `x_next = x + Δt * ω₀² * δθ`.

# Arguments
- `state`: Current loop filter state
- `δθ`: Phase discriminator output
- `Δt`: Integration time
- `bandwidth`: Loop bandwidth

# Returns
New loop filter state with updated frequency estimate.
"""
function propagate(state::T, δθ, Δt, bandwidth) where T <: AbstractSecondOrderLF
ω₀ = bandwidth * 1.89
Expand All @@ -29,7 +89,18 @@ end
"""
$(SIGNATURES)

Calculates the output of the loop filter.
Calculate the filtered output for the second order bilinear loop filter.

Computes `x + (√2 * ω₀ + ω₀² * Δt / 2) * δθ`.

# Arguments
- `state`: Current loop filter state
- `δθ`: Phase discriminator output
- `Δt`: Integration time
- `bandwidth`: Loop bandwidth

# Returns
Filtered frequency estimate.
"""
function get_filtered_output(state::SecondOrderBilinearLF, δθ, Δt, bandwidth)
ω₀ = bandwidth * 1.89
Expand All @@ -39,7 +110,18 @@ end
"""
$(SIGNATURES)

Calculates the output of the loop filter.
Calculate the filtered output for the second order boxcar loop filter.

Computes `x + √2 * ω₀ * δθ`.

# Arguments
- `state`: Current loop filter state
- `δθ`: Phase discriminator output
- `Δt`: Integration time
- `bandwidth`: Loop bandwidth

# Returns
Filtered frequency estimate.
"""
function get_filtered_output(state::SecondOrderBoxcarLF, δθ, Δt, bandwidth)
ω₀ = bandwidth * 1.89
Expand Down
Loading