mecha10_sim/sim/
catalog.rs1use anyhow::Result;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::path::Path;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct EnvironmentCatalog {
10 pub version: String,
11 pub environments: Vec<Environment>,
12 #[serde(default)]
13 pub tags: HashMap<String, String>,
14 #[serde(default)]
15 pub difficulty_levels: HashMap<String, String>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct Environment {
20 pub id: String,
21 pub path: String,
22 pub name: String,
23 pub description: String,
24 pub tags: Vec<String>,
25 pub required_sensors: Vec<String>,
26 #[serde(default)]
27 pub optional_sensors: Vec<String>,
28 pub robot_platforms: Vec<String>,
29 #[serde(default)]
30 pub task_nodes: Vec<String>,
31 pub difficulty: String,
32 #[serde(default)]
33 pub dimensions: Vec<f32>,
34 #[serde(default)]
35 pub features: EnvironmentFeatures,
36 #[serde(default)]
37 pub curriculum_stage: i32,
38 #[serde(default)]
39 pub estimated_duration_s: i32,
40 #[serde(default)]
41 pub reward_config: HashMap<String, f32>,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize, Default)]
45pub struct EnvironmentFeatures {
46 #[serde(default)]
47 pub floor: bool,
48 #[serde(default)]
49 pub walls: bool,
50 #[serde(default)]
51 pub obstacles: String,
52 #[serde(default)]
53 pub obstacle_count: i32,
54 #[serde(default)]
55 pub tables: i32,
56 #[serde(default)]
57 pub waypoints: i32,
58 #[serde(default)]
59 pub goal_zones: i32,
60 #[serde(default)]
61 pub npcs: bool,
62 #[serde(default)]
63 pub npc_count: i32,
64 #[serde(default)]
65 pub dynamic: bool,
66}
67
68impl EnvironmentCatalog {
69 pub fn load_default(robot_tasks_dir: &Path) -> Result<Self> {
76 Self::load(&robot_tasks_dir.join("catalog.json"))
77 }
78
79 pub fn load(path: &Path) -> Result<Self> {
81 super::load_json(path, "catalog file")
82 }
83}
84
85impl Environment {
86 pub fn is_compatible_with_sensors(&self, sensors: &[String]) -> bool {
88 self.required_sensors.iter().all(|required| sensors.contains(required))
89 }
90
91 pub fn is_compatible_with_platform(&self, platform: &str) -> bool {
93 self.robot_platforms.contains(&platform.to_string())
94 }
95}