pub struct SensorSource {
pub id: u8,
pub variance: f64,
pub gate_threshold: f64,
pub anomaly_count: u32,
pub max_anomalies: u32,
pub is_quarantined: bool,
pub health_score: f64,
pub consecutive_healthy: u32,
pub auto_recovery_threshold: u32,
}Expand description
Represents an individual sensor source participating in the multi-sensor fusion pipeline.
Fields§
§id: u8Sensor unique identifier
variance: f64Measurement noise variance (R)
gate_threshold: f643-sigma innovation gating threshold
anomaly_count: u32Consecutive anomaly count for automated isolation
max_anomalies: u32Maximum allowable consecutive anomalies before quarantine
is_quarantined: boolWhether this sensor is currently isolated / quarantined
health_score: f64Health score from 0.0 (failed) to 1.0 (nominal)
consecutive_healthy: u32Consecutive healthy measurements observed while quarantined
auto_recovery_threshold: u32Threshold of consecutive healthy measurements required to auto-recover (0 to disable)
Implementations§
Source§impl SensorSource
impl SensorSource
Sourcepub fn new(
id: u8,
variance: f64,
max_anomalies: u32,
) -> Result<Self, FilterError>
pub fn new( id: u8, variance: f64, max_anomalies: u32, ) -> Result<Self, FilterError>
Creates a new sensor source configuration.
Examples found in repository?
examples/sensor_fault_fdir.rs (line 22)
10fn main() {
11 println!("===============================================================================");
12 println!(" AEGIS-FILTER :: MULTI-SENSOR FUSION & DYNAMIC FAULT ISOLATION (FDIR)");
13 println!(" Developed under Exploidus (https://github.com/Exploidus)");
14 println!("===============================================================================\n");
15
16 // Initialize fusion engine with capacity for 4 redundant sensors
17 let mut fusion =
18 MultiSensorFusion1D::<4>::new(0.0, 5.0, 0.02).expect("Failed to initialize fusion filter");
19
20 // Register sensors:
21 // Sensor 1: Barometer (Variance R = 0.3, Max 4 consecutive anomalies)
22 let baro = SensorSource::new(1, 0.3, 4).expect("Failed to create Baro config");
23 // Sensor 2: GPS Altimeter (Variance R = 1.2, Max 2 consecutive anomalies)
24 let gps = SensorSource::new(2, 1.2, 2).expect("Failed to create GPS config");
25 // Sensor 3: LiDAR Altimeter (Variance R = 0.05, Max 3 consecutive anomalies)
26 let lidar = SensorSource::new(3, 0.05, 3).expect("Failed to create LiDAR config");
27
28 fusion.register_sensor(baro).unwrap();
29 fusion.register_sensor(gps).unwrap();
30 fusion.register_sensor(lidar).unwrap();
31
32 let total_steps = 20;
33 let climb_rate = 2.0;
34
35 println!(
36 "{:<5} | {:<10} | {:<8} | {:<12} | {:<14} | {:<18}",
37 "Step", "True (m)", "Sensor", "Sensor (m)", "Fused Est (m)", "Status"
38 );
39 println!(
40 "{}-+-{}-+-{}-+-{}-+-{}-+-{}",
41 "-".repeat(5),
42 "-".repeat(10),
43 "-".repeat(8),
44 "-".repeat(12),
45 "-".repeat(14),
46 "-".repeat(18)
47 );
48
49 for step in 1..=total_steps {
50 let true_alt = (step as f64) * climb_rate;
51 fusion.predict(climb_rate).unwrap();
52
53 // 1. Barometer measurement (nominal with small noise)
54 let baro_reading = true_alt + 0.15;
55 let s1 = fusion
56 .fuse(SensorMeasurement {
57 sensor_id: 1,
58 value: baro_reading,
59 })
60 .unwrap();
61
62 println!(
63 "{:<5} | {:<10.2} | {:<8} | {:<12.2} | {:<14.2} | {:?}",
64 step,
65 true_alt,
66 "Baro",
67 baro_reading,
68 fusion.state(),
69 s1
70 );
71
72 // 2. GPS measurement (injected with an adversarial RF spoofing attack at step 8 & 9)
73 let gps_reading = if step == 8 || step == 9 {
74 true_alt + 250.0 // Spoofed spike
75 } else {
76 true_alt - 0.25
77 };
78
79 let s2 = fusion
80 .fuse(SensorMeasurement {
81 sensor_id: 2,
82 value: gps_reading,
83 })
84 .unwrap();
85
86 println!(
87 "{:<5} | {:<10.2} | {:<8} | {:<12.2} | {:<14.2} | {:?}",
88 step,
89 true_alt,
90 "GPS",
91 gps_reading,
92 fusion.state(),
93 s2
94 );
95
96 // 3. LiDAR measurement (valid only below 25m)
97 if true_alt <= 25.0 {
98 let lidar_reading = true_alt + 0.02;
99 let s3 = fusion
100 .fuse(SensorMeasurement {
101 sensor_id: 3,
102 value: lidar_reading,
103 })
104 .unwrap();
105
106 println!(
107 "{:<5} | {:<10.2} | {:<8} | {:<12.2} | {:<14.2} | {:?}",
108 step,
109 true_alt,
110 "LiDAR",
111 lidar_reading,
112 fusion.state(),
113 s3
114 );
115 }
116 }
117
118 println!("\n-------------------------------------------------------------------------------");
119 println!(" FINAL FAULT DIAGNOSTICS & SENSOR STATUS:");
120 println!(
121 " - Barometer (ID 1) Health : {:.1}% (Active)",
122 fusion.sensor_health(1).unwrap() * 100.0
123 );
124 println!(
125 " - GPS (ID 2) Health : {:.1}% (QUARANTINED)",
126 fusion.sensor_health(2).unwrap() * 100.0
127 );
128 println!(
129 " - LiDAR (ID 3) Health : {:.1}% (Active)",
130 fusion.sensor_health(3).unwrap() * 100.0
131 );
132 println!(" - Final Variance P : {:.6}", fusion.variance());
133 println!("===============================================================================");
134}Sourcepub fn with_gate_threshold(self, threshold: f64) -> Result<Self, FilterError>
pub fn with_gate_threshold(self, threshold: f64) -> Result<Self, FilterError>
Sets custom chi-square / sigma gating threshold.
Sourcepub fn with_auto_recovery(self, threshold: u32) -> Self
pub fn with_auto_recovery(self, threshold: u32) -> Self
Configures automatic recovery threshold.
Sourcepub fn reset_quarantine(&mut self)
pub fn reset_quarantine(&mut self)
Manually resets quarantine status.
Trait Implementations§
Source§impl Clone for SensorSource
impl Clone for SensorSource
impl Copy for SensorSource
Auto Trait Implementations§
impl Freeze for SensorSource
impl RefUnwindSafe for SensorSource
impl Send for SensorSource
impl Sync for SensorSource
impl Unpin for SensorSource
impl UnsafeUnpin for SensorSource
impl UnwindSafe for SensorSource
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more