基于 ESP32-P4 的工业级智能机械臂设计与实现

本文介绍了一个基于 ESP32-P4 高性能 MCU 的可独立控制机械臂项目,涵盖完整的运动学计算、视觉检测与远程控制方案,展示了 ESP32-P4 在工业级机械臂应用中的巨大潜力。

随着近年来 AI 技术的快速发展,机器人领域正逐步迈入具身智能 (Embodied Intelligence) 时代,机器人开始具备环境感知与自主学习能力。ESP32-P4 凭借强大的算力与丰富的外设接口,为构建智能机械臂控制系统提供了理想的平台。

本文所介绍的机械臂方案具备以下核心优势:

  • 板载运动学计算 :通过基于 D-H 参数的迭代算法实现正向与逆向运动学,无需依赖外部计算平台
  • 板载视觉能力 :支持 USB 摄像头与颜色检测模型,结合视觉标定矩阵实现精准抓取;同时借助 esp-dl,可运行 YOLO11nesp-detection 等轻量模型,实现自定义目标识别
  • 远程控制能力:通过一套同构的小型机械臂采集关节数据,并基于 ESP-NOW(ESP32-P4-Function-EV-Board 上的 ESP32-C6)无线发送,实现远程操控

本文将详细讲解主从机械臂的机械装配、电机控制、视觉标定与系统集成全过程,覆盖机器人与视觉应用的基础原理。同时,依托 ESP32-P4 的高性能,本方案还可进一步扩展至多种应用场景。

安全提示

为防止机械臂在运行过程中因意外动作造成人身伤害或财产损失,请在正式运行前仔细核对所有运动参数,并确保紧急停止按钮始终处于可触达状态,以便在紧急情况下立即断电。

主机械臂 (Leader Robotic Arm,TRLC DK1)

主机械臂仅用于远程控制从机械臂 ,本身不涉及运动学计算。从机械臂可在板载运动学与视觉能力支持下独立运行。如果你不需要远程控制功能,可直接从 从机械臂 (Ragtime Panthera)章节开始阅读。

主机械臂基于 trlc-dk1 项目中的 leader 部分。需要注意的是,目前 leader 结构已更新至 v0.2.0,而本文使用的是初始版本结构 。可在此处下载初版 3D 文件。

完整的主机械臂项目代码位于此处,主要实现 XL330_M077 总线舵机的位置控制与力矩切换。

XL330_M077 总线舵机配置

在正式装配前,需要使用 DYNAMIXEL Protocol 2.0 对 7 个 XL330_M077 总线舵机进行参数配置。请提前准备总线舵机驱动板(用于将标准串口信号转换为总线舵机 DATA 信号),并参考下图或官方调试电路进行连接。

使用上述电路时,请将 USB-TTL 的 TX 接驱动板 TX、RX 接 RX,注意不要接反。

连接完成后,打开 DYNAMIXEL Protocol 2.0 工具,在菜单栏点击 Scan 扫描总线上的舵机。

为保证与主机械臂工程参数一致,请按如下要求配置舵机:

  • ID:1 ~ 7
  • 波特率:115200
  • 工作模式:位置控制
  • 初始角度:180° (2045)

选择 180° 作为初始角度的原因是:若以 0° 作为起始点,上电时有可能被识别为 360°,从而影响后续角度读取与控制。

结构装配

打印完成所有结构件后,请在所有舵机均处于 180° 初始角度 的状态下进行装配。所需螺丝均包含在XL330_M077 舵机包装盒中。

ESP32-C3 驱动板安装与调试

ESP32-C3 驱动板将 ESP32-C3 与总线舵机电路集成在同一模块中,支持外部 5 V / ≥1 A 电源同时为舵机与ESP32-C3 供电。通过板载 Micro-USB 接口可直接烧录和调试固件。点击此处下载用于 PCB 打样的 Gerber 文件。

在开始前,请安装并配置 ESP-IDF v5.5 环境。

随后克隆 esp-iot-solution,并进入 leader 工程目录进行编译与烧录:

