3个版本 (破坏性更新)
0.3.0 | 2023年4月19日 |
---|---|
0.2.0 | 2023年4月5日 |
0.1.0 | 2023年4月4日 |
#521 in 嵌入式开发
89KB
2.5K SLoC
Robo Kit 🤖
为简单的机器人自动化构建自定义固件
模块
robokit
:
固件
关于
短期目标是构建 用于网格梁生产的自动化机器。
长期目标是提供机器人自动化或CNC机床控制的基础(实时中断驱动)基于actor的。
如果你在这里并且喜欢正在发生的事情,请给它一个星并 打招呼! 👋
特性
- 最小化
- 为
无std
环境设计
- 为
- 可扩展
- 使用你自己的执行器和自定义名称设置你的机器人
- 例如,不仅限于x,y,z线性轴
- 使用你自己的执行器和自定义名称设置你的机器人
- 命令系统(如G-Code)
- 运行一系列命令(一次一个)
- 在开始时运行设置命令和在结束时运行拆卸命令(并行)
- 执行器
- LED
- 动作
- 设置 { is_on }
- 闪烁 { duration }
- 动作
- 线性轴
- 驱动器:步进
- 动作
- MoveRelative { max_acceleration, distance }
- MoveAbsolute { max_acceleration, position }
- Home { max_acceleration, back_off_distance }
- 主轴
- 驱动器
- JmcHsv57
- 动作
- Set(On { rpm })
- Set(Off)
- 驱动器
- 继电器(气动执行器)
- LED
- 传感器
- 输入开关
- 按钮
- 限位开关
- 旋转编码器
- 线性编码器
- 输入开关
- 接口
- 物理控制
- JSON-RPC
- Web
示例
(用于 Nucleo-F767ZI)
#![no_main]
#![no_std]
use blinky as _;
use core::task::Poll;
use cortex_m_rt::entry;
use defmt::Debug2Format;
use fugit::ExtU32;
use robokit::{
actuator_set, Command, LedAction, LedDevice, RobotBuilder, Sensor, SuperTimer, SwitchDevice,
SwitchStatus,
};
use stm32f7xx_hal::{pac, prelude::*};
use blinky::init_heap;
const TICK_TIMER_HZ: u32 = 1_000_000;
const ACTIVE_COMMANDS_COUNT: usize = 1;
actuator_set!(
Led { Green, Blue, Red },
LedAction<TICK_TIMER_HZ>,
LedId,
LedSet,
LedSetError
);
fn get_run_commands<const TIMER_HZ: u32>() -> [Command<TIMER_HZ, LedId, (), ()>; 6] {
[
Command::Led(
LedId::Green,
LedAction::Blink {
duration: 50.millis(),
},
),
Command::Led(
LedId::Blue,
LedAction::Blink {
duration: 100.millis(),
},
),
Command::Led(
LedId::Red,
LedAction::Blink {
duration: 200.millis(),
},
),
Command::Led(
LedId::Red,
LedAction::Blink {
duration: 50.millis(),
},
),
Command::Led(
LedId::Blue,
LedAction::Blink {
duration: 100.millis(),
},
),
Command::Led(
LedId::Green,
LedAction::Blink {
duration: 200.millis(),
},
),
]
}
#[entry]
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 tick_timer = p.TIM5.counter_us(&clocks);
let mut super_timer = SuperTimer::new(tick_timer, u32::MAX);
let user_button_pin = gpioc.pc13.into_floating_input();
let user_button_timer = super_timer.sub();
let mut user_button = SwitchDevice::new_active_high(user_button_pin, user_button_timer);
let green_led_pin = gpiob.pb0.into_push_pull_output();
let green_led_timer = super_timer.sub();
let green_led = LedDevice::new(green_led_pin, green_led_timer);
let blue_led_pin = gpiob.pb7.into_push_pull_output();
let blue_led_timer = super_timer.sub();
let blue_led = LedDevice::new(blue_led_pin, blue_led_timer);
let red_led_pin = gpiob.pb14.into_push_pull_output();
let red_led_timer = super_timer.sub();
let red_led = LedDevice::new(red_led_pin, red_led_timer);
let mut robot = RobotBuilder::new()
.with_leds(LedSet::new(green_led, blue_led, red_led))
.build()
.with_run_commands(&get_run_commands())
.build::<ACTIVE_COMMANDS_COUNT>();
super_timer.setup().expect("Failed to setup super time");
loop {
super_timer.tick().expect("Failed to tick super timer");
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();
}
}
}
开发
参见 docs/dev.md
许可
版权所有 2023 Village Kit Limited
根据 Apache License 2.0 许可(“许可证”);除非符合许可证要求或书面同意,否则不得使用此文件。您可以在以下位置获取许可证副本:
https://apache.ac.cn/licenses/LICENSE-2.0
除非适用法律要求或书面同意,否则在许可证下分发的软件按“现状”基础分发,不提供任何明示或暗示的保证或条件。有关许可证的具体语言,请参阅许可证。
依赖项
~5.5MB
~110K SLoC