今天研究如何使用 Python + 低成本 FPGA 开发高性能、精密的机械臂。

简介
由于 FPGA 具有并行特性,它在精密电机控制和机器人领域表现出色。本文是探索开发基于 ROS2 的解决方案,让机器人可以在白板上自主书写文字。
在这个项目中,将展示如何创建一个具有以下功能的机械臂应用程序:
通过 FPGA 控制手臂上的 6 个轴关节
通过远程机器上运行的 Jupyter Lab 实现对机械臂的控制
通信链路为 RS232 - 可使用 LwIP 扩展到以太网
在 Jupyter Lab 中跟踪轴定位信息
能够将手臂的位置存储在文件中
能够重放存储的文件,以根据应用程序的要求驱动手臂完成一系列动作
能够控制选定的关节从一个位置移动到另一个位置
设计流程
本项目将采用的方法是在 FPGA 逻辑中创建 AMD MicroBlaze™ V 处理器,处理器将执行命令行解释器(CLI),接收关节的角度并更新特定关节的驱动逻辑。
使用这种方法,可以轻松更新 CLI 以支持使用 LwIP 和以太网命令,实现长距离远程连接。
手臂上的每个关节将被标记为 A ~ F,通过 UART 链路发送的协议是:
<joint> <angle> <cr><lf>
其中 Joint 为 A~F,angle 为 0 到 180,CR 为回车符,LF 为换行符。
在 FPGA 内部,使用一个简单的 RTL IP ,生成控制电机所需的 PWM 信号。这就要求在处理器上将角度转换为驱动信号。
伺服器以 50 Hz PWM 周期(20 ms)运行。在这 20 ms中,PWM 周期标称开启时间为 1.5 ms,将使伺服器位置处于 90 度点,通常称为中性位置。将开启时间减少到 1 ms将使伺服器移动到 0 度点,而将其增加到 2 ms将使伺服器移动到 180 度点。
因此,该伺服机构有 180 度的潜在运动,粒度为每度 1 ms/180 = 5.555 us。
接线
所选的机械臂使用 Arduino 接口板与 Digilent Arty A7 / S7 板连接。它可以通过接口板从外部供电,也可以通过接口板上的连接器提供的 5V 供电。

由于 5V 电流通过接口板连接器会限流,并且电机可能要求较高,因此本次使用外部DC电源为机械臂本身供电。


Vivado设计
Vivado设计比较简单,添加 AMD MicroBlaze V 处理器及其外设即可。

AMD MicroBlaze V 添加后,单击运行自动化设计。

按照下图进行处理器设置:
64 KB Local Memory
启用调试模块
启用外围 AXI 端口
启用新的中断控制器和时钟向导

完成后如下:

下一步是获取 Digilent Vivado 库,然后添加 PWMV2 IP 。
https://github.com/Digilent/vivado-library

该 IP 非常适合 PWM 生成,并且支持多种 PWM 输出。

将该IP进行如下设置:
六个PWM输出

要添加的倒数第二个 IP 是 AXI UART。

最后需要添加一个设置为逻辑高电平的常量IP来驱动机械臂扩展版上的软启动引脚。

然后按照板卡硬件将时钟引入到系统里即可。
完整的设计如下所示。

然后生成顶层文件和添加约束:
set_property IOSTANDARD LVCMOS33 [get_ports {pwm_0[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pwm_0[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pwm_0[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pwm_0[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pwm_0[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {pwm_0[0]}]
set_property PACKAGE_PIN T11 [get_ports {pwm_0[0]}]
set_property PACKAGE_PIN T14 [get_ports {pwm_0[1]}]
set_property PACKAGE_PIN T15 [get_ports {pwm_0[2]}]
set_property PACKAGE_PIN M16 [get_ports {pwm_0[3]}]
set_property PACKAGE_PIN V17 [get_ports {pwm_0[4]}]
set_property PACKAGE_PIN U18 [get_ports {pwm_0[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {soft_start[0]}]
set_property PACKAGE_PIN R17 [get_ports {soft_start[0]}]
本次设计的扩展板的原理图:
https://store.arduino.cc/products/tinkerkit-braccio-robot?

最后生成bit后导出到Vitis。