复制代码
git clone git@github.com:espressif/esp-iot-solution.git

cd esp-iot-solution/examples/robot/ragtime_panthera/leader

idf.py set-target esp32c3

idf.py -p /dev/ttyACM0 build flash monitor

如需进行更多配置,请运行 `idf.py menuconfig`,并进入 (Top) → Example Configuration:

硬件配置 (Hardware Configuration) 包含 XL330_M077 总线舵机的基础参数设置,包括波特率、TX/RX 引脚、初始位置以及角度容差:
硬件配置

关键说明:

  • XL330_M077 配置说明:如需修改 UART 设置或通信引脚,请调整 XL330_M077 communication speed、XL330_M077 RXD pin number 以及 XL330_M077 init position;
  • 初始角度定义:程序中零位 = 当前角度 − 配置的初始角度;
  • 角度容差:上电后舵机会多次回到初始位置,当目标角度与当前角度差值小于该阈值时,认为到位。

ESP-NOW 配置

  • Channel:默认 1
  • Primary Master Key:默认 bot12345678901234
  • Slave MAC Address:需修改为从机械臂 ESP32-C6 的 MAC 地址

ESP-NOW 是乐鑫定义的低功耗、低时延点对点无线通信协议,无需路由器,广泛应用于智能家居、遥控、传感器等场景。

从机械臂 (Follower Robotic Arm,Ragtime Panthera)

从机械臂基于 Ragtime_Panthera 项目,采用 DM 系列关节电机驱动,并提供完整的 ROS 与 Python 支持。同时,其结构与主机械臂完全一致,可直接进行遥操作控制。

为避免因原项目更新导致结构差异,请使用本文所基于的 fork 版本

运动学建模与验证

D-H 参数建模

由于 MCU 平台不支持 URDF 与成熟运动学库,本文在 ESP32-P4 上使用 Denavit--Hartenberg (D-H) 参数描述机械臂结构,并采用迭代法实现逆运动学求解。

在移植前,推荐使用 robotics-toolbox-python 对 D-H 参数进行预验证:

复制代码
pip3 install roboticstoolbox-python

随后可在仿真环境中查看机械臂模型,并测试正向与逆向运动学。

复制代码
import numpy as np

from roboticstoolbox import DHRobot, RevoluteDH



robot = DHRobot(

    [

        RevoluteDH(a=0.0, d=0.1005, alpha=-np.pi / 2, offset=0.0),

        RevoluteDH(a=0.18, d=0.0, alpha=0.0, offset=np.deg2rad(180)),

        RevoluteDH(a=0.188809, d=0.0, alpha=0.0, offset=np.deg2rad(162.429)),

        RevoluteDH(a=0.08, d=0.0, alpha=-np.pi / 2, offset=np.deg2rad(17.5715)),

        RevoluteDH(a=0.0, d=0.0, alpha=np.pi / 2, offset=np.deg2rad(90)),

        RevoluteDH(a=0.0, d=0.184, alpha=np.pi / 2, offset=np.deg2rad(-90)),

    ],

    name="Ragtime_Panthera"

)



robot.teach(np.array([0, 0, 0, 0, 0, 0]))

正向运动学 (Forward Kinematics)

正向运动学是指:根据输入的各关节角度,计算机械臂末端执行器的位置与姿态
可使用以下代码对正向运动学进行测试:

复制代码
import matplotlib.pyplot as plt
import numpy as np
from roboticstoolbox import DHRobot, RevoluteDH

robot = DHRobot(
    [
        RevoluteDH(a=0.0, d=0.1005, alpha=-np.pi / 2, offset=0.0),
        RevoluteDH(a=0.18, d=0.0, alpha=0.0, offset=np.deg2rad(180)),
        RevoluteDH(a=0.188809, d=0.0, alpha=0.0, offset=np.deg2rad(162.429)),
        RevoluteDH(a=0.08, d=0.0, alpha=-np.pi / 2, offset=np.deg2rad(17.5715)),
        RevoluteDH(a=0.0, d=0.0, alpha=np.pi / 2, offset=np.deg2rad(90)),
        RevoluteDH(a=0.0, d=0.184, alpha=np.pi / 2, offset=np.deg2rad(-90)),
    ],
    name="Ragtime_Panthera"
)

