这是一个基于 Gemini Vision AI 的 PAROL6 机械臂智能控制系统,能够通过自然语言和视觉识别实现机器人的自动化操作。该系统将传统的 GUI 控制方式转变为可编程的研究级平台,支持视觉引导操作和自然语言控制。
- ✅ 自然语言控制:支持文本和语音输入
- ✅ 视觉识别:集成 Intel RealSense D435I 深度相机
- ✅ AI 驱动:使用 Google Gemini 2.5 Flash 视觉模型
- ✅ 精确控制:毫米级定位精度
- ✅ 远程操作:UDP 客户端-服务器架构
- ✅ 安全保护:多层安全检查和急停监控
┌─────────────────────────────────────────────────────────────┐
│ 用户交互层 (顶层) │
│ - 自然语言输入(文本/语音) │
│ - Gemini AI 理解和规划 │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────▼───────────────────────────────────────┐
│ 视觉处理层 (中层) │
│ - RealSense 深度相机 │
│ - 物体检测和3D定位 │
│ - 手眼标定 │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────▼───────────────────────────────────────┐
│ 机器人控制层 (底层) │
│ - UDP 服务器(headless_commander.py) │
│ - 运动学计算和轨迹规划 │
│ - 串口通信和实时控制 (100Hz) │
└─────────────────────────────────────────────────────────────┘
PAROL6-Python-API-Gemini-Vision-Public/
├── Headless/
│ ├── headless_commander.py # 机器人控制服务器
│ ├── robot_api.py # 客户端 API(30+ 控制函数)
│ ├── smooth_motion.py # 平滑轨迹生成
│ ├── PAROL6_ROBOT.py # 机器人参数配置
│ ├── Gemini/
│ │ ├── gemini.py # Gemini AI 控制器
│ │ ├── robot_vision_tools.py # 视觉工具函数
│ │ ├── bounding_box_model.py # 物体检测模型
│ │ └── supplementary_functions.py # 辅助功能
│ └── Vision/
│ ├── vision_controller.py # 视觉处理控制器
│ ├── calibrate_hand_eye.py # 手眼标定
│ └── validate_calibration.py # 标定验证
├── README.md # 英文项目说明
├── API-Specific-README.md # API 详细文档
└── 中文使用说明.md # 本文档
| 输入类型 | 说明 | 示例 |
|---|---|---|
| 自然语言命令 | 文本或语音描述任务 | "请抓取红色的方块并放到蓝色盒子里" |
| 视觉数据 | RealSense D435I 深度相机 | RGB-D 图像流(640×480 @ 30fps) |
| API 调用 | Python 函数直接控制 | move_robot_joints([90, -45, 90, 0, 45, 180]) |
| 关节角度 | 6个关节的角度值(度) | [0, -90, 180, 0, 0, 180] |
| 笛卡尔坐标 | 位置和姿态 (mm 和度) | [250, 0, 200, 180, 0, 90] |
| 输出类型 | 说明 | 精度 |
|---|---|---|
| 关节运动 | 6轴协调运动 | ±0.1° |
| 笛卡尔运动 | 直线/曲线路径 | ±1mm |
| 夹爪控制 | 开合和力控制 | 0-255 级位置 |
| 状态反馈 | 位置、速度、IO状态 | 实时更新 |
| 视觉信息 | 物体3D位置和方向 | 毫米级精度 |
| 语音/文本反馈 | AI 响应和状态报告 | 自然语言 |
- 关节运动 (
move_robot_joints): 控制6个关节到指定角度 - 位置运动 (
move_robot_pose): 移动到笛卡尔坐标位置 - 笛卡尔直线 (
move_robot_cartesian): 保证直线路径运动 - 点动控制 (
jog_robot_joint,jog_cartesian): 手动微调位置
- 圆形轨迹 (
smooth_circle): 在指定平面画圆 - 圆弧运动 (
smooth_arc_center,smooth_arc_parametric): 精确圆弧路径 - 样条曲线 (
smooth_spline): 通过多个路点的平滑曲线 - 螺旋运动 (
smooth_helix): 螺旋式运动路径 - 混合运动 (
smooth_blend): 多段运动平滑衔接
- 物体检测: 使用 Gemini Vision AI 识别物体
- 3D 定位: 深度相机获取物体空间坐标
- 智能抓取: 自动规划抓取姿态和路径
- 精确放置: 视觉引导的放置操作
- 手眼标定: ChArUco 标定板标定系统
- 电动夹爪: 位置、速度、力控制 (0-255)
- 气动夹爪: 开/合控制(数字输出端口)
- 物体检测: 夹爪状态反馈
- 文本模式: 逐步文本命令控制
- 语音模式: 按住空格键语音输入
- 自主模式: AI 自动分解复杂任务
- 组合功能: 多步骤操作自动执行
# 核心依赖
pip3 install roboticstoolbox-python==1.0.3
pip3 install numpy==1.23.4
pip3 install scipy==1.11.4
pip3 install spatialmath
# 串口和计时
pip3 install pyserial
pip3 install oclock
pip3 install keyboard
# 视觉处理
pip3 install pyrealsense2
pip3 install opencv-python
# Gemini AI
pip3 install google-genai
pip3 install python-dotenv
# 音频处理(可选,用于语音输入)
pip3 install pyaudio# 仅需要标准库,如果需要姿态矩阵功能:
pip3 install numpy==1.23.4
pip3 install spatialmath在项目根目录创建 .env 文件:
GEMINI_API_KEY=你的_Gemini_API_密钥获取 API 密钥: https://makersuite.google.com/app/apikey
cd Headless
python headless_commander.py等待提示:✓ Robot ready 和 Listening for commands on port 5001
文本模式(推荐新手):
cd Headless/Gemini
python gemini.py --mode text自主模式(复杂任务):
python gemini.py --mode autonomous语音输入模式:
python gemini.py --mode text --input audio文本模式下的命令示例:
你: 请向前移动 50mm
AI: [执行移动并确认]
你: 抓取红色的方块
AI: [检测物体 → 规划路径 → 抓取]
你: 把它放到蓝色盒子里
AI: [移动到目标 → 放置 → 松开]
自主模式下的复杂任务:
你: 清理桌面上所有的红色物体,把它们放到绿色容器里
AI: [自动执行]
1. 扫描检测所有红色物体
2. 逐个抓取
3. 放置到容器
4. 返回检测更多物体
5. 完成并报告
创建控制脚本 my_control.py:
from Headless.robot_api import *
# 1. 机器人回零
home_robot()
# 2. 移动到指定关节角度(5.5秒完成)
move_robot_joints([90, -45, 90, 0, 45, 180], duration=5.5)
# 3. 移动到笛卡尔坐标(位置:x,y,z 姿态:Rx,Ry,Rz)
move_robot_pose([250, 0, 200, 180, 0, 90], speed_percentage=50)
# 4. 直线运动到目标点
move_robot_cartesian([200, -50, 180, 180, 0, 135], duration=4.0)
# 5. 画圆(中心点,半径,平面,时间)
smooth_circle(center=[200, 0, 200], radius=50, plane='XY', duration=5.0)
# 6. 控制夹爪
control_electric_gripper(action='open')
control_electric_gripper(action='move', position=200, speed=150)
# 7. 查询状态
pose = get_robot_pose()
print(f"当前位置: {pose}")
angles = get_robot_joint_angles()
print(f"当前关节角度: {angles}")
# 8. 执行轨迹
trajectory = [
[200, 0, 200, 0, 0, 0],
[250, 50, 200, 0, 0, 45],
[200, 100, 200, 0, 0, 90]
]
execute_trajectory(trajectory, timing_mode='duration',
timing_value=10.0, motion_type='spline')运行:
python my_control.py使用视觉工具进行智能抓取:
from Headless.Gemini.robot_vision_tools import RobotVisionTools
from Headless.Vision.vision_controller import VisionController
# 初始化视觉系统
vision = VisionController()
vision.start()
robot_vision = RobotVisionTools(vision)
# 智能抓取流程
result = robot_vision.pick_object(
object_description="红色的立方体",
approach_style="vertical" # 垂直抓取
)
if result['success']:
# 放置到指定位置
robot_vision.place_at_position(
target_position=[300, 100, 50], # 目标位置
approach_height=50 # 接近高度
)move_robot_joints(
joint_angles=[90, -45, 90, 0, 45, 180], # 6个关节角度(度)
duration=5.0, # 运动时间(秒)
# 或者使用速度控制:
# speed_percentage=75, # 速度百分比 (0-100)
wait_for_ack=True, # 等待完成确认
timeout=10.0 # 超时时间
)move_robot_pose(
pose=[250, 0, 200, 180, 0, 90], # [x, y, z, Rx, Ry, Rz]
speed_percentage=50, # 速度百分比
wait_for_ack=True
)move_robot_cartesian(
pose=[200, -50, 180, 180, 0, 135],
duration=4.0
)# 单关节点动
jog_robot_joint(
joint_index=0, # 关节索引 (0-5正向, 6-11负向)
speed_percentage=40,
duration=2.0 # 时间
# 或者:distance_deg=15 # 角度
)
# 多关节同时点动
jog_multiple_joints(
joints=[0, 3, 5], # 关节列表
speeds=[70, 40, 60], # 对应速度
duration=1.2
)
# 笛卡尔点动
jog_cartesian(
frame='TRF', # 'TRF'工具坐标系 或 'WRF'世界坐标系
axis='Z+', # 'X+', 'X-', 'Y+', 'Y-', 'Z+', 'Z-'
speed_percentage=50,
duration=1.5
)smooth_circle(
center=[200, 0, 200], # 圆心坐标 (mm)
radius=50, # 半径 (mm)
plane='XY', # 平面: 'XY', 'XZ', 'YZ'
duration=5.0,
clockwise=False # 顺时针/逆时针
)smooth_arc_center(
end_pose=[250, 50, 200, 0, 0, 90], # 终点姿态
center=[200, 0, 200], # 圆弧中心
duration=3.0
)smooth_arc_parametric(
end_pose=[250, 50, 200, 0, 0, 90],
radius=50, # 半径 (mm)
arc_angle=90, # 圆弧角度 (度)
duration=3.0
)waypoints = [
[200, 0, 100, 0, 0, 0],
[250, 50, 150, 0, 15, 45],
[200, 100, 200, 0, 30, 90]
]
smooth_spline(waypoints, duration=8.0)smooth_helix(
center=[200, 0, 150], # 螺旋中心
radius=30, # 半径
pitch=20, # 螺距(每圈高度)
height=100, # 总高度
duration=10.0
)segments = [
{'type': 'LINE', 'end': [250, 0, 200, 0, 0, 0], 'duration': 2.0},
{'type': 'CIRCLE', 'center': [250, 0, 200], 'radius': 50,
'plane': 'XY', 'duration': 4.0},
{'type': 'LINE', 'end': [200, 0, 200, 0, 0, 0], 'duration': 2.0}
]
smooth_blend(segments, blend_time=0.5, duration=10.0)# 校准夹爪
control_electric_gripper(action='calibrate')
# 移动到指定位置
control_electric_gripper(
action='move',
position=200, # 位置 (0-255)
speed=150, # 速度 (0-255)
current=500 # 最大电流 (100-1000 mA)
)
# 查询夹爪状态
status = get_electric_gripper_status(verbose=True)
# 返回: [ID, Position, Speed, Current, StatusByte, ObjectDetected]# 打开夹爪
control_pneumatic_gripper(action='open', port=1)
# 关闭夹爪
control_pneumatic_gripper(action='close', port=1)# 获取当前位置姿态
pose = get_robot_pose() # 返回 [x, y, z, Rx, Ry, Rz]
# 获取当前关节角度
angles = get_robot_joint_angles() # 返回 6个角度值
# 获取关节速度
speeds = get_robot_joint_speeds() # 步/秒
# 获取 IO 状态
io_status = get_robot_io(verbose=True)
# 返回: [IN1, IN2, OUT1, OUT2, ESTOP]
# 检查是否停止
is_stopped = is_robot_stopped(threshold_speed=2.0)
# 检查急停状态
estop = is_estop_pressed()
# 获取完整状态
status = get_robot_status()
# 包含: pose, angles, speeds, IO, gripper, stopped, estop# 延时
delay_robot(2.5) # 延时 2.5 秒
# 停止运动
stop_robot_movement() # 立即停止并清空命令队列
# 回零
home_robot()
# 等待停止
wait_for_robot_stopped(timeout=10.0, poll_rate=0.1)
# 带重试的安全移动
safe_move_with_retry(
move_robot_joints,
[90, -45, 90, 0, 45, 180],
duration=5.0,
max_retries=3,
retry_delay=1.0
)from Headless.robot_api import *
# 1. 初始化
home_robot()
# 2. 移动到观察位置
move_robot_joints([0, -90, 180, 0, -45, 180], duration=3.0)
# 3. 打开夹爪
control_electric_gripper(action='open')
# 4. 移动到抓取位置
move_robot_cartesian([200, 0, 100, 180, 0, 0], duration=2.0)
# 5. 关闭夹爪抓取
control_electric_gripper(action='move', position=200, speed=100, current=500)
delay_robot(1.0)
# 6. 抬起
move_robot_cartesian([200, 0, 200, 180, 0, 0], duration=2.0)
# 7. 移动到放置位置
move_robot_cartesian([300, 100, 200, 180, 0, 0], duration=3.0)
# 8. 下降
move_robot_cartesian([300, 100, 110, 180, 0, 0], duration=2.0)
# 9. 松开
control_electric_gripper(action='open')
# 10. 返回安全位置
home_robot()from Headless.Gemini.robot_vision_tools import RobotVisionTools
from Headless.Vision.vision_controller import VisionController
# 初始化
vision = VisionController()
vision.start()
robot_vision = RobotVisionTools(vision)
# 执行抓取序列
objects_to_pick = ["红色方块", "蓝色圆柱", "绿色三角形"]
for obj_name in objects_to_pick:
# 检测并抓取
result = robot_vision.pick_object(
object_description=obj_name,
approach_style="vertical"
)
if result['success']:
print(f"成功抓取 {obj_name}")
# 放置到分类区域
robot_vision.place_at_position(
target_position=[300, 150, 50],
approach_height=50
)
print(f"{obj_name} 已放置")
else:
print(f"抓取 {obj_name} 失败: {result['message']}")
vision.stop()from Headless.robot_api import *
# 绘制正方形
def draw_square(center, size, height, duration):
half_size = size / 2
corners = [
[center[0] + half_size, center[1] + half_size, height, 0, 0, 0],
[center[0] - half_size, center[1] + half_size, height, 0, 0, 0],
[center[0] - half_size, center[1] - half_size, height, 0, 0, 0],
[center[0] + half_size, center[1] - half_size, height, 0, 0, 0],
[center[0] + half_size, center[1] + half_size, height, 0, 0, 0]
]
execute_trajectory(corners, timing_mode='duration',
timing_value=duration, motion_type='linear')
# 绘制圆形
def draw_circle(center, radius, height, duration):
smooth_circle(center=[center[0], center[1], height],
radius=radius,
plane='XY',
duration=duration)
# 执行
home_robot()
draw_square(center=[200, 0], size=80, height=150, duration=8.0)
delay_robot(1.0)
draw_circle(center=[200, 0], radius=40, height=150, duration=5.0)from Headless.robot_api import *
def pick_and_stack(objects_positions, stack_position, stack_height_increment=30):
"""
从多个位置拾取物体并堆叠
"""
current_stack_height = 50 # 初始高度
for i, obj_pos in enumerate(objects_positions):
print(f"拾取物体 {i+1}/{len(objects_positions)}")
# 打开夹爪
control_electric_gripper(action='open')
# 移动到物体上方
approach_pos = obj_pos.copy()
approach_pos[2] += 100
move_robot_cartesian(approach_pos, duration=2.0)
# 下降抓取
move_robot_cartesian(obj_pos, duration=1.5)
control_electric_gripper(action='move', position=200, speed=80)
delay_robot(1.0)
# 抬起
move_robot_cartesian(approach_pos, duration=1.5)
# 移动到堆叠位置上方
stack_approach = stack_position.copy()
stack_approach[2] = current_stack_height + 100
move_robot_cartesian(stack_approach, duration=3.0)
# 下降放置
place_pos = stack_position.copy()
place_pos[2] = current_stack_height
move_robot_cartesian(place_pos, duration=1.5)
# 松开
control_electric_gripper(action='open')
delay_robot(0.5)
# 抬起
move_robot_cartesian(stack_approach, duration=1.5)
# 更新堆叠高度
current_stack_height += stack_height_increment
print("堆叠完成!")
# 使用示例
objects = [
[200, 100, 50, 180, 0, 0],
[200, -100, 50, 180, 0, 0],
[250, 0, 50, 180, 0, 0]
]
stack_location = [150, 0, 50, 180, 0, 0]
home_robot()
pick_and_stack(objects, stack_location, stack_height_increment=25)
home_robot()视觉引导操作需要先进行手眼标定,将相机坐标系与机器人坐标系对齐。
cd Headless/Vision
python generate_charuco_board.py打印生成的 ChArUco 标定板(A4 纸)
python calibrate_hand_eye.py按照提示:
- 将标定板放在相机视野内
- 机器人自动移动到多个位置采集数据
- 自动计算手眼变换矩阵
- 保存标定结果到
Results/calibration/目录
python validate_calibration.py检查标定精度,应该达到 ±3mm 以内
python calibration_refinement.py通过迭代优化提高精度
如果客户端和服务器不在同一台电脑:
编辑 Headless/robot_api.py:
SERVER_IP = "192.168.1.100" # 改为服务器 IP
SERVER_PORT = 5001 # 默认端口确保防火墙允许 UDP 5001 和 5002 端口
编辑 Headless/Vision/vision_controller.py:
CAMERA_WIDTH = 640
CAMERA_HEIGHT = 480
CAMERA_FPS = 30编辑 Headless/Gemini/robot_vision_tools.py:
APPROACH_HEIGHT = 50 # 接近高度 (mm)
GRASP_HEIGHT = 100 # 抓取后抬升高度 (mm)
SPEED_APPROACH = 40 # 接近速度 (%)
SPEED_GRASP = 20 # 抓取速度 (%)⚠️ 急停按钮: 确保急停按钮随时可触及⚠️ 工作空间: 保持工作区域无障碍物⚠️ 电源: 使用稳定的电源供应⚠️ 固定: 确保机器人底座固定牢固
- ✓ 系统自动检查关节限位
- ✓ 运动前验证逆运动学解
- ✓ 速度同步防止超速
- ✓ 急停触发立即停止所有运动
- ✓ 命令队列自动清空
- 首次使用先在低速度测试
- 确认工作空间范围
- 观察首次运动路径
- 保持监控运行状态
- 异常情况立即按急停
现象: Serial port not found
解决:
- Windows: 检查设备管理器中的 COM 端口号
- Linux: 检查
/dev/ttyUSB*或/dev/ttyACM* - 更新
com_port.txt文件中的端口号 - 检查串口权限:
sudo usermod -a -G dialout $USER
现象: 命令无响应
解决:
- 检查服务器是否启动
- 确认 IP 地址和端口正确
- 检查防火墙设置
- 测试网络连通性:
ping 服务器IP
现象: IK solution not found
解决:
- 目标位置可能超出工作空间范围
- 检查姿态角度是否合理
- 尝试从当前位置分步移动
- 使用
get_robot_pose()查看可达范围
现象: RealSense camera not found
解决:
- 检查 USB 连接(建议 USB 3.0)
- 更新 RealSense 驱动
- 运行
realsense-viewer测试相机 - 检查相机权限
现象: API key invalid
解决:
- 检查
.env文件中的 API 密钥 - 确认 API 密钥未过期
- 检查网络连接
- 验证 API 配额
现象: 抓取位置偏移
解决:
- 重新进行手眼标定
- 增加标定采样点数量
- 确保标定板打印比例准确
- 使用
validate_calibration.py验证 - 尝试
calibration_refinement.py优化
| 指标 | 数值 |
|---|---|
| 控制频率 | 100 Hz |
| 定位精度 | ±1 mm |
| 重复精度 | ±0.5 mm |
| 最大负载 | 1.2 kg |
| 最大速度 | 100%(关节相关) |
| 工作半径 | 100-400 mm |
| 响应延迟 | <50 ms (局域网) |
| 视觉帧率 | 30 fps |
| Gemini 响应 | 1-3 秒 |
✅ 桌面物体分拣 ✅ 视觉引导装配 ✅ 自动化测试 ✅ 教学演示 ✅ 研究实验 ✅ 原型开发
❌ 高速生产线(速度限制) ❌ 精密微米级加工 ❌ 重载工业应用 ❌ 长时间连续运行(建议<4小时/次)
- PAROL6 官方: https://github.com/PCrnjak/PAROL-commander-software
- Discord 社区: https://discord.com/invite/prjUvjmGpZ
- Gemini API: https://ai.google.dev/gemini-api/docs
- RealSense SDK: https://github.com/IntelRealSense/librealsense
- 问题反馈: 项目 Issues 页面
请参考项目根目录的 LICENSE 文件
- PAROL6 创建者及社区
- Google Gemini AI 团队
- Intel RealSense 团队
- 所有贡献者和测试者
如有问题或建议:
- 提交 GitHub Issue
- 加入 PAROL6 Discord 频道
- 查看详细 API 文档:
API-Specific-README.md
祝使用愉快!🤖