Ehu shubham shaw contribution --> Hardware support (#306)
* feat: add ZeroClaw firmware for ESP32 and Nucleo * Introduced new firmware for ZeroClaw on ESP32 and Nucleo-F401RE, enabling JSON-over-serial communication for GPIO control. * Added `zeroclaw-esp32` with support for commands like `gpio_read` and `gpio_write`, along with capabilities reporting. * Implemented `zeroclaw-nucleo` firmware with similar functionality for STM32, ensuring compatibility with existing ZeroClaw protocols. * Updated `.gitignore` to include new firmware targets and added necessary dependencies in `Cargo.toml` for both platforms. * Created README files for both firmware projects detailing setup, build, and usage instructions. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * feat: enhance hardware peripheral support and documentation - Added `Peripheral` trait implementation in `src/peripherals/` to manage hardware boards (STM32, RPi GPIO). - Updated `AGENTS.md` to include new extension points for peripherals and their configuration. - Introduced comprehensive documentation for adding boards and tools, including a quick start guide and supported boards. - Enhanced `Cargo.toml` to include optional dependencies for PDF extraction and peripheral support. - Created new datasheets for Arduino Uno, ESP32, and Nucleo-F401RE, detailing pin aliases and GPIO usage. - Implemented new tools for hardware memory reading and board information retrieval in the agent loop. This update significantly improves the integration and usability of hardware peripherals within the ZeroClaw framework. * feat: add ZeroClaw firmware for ESP32 and Nucleo * Introduced new firmware for ZeroClaw on ESP32 and Nucleo-F401RE, enabling JSON-over-serial communication for GPIO control. * Added `zeroclaw-esp32` with support for commands like `gpio_read` and `gpio_write`, along with capabilities reporting. * Implemented `zeroclaw-nucleo` firmware with similar functionality for STM32, ensuring compatibility with existing ZeroClaw protocols. * Updated `.gitignore` to include new firmware targets and added necessary dependencies in `Cargo.toml` for both platforms. * Created README files for both firmware projects detailing setup, build, and usage instructions. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * feat: enhance hardware peripheral support and documentation - Added `Peripheral` trait implementation in `src/peripherals/` to manage hardware boards (STM32, RPi GPIO). - Updated `AGENTS.md` to include new extension points for peripherals and their configuration. - Introduced comprehensive documentation for adding boards and tools, including a quick start guide and supported boards. - Enhanced `Cargo.toml` to include optional dependencies for PDF extraction and peripheral support. - Created new datasheets for Arduino Uno, ESP32, and Nucleo-F401RE, detailing pin aliases and GPIO usage. - Implemented new tools for hardware memory reading and board information retrieval in the agent loop. This update significantly improves the integration and usability of hardware peripherals within the ZeroClaw framework. * feat: Introduce hardware auto-discovery and expanded configuration options for agents, hardware, and security. * chore: update dependencies and improve probe-rs integration - Updated `Cargo.lock` to remove specific version constraints for several dependencies, including `zerocopy`, `syn`, and `strsim`, allowing for more flexibility in version resolution. - Upgraded `bincode` and `bitfield` to their latest versions, enhancing serialization and memory management capabilities. - Updated `Cargo.toml` to reflect the new version of `probe-rs` from `0.24` to `0.30`, improving hardware probing functionality. - Refactored code in `src/hardware` and `src/tools` to utilize the new `SessionConfig` for session management in `probe-rs`, ensuring better compatibility and performance. - Cleaned up documentation in `docs/datasheets/nucleo-f401re.md` by removing unnecessary lines. * fix: apply cargo fmt * docs: add hardware architecture diagram. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b36f23784a
commit
de3ec87d16
59 changed files with 9607 additions and 1885 deletions
143
src/peripherals/uno_q_setup.rs
Normal file
143
src/peripherals/uno_q_setup.rs
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
//! Deploy ZeroClaw Bridge app to Arduino Uno Q.
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use std::process::Command;
|
||||
|
||||
const BRIDGE_APP_NAME: &str = "zeroclaw-uno-q-bridge";
|
||||
|
||||
/// Deploy the Bridge app. If host is Some, scp from repo and ssh to start.
|
||||
/// If host is None, assume we're ON the Uno Q — use embedded files and start.
|
||||
pub fn setup_uno_q_bridge(host: Option<&str>) -> Result<()> {
|
||||
let bridge_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("firmware")
|
||||
.join("zeroclaw-uno-q-bridge");
|
||||
|
||||
if let Some(h) = host {
|
||||
if bridge_dir.exists() {
|
||||
deploy_remote(h, &bridge_dir)?;
|
||||
} else {
|
||||
anyhow::bail!(
|
||||
"Bridge app not found at {}. Run from zeroclaw repo root.",
|
||||
bridge_dir.display()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
deploy_local(if bridge_dir.exists() {
|
||||
Some(&bridge_dir)
|
||||
} else {
|
||||
None
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deploy_remote(host: &str, bridge_dir: &std::path::Path) -> Result<()> {
|
||||
let ssh_target = if host.contains('@') {
|
||||
host.to_string()
|
||||
} else {
|
||||
format!("arduino@{}", host)
|
||||
};
|
||||
|
||||
println!("Copying Bridge app to {}...", host);
|
||||
let status = Command::new("ssh")
|
||||
.args([&ssh_target, "mkdir", "-p", "~/ArduinoApps"])
|
||||
.status()
|
||||
.context("ssh mkdir failed")?;
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to create ArduinoApps dir on Uno Q");
|
||||
}
|
||||
|
||||
let status = Command::new("scp")
|
||||
.args([
|
||||
"-r",
|
||||
bridge_dir.to_str().unwrap(),
|
||||
&format!("{}:~/ArduinoApps/", ssh_target),
|
||||
])
|
||||
.status()
|
||||
.context("scp failed")?;
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to copy Bridge app");
|
||||
}
|
||||
|
||||
println!("Starting Bridge app on Uno Q...");
|
||||
let status = Command::new("ssh")
|
||||
.args([
|
||||
&ssh_target,
|
||||
"arduino-app-cli",
|
||||
"app",
|
||||
"start",
|
||||
&format!("~/ArduinoApps/zeroclaw-uno-q-bridge"),
|
||||
])
|
||||
.status()
|
||||
.context("arduino-app-cli start failed")?;
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to start Bridge app. Ensure arduino-app-cli is installed on Uno Q.");
|
||||
}
|
||||
|
||||
println!("ZeroClaw Bridge app started. Add to config.toml:");
|
||||
println!(" [[peripherals.boards]]");
|
||||
println!(" board = \"arduino-uno-q\"");
|
||||
println!(" transport = \"bridge\"");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deploy_local(bridge_dir: Option<&std::path::Path>) -> Result<()> {
|
||||
let home = std::env::var("HOME").unwrap_or_else(|_| "/home/arduino".into());
|
||||
let apps_dir = std::path::Path::new(&home).join("ArduinoApps");
|
||||
let dest_dir = apps_dir.join(BRIDGE_APP_NAME);
|
||||
|
||||
std::fs::create_dir_all(&dest_dir).context("create dest dir")?;
|
||||
|
||||
if let Some(src) = bridge_dir {
|
||||
println!("Copying Bridge app from repo...");
|
||||
copy_dir(src, &dest_dir)?;
|
||||
} else {
|
||||
println!("Writing embedded Bridge app...");
|
||||
write_embedded_bridge(&dest_dir)?;
|
||||
}
|
||||
|
||||
println!("Starting Bridge app...");
|
||||
let status = Command::new("arduino-app-cli")
|
||||
.args(["app", "start", dest_dir.to_str().unwrap()])
|
||||
.status()
|
||||
.context("arduino-app-cli start failed")?;
|
||||
if !status.success() {
|
||||
anyhow::bail!("Failed to start Bridge app. Ensure arduino-app-cli is installed on Uno Q.");
|
||||
}
|
||||
|
||||
println!("ZeroClaw Bridge app started.");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_embedded_bridge(dest: &std::path::Path) -> Result<()> {
|
||||
let app_yaml = include_str!("../../firmware/zeroclaw-uno-q-bridge/app.yaml");
|
||||
let sketch_ino = include_str!("../../firmware/zeroclaw-uno-q-bridge/sketch/sketch.ino");
|
||||
let sketch_yaml = include_str!("../../firmware/zeroclaw-uno-q-bridge/sketch/sketch.yaml");
|
||||
let main_py = include_str!("../../firmware/zeroclaw-uno-q-bridge/python/main.py");
|
||||
let requirements = include_str!("../../firmware/zeroclaw-uno-q-bridge/python/requirements.txt");
|
||||
|
||||
std::fs::write(dest.join("app.yaml"), app_yaml)?;
|
||||
std::fs::create_dir_all(dest.join("sketch"))?;
|
||||
std::fs::write(dest.join("sketch").join("sketch.ino"), sketch_ino)?;
|
||||
std::fs::write(dest.join("sketch").join("sketch.yaml"), sketch_yaml)?;
|
||||
std::fs::create_dir_all(dest.join("python"))?;
|
||||
std::fs::write(dest.join("python").join("main.py"), main_py)?;
|
||||
std::fs::write(dest.join("python").join("requirements.txt"), requirements)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_dir(src: &std::path::Path, dst: &std::path::Path) -> Result<()> {
|
||||
for entry in std::fs::read_dir(src)? {
|
||||
let e = entry?;
|
||||
let name = e.file_name();
|
||||
let src_path = src.join(&name);
|
||||
let dst_path = dst.join(&name);
|
||||
if e.file_type()?.is_dir() {
|
||||
std::fs::create_dir_all(&dst_path)?;
|
||||
copy_dir(&src_path, &dst_path)?;
|
||||
} else {
|
||||
std::fs::copy(&src_path, &dst_path)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue