omega_brain/
sleep_system.rs1use crate::{BrainConfig, Result};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
8pub enum SleepStage { Awake, N1, N2, N3, REM }
9
10impl SleepStage {
11 pub fn name(&self) -> &str {
12 match self { Self::Awake => "Awake", Self::N1 => "N1", Self::N2 => "N2", Self::N3 => "N3", Self::REM => "REM" }
13 }
14}
15
16#[derive(Debug, Clone)]
18pub struct SleepController {
19 stage: SleepStage,
20 cycle_position: usize,
21 cycle_length: usize,
22 sws_ratio: f64,
23 rem_ratio: f64,
24}
25
26impl SleepController {
27 pub fn new() -> Self {
28 Self { stage: SleepStage::Awake, cycle_position: 0, cycle_length: 1000, sws_ratio: 0.6, rem_ratio: 0.25 }
29 }
30 pub fn start_sleep(&mut self) { self.stage = SleepStage::N1; self.cycle_position = 0; }
31 pub fn end_sleep(&mut self) { self.stage = SleepStage::Awake; }
32 pub fn advance(&mut self) -> SleepStage {
33 self.cycle_position += 1;
34 let p = self.cycle_position as f64 / self.cycle_length as f64;
35 self.stage = if p < 0.1 { SleepStage::N1 }
36 else if p < 0.3 { SleepStage::N2 }
37 else if p < 0.3 + self.sws_ratio * 0.5 { SleepStage::N3 }
38 else if p < 1.0 - self.rem_ratio { SleepStage::N2 }
39 else { SleepStage::REM };
40 self.stage
41 }
42 pub fn current_stage(&self) -> SleepStage { self.stage }
43 pub fn should_wake(&self) -> bool { self.cycle_position >= self.cycle_length }
44 pub fn sleep_depth(&self) -> f64 {
45 match self.stage { SleepStage::Awake => 0.0, SleepStage::N1 => 0.2, SleepStage::N2 => 0.4, SleepStage::N3 => 0.9, SleepStage::REM => 0.3 }
46 }
47}
48
49impl Default for SleepController {
50 fn default() -> Self { Self::new() }
51}
52
53#[derive(Debug, Clone)]
55pub struct CircadianRhythm {
56 phase: f64,
57}
58
59impl CircadianRhythm {
60 pub fn new() -> Self { Self { phase: 0.5 } }
61 pub fn current_phase(&self) -> f64 { self.phase }
62 pub fn advance(&mut self, hours: f64) { self.phase = (self.phase + hours / 24.0) % 1.0; }
63 pub fn should_sleep(&self) -> bool { self.phase > 0.75 || self.phase < 0.25 }
64}
65
66impl Default for CircadianRhythm {
67 fn default() -> Self { Self::new() }
68}
69
70#[derive(Debug, Clone)]
72pub struct SleepOutput {
73 pub is_sws: bool,
74 pub is_rem: bool,
75 pub replay_count: usize,
76 pub depth: f64,
77 pub stage_name: String,
78}
79
80pub struct SleepSystem {
82 controller: SleepController,
83 circadian: CircadianRhythm,
84 is_sleeping: bool,
85 cycles_completed: usize,
86}
87
88impl SleepSystem {
89 pub fn new(_config: &BrainConfig) -> Self {
90 Self { controller: SleepController::new(), circadian: CircadianRhythm::new(), is_sleeping: false, cycles_completed: 0 }
91 }
92 pub fn should_sleep(&self) -> bool { self.is_sleeping }
93 pub fn initiate_sleep(&mut self) -> Result<()> {
94 if !self.is_sleeping { self.is_sleeping = true; self.controller.start_sleep(); }
95 Ok(())
96 }
97 pub fn wake_up(&mut self) -> Result<()> {
98 if self.is_sleeping { self.is_sleeping = false; self.controller.end_sleep(); self.cycles_completed += 1; }
99 Ok(())
100 }
101 pub fn process_cycle(&mut self) -> Result<SleepOutput> {
102 if !self.is_sleeping {
103 return Ok(SleepOutput { is_sws: false, is_rem: false, replay_count: 0, depth: 0.0, stage_name: "Awake".to_string() });
104 }
105 let stage = self.controller.advance();
106 let (is_sws, is_rem, replay_count, depth) = match stage {
107 SleepStage::N1 => (false, false, 0, 0.2),
108 SleepStage::N2 => (false, false, 5, 0.4),
109 SleepStage::N3 => (true, false, 20, 0.9),
110 SleepStage::REM => (false, true, 10, 0.3),
111 SleepStage::Awake => (false, false, 0, 0.0),
112 };
113 if self.controller.should_wake() { self.wake_up()?; }
114 Ok(SleepOutput { is_sws, is_rem, replay_count, depth, stage_name: stage.name().to_string() })
115 }
116 pub fn current_stage_name(&self) -> Option<String> {
117 if self.is_sleeping { Some(self.controller.current_stage().name().to_string()) } else { None }
118 }
119 pub fn is_rem(&self) -> bool { self.is_sleeping && self.controller.current_stage() == SleepStage::REM }
120 pub fn is_sws(&self) -> bool { self.is_sleeping && self.controller.current_stage() == SleepStage::N3 }
121 pub fn sleep_depth(&self) -> f64 { if !self.is_sleeping { 0.0 } else { self.controller.sleep_depth() } }
122 pub fn cycles_completed(&self) -> usize { self.cycles_completed }
123 pub fn circadian_phase(&self) -> f64 { self.circadian.current_phase() }
124 pub fn update_circadian(&mut self, hours: f64) { self.circadian.advance(hours); }
125 pub fn circadian_suggests_sleep(&self) -> bool { self.circadian.should_sleep() }
126 pub fn reset(&mut self) {
127 self.controller = SleepController::new();
128 self.circadian = CircadianRhythm::new();
129 self.is_sleeping = false;
130 self.cycles_completed = 0;
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137 #[test]
138 fn test_sleep_controller() {
139 let mut ctrl = SleepController::new();
140 ctrl.start_sleep();
141 assert_eq!(ctrl.current_stage(), SleepStage::N1);
142 }
143}