state = np.deg2rad([0, 30, -36, 65, 0, 0])
T1 = robot.fkine(state)
print("T1:\n{}".format(T1))

robot.plot(state, jointaxes=True, eeframe=True, block=True)
plt.show()

运行结果如下:

复制代码
T1:
   0.8572    0.515     0         0.1531    
   0         0         1         0         
   0.515    -0.8572    0         0.03971   
   0         0         0         1         

通过调用 fkine 函数,可以快速计算出在当前关节角度下,末端执行器对应的空间位姿(位置与方向)

逆向运动学(Inverse Kinematics)

逆向运动学是指:根据给定的末端执行器位置与姿态,反求每个关节所需的旋转角度
可使用以下代码对逆向运动学进行测试:

复制代码
import matplotlib.pyplot as plt
import numpy as np
from roboticstoolbox import DHRobot, RevoluteDH

robot = DHRobot(
    [
        RevoluteDH(a=0.0, d=0.1005, alpha=-np.pi / 2, offset=0.0),
        RevoluteDH(a=0.18, d=0.0, alpha=0.0, offset=np.deg2rad(180)),
        RevoluteDH(a=0.188809, d=0.0, alpha=0.0, offset=np.deg2rad(162.429)),
        RevoluteDH(a=0.08, d=0.0, alpha=-np.pi / 2, offset=np.deg2rad(17.5715)),
        RevoluteDH(a=0.0, d=0.0, alpha=np.pi / 2, offset=np.deg2rad(90)),
        RevoluteDH(a=0.0, d=0.184, alpha=np.pi / 2, offset=np.deg2rad(-90)),
    ],
    name="Ragtime_Panthera"
)

state = np.deg2rad([0, 30, -36, 65, 0, 0])
T1 = robot.fkine(state)
print("T1:\n{}".format(T1))

T2 = np.array(T1)
T2[0, 3] = T2[0, 3] + 0.1
print("T2:\n{}".format(T2))

sol = robot.ikine_LM(T2, q0=state, ilimit=100, mask=[1, 1, 1, 1, 1, 0], joint_limits=True)
print(sol)

T3 = robot.fkine(sol.q)
print("T3:\n{}".format(T3))

robot.plot(sol.q, jointaxes=True, eeframe=True, block=True)
plt.show()
复制代码
T1:
   0.8572    0.515     0         0.1531    
   0         0         1         0         
   0.515    -0.8572    0         0.03971   
   0         0         0         1         

T2:
[[ 8.57171795e-01  5.15030595e-01  1.04973270e-16  2.53139272e-01]
 [-1.54001208e-16  5.24866348e-17  1.00000000e+00  1.49891524e-17]
 [ 5.15030595e-01 -8.57171795e-01  1.24305397e-16  3.97085648e-02]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00  1.00000000e+00]]
IKSolution: q=[0, 1.161, -0.8568, 0.725, 0, 0], success=True, iterations=4, searches=1, residual=4.59e-10

T3:
   0.8572    0.515     0         0.2531    
   0         0         1         0         
   0.515    -0.8572    0         0.03971   
   0         0         0         1         

在该示例中,我们以初始位姿为基础,尝试将末端执行器沿 X 轴正方向移动 0.1 m,并在当前位姿附近求解对应的关节角度 sol.q。随后,通过再次执行正向运动学对结果进行验证。

输出结果如下:

复制代码
T1:

   0.8572    0.515     0         0.1531    

   0         0         1         0         

   0.515    -0.8572    0         0.03971   

   0         0         0         1         



T2:

[[ 8.57171795e-01  5.15030595e-01  1.04973270e-16  2.53139272e-01]

 [-1.54001208e-16  5.24866348e-17  1.00000000e+00  1.49891524e-17]

 [ 5.15030595e-01 -8.57171795e-01  1.24305397e-16  3.97085648e-02]

 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00  1.00000000e+00]]

IKSolution: q=[0, 1.161, -0.8568, 0.725, 0, 0], success=True, iterations=4, searches=1, residual=4.59e-10



T3:

   0.8572    0.515     0         0.2531    

   0         0         1         0         

   0.515    -0.8572    0         0.03971   

   0         0         0         1

从测试结果可以看出,逆运动学求解是有效的,且由逆解计算得到的正向运动学结果与期望的末端位姿完全一致,验证了运动学模型的正确性。

工作空间验证

由于当前项目不支持姿态估计,因此在固定末端姿态的前提下,通过遍历末端位移范围验证逆运动学是否可解,从而确定机械臂安全工作空间。

复制代码
import numpy as np
from roboticstoolbox import DHRobot, RevoluteDH

robot = DHRobot(
    [
        RevoluteDH(a=0.0, d=0.1005, alpha=-np.pi / 2, offset=0.0),
        RevoluteDH(a=0.18, d=0.0, alpha=0.0, offset=np.deg2rad(180)),
        RevoluteDH(a=0.188809, d=0.0, alpha=0.0, offset=np.deg2rad(162.429)),
        RevoluteDH(a=0.08, d=0.0, alpha=-np.pi / 2, offset=np.deg2rad(17.5715)),
        RevoluteDH(a=0.0, d=0.0, alpha=np.pi / 2, offset=np.deg2rad(90)),
        RevoluteDH(a=0.0, d=0.184, alpha=np.pi / 2, offset=np.deg2rad(-90)),
    ],
    name="Ragtime_Panthera"
)

state = np.deg2rad([0, 30, -36, 65, 0, 0])
T1 = robot.fkine(state)
print("T1:\n{}".format(T1))

x_range = np.linspace(0, 23, 30)
y_range = np.linspace(-15, 15, 30)

for dx in x_range:
    for dy in y_range:
        T_test = np.array(T1).copy()
        T_test[0, 3] += dx / 100
        T_test[1, 3] += dy / 100

        sol = robot.ikine_LM(T_test, q0=state)
        if sol.success:
            pass
        else:
            print(f"Failed in dx: {dx:.4f} cm, dy: {dy:.4f} cm")

print("Test Done")

测试结果表明,在 23 cm × 30 cm 区域内均可成功求解逆运动学。

ESP32-P4 板载运动学测试

为了使 ESP32-P4 能够独立控制机械臂,板载运动学能力是必不可少的。受 Matrix_and_Robotics_on_STM32 项目的启发,我们尝试将其移植并部署到 ESP32 平台上。运动学模块可以作为一个独立的组件引入到单独的工程中进行测试。需要注意的是,该项目目前仅移植了运动学 (Kinematics) 部分,尚不支持动力学 (Dynamics)

逆运动学 (Inverse Kinematics) 为例,在完成 ESP-IDF v5.5 环境搭建后,可在examples/robot/ragtime_panthera/follower 工程中进行测试。该工程已经将 kinematic 作为组件加入:

复制代码
#include <stdio.h>
#include <iostream>
#include "kinematic.h"

extern "C" void app_main(void)
{
    Kinematic kinematic;
    Joint j1 = Joint(0.0, DEG2RAD(30.0), DEG2RAD(-36.0), DEG2RAD(65.0), 0.0, 0.0);
    TransformMatrix t1;
    kinematic.solve_forward_kinematics(j1, t1);
    std::cout << "t1: " << std::endl;
    t1.print();

    TransformMatrix t2 = t1;
    t2(0, 3) += 0.1f;
    std::cout << "t2: " << std::endl;
    t2.print();

    Joint j2 = j1;
    kinematic.solve_inverse_kinematics(t2, j2);
    std::cout << "j2: " << std::endl;
    for (int i = 0; i < 6; i++) {
        std::cout << j2[i] << " ";
    }
    std::cout << std::endl;

    TransformMatrix t3;
    kinematic.solve_forward_kinematics(j2, t3);
    std::cout << "t3: " << std::endl;
    t3.print();
}

