use std::collections::{BTreeMap, BTreeSet};
use crate::model::component::Component;
use crate::model::component::capability::{Capability, CapabilityRole};
use crate::model::connection::Connection;
use crate::model::error::ModelError;
use crate::model::identity::{
CapabilityId, ComponentInstanceId, ComponentTypeId, LinkId, RobotId, ServiceId,
};
use crate::model::robot::{
ComponentInstance, Driver, KinematicConfig, MotionLimits, Robot, Service,
};
use crate::model::simulation::{self, Simulation};
use crate::model::structure::Structure;
pub struct RobotParts {
pub id: RobotId,
pub kinematic: KinematicConfig,
pub motion_limits: MotionLimits,
pub services: BTreeMap<ServiceId, Service>,
pub components: BTreeMap<ComponentInstanceId, ComponentInstance>,
pub component_types: BTreeMap<ComponentTypeId, Component>,
pub structure: Structure,
}
pub fn structure(document: serde_json::Value) -> Result<Structure, ModelError> {
Ok(Structure::from_compiler_value(document)?)
}
#[must_use]
pub fn component(
capabilities: BTreeMap<CapabilityId, Capability>,
structure: Structure,
simulation: Option<Simulation>,
) -> Component {
Component::new(capabilities, structure, simulation)
}
#[must_use]
pub const fn service(config: Option<serde_json::Value>) -> Service {
Service::new(config)
}
#[must_use]
pub const fn driver(connection: Connection, config: Option<serde_json::Value>) -> Driver {
Driver::new(connection, config)
}
#[must_use]
pub fn simulation(
capabilities: BTreeMap<CapabilityId, simulation::Capability>,
links: BTreeMap<LinkId, Option<String>>,
) -> Simulation {
Simulation::new(capabilities, links)
}
#[must_use]
pub fn component_instance(
component_type: ComponentTypeId,
mount_link: LinkId,
direction_signs: BTreeMap<CapabilityId, i8>,
roles: BTreeMap<CapabilityId, BTreeSet<CapabilityRole>>,
driver: Option<Driver>,
) -> ComponentInstance {
ComponentInstance::new(component_type, mount_link, direction_signs, roles, driver)
}
pub fn robot(parts: RobotParts) -> Result<Robot, ModelError> {
let footprint = crate::model::footprint::compile(
&parts.structure,
&parts.components,
&parts.component_types,
)?;
Robot::new(parts, footprint)
}