Renames RobotNode to Dixon and adds Rustylee core
Refactors the existing `RobotNode` module by renaming its directory and associated files to `Dixon`. This consolidates the core C++ robot node under a new name. Introduces the initial `rustylee` module, establishing a foundational structure for the robot's brain. This new Rust component includes: - A state machine (Starting, Running, Stopping, Stopped) to manage the brain's operational lifecycle. - Graceful shutdown capabilities using a `ctrlc` signal handler. - A main watchdog loop that orchestrates state transitions and responds to shutdown requests.
This commit is contained in:
parent
d452578afc
commit
2f0cb6e359
22 changed files with 198 additions and 4 deletions
1
src/Dixon/version.txt
Normal file
1
src/Dixon/version.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
1.0.70
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
1.0.67
|
|
||||||
101
src/rustylee/Cargo.lock
generated
101
src/rustylee/Cargo.lock
generated
|
|
@ -2,6 +2,107 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block2"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
|
||||||
|
dependencies = [
|
||||||
|
"objc2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg_aliases"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ctrlc"
|
||||||
|
version = "3.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162"
|
||||||
|
dependencies = [
|
||||||
|
"dispatch2",
|
||||||
|
"nix",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dispatch2"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"block2",
|
||||||
|
"libc",
|
||||||
|
"objc2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.180"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "225e7cfe711e0ba79a68baeddb2982723e4235247aefce1482f2f16c27865b66"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if",
|
||||||
|
"cfg_aliases",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05"
|
||||||
|
dependencies = [
|
||||||
|
"objc2-encode",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-encode"
|
||||||
|
version = "4.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustylee"
|
name = "rustylee"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"ctrlc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.61.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,4 @@ version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
ctrlc = "3.5.2"
|
||||||
|
|
|
||||||
45
src/rustylee/src/brain/mod.rs
Normal file
45
src/rustylee/src/brain/mod.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
//src/brain/mod.rs
|
||||||
|
pub mod state;
|
||||||
|
pub use self::state::State;
|
||||||
|
use std::thread::{self, JoinHandle};
|
||||||
|
|
||||||
|
|
||||||
|
pub struct Brain {
|
||||||
|
pub state: State,
|
||||||
|
device_threads: Vec<JoinHandle<()>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Brain {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state: State::Starting,
|
||||||
|
device_threads: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn request_shutdown(&mut self) {
|
||||||
|
if self.state == State::Running {
|
||||||
|
self.state = State::Stopping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self) {
|
||||||
|
match self.state {
|
||||||
|
State::Starting => {
|
||||||
|
// For now, we just instantly transition
|
||||||
|
self.state = State::Running;
|
||||||
|
}
|
||||||
|
State::Running => {
|
||||||
|
// Logic will go here eventually
|
||||||
|
}
|
||||||
|
State::Stopping => {
|
||||||
|
println!("Brain: Waiting for all threads to join...");
|
||||||
|
while let Some(handle) = self.device_threads.pop() {
|
||||||
|
let _ = handle.join();
|
||||||
|
}
|
||||||
|
self.state = State::Stopped;
|
||||||
|
}
|
||||||
|
State::Stopped => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/rustylee/src/brain/state.rs
Normal file
8
src/rustylee/src/brain/state.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
//src/brain/state.rs
|
||||||
|
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||||
|
pub enum State {
|
||||||
|
Starting,
|
||||||
|
Running,
|
||||||
|
Stopping,
|
||||||
|
Stopped,
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,42 @@
|
||||||
|
mod brain;
|
||||||
|
use brain::{Brain, State};
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::mpsc::{self, Receiver, Sender};
|
||||||
|
use std::{thread, time::Duration};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
// We wrap the Brain in an Arc + Mutex so the Signal Handler can access it
|
||||||
|
// though for simple flag-setting, an Atomic works too.
|
||||||
|
// Here we'll use a simple shared flag to tell the Brain to stop.
|
||||||
|
let shutdown_requested = Arc::new(AtomicBool::new(false));
|
||||||
|
let s = shutdown_requested.clone();
|
||||||
|
|
||||||
|
// 1. Signal Handling
|
||||||
|
// By default, in Rust/Unix, signals are delivered to the process.
|
||||||
|
// Setting the handler here ensures the main thread catches it.
|
||||||
|
ctrlc::set_handler(move || {
|
||||||
|
println!("\n[Signal] Shutdown signal caught!");
|
||||||
|
s.store(true, Ordering::SeqCst);
|
||||||
|
}).expect("Error setting signal handler");
|
||||||
|
|
||||||
|
let mut robot_brain = Brain::new();
|
||||||
|
|
||||||
|
// 2. The Watchdog Loop
|
||||||
|
// This loop runs until the Brain reaches the terminal 'Stopped' state
|
||||||
|
while robot_brain.state != State::Stopped {
|
||||||
|
|
||||||
|
// If the signal handler tripped the flag, tell the brain to stop
|
||||||
|
if shutdown_requested.load(Ordering::SeqCst) && robot_brain.state == State::Running {
|
||||||
|
robot_brain.request_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run one "tick" of brain logic
|
||||||
|
robot_brain.update();
|
||||||
|
|
||||||
|
println!("Main Loop: I'm alive! State: {:?}", robot_brain.state);
|
||||||
|
thread::sleep(Duration::from_millis(500));
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Main Loop: Brain has Stopped. Exiting cleanly.");
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
LOCAL_BIN="$HOME/dev/Dixon/src/RobotNode/cmake-build-pi5-debug/dixon"
|
LOCAL_BIN="$HOME/dev/Dixon/src/Dixon/cmake-build-pi5-debug/dixon"
|
||||||
REMOTE_TARGET="russellg59@dixon1"
|
REMOTE_TARGET="russellg59@dixon1"
|
||||||
REMOTE_DIR="/home/russellg59/dixon"
|
REMOTE_DIR="/home/russellg59/dixon"
|
||||||
REMOTE_EXE="$REMOTE_DIR/dixon"
|
REMOTE_EXE="$REMOTE_DIR/dixon"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue