ruvector_robotics/perception/
config.rs1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14pub struct SceneGraphConfig {
15 pub cluster_radius: f64,
18 pub min_cluster_size: usize,
20 pub max_objects: usize,
22 pub edge_distance_threshold: f64,
25}
26
27impl Default for SceneGraphConfig {
28 fn default() -> Self {
29 Self {
30 cluster_radius: 0.5,
31 min_cluster_size: 3,
32 max_objects: 256,
33 edge_distance_threshold: 5.0,
34 }
35 }
36}
37
38#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
44pub struct ObstacleConfig {
45 pub min_obstacle_size: usize,
48 pub max_detection_range: f64,
51 pub safety_margin: f64,
53}
54
55impl Default for ObstacleConfig {
56 fn default() -> Self {
57 Self {
58 min_obstacle_size: 3,
59 max_detection_range: 20.0,
60 safety_margin: 0.2,
61 }
62 }
63}
64
65#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
71pub struct PerceptionConfig {
72 pub scene_graph: SceneGraphConfig,
73 pub obstacle: ObstacleConfig,
74}
75
76#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn test_scene_graph_config_defaults() {
86 let cfg = SceneGraphConfig::default();
87 assert!((cfg.cluster_radius - 0.5).abs() < f64::EPSILON);
88 assert_eq!(cfg.min_cluster_size, 3);
89 assert_eq!(cfg.max_objects, 256);
90 assert!((cfg.edge_distance_threshold - 5.0).abs() < f64::EPSILON);
91 }
92
93 #[test]
94 fn test_obstacle_config_defaults() {
95 let cfg = ObstacleConfig::default();
96 assert_eq!(cfg.min_obstacle_size, 3);
97 assert!((cfg.max_detection_range - 20.0).abs() < f64::EPSILON);
98 assert!((cfg.safety_margin - 0.2).abs() < f64::EPSILON);
99 }
100
101 #[test]
102 fn test_perception_config_defaults() {
103 let cfg = PerceptionConfig::default();
104 assert_eq!(cfg.scene_graph, SceneGraphConfig::default());
105 assert_eq!(cfg.obstacle, ObstacleConfig::default());
106 }
107
108 #[test]
109 fn test_scene_graph_config_serde_roundtrip() {
110 let cfg = SceneGraphConfig {
111 cluster_radius: 1.0,
112 min_cluster_size: 5,
113 max_objects: 128,
114 edge_distance_threshold: 3.0,
115 };
116 let json = serde_json::to_string(&cfg).unwrap();
117 let restored: SceneGraphConfig = serde_json::from_str(&json).unwrap();
118 assert_eq!(cfg, restored);
119 }
120
121 #[test]
122 fn test_obstacle_config_serde_roundtrip() {
123 let cfg = ObstacleConfig {
124 min_obstacle_size: 10,
125 max_detection_range: 50.0,
126 safety_margin: 0.5,
127 };
128 let json = serde_json::to_string(&cfg).unwrap();
129 let restored: ObstacleConfig = serde_json::from_str(&json).unwrap();
130 assert_eq!(cfg, restored);
131 }
132
133 #[test]
134 fn test_perception_config_serde_roundtrip() {
135 let cfg = PerceptionConfig::default();
136 let json = serde_json::to_string_pretty(&cfg).unwrap();
137 let restored: PerceptionConfig = serde_json::from_str(&json).unwrap();
138 assert_eq!(cfg, restored);
139 }
140
141 #[test]
142 fn test_config_clone_equality() {
143 let a = PerceptionConfig::default();
144 let b = a.clone();
145 assert_eq!(a, b);
146 }
147
148 #[test]
149 fn test_config_debug_format() {
150 let cfg = PerceptionConfig::default();
151 let dbg = format!("{:?}", cfg);
152 assert!(dbg.contains("PerceptionConfig"));
153 assert!(dbg.contains("SceneGraphConfig"));
154 assert!(dbg.contains("ObstacleConfig"));
155 }
156
157 #[test]
158 fn test_custom_perception_config() {
159 let cfg = PerceptionConfig {
160 scene_graph: SceneGraphConfig {
161 cluster_radius: 2.0,
162 min_cluster_size: 10,
163 max_objects: 64,
164 edge_distance_threshold: 10.0,
165 },
166 obstacle: ObstacleConfig {
167 min_obstacle_size: 5,
168 max_detection_range: 100.0,
169 safety_margin: 1.0,
170 },
171 };
172 assert!((cfg.scene_graph.cluster_radius - 2.0).abs() < f64::EPSILON);
173 assert_eq!(cfg.obstacle.min_obstacle_size, 5);
174 }
175}