robokit
: The short-term goal is to build an automated machine for grid beam production.
The long-term goal is to provide a (real-time interrupt-driven) actor-based foundation for robotic automation or CNC machine control.
If you're here and like what's happening, please give this a star and say hi! 👋
no-std
environmentsalloc
for dynamic Box
's at the moment (to be extensible and ergonomic)(for Nucleo-F767ZI)
```rust
use blinky as _;
use core::task::Poll; use cortexmrt::entry; use defmt::Debug2Format; use fugit::ExtU32; use robokit::{actuators::led::LedAction, runner::Command}; use robokit::{ actuators::led::LedDevice, robot::RobotBuilder, sensors::{ switch::{SwitchDevice, SwitchStatus}, Sensor, }, timer::{setup as timersetup, tick as timertick, SubTimer, TICKTIMERHZ}, }; use stm32f7xx_hal::{pac, prelude::*};
use blinky::init_heap;
pub const TICKTIMERMAX: u32 = u32::MAX;
pub fn getruncommands() -> [Command<'static, TICKTIMERHZ>; 6] { [ Command::Led( "green", LedAction::Blink { duration: 50.millis(), }, ), Command::Led( "blue", LedAction::Blink { duration: 100.millis(), }, ), Command::Led( "red", LedAction::Blink { duration: 200.millis(), }, ), Command::Led( "red", LedAction::Blink { duration: 50.millis(), }, ), Command::Led( "blue", LedAction::Blink { duration: 100.millis(), }, ), Command::Led( "green", LedAction::Blink { duration: 200.millis(), }, ), ] }
fn main() -> ! { init_heap();
defmt::println!("Init!");
let p = pac::Peripherals::take().unwrap();
let rcc = p.RCC.constrain();
let clocks = rcc.cfgr.sysclk(216.MHz()).freeze();
let gpiob = p.GPIOB.split();
let gpioc = p.GPIOC.split();
let mut tick_timer = p.TIM5.counter_us(&clocks);
timer_setup(&mut tick_timer, TICK_TIMER_MAX).unwrap();
let user_button_pin = gpioc.pc13.into_floating_input();
let user_button_timer = SubTimer::new();
let mut user_button = SwitchDevice::new_active_high(user_button_pin, user_button_timer);
let mut robot_builder = RobotBuilder::new();
let green_led_pin = gpiob.pb0.into_push_pull_output();
let green_led_timer = SubTimer::new();
let green_led = LedDevice::new(green_led_pin, green_led_timer);
robot_builder.add_led("green", green_led).unwrap();
let blue_led_pin = gpiob.pb7.into_push_pull_output();
let blue_led_timer = SubTimer::new();
let blue_led = LedDevice::new(blue_led_pin, blue_led_timer);
robot_builder.add_led("blue", blue_led).unwrap();
let red_led_pin = gpiob.pb14.into_push_pull_output();
let red_led_timer = SubTimer::new();
let red_led = LedDevice::new(red_led_pin, red_led_timer);
robot_builder.add_led("red", red_led).unwrap();
robot_builder.set_run_commands(&get_run_commands()).unwrap();
let mut robot = robot_builder.build();
loop {
timer_tick(&mut tick_timer, TICK_TIMER_MAX).unwrap();
if let Some(user_button_update) = user_button.sense().expect("Error reading user button") {
if let SwitchStatus::On = user_button_update.status {
robot.toggle();
}
}
if let Poll::Ready(Err(err)) = robot.poll() {
defmt::println!("Unexpected error: {}", Debug2Format(&err));
robot.stop();
}
}
} ```
See docs/dev.md
Copyright 2023 Village Kit Limited
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.