输出结果如下:

复制代码
t1: 
Transform Matrix:
[  0.8572,   0.5150,  -0.0000,   0.1531]
[  0.0000,  -0.0000,   1.0000,  -0.0000]
[  0.5150,  -0.8572,  -0.0000,   0.0397]
[  0.0000,   0.0000,   0.0000,   1.0000]
t2: 
Transform Matrix:
[  0.8572,   0.5150,  -0.0000,   0.2531]
[  0.0000,  -0.0000,   1.0000,  -0.0000]
[  0.5150,  -0.8572,  -0.0000,   0.0397]
[  0.0000,   0.0000,   0.0000,   1.0000]
j2: 
-4.71993e-13 1.1615 -0.856673 0.724918 -2.53619e-13 -4.4205e-13 
t3: 
Transform Matrix:
[  0.8572,   0.5150,  -0.0000,   0.2531]
[  0.0000,  -0.0000,   1.0000,  -0.0000]
[  0.5150,  -0.8572,  -0.0000,   0.0397]
[  0.0000,   0.0000,   0.0000,   1.0000]

从测试结果可以看出,ESP32-P4 板载运动学的计算结果与 逆运动学测试结果保持一致,验证了该实现的正确性。

URDFly (可选)

URDF ( **Unified Robot Description Format,统一机器人描述格式)**是一种基于 XML 的标准,用于描述机器人的运动学结构及基本动力学属性。它可用于定义连杆(link)、关节(joint)、惯性参数、关节限制,以及碰撞模型和可视化几何模型。URDF 在机器人领域被广泛采用,是 ROS 生态中的通用模型格式,并被Gazebo、RViz、MoveIt 等主流仿真与运动规划工具原生支持。

然而,在 MCU 平台上直接使用 URDF 相对复杂,更适合采用 D-H 参数 来描述机械臂并进行正、逆运动学计算。可使用 URDFly 或其他类似工具,将 URDF 解析并转换为 D-H 参数。

Ragtime_Panthera 为例,在克隆 URDFly 并按照 README 安装完成所有依赖后,按照以下步骤对Ragtime_Panthera 的 URDF 进行可视化与转换:

  1. 将 URDF 文件中的 package://panther_description 替换为 ../
  1. 打开 URDFly 并加载修改后的 URDF 文件

    (urdfly) PS D:\project\github\URDFly> python .\main.py

拖动右侧滑块以驱动各个关节运动,点击左侧按钮可获取 MDH 参数及其他相关信息。

关节电机调试 (Joint Motor Debugging)

在正式开始调试 DM 电机之前,请先参考 DM Motor Getting Started Guide,了解 DM 电机的控制流程。可在此下载 DM Debug Tool v1.6.8.6

DM4310-24V 为例,打开 DM 电机套件后,包含以下组件:
DM Motor kit

按照下图所示的接线方式连接套件中的所有组件,为电源适配板提供 24 V 电源,并通过 USB Type-C 数据线将 PC 连接至 USB-to-CAN 模块:
DM Motor Connect

随后打开 DM 调试工具进行测试,选择正确的串口,并在 Parameter Settings 页签中尝试读取参数:
DM Debug Tool

当参数读取成功时,说明电机连接正常。随后可在 Debug 页签中尝试位置模式测试:
DM Position Control

机械装配 (Mechanical Assembly)

在对上述运动学和 DM 电机有初步了解后,可按照以下步骤组装 follower 机械臂。在此之前,请准备以下材料:

  • ESP32-P4-Function-EV-Board:由 ESP32-P4 开发板和一块 7 英寸 MIPI DSI 电容触摸屏(1024 × 600)组成
  • CAN 模块:用于连接 ESP32-P4 与 DM 电机
  • USB 摄像头:本项目选用分辨率为 640 × 480,请确认所选 USB 摄像头支持该分辨率
  • XT30 2+2 双端线缆:用于连接各电机,至少准备 6 根
  • 各类 CNC 与钣金结构件:将在结构装配章节中详细说明
  • 24 V 电源:用于为 DM 电机供电
  • DM 电机:4 × DM4340、2 × DM4310、1 × DMH3510

