init
This commit is contained in:
768
README.md
768
README.md
@ -1,87 +1,717 @@
|
||||
# 他山触觉传感器python(64bit)demo
|
||||
# 触觉传感器与执行器控制系统 —— 使用手册
|
||||
|
||||
此demo为他山触觉传感器python(64bit)demo,可以读取传感器的通道原始值和三维力值
|
||||
## 项目概述
|
||||
|
||||
# Getting started
|
||||
本项目提供了一套完整的触觉传感器数据采集与执行器(舵机、直线电机)控制系统,包含底层 I2C 通信驱动、传感器数据解析、多指数据采集、串口执行器控制、手柄/键盘遥控以及数据记录等功能模块。
|
||||
|
||||
## 安装ch341驱动
|
||||
### 系统架构
|
||||
|
||||
### windows
|
||||
直接运行CH341PAR.exe,按照提示安装
|
||||
|
||||
### linux
|
||||
|
||||
按照“CH341PAR_LINUX”文件夹下的“README.md"安装驱动
|
||||
|
||||
## linux下环境搭建
|
||||
对于linux用户,需要将ch341添加到udev规则(普通用户也可以访问ch341设备),或者使用sudo权限来运行程序(不推荐)
|
||||
|
||||
### 将用户添加到dialout组
|
||||
查看 dialout 组的成员,如果不包含当前用户则需要将用户添加到 dialout 组,“john”替换为你想要添加到组的用户名
|
||||
```
|
||||
# 查看 dialout 组的成员
|
||||
getent group dialout
|
||||
|
||||
# 将用户 'john' 添加到 dialout 组
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ 应用层 (Application) │
|
||||
│ demo_auto_grasp.py test_dof_control.py │
|
||||
│ gamepad_remote.py gamepad_remote_new_pcb.py │
|
||||
│ keyboard_remote_new_pcb.py data_logger.py │
|
||||
│ grasp_network_model.py │
|
||||
├──────────────────────────────────────────────────────┤
|
||||
│ 数据采集层 (DAQ Layer) │
|
||||
│ cap_read.py tactile_sensor_daq.py │
|
||||
├──────────────────────────────────────────────────────┤
|
||||
│ 驱动抽象层 (Driver Layer) │
|
||||
│ class_finger.py class_sensorcmd.py sensorPara.py │
|
||||
│ class_ch341.py serial_robot_driver.py │
|
||||
├──────────────────────────────────────────────────────┤
|
||||
│ 硬件层 (Hardware) │
|
||||
│ CH341 (USB-I2C) STM32F103 (Serial) │
|
||||
│ 触觉传感器 舵机 / 直线电机 │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [环境准备](#1-环境准备)
|
||||
2. [模块说明](#2-模块说明)
|
||||
3. [快速开始](#3-快速开始)
|
||||
4. [底层驱动详解](#4-底层驱动详解)
|
||||
5. [数据采集模块](#5-数据采集模块)
|
||||
6. [执行器控制](#6-执行器控制)
|
||||
7. [遥控模块](#7-遥控模块)
|
||||
8. [数据记录](#8-数据记录)
|
||||
9. [神经网络模型](#9-神经网络模型)
|
||||
10. [STM32 固件](#10-stm32-固件)
|
||||
11. [硬件接线](#11-硬件接线)
|
||||
12. [常见问题](#12-常见问题)
|
||||
|
||||
---
|
||||
|
||||
## 1. 环境准备
|
||||
|
||||
> **重要:请严格按照以下顺序操作,先安装驱动,再安装 Python 依赖。**
|
||||
|
||||
### 1.1 CH341 驱动安装(必须首先完成)
|
||||
|
||||
CH341 是 USB 转 I2C 芯片,用于与触觉传感器通信。**使用本项目前,必须先安装此驱动**,否则传感器无法被电脑识别。
|
||||
|
||||
#### Windows
|
||||
|
||||
1. 在项目根目录下找到压缩包 **`CH341驱动(先卸载再安装).zip`**,将其解压。
|
||||
2. **如果之前安装过其它版本的 CH341 驱动,请先卸载**。
|
||||
3. 运行解压后的 `CH341PAR.exe`,按照提示完成安装。
|
||||
4. 安装完成后,将传感器通过 CH341 转接板连接电脑 USB,系统会自动识别设备。
|
||||
|
||||
> 驱动安装后,项目代码会自动加载 `lib/ch341/CH341DLLA64.DLL`,无需额外配置。
|
||||
|
||||
#### Linux
|
||||
|
||||
1. 将 `lib/ch341/libch347.so` 放置到系统库路径或项目目录下。
|
||||
|
||||
2. 配置 udev 规则(将 `john` 替换为你的用户名):
|
||||
```bash
|
||||
# 将用户添加到 dialout 组
|
||||
sudo usermod -a -G dialout john
|
||||
```
|
||||
### 创建rules文件
|
||||
在 /etc/udev/rules.d/ 目录下创建一个新的规则文件,例如 ch341.rules,添加如下内容:
|
||||
```
|
||||
SUBSYSTEM=="usbmisc", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="5512", MODE="0666", GROUP="dialout"
|
||||
```
|
||||
idVendor和idProduct是CH341设备的供应商和产品ID,可以通过lsusb命令查找这些ID
|
||||
### 更新规则文件
|
||||
```
|
||||
|
||||
# 创建 udev 规则文件
|
||||
sudo bash -c 'echo "SUBSYSTEM==\"usbmisc\", ATTRS{idVendor}==\"1a86\", ATTRS{idProduct}==\"5512\", MODE=\"0666\", GROUP=\"dialout\"" > /etc/udev/rules.d/ch341.rules'
|
||||
|
||||
# 重载规则
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger
|
||||
```
|
||||
|
||||
# 运行示例
|
||||
3. 重新插拔 CH341 设备,或重启计算机使 udev 规则生效。
|
||||
|
||||
## 上电
|
||||
传感器不同版本的固件上电时间存在差异,建议在传感器上电3s后再运行读取程序
|
||||
## demo根目录下运行如下命令执行程序
|
||||
### 1.2 Python 依赖
|
||||
|
||||
推荐使用 Python 3.8 及以上版本。安装依赖:
|
||||
|
||||
```bash
|
||||
pip install pyserial numpy pygame keyboard torch
|
||||
```
|
||||
|
||||
各模块依赖说明:
|
||||
|
||||
| 模块 | 依赖 |
|
||||
|------|------|
|
||||
| 底层驱动 (class_ch341, class_sensorcmd, class_finger) | 无额外依赖 |
|
||||
| 数据采集 (cap_read, tactile_sensor_daq) | numpy |
|
||||
| 串口执行器 (serial_robot_driver) | pyserial |
|
||||
| 手柄遥控 (gamepad_remote, gamepad_remote_new_pcb) | pyserial, pygame |
|
||||
| 键盘遥控 (keyboard_remote_new_pcb) | pyserial, keyboard, numpy |
|
||||
| 数据记录 (data_logger) | numpy |
|
||||
| 神经网络 (grasp_network_model) | torch (PyTorch) |
|
||||
|
||||
> **说明:** 如果仅使用传感器数据读取功能(cap_read、tactile_sensor_daq),只需安装 `numpy`。执行器控制、遥控、神经网络等模块可按需安装对应依赖。
|
||||
|
||||
---
|
||||
|
||||
## 2. 模块说明
|
||||
|
||||
### 2.1 文件清单
|
||||
|
||||
| 文件名 | 功能说明 |
|
||||
|--------|----------|
|
||||
| `class_ch341.py` | CH341 USB-I2C 底层驱动,封装 I2C 读写、速度设置、INT 引脚控制 |
|
||||
| `class_sensorcmd.py` | 传感器 I2C 命令协议,封装所有传感器配置与读取命令 |
|
||||
| `class_finger.py` | 传感器(手指)数据解析,包含电容/力数据读取与协议解析 |
|
||||
| `sensorPara.py` | 传感器参数定义(通道数、力单元数、数据格式等) |
|
||||
| `cap_read.py` | 基础电容读取入口,支持单指/多指数据采集与实时可视化 |
|
||||
| `tactile_sensor_daq.py` | 多指触觉传感器数据采集模块(线程安全,支持去皮) |
|
||||
| `serial_robot_driver.py` | 串口执行器驱动,控制舵机和直线电机 |
|
||||
| `stm32f103_drv8870_servo_main.c` | STM32F103 下位机固件源码 |
|
||||
| `demo_auto_grasp.py` | 演示程序:触觉反馈自动抓取任务 |
|
||||
| `gamepad_remote.py` | 游戏手柄遥控程序 |
|
||||
| `gamepad_remote_new_pcb.py` | 新 PCB 版手柄遥控(支持 ACK 协议和自检) |
|
||||
| `keyboard_remote_new_pcb.py` | 新 PCB 版键盘遥控(支持力反馈与压力计算) |
|
||||
| `test_dof_control.py` | 自由度独立控制测试 |
|
||||
| `data_logger.py` | CSV 数据记录器 |
|
||||
| `grasp_network_model.py` | 条件抓取网络模型(Conditional MLP) |
|
||||
| `接线说明.txt` | 硬件接线参考 |
|
||||
| `新PCB控制实施方案.md` | 新 PCB 控制系统实施方案 |
|
||||
| `CH341驱动(先卸载再安装).zip` | CH341 驱动程序压缩包,使用前必须先解压安装 |
|
||||
| `传感器iic地址和转接板位置定义.png` | I2C 地址与接口位置对照图 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 快速开始
|
||||
|
||||
### 3.1 仅读取单个传感器数据
|
||||
|
||||
```bash
|
||||
python cap_read.py
|
||||
```
|
||||
程序运行结果:
|
||||
```
|
||||
capChannelDat=[3020838, 3006548, 2986382, 2929380, 2995152, 2992100, 2988970, 2996232, 2904946, 2947736, 2895000, 2842188, 2999608, 2922258, 2776718, 7950022]
|
||||
nf[0] = 0.0
|
||||
tf[0] = 0.0
|
||||
tfDir[0] = 0
|
||||
nf[1] = 0.0
|
||||
tf[1] = 0.0
|
||||
tfDir[1] = 0
|
||||
sProxCapData[0] = 0
|
||||
sProxCapData[1] = 0
|
||||
mProxCapData[0] = 0
|
||||
```
|
||||
* capChannelDat为电容通道原始值
|
||||
* nf、tf、tfDir分别为一组三维力的法向力、切向力和切向力方向
|
||||
* sProxCapData为自电容接近值
|
||||
* mProxCapData为互电容接近值
|
||||
|
||||
## 连接手指数量设定
|
||||
手指连接板最大支持5个传感器连接,不足5个传感器连接会影响读取频率,可以修改如下宏定义配置连接数量:
|
||||
```
|
||||
DEF_MAX_FINGER_NUM = 2 # 需要连接的手指数量,最大5个
|
||||
```
|
||||
## iic接口顺序和iic地址定义
|
||||
此demo中的iic地址和插入转接板的接口位置是固定对应关系,iic地址和iic接口顺序对照关系如下:
|
||||
运行前可在 `cap_read.py` 中修改传感器连接数量:
|
||||
|
||||

|
||||
如果插入的传感器和对应接口的iic地址不同,在初始化阶段会强制将传感器的iic地址设置为图中对应的地址:
|
||||
```python
|
||||
DEF_MAX_FINGER_NUM = 1 # 需要连接的手指数量,最大5个
|
||||
```
|
||||
def checkSensor(self):
|
||||
# 广播的方式读取当前传感器地址,并默认将iic地址配置为和pca相同的地址
|
||||
addrRead = self.snsCmd.getAddr(0)
|
||||
if addrRead != self.pcaIdx:
|
||||
if self.pcaIdx != self.snsCmd.setAddr(addrRead, self.pcaIdx):
|
||||
print(f"set addr false, setaddr={self.pcaIdx}")
|
||||
return False
|
||||
else:
|
||||
addrRead = self.pcaIdx
|
||||
print(f"update iic addr, new addr ={addrRead}")
|
||||
|
||||
输出数据包括:
|
||||
- `capChannelDat`:电容通道原始值
|
||||
- `nf[i]`:第 i 个单元的法向力
|
||||
- `tf[i]`:第 i 个单元的切向力
|
||||
- `tfDir[i]`:第 i 个单元的切向力方向
|
||||
- `sProxCapData`:自电容接近值
|
||||
- `mProxCapData`:互电容接近值
|
||||
|
||||
### 3.2 读取多个传感器数据(100Hz)
|
||||
|
||||
```python
|
||||
from tactile_sensor_daq import TactileSensorDAQ
|
||||
|
||||
sensor = TactileSensorDAQ()
|
||||
sensor.start()
|
||||
|
||||
# 等待传感器连接稳定
|
||||
import time
|
||||
time.sleep(3)
|
||||
sensor.tare() # 去皮
|
||||
|
||||
while True:
|
||||
data = sensor.get_data() # 获取 12 维力数据
|
||||
print(data)
|
||||
time.sleep(0.1)
|
||||
```
|
||||
|
||||
### 3.3 控制执行器(串口)
|
||||
|
||||
```python
|
||||
from serial_robot_driver import RobotDriver
|
||||
|
||||
robot = RobotDriver(port='COM9')
|
||||
robot.motor_open() # 直线电机张开
|
||||
robot.motor_close() # 直线电机闭合
|
||||
robot.motor_stop() # 停止
|
||||
robot.set_servo(1, 90) # 舵机1转到90度
|
||||
robot.set_config(0) # 构型0(初始位)
|
||||
robot.close()
|
||||
```
|
||||
|
||||
### 3.4 命令行快速测试
|
||||
|
||||
```bash
|
||||
# 测试通信
|
||||
python gamepad_remote_new_pcb.py --port COM9 --cmd PING
|
||||
|
||||
# 硬件自检
|
||||
python gamepad_remote_new_pcb.py --port COM9 --test
|
||||
|
||||
# 手柄遥控
|
||||
python gamepad_remote_new_pcb.py --port COM9
|
||||
|
||||
# 键盘遥控
|
||||
python keyboard_remote_new_pcb.py --port COM9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 底层驱动详解
|
||||
|
||||
### 4.1 class_ch341.py —— CH341 I2C 通信驱动
|
||||
|
||||
封装 CH341 USB-I2C 转换芯片的操作。
|
||||
|
||||
**主要接口:**
|
||||
|
||||
```python
|
||||
from class_ch341 import ClassCh341
|
||||
|
||||
ch341 = ClassCh341()
|
||||
|
||||
# 初始化并打开设备
|
||||
ch341.init() # 加载 DLL/SO 库
|
||||
ch341.open() # 打开 USB 设备
|
||||
|
||||
# 设置 I2C 速度
|
||||
ch341.set_speed(ch341.IIC_SPEED_400) # 20/100/400/750 kHz
|
||||
|
||||
# I2C 读写
|
||||
ch341.write(addr, data_list) # 向从机地址写入数据列表
|
||||
ch341.read(addr, data_list) # 从从机地址读取数据到列表
|
||||
|
||||
# 连接检查
|
||||
ch341.connectCheck() # 返回 True/False
|
||||
|
||||
# 断开
|
||||
ch341.disconnect()
|
||||
```
|
||||
|
||||
### 4.2 class_sensorcmd.py —— 传感器命令协议
|
||||
|
||||
封装与触觉传感器 MCU 的 I2C 命令协议。
|
||||
|
||||
**主要接口:**
|
||||
|
||||
```python
|
||||
from class_sensorcmd import ClassSensorCmd
|
||||
|
||||
snsCmd = ClassSensorCmd(ch341)
|
||||
|
||||
# 地址管理
|
||||
snsCmd.getAddr(addr) # 读取传感器 I2C 地址
|
||||
snsCmd.setAddr(old_addr, new) # 设置新地址
|
||||
|
||||
# 传感器配置
|
||||
snsCmd.setSensorSendType(addr, 0) # 设置数据发送类型为原始值
|
||||
snsCmd.setSensorCapOffset(addr, offset) # 设置电容采集时序偏移
|
||||
|
||||
# 读取数据
|
||||
snsCmd.getSensorCapData(addr, buf) # 读取电容数据
|
||||
snsCmd.getSensorProjectIdex(addr) # 读取项目编号
|
||||
|
||||
# 同步
|
||||
snsCmd.setSensorSync(addr) # 多传感器同步
|
||||
```
|
||||
|
||||
### 4.3 sensorPara.py —— 传感器参数定义
|
||||
|
||||
定义了传感器项目的参数结构和具体参数值。
|
||||
|
||||
```python
|
||||
from sensorPara import finger_params, FingerParamTS, DynamicYddsU16Ts
|
||||
|
||||
# finger_params 包含所有支持的传感器类型
|
||||
# 目前支持:
|
||||
# - 项目2: "通用手指", 8通道, 1个三维力单元
|
||||
# - 项目17: "两指-大包", 16通道, 2个三维力单元
|
||||
```
|
||||
|
||||
如需添加新的传感器型号,在 `sensorPara.py` 中追加 `FingerParamTS` 条目即可。
|
||||
|
||||
### 4.4 class_finger.py —— 传感器数据解析
|
||||
|
||||
管理单个传感器(手指)的连接状态和数据读取。
|
||||
|
||||
```python
|
||||
from class_finger import ClassFinger, capData
|
||||
|
||||
finger = ClassFinger(pca_idx=2, ch341=ch341)
|
||||
|
||||
# 检查传感器连接
|
||||
if finger.checkSensor():
|
||||
print("Sensor connected")
|
||||
|
||||
# 读取数据
|
||||
finger.capRead()
|
||||
|
||||
# 访问数据
|
||||
finger.readData.channelCapData # 电容通道原始值
|
||||
finger.readData.nf[i] # 第i个单元的法向力
|
||||
finger.readData.tf[i] # 第i个单元的切向力
|
||||
finger.readData.tfDir[i] # 第i个单元的切向力方向
|
||||
finger.readData.sProxCapData # 自电容接近值
|
||||
finger.readData.mProxCapData # 互电容接近值
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 数据采集模块
|
||||
|
||||
### 5.1 cap_read.py —— 基础电容读取
|
||||
|
||||
最简单直接的传感器数据读取入口。内部维护 CH341 连接状态机,定时轮询读取电容数据,并通过 TCP Socket 发送到 VOFA+ 等调试工具进行实时可视化。
|
||||
|
||||
**配置参数:**
|
||||
|
||||
```python
|
||||
DEF_MAX_FINGER_NUM = 1 # 连接手指数量 (1-5)
|
||||
DEF_GET_CAP_MS = 30 # 读取间隔 (ms)
|
||||
DEF_CDC_SYNC_MS = 1000 # 电容同步间隔 (ms),多传感器时使用
|
||||
```
|
||||
|
||||
**运行:**
|
||||
|
||||
```bash
|
||||
python cap_read.py
|
||||
```
|
||||
|
||||
数据通过 Socket 发送到 `127.0.0.1:1347`(VOFA+ 默认端口)。
|
||||
|
||||
### 5.2 tactile_sensor_daq.py —— 多指触觉传感器 DAQ
|
||||
|
||||
线程安全的传感器数据采集模块,支持 3 个手指、12 维力数据输出,含去皮(tare)功能。
|
||||
|
||||
```python
|
||||
from tactile_sensor_daq import TactileSensorDAQ
|
||||
|
||||
sensor = TactileSensorDAQ()
|
||||
sensor.start() # 启动后台采集线程
|
||||
sensor.tare() # 去皮:将当前读数归零
|
||||
data = sensor.get_data() # 获取 12 维 numpy 数组 [F0_U1_Fn, F0_U1_Ft, F0_U2_Fn, ...]
|
||||
sensor.stop() # 停止采集
|
||||
```
|
||||
|
||||
**数据格式**(12 维 float32):
|
||||
|
||||
| 索引 | 含义 |
|
||||
|------|------|
|
||||
| 0-1 | 手指0-单元1: 法向力(Fn), 切向力(Ft) |
|
||||
| 2-3 | 手指0-单元2: 法向力(Fn), 切向力(Ft) |
|
||||
| 4-5 | 手指1-单元1: 法向力(Fn), 切向力(Ft) |
|
||||
| 6-7 | 手指1-单元2: 法向力(Fn), 切向力(Ft) |
|
||||
| 8-9 | 手指2-单元1: 法向力(Fn), 切向力(Ft) |
|
||||
| 10-11| 手指2-单元2: 法向力(Fn), 切向力(Ft) |
|
||||
|
||||
**配置参数:**
|
||||
|
||||
```python
|
||||
DEF_MAX_FINGER_NUM = 3 # 传感器数量
|
||||
SAMPLE_RATE_MS = 10 # 采样间隔 (ms),默认 100Hz
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 执行器控制
|
||||
|
||||
### 6.1 serial_robot_driver.py —— 串口执行器驱动
|
||||
|
||||
通过串口(USB-TTL)向 STM32 下位机发送 ASCII 命令,控制直线电机和舵机。
|
||||
|
||||
```python
|
||||
from serial_robot_driver import RobotDriver
|
||||
|
||||
robot = RobotDriver(port='COM9', baud=115200)
|
||||
|
||||
# 直线电机控制
|
||||
robot.motor_open() # 张开
|
||||
robot.motor_close() # 闭合
|
||||
robot.motor_stop() # 停止
|
||||
|
||||
# 舵机控制
|
||||
robot.set_servo(1, 90) # 舵机1转到90度
|
||||
robot.set_servo(2, 120) # 舵机2转到120度
|
||||
|
||||
# 构型切换(组合动作)
|
||||
robot.set_config(0) # 初始构型: S1=90, S2=90
|
||||
robot.set_config(1) # 错位构型: S1=30, S2=150
|
||||
robot.set_config(2) # 对握构型: S1=120, S2=60
|
||||
|
||||
robot.close()
|
||||
```
|
||||
|
||||
### 6.2 串口通信协议
|
||||
|
||||
上位机向 STM32 发送 ASCII 命令(以 `\r\n` 结尾),STM32 回复 `OK:` 或 `ERR:` 确认。
|
||||
|
||||
| 命令 | 功能 | 回复 |
|
||||
|------|------|------|
|
||||
| `PING` | 通信测试 | `OK:PONG` |
|
||||
| `M:OPEN` | 直线电机张开 | `OK:M:OPEN` |
|
||||
| `M:CLOSE` | 直线电机闭合 | `OK:M:CLOSE` |
|
||||
| `M:STOP` | 直线电机停止 | `OK:M:STOP` |
|
||||
| `S1:<angle>` | 舵机1角度(0-180) | `OK:S1` |
|
||||
| `S2:<angle>` | 舵机2角度(0-180) | `OK:S2` |
|
||||
| `CFG:<mode>` | 构型切换(0/1/2) | `OK:CFG` |
|
||||
|
||||
### 6.3 gamepad_remote_new_pcb.py —— 新 PCB 版执行器驱动
|
||||
|
||||
相比 `serial_robot_driver.py`,增加了 ACK 确认、命令行参数、自检等功能。
|
||||
|
||||
```bash
|
||||
# 单条命令
|
||||
python gamepad_remote_new_pcb.py --port COM9 --cmd PING
|
||||
python gamepad_remote_new_pcb.py --port COM9 --cmd S1:90
|
||||
|
||||
# 硬件自检
|
||||
python gamepad_remote_new_pcb.py --port COM9 --test
|
||||
|
||||
# 不等待 ACK (适用于简单固件)
|
||||
python gamepad_remote_new_pcb.py --port COM9 --no-ack
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 遥控模块
|
||||
|
||||
### 7.1 gamepad_remote.py —— 手柄遥控
|
||||
|
||||
使用 Xbox/兼容游戏手柄远程控制执行器。
|
||||
|
||||
**按键映射:**
|
||||
|
||||
| 按键 | 功能 |
|
||||
|------|------|
|
||||
| A | 构型0(初始) |
|
||||
| B | 构型1(错位) |
|
||||
| X | 构型2(对握) |
|
||||
| LB 长按 | 直线电机张开 |
|
||||
| RB 长按 | 直线电机闭合 |
|
||||
| 松开 LB/RB | 电机停止 |
|
||||
| BACK | 急停切换 |
|
||||
| START | 退出 |
|
||||
|
||||
**运行:**
|
||||
|
||||
```bash
|
||||
python gamepad_remote.py
|
||||
```
|
||||
|
||||
默认连接 COM9,可在代码中修改 `port` 变量。
|
||||
|
||||
### 7.2 keyboard_remote_new_pcb.py —— 键盘遥控
|
||||
|
||||
使用键盘远程控制执行器,同时读取触觉传感器数据,支持力反馈自动抓取。
|
||||
|
||||
**按键映射:**
|
||||
|
||||
| 按键 | 功能 |
|
||||
|------|------|
|
||||
| q | 构型0(初始) |
|
||||
| w | 构型1(错位) |
|
||||
| e | 构型2(对握) |
|
||||
| ← 长按 | 直线电机闭合 |
|
||||
| → 长按 | 直线电机张开 |
|
||||
| 空格 | 急停/恢复 |
|
||||
| Esc | 退出 |
|
||||
|
||||
**主要功能:**
|
||||
- 按下闭合键持续闭合,松开自动停止并打印执行时间
|
||||
- 实时显示接触压力(KPa)
|
||||
- 支持急停保护和构型切换
|
||||
|
||||
**运行:**
|
||||
|
||||
```bash
|
||||
python keyboard_remote_new_pcb.py --port COM9
|
||||
python keyboard_remote_new_pcb.py --port COM9 --test # 自检模式
|
||||
python keyboard_remote_new_pcb.py --port COM9 --contact-area-mm2 240 # 自定义接触面积
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 数据记录
|
||||
|
||||
### data_logger.py —— CSV 数据记录器
|
||||
|
||||
将触觉传感器数据记录为 CSV 文件,自动创建 `data/` 目录并以时间戳命名。
|
||||
|
||||
```python
|
||||
from data_logger import DataLogger
|
||||
|
||||
logger = DataLogger(filename_prefix="experiment_01")
|
||||
|
||||
# 记录一行数据
|
||||
# sensor_data: 12维触觉数据
|
||||
# config_id: 构型ID (0/1/2)
|
||||
# label_vector: 标签 [x, y, theta]
|
||||
logger.log(sensor_data=sensor.get_data(), config_id=1, label_vector=[0.0, 5.5, -2.0])
|
||||
```
|
||||
|
||||
**CSV 格式:**
|
||||
|
||||
| Timestamp | Config_ID | F0_U1_Fn | F0_U1_Ft | ... | Label_X | Label_Y | Label_Theta |
|
||||
|-----------|-----------|----------|----------|-----|---------|---------|-------------|
|
||||
|
||||
---
|
||||
|
||||
## 9. 神经网络模型
|
||||
|
||||
### grasp_network_model.py —— 条件抓取网络 (CondGraspNet)
|
||||
|
||||
一个条件 MLP 网络,输入 12 维触觉数据 + 3 维构型编码,输出 3 维偏差预测 [ΔX, ΔY, Δθ]。
|
||||
|
||||
**网络结构:**
|
||||
|
||||
```
|
||||
Input(15) → FC(64)+BN+ReLU → FC(128)+BN+ReLU → FC(64)+ReLU → Output(3)
|
||||
```
|
||||
|
||||
**使用示例:**
|
||||
|
||||
```python
|
||||
from grasp_network_model import CondGraspNet
|
||||
import torch
|
||||
|
||||
model = CondGraspNet()
|
||||
tactile_data = torch.randn(8, 12) # Batch=8, 12维触觉
|
||||
config_ids = torch.tensor([0,0,1,1,2,2,0,2]) # 构型ID
|
||||
predictions = model(tactile_data, config_ids) # [8, 3] 输出
|
||||
```
|
||||
|
||||
**单元测试:**
|
||||
|
||||
```bash
|
||||
python grasp_network_model.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. STM32 固件
|
||||
|
||||
### stm32f103_drv8870_servo_main.c
|
||||
|
||||
STM32F103C8T6 下位机固件,负责接收上位机串口命令并控制硬件。
|
||||
|
||||
**硬件映射:**
|
||||
|
||||
| 功能 | STM32引脚 | 说明 |
|
||||
|------|-----------|------|
|
||||
| USART1 TX | PA9 | 连接 USB-TTL RXD |
|
||||
| USART1 RX | PA10 | 连接 USB-TTL TXD |
|
||||
| 直线电机 IN1 | PB12 | 连接 DRV8870 IN1 |
|
||||
| 直线电机 IN2 | PB13 | 连接 DRV8870 IN2 |
|
||||
| 舵机1 PWM | PB11 | TIM2_CH4, 50Hz |
|
||||
| 舵机2 PWM | PB10 | TIM2_CH3, 50Hz |
|
||||
|
||||
**CubeMX 配置要点:**
|
||||
|
||||
- TIM2: Prescaler=71, Counter Period=19999, 产生 50Hz PWM
|
||||
- USART1: 115200 8N1
|
||||
- 需开启 TIM2 重映射(AFIO Remap)
|
||||
|
||||
**集成方法:**
|
||||
|
||||
将 `stm32f103_drv8870_servo_main.c` 中的用户代码集成到 CubeMX 生成的工程:
|
||||
|
||||
```c
|
||||
int main(void)
|
||||
{
|
||||
HAL_Init();
|
||||
SystemClock_Config();
|
||||
MX_GPIO_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_TIM2_Init();
|
||||
|
||||
app_init(); // 初始化舵机和电机
|
||||
|
||||
while (1) {
|
||||
app_loop(); // 主循环:处理串口命令 + 看门狗
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**安全特性:**
|
||||
|
||||
- 1 秒无指令自动停止直线电机(通信丢失保护)
|
||||
- 命令超长自动拒绝
|
||||
|
||||
### 调试顺序
|
||||
|
||||
1. 仅给 PCB/STM32 上电(不接电机和舵机)
|
||||
2. `python gamepad_remote_new_pcb.py --port COM9 --cmd PING` → 应返回 `OK:PONG`
|
||||
3. 用示波器测舵机 PWM 信号:
|
||||
- `S1:0` → PB11 约 0.5ms 高电平
|
||||
- `S1:90` → PB11 约 1.5ms 高电平
|
||||
- `S1:180` → PB11 约 2.5ms 高电平
|
||||
4. 测直线电机控制引脚:
|
||||
- `M:OPEN` → PB12=高, PB13=低
|
||||
- `M:CLOSE` → PB12=低, PB13=高
|
||||
- `M:STOP` → PB12=低, PB13=低
|
||||
5. 信号确认正确后,接舵机独立 5V 电源
|
||||
6. 最后接直线电机电源和负载
|
||||
|
||||
---
|
||||
|
||||
## 11. 硬件接线
|
||||
|
||||
### 11.1 传感器接线(CH341 USB-I2C)
|
||||
|
||||
传感器通过 I2C 转接板连接,转接板通过 CH341 芯片与 PC 的 USB 连接。
|
||||
|
||||
I2C 地址与转接板接口位置为固定对应关系,详见 `传感器iic地址和转接板位置定义.png`。
|
||||
|
||||
### 11.2 执行器接线(USB-TTL + STM32)
|
||||
|
||||
```
|
||||
USB-TTL STM32F103C8T6
|
||||
3.3V → 3.3V
|
||||
GND → GND
|
||||
TXD → PA10 (RXD)
|
||||
RXD → PA9 (TXD)
|
||||
|
||||
STM32 外设
|
||||
PB12 → DRV8870 IN1
|
||||
PB13 → DRV8870 IN2
|
||||
PB11 → 舵机1 信号线 (A0绿)
|
||||
PB10 → 舵机2 信号线 (A1橙)
|
||||
GND → 舵机 GND
|
||||
GND → 直线电机 GND
|
||||
```
|
||||
|
||||
详见 `接线说明.txt`。
|
||||
|
||||
### 11.3 供电注意事项
|
||||
|
||||
- MG996R 舵机不可由 STM32 板载 5V 供电,需使用独立 5V 3A 以上电源
|
||||
- 舵机电源 GND、直线电机电源 GND、STM32 GND 必须共地
|
||||
- DRV8870 的 VM 电压须匹配直线电机额定电压
|
||||
- 直线电机首次测试建议只点动 0.5s,防止方向相反或机械顶死
|
||||
- 如果 M:OPEN 和 M:CLOSE 方向相反,可在固件中交换 PB12/PB13 输出逻辑,或交换电机两线
|
||||
|
||||
---
|
||||
|
||||
## 12. 常见问题
|
||||
|
||||
### Q: 运行 cap_read.py 提示 "ch341加载失败"?
|
||||
|
||||
A: 检查 `lib/ch341/` 目录下是否有对应平台的库文件:
|
||||
- Windows: `CH341DLLA64.DLL`
|
||||
- Linux: `libch347.so`
|
||||
|
||||
并确保已安装 CH341 驱动程序。
|
||||
|
||||
### Q: 传感器无法连接?
|
||||
|
||||
A:
|
||||
1. 确认传感器已上电 3 秒以上再运行程序
|
||||
2. 检查 I2C 地址是否与转接板接口匹配
|
||||
3. 运行后查看终端输出,程序会自动尝试匹配地址
|
||||
|
||||
### Q: 手柄遥控无法识别手柄?
|
||||
|
||||
A:
|
||||
1. 确保手柄已通过蓝牙/USB 连接并被系统识别
|
||||
2. Windows 下可在"控制面板→设备和打印机"中验证
|
||||
3. 确保安装了 pygame 库
|
||||
|
||||
### Q: 串口命令无响应?
|
||||
|
||||
A:
|
||||
1. 确认 COM 口号正确(Windows 在设备管理器中查看)
|
||||
2. 确认波特率为 115200
|
||||
3. 用 `--cmd PING` 测试基本通信
|
||||
4. 检查 USB-TTL 的 TXD/RXD 是否交叉连接
|
||||
|
||||
### Q: 如何修改采样频率?
|
||||
|
||||
A: 修改对应文件中的配置参数:
|
||||
- `cap_read.py`: `DEF_GET_CAP_MS`
|
||||
- `tactile_sensor_daq.py`: `SAMPLE_RATE_MS`
|
||||
|
||||
### Q: 如何支持更多传感器型号?
|
||||
|
||||
A: 在 `sensorPara.py` 的 `finger_params` 列表中追加 `FingerParamTS` 参数定义。传感器会自动根据项目编号匹配对应参数。
|
||||
|
||||
---
|
||||
|
||||
## 项目文件结构
|
||||
|
||||
```
|
||||
HandControl/
|
||||
├── class_ch341.py # CH341 I2C 底层驱动
|
||||
├── class_sensorcmd.py # 传感器 I2C 命令协议
|
||||
├── class_finger.py # 传感器数据解析
|
||||
├── sensorPara.py # 传感器参数定义
|
||||
├── cap_read.py # 基础电容读取入口
|
||||
├── tactile_sensor_daq.py # 多指触觉传感器 DAQ
|
||||
├── serial_robot_driver.py # 串口执行器驱动
|
||||
├── gamepad_remote.py # 手柄遥控
|
||||
├── gamepad_remote_new_pcb.py # 新 PCB 手柄遥控
|
||||
├── keyboard_remote_new_pcb.py # 新 PCB 键盘遥控
|
||||
├── demo_auto_grasp.py # 演示:自动抓取任务
|
||||
├── test_dof_control.py # 自由度独立控制测试
|
||||
├── data_logger.py # CSV 数据记录器
|
||||
├── grasp_network_model.py # 抓取预测神经网络
|
||||
├── stm32f103_drv8870_servo_main.c # STM32 固件
|
||||
├── lib/ch341/ # CH341 驱动库
|
||||
│ ├── CH341DLLA64.DLL
|
||||
│ ├── CH341DLLA64.LIB
|
||||
│ ├── ch341_lib.h
|
||||
│ └── libch347.so
|
||||
├── 接线说明.txt # 硬件接线参考
|
||||
├── 新PCB控制实施方案.md # 控制系统实施方案
|
||||
├── 传感器iic地址和转接板位置定义.png # I2C 地址图
|
||||
└── README.md # 本文件
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user