Skip to main content

feagi_agent/sdk/motor/perception/
config.rs

1//! Perception decoder configuration.
2
3use crate::core::{AgentConfig, AgentType, SdkError};
4use crate::sdk::types::{
5    CorticalID, CorticalSubUnitIndex, CorticalUnitIndex, FrameChangeHandling,
6    IOCorticalAreaConfigurationFlag, MotorCorticalUnit,
7};
8use feagi_io::{MotorUnit, MotorUnitSpec};
9
10/// Configuration for the perception decoder.
11#[derive(Debug, Clone)]
12pub struct PerceptionDecoderConfig {
13    pub agent_id: String,
14    pub cortical_unit_id: u8,
15    pub feagi_host: String,
16    pub feagi_api_port: u16,
17    pub feagi_zmq_registration_port: u16,
18    pub feagi_zmq_agent_sensory_port: u16,
19    pub feagi_zmq_motor_port: u16,
20    pub feagi_heartbeat_interval_s: f64,
21    pub feagi_connection_timeout_ms: u64,
22    pub feagi_registration_retries: u32,
23    pub feagi_motor_poll_interval_s: f64,
24}
25
26impl PerceptionDecoderConfig {
27    /// Build an AgentConfig for this perception decoder.
28    pub fn to_agent_config(&self) -> Result<AgentConfig, SdkError> {
29        let registration_endpoint = format!(
30            "tcp://{}:{}",
31            self.feagi_host, self.feagi_zmq_registration_port
32        );
33        let sensory_endpoint = format!(
34            "tcp://{}:{}",
35            self.feagi_host, self.feagi_zmq_agent_sensory_port
36        );
37        let motor_endpoint = format!("tcp://{}:{}", self.feagi_host, self.feagi_zmq_motor_port);
38
39        let agent_type = AgentType::Motor;
40        let group = self.cortical_unit_id;
41        let motor_units = vec![
42            MotorUnitSpec {
43                unit: MotorUnit::ObjectSegmentation,
44                group,
45            },
46            MotorUnitSpec {
47                unit: MotorUnit::SimpleVisionOutput,
48                group,
49            },
50            MotorUnitSpec {
51                unit: MotorUnit::TextEnglishOutput,
52                group,
53            },
54        ];
55        let output_count = 1;
56
57        Ok(AgentConfig::new(self.agent_id.clone(), agent_type)
58            .with_motor_units("perception", output_count, motor_units)
59            .with_registration_endpoint(registration_endpoint)
60            .with_sensory_endpoint(sensory_endpoint)
61            .with_motor_endpoint(motor_endpoint)
62            .with_heartbeat_interval(self.feagi_heartbeat_interval_s)
63            .with_connection_timeout_ms(self.feagi_connection_timeout_ms)
64            .with_registration_retries(self.feagi_registration_retries))
65    }
66
67    /// Returns the cortical IDs used by this decoder (oseg, oimg, oten).
68    pub fn cortical_ids(&self) -> Vec<CorticalID> {
69        let unit = CorticalUnitIndex::from(self.cortical_unit_id);
70        let frame = FrameChangeHandling::Absolute;
71
72        let oseg =
73            MotorCorticalUnit::get_cortical_ids_array_for_object_segmentation_with_parameters(
74                frame, unit,
75            )
76            .first()
77            .copied();
78
79        let oimg =
80            MotorCorticalUnit::get_cortical_ids_array_for_simple_vision_output_with_parameters(
81                frame, unit,
82            )
83            .first()
84            .copied();
85
86        let oten =
87            MotorCorticalUnit::get_cortical_ids_array_for_text_english_output_with_parameters(
88                frame, unit,
89            )
90            .first()
91            .copied();
92
93        [oseg, oimg, oten].into_iter().flatten().collect()
94    }
95
96    /// Returns the cortical ID for OTEN output.
97    pub fn oten_cortical_id(&self) -> CorticalID {
98        IOCorticalAreaConfigurationFlag::Misc(FrameChangeHandling::Absolute).as_io_cortical_id(
99            false,
100            *b"ten",
101            CorticalUnitIndex::from(self.cortical_unit_id),
102            CorticalSubUnitIndex::from(0u8),
103        )
104    }
105}