注意:在原始 Ragtime_Panthera 项目中,采用的是 3 × DM4310、3 × DM4340 与 1 × DMH3510 的组合,其中DM4310 用于 base_link 旋转。但在实际运行中,由于机械臂完全伸展时惯量较大,最终将 base_link 的DM4310 更换为 DM4340,且无需进行额外的结构修改。

DM 电机配置 (DM Motor Configuration)

在将电机安装到机械结构之前,请使用 DM 调试工具为每个电机预先设置 Master IDCAN ID
ID Setting

结构装配

在装配前,请根据 BOM 提前准备所需材料,如螺丝、螺母、固定板、滑块、导轨、线缆等。由于涉及材料种类较多,需要采用不同的加工方式进行制造:

钣金加工

  • Joint 1--2 connector:加工孔需攻丝,见此处,材质选用不锈钢 304
  • Joint 2--3 link:加工孔需攻丝,见此处,材质选用不锈钢 304
  • Joint 3--4 link:加工孔需攻丝,见此处,材质选用不锈钢 304
  • Joint 4--5 connector:无需攻丝,材质选用铝合金 5052
  • Joint 5--6 connector:无需攻丝,材质选用铝合金 5052

CNC 加工

  • Base plate:无需攻丝,材质选用铝合金 6061

可使用 JLC 等在线加工服务商进行加工,其余材料可通过 3D 打印完成。

ESP32-P4-Function-EV-Board 安装与调试

由于 follower 项目使用的是 ESP32-P4-Function-EV-Board 套件,请提前将 LCD 屏幕安装到 ESP32-P4-Function-EV 上。并参考用户指南完成基础硬件与软件测试:

LCD Adapter Board ESP32-P4-Function-EV
J3 header MIPI DSI connector
J6 的 RST_LCD J1 的 GPIO27
J6 的 PWM J1 的 GPIO26
J6 的 5 V J1 的 5 V
J6 的 GND J1 的 GND

硬件连接与工程编译

克隆 follower 工程后,使用 idf.py menuconfig 进入
(Top) → Panthera Follower Configuration
对工程进行配置,例如 CAN TX/RX 引脚、C6 固件烧录引脚等。

复制代码
git clone git@github.com:espressif/esp-iot-solution.git

cd esp-iot-solution/examples/robot/ragtime_panthera/follower

idf.py set-target esp32p4

idf.py menuconfig

idf.py build

Follower Menuconfig

配置项说明:

  • Direct control robot arm via console:启用后,可在使用 idf.py monitor 时通过终端命令直接控制 follower
  • Hardware Configuration:配置 ESP32-P4 与 CAN 模块的连接,默认 TX 为 GPIO24,RX 为 GPIO25
  • Leader and Follower Gripper Mapping:配置 leader 与 follower 机械臂夹爪角度的映射关系,默认单位为弧度并乘以 100
  • Leader and Follower Angle Inversion:配置 leader 与 follower 之间的关节角度是否需要取反。由于机械结构安装方式不同,各关节的正向旋转方向可能不同,请根据右手定则判断并配置是否取反
  • Receiver Serial Flash Config :用于配置 follower 的 ESP-NOW 接收端。由于当前 esp-hosted-mcu 不支持ESP-NOW,项目在 ESP32-C6 侧独立实现了 ESP-NOW 数据包接收,并使用 esp-serial-flasher 将固件下载至 ESP32-C6。默认连接如下:
ESP32-P4 引脚 连接说明
GPIO24 连接 CAN 模块 TX
GPIO25 连接 CAN 模块 RX
GPIO6 连接 ESP32-C6 U0RXD
GPIO5 连接 ESP32-C6 U0TXD
GPIO54 连接 ESP32-C6 EN
GPIO53 连接 ESP32-C6 BOOT

