99 lines
2.9 KiB
Rust
99 lines
2.9 KiB
Rust
use diesel::prelude::*;
|
|
use std::f64::consts::PI;
|
|
|
|
use crate::{unit_conversion::UnitsConversion, Point};
|
|
|
|
#[derive(Debug, Clone, Default, Queryable, Selectable, 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>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, Insertable, AsChangeset, serde::Deserialize)]
|
|
#[diesel(table_name = crate::schema::antennas)]
|
|
pub struct NewAntenna<'a> {
|
|
pub id: &'a str,
|
|
pub tssi: f64,
|
|
pub pos_x: f64,
|
|
pub pos_y: f64,
|
|
pub pos_z: f64,
|
|
pub comment: Option<&'a str>,
|
|
}
|
|
|
|
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");
|
|
}
|