Files
KairoXYZ/kairo-common/src/models/antenna.rs

97 lines
2.7 KiB
Rust

use diesel::prelude::*;
use std::f64::consts::PI;
use crate::{unit_conversion::UnitsConversion, Point};
#[derive(
Debug,
Clone,
Queryable,
Selectable,
Insertable,
AsChangeset,
serde::Serialize,
serde::Deserialize,
)]
#[diesel(check_for_backend(diesel::pg::Pg))]
#[diesel(table_name = crate::schema::antennas)]
pub struct Antenna {
pub id: String,
pub tssi: f64,
pub pos_x: f64,
pub pos_y: f64,
pub pos_z: f64,
pub comment: Option<String>,
}
impl Antenna {
const C: f64 = 2.99e8;
const F: f64 = 2.4e9;
const λ: f64 = Self::C / Self::F;
pub fn new(id: &str, tssi: f64, coord: Point) -> Antenna {
Antenna {
id: id.into(),
comment: None,
pos_x: coord.x,
pos_y: coord.y,
pos_z: 0.0,
tssi,
}
}
pub fn coord(&self) -> Point {
Point::new(self.pos_x, self.pos_y)
}
pub fn get_rssi(&self, distance: f64) -> f64 {
#[allow(non_snake_case)]
// Free Space Path Loss
let FSPL = (((distance * 4.0 * PI) / Self::λ).powi(2)).to_dB();
self.tssi - FSPL
}
#[allow(non_snake_case)]
pub fn get_distance_with_dBm(&self, rssi_dBm: f64) -> f64 {
let loss = self.tssi.dBm_to_W() / rssi_dBm.dBm_to_W();
let distance = (loss.sqrt() * Self::λ) / (4.0 * PI);
distance.abs()
}
#[allow(non_snake_case)]
pub fn get_distance_with_W(&self, rssi_W: f64) -> f64 {
let loss = self.tssi.dBm_to_W() / rssi_W;
let distance = (loss.sqrt() * Self::λ) / (4.0 * PI);
distance.abs()
}
}
#[test]
fn test() {
let tssi = 0.0; // dBm
let a = Antenna::new("AB:CD:EF:12:34:56", tssi, Point { x: 0.0, y: 0.0 });
// Known Attenuation values for 2.4GHz
// 5 meter = 54.02 dB = 3.96e-9 W
// 10 meter = 60.04 dB = 9.91e-10 W
// 20 meter = 66.06 dB = 2.48e-10 W
print!("Testing Antenna::get_rssi()");
assert!(f64::abs(-54.02 - a.get_rssi(5.0)) < 0.1);
assert!(f64::abs(-60.04 - a.get_rssi(10.0)) < 0.1);
assert!(f64::abs(-66.06 - a.get_rssi(20.0)) < 0.1);
println!(" ... ok");
print!("Testing Antenna::get_distance_with_dBm()");
assert!(f64::abs(5.0 - a.get_distance_with_dBm(-54.02)) < 0.5);
assert!(f64::abs(10.0 - a.get_distance_with_dBm(-60.04)) < 0.5);
assert!(f64::abs(20.0 - a.get_distance_with_dBm(-66.06)) < 0.5);
println!(" ... ok");
print!("Testing Antenna::get_distance_with_W()");
assert!(f64::abs(5.0 - a.get_distance_with_W(3.98e-9)) < 0.5);
assert!(f64::abs(10.0 - a.get_distance_with_W(9.91e-10)) < 0.5);
assert!(f64::abs(20.0 - a.get_distance_with_W(2.48e-10)) < 0.5);
println!(" ... ok");
}