重要提示 :首次编译固件时,请启用 Direct control robot arm via consoleEnable update C6 Flash 选项,并按照默认配置完成接线。

烧录与运行

以 Linux 为例,完成编译后将 ESP32-P4 连接至 PC,系统会自动生成串口设备节点(如 /dev/ttyUSB0),用于固件下载与串口日志调试:

复制代码
idf.py -p /dev/ttyUSB0 flash monitor

烧录完成后,可在终端中测试以下控制台命令:

命令 描述 用法
panthera_enable 启用或禁用所有电机 panthera_enable <on|off>
panthera_goto_zero 所有关节回零 panthera_goto_zero
panthera_set_zero 将当前位置设为零位 panthera_set_zero
panthera_goto_position 将末端移动至指定笛卡尔坐标 panthera_goto_position -x -y -z
panthera_set_vision_matrix 设置视觉标定矩阵 panthera_set_vision_matrix -1 ... -9
panthera_get_vision_matrix 读取当前标定矩阵 panthera_get_vision_matrix
panthera_read_position 读取所有关节位置 panthera_read_position

首次烧录后,请先执行 panthera_read_position,确认电机通信是否正常。正常情况下,应能读取所有已添加电机的角度信息。执行 panthera_enable on 时,所有电机应亮起绿色 LED;执行 panthera_enable off 时,电机应恢复为红色 LED。随后将 follower 机械臂调整至结构零位,并执行 panthera_set_zero,使结构零位与电机零位对齐。

可直接在屏幕上启动所有电机、执行抓取动作(需已完成视觉标定)、回零及设置零位。

对于 DMH3510 电机,请在安装夹持结构后、夹爪闭合状态下设置 DMH3510 的零点。此外,在为 DMH3510 上电前,请确保其角度范围位于 0--360° 之间;若在断电状态下转动角度超过 360°,将导致 DMH3510 零点发生变化。因此,上电前应确保 DMH3510 保持在接近零位的位置。

视觉标定

本文采用 eye-to-hand 视觉配置方式,即相机与机械臂位置固定,相比 eye-in-hand 更为简单。在正式标定前,将机械臂移动至若干指定位置,并记录对应的像素坐标。为简化流程,可制作一块独立的标定板,并在指定位置放置 AprilTag,通过 PC 识别后直接生成标定矩阵:

参考上图,将机械臂放置在 300 mm × 300 mm 平板上,相机固定在 300 mm × 600 mm 平板一侧,并使用以下脚本进行标定:

复制代码
import numpy as np

A = np.array([[170, 250, 331, 332, 246, 247],
              [232, 227, 228, 375, 377, 291]])
B = np.array([[0.4431, 0.4431, 0.4431, 0.17, 0.17, 0.3277],
              [0.15, 0, -0.15, -0.15, 0, -0.1],
              [0.0397, 0.0397, 0.0397, 0.0397, 0.0397, 0.0397]])


A_hom = np.vstack([A, np.ones(A.shape[1])])

M = np.zeros((3, 3))

for i in range(3):
    m_i, _, _, _ = np.linalg.lstsq(A_hom.T, B[i, :], rcond=None)
    M[i, :] = m_i

print(repr(M))

flat = M.flatten()
print_str = 'panthera_set_vision_matrix'
for idx, val in enumerate(flat, start=1):
    print_str += f' -{idx} {val:.6f}'
print(print_str)

for i in range(A.shape[1]):
    a = np.array([0, 0, 1])
    a[0] = A[0][i]
    a[1] = A[1][i]
    b = M @ a
    print(repr(b))

上述脚本的输出结果不能直接作为项目的最终标定结果,因为其依赖于相机的安装位置与角度。请使用panthera_set_vision_matrix 命令,将机械臂末端依次移动至 B 中的各个点,记录其像素坐标并替换 A;或在这些点放置 AprilTag,以便 PC 自动识别像素位置。

