operator_advisor/observation/
mod.rs

1pub mod discrete_observation;
2use crate::InternalData as Data;
3pub mod util;
4use core::fmt::Debug;
5use discrete_observation::DiscreteObservation;
6use md_continuous_observation::ContinuousObservation;
7pub mod md_continuous_observation;
8use serde::{Deserialize, Serialize};
9
10/// trait of an observation which are simple transformation of `Data` struct
11pub trait Observation {
12    /// unique identifier of the observation
13    fn to_int(&self) -> Option<usize> {
14        None
15    }
16    /// observation feature the order is: tree observation (tree_1, tree_2 ...), excavator speed, excavator angular speed, stick extension, stick angle, finger state
17    fn to_vec(&self) -> Option<Vec<f32>> {
18        None
19    }
20    /// number of trees at proximity of the operator
21    fn tree_observation(&self) -> TreeObservation;
22    fn excavator_speed_observation(&self) -> String;
23    fn excavator_speed_direction_observation(&self) -> Option<String> {
24        None
25    }
26    fn excavator_angular_speed_observation(&self) -> String;
27    fn stick_extension_observation(&self) -> String;
28    fn stick_angle_observation(&self) -> String;
29    fn finger_state_observation(&self) -> String;
30}
31
32impl Debug for dyn Observation {
33    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
34        let excavator_speed_direction =
35            if let Some(direction) = self.excavator_speed_direction_observation() {
36                direction
37            } else {
38                String::from("unavailable")
39            };
40        write!(f, "Observation {{ tree_observation: {tree_observation:?}, excavator_speed: {excavator_speed},excavator_speed_direction: {excavator_speed_direction}, excavator_angular_speed: {excavator_angular_speed} stick_extension:{stick_extension}, stick_angle: {stick_angle}, finger_state:{finger_state} }} ",
41         tree_observation = self.tree_observation(),
42         excavator_speed = self.excavator_speed_observation(),
43         excavator_speed_direction = excavator_speed_direction,
44         excavator_angular_speed = self.excavator_angular_speed_observation(),
45         stick_extension = self.stick_extension_observation(),
46         stick_angle = self.stick_angle_observation(),
47         finger_state = self.finger_state_observation()
48
49        )
50    }
51}
52
53#[derive(Debug)]
54/// type of tree observation
55pub enum TreeObservation {
56    NumberOfTreesClose(String),
57    DistanceOfTrees(Vec<String>),
58}
59
60#[derive(Clone, Deserialize, Serialize)]
61pub enum ObservationType {
62    DiscreteObservation,
63    ContinuousObservation,
64}
65
66pub fn new_observation(
67    observation_type: &ObservationType,
68    data: &[Data; 2],
69) -> Box<dyn Observation> {
70    match observation_type {
71        ObservationType::DiscreteObservation => Box::new(DiscreteObservation::new(data)),
72        ObservationType::ContinuousObservation => Box::new(ContinuousObservation::new(data)),
73    }
74}
75
76pub fn new_observation_vector(
77    data: Vec<Data>,
78    observation_type: &ObservationType,
79    n_step: usize,
80) -> Result<Vec<Box<dyn Observation>>, &'static str> {
81    if data.len() < 2 {
82        return Err("the len of data must be at least 2");
83    }
84    let mut resp: Vec<Box<dyn Observation>> = Vec::with_capacity((data.len() / 2) + 1);
85    let mut prev_data = data[0].clone();
86    let iter = data.iter().skip(1).step_by(n_step);
87    for el in iter {
88        let current_data = [prev_data, el.clone()];
89        let obs = new_observation(&observation_type, &current_data);
90        prev_data = el.clone();
91        resp.push(obs);
92    }
93    Ok(resp)
94}
95
96pub fn new_observation_feature_vector(
97    data: Vec<Data>,
98    observation_type: ObservationType,
99    n_step: usize,
100) -> Result<Vec<Vec<f32>>, &'static str> {
101    if data.len() < 2 {
102        return Err("the len of data must be at least 2");
103    } else if is_discrete(&observation_type) {
104        return Err("must be a continuous type");
105    }
106    let mut resp: Vec<Vec<f32>> = Vec::with_capacity((data.len() / 2) + 1);
107    let mut prev_data = data[0].clone();
108    let iter = data.iter().skip(1).step_by(n_step);
109    for el in iter {
110        let current_data = [prev_data, el.clone()];
111        let obs = new_observation(&observation_type, &current_data);
112        prev_data = el.clone();
113        resp.push(obs.to_vec().unwrap());
114    }
115    Ok(resp)
116}
117
118/// return the observation and the number of possible state
119pub fn new_observation_int_vector(
120    data: Vec<Data>,
121    observation_type: ObservationType,
122    n_step: usize,
123) -> Result<(Vec<usize>, usize), &'static str> {
124    if data.len() < 2 {
125        return Err("the len of data must be at least 2");
126    } else if !is_discrete(&observation_type) {
127        return Err("must be a discrete type");
128    }
129    let mut resp = Vec::with_capacity((data.len() / 2) + 1);
130    let mut prev_data = data[0].clone();
131    let iter = data.iter().skip(1).step_by(n_step);
132    for el in iter {
133        let current_data = [prev_data, el.clone()];
134        let obs = new_observation(&observation_type, &current_data);
135        prev_data = el.clone();
136        resp.push(obs.to_int().unwrap());
137    }
138    Ok((
139        resp,
140        number_possible_observation(&observation_type).unwrap(),
141    ))
142}
143
144fn is_discrete(observation_type: &ObservationType) -> bool {
145    match observation_type {
146        ObservationType::DiscreteObservation => true,
147        ObservationType::ContinuousObservation => false,
148    }
149}
150
151pub fn number_possible_observation(observation_type: &ObservationType) -> Option<usize> {
152    match observation_type {
153        ObservationType::DiscreteObservation => {
154            Some(DiscreteObservation::number_possible_observation())
155        }
156        ObservationType::ContinuousObservation => None,
157    }
158}