当前位置: 首页 > article >正文

FPGA/SoC控制机械臂

FPGA/SoC控制机械臂

机器人技术处于工业 4.0、人工智能和边缘革命的前沿。让我们看看如何创建 FPGA 控制的机器人手臂。

ad71334121a48d1da534adcc3bdc5b95.png

介绍

机器人技术与人工智能和机器学习一起处于工业 4.0 和边缘革命的最前沿。

因此,我认为创建一个基础机器人手臂项目会很有趣,我们可以回过头来添加几个功能,例如:

  • 逆运动学 - 确定末端执行器的位置。

  • AI / ML - 操作期间的对象分类。

  • 网络控制——实现边缘远程控制。

585dd5f7d3f1be7a8a3e42f1143b3db3.png

此示例将使用一个机器人手臂,该机器人手臂在 Zynq SoC 的控制六个伺服系统。可以使用简单的软件界面或使用两个操纵杆进行直接控制。

伺服控制

我们需要做的第一件事是弄清楚如何控制伺服位置。伺服电机是最简单的驱动电机之一,也是机器人技术的理想选择,因为只要我们保持相同的驱动信号,它们就能保持相对位置。

40d010317c66114f2896793f7abfbb79.png

那么伺服的驱动信号是什么呢?我们使用的同类伺服系统中的大多数都使用 60Hz PWM 波形。在 60Hz 波形的 16.66 ms 周期中,信号将在 0.5 ms 到 2.5 ms 之间为高电平。信号的持续时间将驱动伺服器在 0 到 180 度之间运动。

0.5 ms 脉冲驱动 0 度位置,而 2.5 ms 脉冲将驱动 180 度位置。因此,可以通过将信号驱动为 1.5 ms 脉冲来维持 90 度。

因此,增加或减少脉冲13.9 us宽度会使舵机移动 1 度。

1dad3efd7371d7b693c302a74bf3e155.png

接下来要解决的是如何生成驱动信号,PWM 扩展板(上图)使用四个 8 位寄存器来驱动每个 PWM 信号。

on 寄存器定义信号变高的计数,off 寄存器定义信号变低的计数。

因此,我们可以将开启时间设置为 0,然后定义关闭信号的计数,以获得所需的信号宽度。

Vivado 构建

0c3ab7bc7471412bcc3b361778b3068f.png
  • Zynq PS - 这是 Zynq 处理系统

  • AXI IIC - 在 PL 中实现的 I2C 接口

一旦完成了PL设计,我们就可以构建设计并将其导出到软件。

软件设计

我们将在软件中开发大部分应用程序。由于我们希望在多种模式下使用它,并在将来进行升级时使用它,因此我们需要一种模块化方法。

因此,为每个关节开发了一个可以根据需要调用和使用的函数。每个关节都能够接收无符号的 8 位值,然后将该 8 位值与 90 度 (1.5 ms) 脉冲宽度相加或相减,以获得所需的角度。

我这样做有几个原因:

  • 单个 RS232 字节可以包含所需的电机位置。

  • 从操纵杆读取的值也是 8 位。

因此,我们需要确保操纵杆和手臂之间的运动对齐。

两个操纵杆中,第一个连接到 JA,第二个连接到 JB(JA和JB是PMOD接口,就是普通的GPIO)。

JA 当沿 X 方向移动时,将向前或向后移动手臂;当沿 Y 方向移动时,它将上下移动手臂。

71a77bcc8ef425fad0922669230a9da4.png 7f7ec74539c855818e433a36b8948191.png

JB 在 X 方向移动时会旋转手腕,在 Y 方向移动时会上下移动手腕。

4d1962d2d0d24aeaa2e671157a409a28.png 690663b44654e2b20a530cdd22a3efd8.png

每个移动函数的代码都非常相似,并且可以在后面提供的代码找到,但是,下面提供了向上向下函数以供参考

void up_dwn(u8 YData){
 SendBuffer[0] = 0x0A;
 SendBuffer[1] = 0x00;
 XIic_Send(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&SendBuffer, sizeof(SendBuffer),XIIC_STOP);
 SendBuffer[0] = 0x0B;
 SendBuffer[1] = 0x00;
 XIic_Send(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&SendBuffer, sizeof(SendBuffer),XIIC_STOP);
 SendBuffer[0] = 0x0C;
 u16 signal;
 if( YData < 128 ){
  signal = 122 + (YData * 1.91);
 }
 else if (YData == 128){
  signal = 369;
 }
 else{
  signal = 369 + ((YData - 128) * 1.91);
 }
 u8 cent_l_off, cent_h_off;
 cent_l_off = (u8)signal;
 cent_h_off = (u8) (signal>>8);
 SendBuffer[1] = cent_l_off;
 XIic_Send(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&SendBuffer, sizeof(SendBuffer),XIIC_STOP);
 SendBuffer[0] = 0x0D;
 SendBuffer[1] = cent_h_off;
 XIic_Send(iic.BaseAddress,IIC_SLAVE_ADDR,(u8 *)&SendBuffer, sizeof(SendBuffer),XIIC_STOP);
 }

软件应用程序结构的其余部分是:

  • 初始化 PWM 扩展板和 Pmod 操纵杆。

  • 对手臂进行自检并将所有伺服系统定位在 90 度。

  • 通过 RS232 接收命令或来自操纵杆的命令。

当然,如果我们希望在命令中进行硬编码来执行重复任务,我们也可以。

初步测试

一旦 Vivado 构建和初始软件可用,下一步就是确保软件能够正确移动伺服系统。

当移动操纵杆时,可以使用示波器测量 PWM 信号。

随着操纵杆的移动,脉冲宽度逐渐从 0.5 ms 变为 2.5 ms。

ea5842347b9c25caff4f7c48c88a052f.png

视频演示

参考代码

!! https://github.com/ATaylorCEngFIET/Hackster

!! https://github.com/ATaylorCEngFIET/Hackster/tree/master/Hexapod_servo


http://www.kler.cn/a/104884.html

相关文章:

  • 科大讯飞发布讯飞星火 3.0;开源AI的现状
  • Java后端开发(九)-- idea(2022版)将commit(未push)的 本地仓库 的 多条commit记录 进行撤销
  • unity 基于UGUI的无限动态滚动列表
  • 【考研数学】线性代数第六章 —— 二次型(3,正定矩阵与正定二次型)
  • 鸿蒙应用开发之弹窗
  • css实现鼠标多样化
  • 微信小程序如何跳转页面
  • LVDS、LVPECL、CML三种高速逻辑电平的比较
  • js 正则表达式
  • 物联网AI MicroPython传感器学习 之 MDL0025心率传感器
  • 环境编程代码实例:“加/卸载” Zend Framework 2
  • 热点不热!如何修复笔记本电脑未连接到移动热点的问题
  • 大模型在数据分析场景下的能力评测
  • 汽车电子专有名词与相应技术
  • Java面试(JVM篇)——JVM 面试题合集 深入理解JVM虚拟机
  • JAVA毕业设计104—基于Java+Springboot+Vue的医院预约挂号小程序(源码+数据库)
  • 【在英伟达nvidia的jetson-orin-nx和PC电脑ubuntu20.04上-装配ESP32开发调试环境-基础测试】
  • springboot配置redis、Spring cache
  • 【Python第三方包】使用Python的Translate包进行文本翻译
  • CentOS 7