标定完成后,将输出命令直接输入至 idf monitor 终端,标定数据将自动保存至 NVS。

目标检测

本文默认使用 color_detect 模型,对绿色方块进行检测,作为机械臂的抓取目标。

此外,esp-dl 还提供了多种 AI 模型,可前往 esp-dl 获取更多板载 AI 模型。

目标抓取

完成标定、参数正确保存至 NVS,并将 USB 摄像头插入 ESP32-P4-Function-EV-Board 的高速 USB 接口后,LCD 屏幕将显示摄像头画面。放置绿色方块,确认其在屏幕上被正确识别后,点击 Grasp 按钮尝试抓取。

注意:当前 follower 项目仅集成了绿色颜色检测,后续维护中将尝试支持更多目标的识别。

主从机械臂同步

主从机械臂通过 ESP-NOW 进行通信(目前仅支持 leader → follower 的单向通信)。leader 机械臂通过 ESP-NOW 将关节角度信息同步至 follower,实现远程控制。在屏幕上点击 SyncEnable 开关以启用同步。

leader 端舵机角度数据包结构如下:

字段 大小(字节) 描述 说明 / 编码
Header 2 数据包起始标志 固定为 0xFF 0xFF
Joint Data 14 (7×2) 7 个舵机关节角度 弧度 × 100,转为 uint16,低字节在前
CRC 2 CRC 校验 CRC16,小端序,初始值 UINT16_MAX

如遇同步异常,请检查以下问题:

  • ESP32-C6 固件问题 :确认 follower 的 ESP32-C6 固件已下载。在 follower 工程中运行 idf.py menuconfig,进入
    (Top) → Panthera Follower Configuration → Receiver Serial Flash Config,启用 Enable update C6 Flash 完成首次烧录;烧录完成后关闭该选项以减少启动时间
  • ESP-NOW 通信问题:确认 leader 工程中配置的接收端 MAC 地址是否正确,应填写 ESP32-P4-Function-EV-Board 上 ESP32-C6 的 MAC 地址
  • Leader and Follower Synchronization
  • Leader and Follower Synchronization

总结

本文介绍了在 ESP32-P4 上实现机械臂项目的完整流程,涵盖运动学基础、视觉标定以及远程通信,验证了ESP32-P4 在工业机械臂应用中的可行性。基于本文内容,可进一步探索 ESP32-P4 的应用边界。

欢迎尝试这些示例,构建属于你自己的应用,并分享你的实践经验!

相关推荐
不知名的老吴11 小时前
思考:AI算法领域主流语言是什么?
人工智能
彭祥.11 小时前
基于计算机视觉的运动计数与饮食热量分析系统
人工智能·计算机视觉
超b小哥11 小时前
【超详细】Claude Code Ubuntu平台完整部署指南
linux·人工智能·ubuntu·ai·claude code
wotaifuzao11 小时前
给 AI 编写“外设驱动”——Agent Skills 工程落地全解析
人工智能·嵌入式架构·agent工程化·ai开发实践·自动化工具链·prompt工程进阶
剑穗挂着新流苏31211 小时前
204_从回归到分类:Softmax 回归、损失函数与多分类实战
人工智能·pytorch·python·深度学习
人工智能AI技术11 小时前
字节开源 DeerFlow 2.0——登顶 GitHub Trending 1,让 AI 可做任何事情
人工智能
spider'11 小时前
系统的架构
人工智能
莱歌数字11 小时前
强化学习如何重构芯片热管理?
人工智能·重构·制造·cae·散热
光仔December11 小时前
【从0学习Spring AI Alibaba】2、Spring AI Alibaba版本选型及环境搭建
人工智能·大模型·saa·spring ai·ai alibaba
凸头11 小时前
从“搜了就答”到“智能决策”:拥抱 RAG 2.0 时代的架构演进 ——Java 后端工程师视角下的 AI 应用工程化落地
java·人工智能·架构·rag