Skip to content

Commit

Permalink
Add initial functions for slant range and Free-space path loss (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
iancleary authored Oct 10, 2023
1 parent a56edd2 commit bebf86a
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 4 deletions.
10 changes: 10 additions & 0 deletions cspell.config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: "0.2"
ignorePaths: []
dictionaryDefinitions: []
dictionaries: []
words:
- consts
- fspl
- powf
ignoreWords: []
import: []
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ help:

# lint the code
lint:
cargo clippy --all-targets --all-features -- -D warnings
cargo clippy --all-targets --all-features

# dev server
dev:
Expand Down
12 changes: 12 additions & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pub const SPEED_OF_LIGHT: f64 = 299792458.0;

#[cfg(test)]
mod tests {

#[test]
fn speed_of_light() {
use super::SPEED_OF_LIGHT;

assert_eq!(299792458.0, SPEED_OF_LIGHT);
}
}
34 changes: 34 additions & 0 deletions src/conversions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use std::f64::consts::PI;

pub fn degrees_to_radians(degrees: f64) -> f64 {
degrees * PI / 180.0
}

#[cfg(test)]
mod tests {
use std::f64::consts::PI;

#[test]
fn one_hundred_eighty() {
let radians = super::degrees_to_radians(180.0);
assert_eq!(PI, radians);
}

#[test]
fn ninety() {
let radians = super::degrees_to_radians(90.0);
assert_eq!(PI / 2.0, radians);
}

#[test]
fn fourty_five() {
let radians = super::degrees_to_radians(45.0);
assert_eq!(PI / 4.0, radians);
}

#[test]
fn negative_fourty_five() {
let radians = super::degrees_to_radians(-45.0);
assert_eq!(-PI / 4.0, radians);
}
}
37 changes: 37 additions & 0 deletions src/frequency.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
pub fn frequency_to_wavelength(frequency: f64) -> f64 {
crate::constants::SPEED_OF_LIGHT / frequency
}

#[cfg(test)]
mod tests {

#[test]
fn one_gigahertz() {
let base: f64 = 10.0;
let frequency: f64 = 1.0 * base.powf(9.0);

let wavelength: f64 = super::frequency_to_wavelength(frequency);

assert_eq!(0.299792458, wavelength);
}

#[test]
fn twenty_seven_point_five_gigahertz() {
let base: f64 = 10.0;
let frequency: f64 = 27.5 * base.powf(9.0);

let wavelength: f64 = super::frequency_to_wavelength(frequency);

assert_eq!(0.010901543927272727, wavelength);
}

#[test]
fn thirty_gigahertz() {
let base: f64 = 10.0;
let frequency: f64 = 30.0 * base.powf(9.0);

let wavelength: f64 = super::frequency_to_wavelength(frequency);

assert_eq!(0.009993081933333333, wavelength);
}
}
97 changes: 97 additions & 0 deletions src/fspl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use crate::frequency::frequency_to_wavelength;
use std::f64::consts::PI;

pub fn calculate_slant_range(elevation_angle_degrees: f64, altitude: f64, body_radius: f64) -> f64 {
let elevation_angle_radians: f64 =
crate::conversions::degrees_to_radians(elevation_angle_degrees);
let total_radius: f64 = altitude + body_radius;

let total_radius_ratio: f64 = total_radius / body_radius;

let radius_ratio_squared: f64 = total_radius_ratio * total_radius_ratio;

let inner_term: f64 = f64::sqrt(
radius_ratio_squared
- f64::cos(elevation_angle_radians) * f64::cos(elevation_angle_radians),
);

body_radius * (inner_term - f64::sin(elevation_angle_radians))
}

pub fn calculate_free_space_path_loss(frequency: f64, distance: f64) -> f64 {
let wavelength: f64 = frequency_to_wavelength(frequency);
let distance_wavelength_ratio: f64 = distance / wavelength;

// (4 * PI * distance / wavelength).powf(2.0) in decibels
let free_space_path_loss: f64 = 20.0 * f64::log10(4.0 * PI * distance_wavelength_ratio);

free_space_path_loss
}

#[cfg(test)]
mod tests {
use crate::fspl::calculate_slant_range;

#[test]
fn straight_above() {
let elevation_angle_degrees: f64 = 90.0;
let base: f64 = 10.0;
let altitude: f64 = base.powf(6.0);
let body_radius: f64 = 6371000.0;

let slant_range: f64 =
calculate_slant_range(elevation_angle_degrees, altitude, body_radius);
assert_eq!(altitude, slant_range);
}

#[test]
fn thirty_five_degrees() {
let elevation_angle_degrees: f64 = 35.0;
let base: f64 = 10.0;
let altitude: f64 = base.powf(6.0);
let body_radius: f64 = 6371000.0;

let slant_range: f64 =
calculate_slant_range(elevation_angle_degrees, altitude, body_radius);
assert_eq!(1.551086307581479 * altitude, slant_range);
}

#[test]
fn horizon() {
let elevation_angle_degrees: f64 = 0.0;
let base: f64 = 10.0;
let altitude: f64 = base.powf(6.0);
let body_radius: f64 = 6371000.0;

let slant_range: f64 =
calculate_slant_range(elevation_angle_degrees, altitude, body_radius);
assert_eq!(3.707020366817534 * altitude, slant_range);
}

use crate::fspl::calculate_free_space_path_loss;

#[test]
fn leo() {
let base: f64 = 10.0;
let frequency: f64 = 27.5 * base.powf(9.0);

let distance: f64 = 1.0 * base.powf(6.0);

let free_space_path_loss: f64 = calculate_free_space_path_loss(frequency, distance);
assert_eq!(181.23443709848863, free_space_path_loss);
}

#[test]
fn leo_slant_range() {
let base: f64 = 10.0;
let frequency: f64 = 27.5 * base.powf(9.0);

let altitude: f64 = 1.0 * base.powf(6.0);
let elevation_angle_degrees: f64 = 35.0;

let slant_range: f64 = calculate_slant_range(elevation_angle_degrees, altitude, 6371000.0);

let free_space_path_loss: f64 = calculate_free_space_path_loss(frequency, slant_range);
assert_eq!(185.04715637988681, free_space_path_loss);
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod constants;
pub mod conversions;
pub mod frequency;
pub mod fspl;
3 changes: 0 additions & 3 deletions src/main.rs

This file was deleted.

0 comments on commit bebf86a

Please sign in to comment.