mecha10-sim 0.8.0

Mecha10 simulation support — scene generation, asset management
Documentation
//! Environment catalog loading and management

use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::Path;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnvironmentCatalog {
    pub version: String,
    pub environments: Vec<Environment>,
    #[serde(default)]
    pub tags: HashMap<String, String>,
    #[serde(default)]
    pub difficulty_levels: HashMap<String, String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Environment {
    pub id: String,
    pub path: String,
    pub name: String,
    pub description: String,
    pub tags: Vec<String>,
    pub required_sensors: Vec<String>,
    #[serde(default)]
    pub optional_sensors: Vec<String>,
    pub robot_platforms: Vec<String>,
    #[serde(default)]
    pub task_nodes: Vec<String>,
    pub difficulty: String,
    #[serde(default)]
    pub dimensions: Vec<f32>,
    #[serde(default)]
    pub features: EnvironmentFeatures,
    #[serde(default)]
    pub curriculum_stage: i32,
    #[serde(default)]
    pub estimated_duration_s: i32,
    #[serde(default)]
    pub reward_config: HashMap<String, f32>,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct EnvironmentFeatures {
    #[serde(default)]
    pub floor: bool,
    #[serde(default)]
    pub walls: bool,
    #[serde(default)]
    pub obstacles: String,
    #[serde(default)]
    pub obstacle_count: i32,
    #[serde(default)]
    pub tables: i32,
    #[serde(default)]
    pub waypoints: i32,
    #[serde(default)]
    pub goal_zones: i32,
    #[serde(default)]
    pub npcs: bool,
    #[serde(default)]
    pub npc_count: i32,
    #[serde(default)]
    pub dynamic: bool,
}

impl EnvironmentCatalog {
    /// Load the catalog from `<robot_tasks_dir>/catalog.json`, under a freshly-fetched
    /// `mecha10-assets` extraction (`configs/simulation/environments/robot-tasks`). The caller
    /// is responsible for fetching/extracting the assets tarball (see
    /// `EnvironmentSelector::new`) - this no longer falls back to any bundled-in-the-monorepo
    /// copy, since `mecha10-templates/templates/configs/simulation/...` was deleted when the
    /// framework cut over to fetching published `mecha10-assets` content live.
    pub fn load_default(robot_tasks_dir: &Path) -> Result<Self> {
        Self::load(&robot_tasks_dir.join("catalog.json"))
    }

    /// Load catalog from specific path
    pub fn load(path: &Path) -> Result<Self> {
        super::load_json(path, "catalog file")
    }
}

impl Environment {
    /// Check if environment is compatible with robot (has all required sensors)
    pub fn is_compatible_with_sensors(&self, sensors: &[String]) -> bool {
        self.required_sensors.iter().all(|required| sensors.contains(required))
    }

    /// Check if environment is compatible with platform
    pub fn is_compatible_with_platform(&self, platform: &str) -> bool {
        self.robot_platforms.contains(&platform.to_string())
    }
}