geop_core_program/
values.rs1use std::collections::BTreeMap;
9
10use geop_core_math::{
11 geop_error::{GeopError, GeopResult},
12 primitives::Pose,
13 scalars::{Scalar, as_f64},
14 solvers::{least_squares::Rows, system::Variable},
15};
16use serde::{Deserialize, Serialize};
17
18#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
22#[serde(untagged)]
23pub enum Setting {
24 Number(f64),
25 Text(String),
26}
27
28pub type Settings = BTreeMap<String, Setting>;
30
31#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
34#[serde(untagged)]
35pub enum StateValue {
36 Number(#[serde(with = "as_f64")] Scalar),
37 Pose(Pose),
38}
39
40pub type StateValues = BTreeMap<String, StateValue>;
42
43impl Default for StateValue {
45 fn default() -> Self {
46 StateValue::Number(Scalar::ZERO)
47 }
48}
49
50pub fn pose_state(instance: &str) -> String {
53 format!("{instance}.pose")
54}
55
56pub fn pose_in(value: &StateValue) -> Option<Pose> {
59 match value {
60 StateValue::Pose(pose) => Some(*pose),
61 StateValue::Number(_) => None,
62 }
63}
64
65impl Variable for StateValue {
69 fn dimension(&self) -> usize {
70 match self {
71 StateValue::Number(v) => v.dimension(),
72 StateValue::Pose(pose) => pose.dimension(),
73 }
74 }
75
76 fn retract(&self, step: &[Scalar]) -> GeopResult<Self> {
77 Ok(match self {
78 StateValue::Number(v) => StateValue::Number(v.retract(step)?),
79 StateValue::Pose(pose) => StateValue::Pose(pose.retract(step)?),
80 })
81 }
82
83 fn retract_over(&self, step: &[Scalar]) -> GeopResult<Self> {
84 Ok(match self {
85 StateValue::Number(v) => StateValue::Number(v.retract_over(step)?),
86 StateValue::Pose(pose) => StateValue::Pose(pose.retract_over(step)?),
87 })
88 }
89
90 fn differential(&self, step: &[Scalar]) -> GeopResult<Option<Vec<Vec<Scalar>>>> {
91 match self {
92 StateValue::Number(v) => v.differential(step),
93 StateValue::Pose(pose) => pose.differential(step),
94 }
95 }
96
97 fn stay(&self, at: &Self, scale: Scalar) -> GeopResult<Rows> {
101 match (self, at) {
102 (StateValue::Number(v), StateValue::Number(at)) => v.stay(at, scale),
103 (StateValue::Pose(pose), StateValue::Pose(at)) => pose.stay(at, scale),
104 _ => Err(GeopError::new(format!(
105 "{self:?} cannot stay at {at:?}: they are values of different kinds"
106 ))),
107 }
108 }
109
110 fn same(&self, other: &Self) -> bool {
112 self == other
113 }
114
115 fn carried(&self, from: &Self, to: &Self) -> Option<Self> {
118 match (self, from, to) {
119 (StateValue::Pose(pose), StateValue::Pose(from), StateValue::Pose(to)) => {
120 pose.carried(from, to).map(StateValue::Pose)
121 }
122 _ => None,
123 }
124 }
125}