zeitgeist_protocol/
precision.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
8pub struct PrecisionState {
9 pub deadband: f64,
11 pub funnel_pos: f64,
13 pub snap_imminent: bool,
15}
16
17impl PrecisionState {
18 pub const COVERING_RADIUS: f64 = 1e6;
19
20 pub fn new(deadband: f64, funnel_pos: f64, snap_imminent: bool) -> Self {
21 Self { deadband, funnel_pos, snap_imminent }
22 }
23
24 pub fn default() -> Self {
25 Self {
26 deadband: Self::COVERING_RADIUS / 2.0,
27 funnel_pos: 0.0,
28 snap_imminent: false,
29 }
30 }
31
32 pub fn check_alignment(&self) -> Vec<String> {
34 let mut violations = Vec::new();
35 if self.deadband <= 0.0 {
36 violations.push("precision.deadband must be > 0".into());
37 }
38 if self.deadband >= Self::COVERING_RADIUS {
39 violations.push("precision.deadband must be < covering_radius".into());
40 }
41 if !(0.0..=1.0).contains(&self.funnel_pos) {
42 violations.push("precision.funnel_pos must be 0-1".into());
43 }
44 violations
45 }
46
47 pub fn merge(&self, other: &Self) -> Self {
49 Self {
50 deadband: self.deadband.min(other.deadband),
51 funnel_pos: self.funnel_pos.max(other.funnel_pos),
52 snap_imminent: self.snap_imminent || other.snap_imminent,
53 }
54 }
55}