#自动化 #固件 #机器 #CNC #机器人 #动作 #驱动

无std robokit

为简单的机器人自动化构建自定义固件

3个版本 (破坏性更新)

0.3.0 2023年4月19日
0.2.0 2023年4月5日
0.1.0 2023年4月4日

#521 in 嵌入式开发

Apache-2.0

89KB
2.5K SLoC

Robo Kit 🤖

为简单的机器人自动化构建自定义固件

模块

固件

关于

短期目标是构建 用于网格梁生产的自动化机器

长期目标是提供机器人自动化或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)
    • 继电器(气动执行器)
  • 传感器
    • 输入开关
      • 按钮
      • 限位开关
    • 旋转编码器
    • 线性编码器
  • 接口
    • 物理控制
    • JSON-RPC
    • Web

示例

./blinky/src/main.rs

(用于 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