FallenSigh 6a0ff886f3 fix(arm): compensate for reversed J1 motor direction
J1 motor rotation is reversed after replacement: code height=0 now maps to physical bottom (was -290). Fix by adding +290 offset in UDP command (to_udp_message and keyboard_control). User-facing coordinate system (-290=bottom, 0=top) is unchanged; FK/IK/state tracking unaffected.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-19 10:17:58 +08:00
2026-06-19 06:30:02 +08:00
2026-06-16 21:34:38 +08:00
2026-06-16 19:01:42 +08:00

CRAIC — Camera-Robot AI Control System

本仓库为 中国机器人及人工智能大赛CRAIC机器人任务挑战赛(小型桌面级) 参赛代码。

ESP32-S3 双核摄像头 + ROS 2 机械臂控制 + 视觉抓取的一体化机器人系统。

赛事信息

中国机器人及人工智能大赛China Robot and Artificial Intelligence Competition简称 CRAIC)是由 中国人工智能学会CAAI主办的全国性学科竞赛始于 1999 年,已列入全国普通高等学校学科竞赛排行榜教育部 A 类竞赛名单

本仓库参加赛项:机器人任务挑战赛(小型桌面级) — Robot Task Challenge (Small Desktop Level)

项目 信息
大赛名称 中国机器人及人工智能大赛
英文名称 China Robot and Artificial Intelligence Competition (CRAIC)
主办单位 中国人工智能学会 (CAAI)
赛事级别 全国普通高等学校学科竞赛排行榜 / 教育部 A 类
参赛赛项 机器人任务挑战赛(小型桌面级)
官方网站 www.caairobot.com

项目结构

craic/
├── jxbeye/                    # ESP32-S3 固件 (PlatformIO)
│   ├── src/main.cpp           # 双核摄像头推流 + UDP 控制
│   └── platformio.ini         # ESP32-S3-WROOM-1-N16R8 配置
├── ros2/                      # ROS 2 控制系统
│   ├── src/arm_control_msgs/  # 消息和服务定义
│   └── src/udp_teleop/        # 机械臂控制和视觉抓取节点
├── tools/                     # 独立工具脚本
│   ├── udp_control.py         # 命令行机械臂控制(带逆运动学)
│   ├── camera_to_base.py      # 相机坐标到基坐标变换
│   └── camera_capture.py      # MJPEG 流采集
└── docs/                      # 技术文档
    └── arm.md                 # 机械臂运动学推导

硬件

组件 型号
主控 ESP32-S3-WROOM-1-N16R8 (16MB Flash, 8MB PSRAM)
摄像头 OV2640 (XGA 1024×768, JPEG)
机械臂 6-DOF飞特 SCS/STS 串行舵机

核心功能

1. ESP32-S3 固件 (jxbeye/)

  • 双核架构Core 0 采集Core 1 推流
  • MJPEG 推流http://<IP> 实时查看
  • UDP 控制:端口 8888非阻塞异步处理
  • WiFi 配置:串口发送 WIFI:SSID:PASSWORD 配置

2. ROS 2 机械臂控制 (ros2/)

arm_control 节点

  • 关节空间和笛卡尔空间运动控制
  • 完整逆运动学和正运动学
  • 服务接口:move_joints, move_pose, get_pose, set_gripper
  • 状态发布10Hz

vision_grasp 节点

  • 相机坐标到基坐标系自动转换
  • 自动抓取:释放 → 移动 → 抓取 → 回收
  • 自动释放:移动 → 释放 → 回收

3. 工具脚本 (tools/)

  • udp_control.py - 命令行机械臂控制(支持逆运动学)
  • camera_to_base.py - 坐标变换工具
  • camera_capture.py - 相机帧采集(支持自动扫描)

快速开始

ESP32 固件

cd jxbeye
pio run -t upload
pio device monitor

