use crate::{Frame, Result};
use std::{path::Path, sync::Arc};
mod dynamics;
mod kinematics;
mod loads;
mod model;
mod topology;
mod workspace;
pub use kinematics::InverseKinematicsOptions;
pub use loads::{IndexedLoad, LoadBuffer};
use model::Model;
pub use model::RobotModel;
pub use topology::LinkId;
use workspace::Workspace;
const FLOATING_BASE_DOF: usize = 6;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(super) enum RootMode {
Fixed,
Floating,
}
#[derive(Debug)]
pub struct Robot {
model: Arc<Model>,
workspace: Workspace,
world_from_root: Frame,
}
#[derive(Debug)]
pub struct FloatingRobot {
model: Arc<Model>,
workspace: Workspace,
}
const fn base_dof_count(base_mode: RootMode) -> usize {
match base_mode {
RootMode::Fixed => 0,
RootMode::Floating => FLOATING_BASE_DOF,
}
}
fn generalized_count(model: &Model, base_mode: RootMode) -> usize {
base_dof_count(base_mode) + model.joint_count()
}
impl Robot {
pub fn from_urdf(path: impl AsRef<Path>) -> Result<Self> {
Ok(RobotModel::from_urdf(path)?.robot())
}
pub const fn base_frame(&self) -> &Frame {
&self.world_from_root
}
pub fn set_base_frame(&mut self, frame: Frame) -> Result<()> {
crate::base::validate_frame(&frame)?;
self.world_from_root = frame;
Ok(())
}
pub fn model(&self) -> RobotModel {
RobotModel {
model: Arc::clone(&self.model),
}
}
pub fn fork(&self) -> Self {
let model = Arc::clone(&self.model);
let workspace = Workspace::new(model.as_ref());
Self {
model,
workspace,
world_from_root: self.world_from_root,
}
}
pub fn generalized_count(&self) -> usize {
self.model.joint_count()
}
}
impl FloatingRobot {
pub fn from_urdf(path: impl AsRef<Path>) -> Result<Self> {
RobotModel::from_urdf(path)?.floating_robot()
}
pub fn model(&self) -> RobotModel {
RobotModel {
model: Arc::clone(&self.model),
}
}
pub fn fork(&self) -> Self {
let model = Arc::clone(&self.model);
let workspace = Workspace::new(model.as_ref());
Self { model, workspace }
}
pub fn generalized_count(&self) -> usize {
generalized_count(self.model.as_ref(), RootMode::Floating)
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests;