mecha10_nodes_object_detector/
config.rs1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct ObjectDetectorConfig {
9 #[serde(default = "default_model_path")]
11 pub model_path: String,
12
13 #[serde(default = "default_model_name")]
15 pub model_name: String,
16
17 #[serde(default = "default_input_size")]
19 pub input_size: u32,
20
21 #[serde(default = "default_confidence_threshold")]
23 pub confidence_threshold: f32,
24
25 #[serde(default = "default_iou_threshold")]
27 pub iou_threshold: f32,
28
29 #[serde(default = "default_max_detections")]
31 pub max_detections: usize,
32
33 #[serde(default = "default_frame_skip")]
35 pub frame_skip: u32,
36
37 #[serde(default = "default_enabled")]
39 pub default_enabled: bool,
40
41 #[serde(default = "default_use_int8")]
43 pub use_int8: bool,
44
45 #[serde(default = "default_max_async_frames")]
47 pub max_async_frames: usize,
48
49 #[serde(default)]
51 pub topics: Topics,
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct Topics {
57 #[serde(default)]
60 pub publishes: Vec<HashMap<String, String>>,
61
62 #[serde(default)]
65 pub subscribes: Vec<HashMap<String, String>>,
66}
67
68impl Default for Topics {
69 fn default() -> Self {
70 let mut publishes = Vec::new();
71 let mut subscribes = Vec::new();
72
73 let mut pub_map = HashMap::new();
75 pub_map.insert("output".to_string(), "/vision/object/detections".to_string());
76 publishes.push(pub_map);
77
78 let mut input_map = HashMap::new();
80 input_map.insert("input".to_string(), "/camera/rgb".to_string());
81 subscribes.push(input_map);
82
83 let mut control_map = HashMap::new();
84 control_map.insert("control".to_string(), "/vision/object/control".to_string());
85 subscribes.push(control_map);
86
87 Self { publishes, subscribes }
88 }
89}
90
91impl ObjectDetectorConfig {
92 pub fn input_topic(&self) -> String {
94 self.topics
95 .subscribes
96 .iter()
97 .find_map(|t| t.get("input"))
98 .cloned()
99 .unwrap_or_else(|| "/camera/rgb".to_string())
100 }
101
102 pub fn output_topic(&self) -> String {
104 self.topics
105 .publishes
106 .iter()
107 .find_map(|t| t.get("output"))
108 .cloned()
109 .unwrap_or_else(|| "/vision/object/detections".to_string())
110 }
111
112 pub fn control_topic(&self) -> String {
114 self.topics
115 .subscribes
116 .iter()
117 .find_map(|t| t.get("control"))
118 .cloned()
119 .unwrap_or_else(|| "/vision/object/control".to_string())
120 }
121}
122
123fn default_model_path() -> String {
124 "models/yolov8n/model.onnx".to_string()
125}
126
127fn default_model_name() -> String {
128 "yolov8n".to_string()
129}
130
131fn default_input_size() -> u32 {
132 640
133}
134
135fn default_confidence_threshold() -> f32 {
136 0.5
137}
138
139fn default_iou_threshold() -> f32 {
140 0.45
141}
142
143fn default_max_detections() -> usize {
144 100
145}
146
147fn default_frame_skip() -> u32 {
148 1
149}
150
151fn default_enabled() -> bool {
152 false
153}
154
155fn default_use_int8() -> bool {
156 false
157}
158
159fn default_max_async_frames() -> usize {
160 1
161}
162
163impl Default for ObjectDetectorConfig {
164 fn default() -> Self {
165 Self {
166 model_path: default_model_path(),
167 model_name: default_model_name(),
168 input_size: default_input_size(),
169 confidence_threshold: default_confidence_threshold(),
170 iou_threshold: default_iou_threshold(),
171 max_detections: default_max_detections(),
172 frame_skip: default_frame_skip(),
173 default_enabled: default_enabled(),
174 use_int8: default_use_int8(),
175 max_async_frames: default_max_async_frames(),
176 topics: Topics::default(),
177 }
178 }
179}