首次启动创建热点 ESP32-S3-Camera(密码 12345678),访问 http://192.168.4.1

ROS 2 控制系统

# 环境准备(首次)
conda create -n ros2_humble -c robostack-staging -c conda-forge ros-humble-desktop
conda activate ros2_humble

# 编译
cd ros2
export PYTHON_EXECUTABLE=$CONDA_PREFIX/bin/python
export PYTHON_INCLUDE_DIR=$CONDA_PREFIX/include/python3.12
export PYTHON_LIBRARY=$CONDA_PREFIX/lib/libpython3.12.so

colcon build --packages-select arm_control_msgs \
  --cmake-args \
    -DPython_EXECUTABLE=$PYTHON_EXECUTABLE \
    -DPython_INCLUDE_DIR=$PYTHON_INCLUDE_DIR \
    -DPython_LIBRARY=$PYTHON_LIBRARY

colcon build --packages-select udp_teleop
source install/setup.bash

# 运行机械臂控制
ros2 run udp_teleop arm_control \
    --ros-args --params-file src/udp_teleop/config/arm_control.yaml

# 运行视觉抓取(新终端)
ros2 run udp_teleop vision_grasp \
    --ros-args --params-file src/udp_teleop/config/vision_grasp.yaml

命令行工具

# 机械臂控制(关节空间)
python tools/udp_control.py joints \
    --height -100 --j2 10 --j3 20 --j4 30 --duration 2.0

# 机械臂控制(笛卡尔空间)
python tools/udp_control.py pose \
    --x 200 --y 100 --z -100 --phi 45 --duration 2.0

# 相机采集
python tools/camera_capture.py --ip 192.168.4.1
python tools/camera_capture.py --scan  # 自动扫描

UDP 协议

所有指令通过 UDP 端口 8888 发送:

# 底盘控制(麦克纳姆轮)
XYW:<X>:<Y>:<W>:XZHY\n

# 机械臂控制6 轴)
JXB:<height>:<J2>:<J3>:<J4>:<J5>:<J6>:0:0:EZHY\n

# 激光控制
LASERON / LASEROFF

使用示例

ROS 服务调用

# 查询位姿
ros2 service call /arm_control/get_pose arm_control_msgs/srv/GetPose

# 移动到目标位置
ros2 service call /arm_control/move_pose arm_control_msgs/srv/MovePose \
    "{x: 200.0, y: 100.0, z: -100.0, phi: 45.0, duration: 2.0}"

# 视觉抓取(发布相机坐标)
ros2 topic pub --once /vision_grasp/grasp_target geometry_msgs/Point \
    "{x: 10.0, y: 5.0, z: 250.0}"

Python 集成

import rclpy
from geometry_msgs.msg import Point

class VisionDetector:
    def __init__(self):
        self.grasp_pub = self.create_publisher(Point, 'vision_grasp/grasp_target', 10)
    
    def on_detection(self, camera_x, camera_y, camera_z):
        msg = Point()
        msg.x = camera_x
        msg.y = camera_y
        msg.z = camera_z
        self.grasp_pub.publish(msg)

文档

坐标系说明

机械臂基坐标系Z 轴朝上):

  • 原点J1 线性滑轨底部
  • X 轴:基座正前方
  • Y 轴:基座左侧
  • Z 轴:竖直向上(高度)

相机坐标系(水平安装):

  • X 轴:右侧
  • Y 轴:向下
  • Z 轴:正前方(光轴)

变换由 camera_to_base.pyvision_grasp 节点自动处理。

依赖

环境 依赖
ESP32 PlatformIO, Arduino framework, esp32-camera
ROS 2 ROS 2 Humble (robostack), Python 3.12
工具 NumPy, OpenCV (可选)

许可

MIT License

Description
No description provided
Readme 6.7 MiB
Languages
Python 56.9%
C++ 40.9%
CMake 1.6%
C 0.3%
Shell 0.2%
Other 0.1%