Programming
编程教程
预计 2 小时、中等难度:GCode 基础与 M 指令、完整抓取序列、Python 串口 API、YOLOv8 视觉处理、坐标变换、固件运动学与插补、代码示例。
编程教程
预计用时:2 小时 | 难度:中等
1. GCode 基础
什么是 GCode? GCode 是数控机床的标准编程语言,Delta 机器人同样使用 GCode 进行运动控制。
1.1 基本运动指令
| 指令 | 说明 | 参数 | 示例 |
|---|---|---|---|
G0 |
快速定位 | X, Y, Z, F | G0 X10 Y20 Z-200 |
G1 |
直线插补 | X, Y, Z, F | G1 X50 F1000 |
G28 |
回零 | 无 | G28 |
G90 |
绝对坐标 | 无 | G90 |
G91 |
相对坐标 | 无 | G91 |
1.2 M 指令(辅助功能)
| 指令 | 功能 | 示例 |
|---|---|---|
M121 |
开泵 | M121 |
M122 |
关泵 | M122 |
M1 |
开阀(泄气,放下物体) | M1 |
M2 |
关阀(保持真空,吸住) | M2 |
M17 |
使能电机 | M17 |
M18 |
关闭电机 | M18 |
1.3 完整抓取序列示例
# 第 1 步:回零
G28
# 第 2 步:移到物体上方
G0 X30 Y-20 Z-160
# 第 3 步:下降到抓取高度
G0 Z-200
# 第 4 步:开泵并关阀(形成真空)
M121
M2
G4 S1 # 等待 1 秒
# 第 5 步:上升
G0 Z-160
# 第 6 步:移到目标位置
G0 X-50 Y30
# 第 7 步:下降
G0 Z-200
# 第 8 步:释放(开阀泄气)
M1
G4 S1
# 第 9 步:上升并关泵
G0 Z-160
M122
2. Python API
2.1 串口通信
from serial import Serial
import time
# 连接 ESP32
robot = Serial('COM3', 115200, timeout=1)
time.sleep(2) # 等待连接稳定
# 发送 GCode 指令
def send_gcode(command):
robot.write((command + '\n').encode())
response = robot.readline().decode().strip()
print(f"Sent: {command} | Response: {response}")
return response
# 使用示例
send_gcode("G28")
send_gcode("G0 X10 Y20 Z-200")
2.2 视觉处理(YOLOv8)
import cv2
from ultralytics import YOLO
# 加载 YOLOv8 模型
model = YOLO('yolov8n.pt')
# 打开摄像头
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
# 目标检测
results = model(frame)
# 读取检测结果
for r in results:
boxes = r.boxes
for box in boxes:
x1, y1, x2, y2 = box.xyxy[0].tolist()
conf = box.conf[0].item()
cls = int(box.cls[0].item())
# 计算物体中心
cx = int((x1 + x2) / 2)
cy = int((y1 + y2) / 2)
print(f"Object at pixel: ({cx}, {cy})")
# 显示结果
annotated = results[0].plot()
cv2.imshow('Detection', annotated)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
2.3 坐标变换
import numpy as np
# 加载透视变换矩阵(标定时生成)
H = np.load('homography_matrix.npy')
def pixel_to_robot(px, py):
"""把像素坐标转换为机器人坐标"""
# 输入:像素坐标 (px, py)
# 输出:机器人坐标 (x, y),单位 mm
pixel_point = np.array([[px, py]], dtype='float32')
pixel_point = np.array([pixel_point])
robot_point = cv2.perspectiveTransform(pixel_point, H)
x = robot_point[0][0][0]
y = robot_point[0][0][1]
return x, y
# 使用示例
px, py = 320, 240 # 图像中心
x, y = pixel_to_robot(px, py)
print(f"Robot coordinate: X={x:.1f}, Y={y:.1f}")
3. 固件开发
3.1 运动学解算(robotGeometry.cpp)
Delta 机器人使用逆运动学:给定末端执行器坐标 (x, y, z),计算 3 个电机角度 (θ1, θ2, θ3)。
// 核心函数:逆运动学解算
int delta_calcInverse(float x0, float y0, float z0,
float &theta1, float &theta2, float &theta3) {
// 详细数学推导见 robotGeometry.cpp
// 返回:0 成功,-1 超出范围
}
3.2 插补算法(interpolation.cpp)
使用余弦加速曲线实现平滑运动:
// SPEED_PROFILE = 2(余弦加速)
// 特点:启停平滑,无冲击
float Interpolation::cosineProfile(float t) {
// 真正的余弦加速曲线:平滑启动与停止
return -cos(t * PI) * 0.5 + 0.5;
}
4. 代码示例
示例 1:Hello World(移动到指定位置)
from serial import Serial
import time
robot = Serial('COM3', 115200, timeout=1)
time.sleep(2)
robot.write(b'G28\n') # 回零
time.sleep(3)
robot.write(b'G0 X10 Y20 Z-200\n') # 移动
print("Hello, Delta Robot!")
示例 2:画正方形
def draw_square(size=40):
send_gcode("G28")
send_gcode("G0 X0 Y0 Z-200")
# 4 个顶点
corners = [
(size/2, size/2),
(-size/2, size/2),
(-size/2, -size/2),
(size/2, -size/2),
]
for x, y in corners:
send_gcode(f"G1 X{x} Y{y} F1000")
time.sleep(1)
send_gcode(f"G1 X{size/2} Y{size/2}") # 回到起点
draw_square()
进阶学习
查看完整示例项目:
最后更新 21 Sep 2026