找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1009

积分

0

好友

131

主题
发表于 4 天前 | 查看: 13| 回复: 0

人机交互方式正不断演进。当键盘、鼠标、数位板已成为日常,你是否想象过,只需在空中挥写一个数字“1”,电脑便能精准输入?

本项目基于 MAX78000微控制器 内置的CNN硬件加速器,结合IMU传感器与ESP32蓝牙模块,打造了一支功能强大的“AI智能遥控笔”。它不仅具备翻页、视频控制等传统遥控笔功能,更能识别空中手势,将“书空”动作直接转化为文本输入。下文将详细解析其设计思路、模型训练、硬件集成与部署的全过程。

项目整体示意图

项目核心:空中手势输入

当前,遥控笔因其便携与远程操控特性,在演示、教学等场景中广泛应用。我们旨在开发一款功能升级的智能遥控笔,其核心突破在于将空中书写(“书空”)转化为字符输入。例如,在空中书写数字“1”,即可在电脑端输入数字1。

市面常见翻页笔支持的手势有限。为此,我们充分利用MAX78000的CNN加速模块,通过人工智能技术训练笔识别更丰富的手势模式,以满足用户多样化需求。

系统设计思路

遥控笔的交互模块包括实体按钮、开关、惯性测量单元(IMU)及激光头。MAX78000负责读取这些输入(开关电平、按钮状态及IMU数据),经过逻辑处理与神经网络对IMU信号的分类,生成控制指令。指令通过串口发送至ESP32,再由ESP32通过蓝牙HID协议转发给电脑,从而实现手势控制与输入。此外,我们使用 KiCad 设计了专用拓展板,优化握持手感。

拓展板设计图

最终效果展示

最终成品如下图所示:

最终产品实物图

手势输入数字的实例如下:

手势输入数字演示
电脑端输入效果

除基础数字输入外,还实现了手势截图、切换应用等功能:

手势截图功能
手势切换应用

当然,作为一款翻页笔,聚光灯、数字/实体激光、音量调节、PPT翻页、视频快进/快退以及飞鼠功能一应俱全。

功能集合展示


实现过程详解

1. 数据采集与数据集制作

1.1 IMU数据读取与采集

项目选用 ICM20602 6轴运动传感器(3轴陀螺仪+3轴加速度计)。我们通过SPI协议与传感器通信。读取过程分为两步:先发送要读取的寄存器地址,再接收数据。

mxc_spi_req_t request;
// 写入要读取的地址
request.txData = tx_data;
request.txLen = 1;
request.rxData = NULL;
request.rxLen = 0;
request.ssDeassert = 0;
MXC_SPI_MasterTransaction(&request);

// 读取返回的数据
request.txData = NULL;
request.txLen = 0;
request.rxData = rx_data;
request.rxLen = 128;
request.ssDeassert = 1;
MXC_SPI_MasterTransaction(&request);

每次读取包含14字节数据(加速度、温度、陀螺仪)。手持遥控笔做出特定动作,单片机通过串口将实时数据发送至电脑保存。采集周期为1秒。

1.2 数据清洗与图像化

为便于网络移植与可视化,我们将IMU时序数据转化为3通道图像。这便于直接利用图像分类网络框架及PyTorch丰富的数据处理工具。

首先,使用正则表达式提取有效传感器数据:
pattern = r'([0-9A-Z]{2} ){14}00 00 00 (?!00 00 )'

随后进行数据标准化。由于原始角速度为16位,而CNN输入要求8位,需进行缩放。为确保单片机与PC端处理一致,并兼顾单片机算力,我们设计了移位替代除法的标准化流程(PC端使用Python,单片机端使用C语言实现逻辑等价操作)。

Python处理示例:

@staticmethod
def process_matrix(matrix):
    if not isinstance(matrix, np.ndarray):
        matrix = np.array(matrix)
    matrix = np.where(matrix > 32767, matrix-65536, matrix)
    matrix = matrix/32
    matrix = np.where(matrix > 127, 127, matrix)
    matrix = np.where(matrix < -128, -128, matrix)
    matrix = matrix+128
    return matrix

单片机C语言实现:

uint8_t nomilization(uint8_t h, uint8_t l, int16_t mean, int16_t bits) {
    int16_t _16bit = (*(int16_t*)&h) << 8 | l;
    _16bit = ((_16bit - mean) >> bits) + 128;
    if (_16bit >= 255) return 255;
    if (_16bit <= 0) return 0;
    return (uint8_t)_16bit;
}
// 应用
uint8_t gx = nomilization(rx_data[8], rx_data[9], 0, 5) ^ 0x80;
uint8_t gy = nomilization(rx_data[10], rx_data[11], 0, 5) ^ 0x80;
uint8_t gz = nomilization(rx_data[12], rx_data[13], 0, 5) ^ 0x80;

最后,将标准化后的gx, gy, gz数据作为三个通道,按行填充至6x6的图像中,生成最终的数据集样本。

数据图像化示例

2. 模型设计与网络训练

输入数据尺寸较小(3x6x6),且数据集规模有限,因此我们设计了一个轻量级卷积神经网络,结构如下:

网络结构图

模型定义文件示例 (基于Maxim AI框架):

from torch import nn
import ai8x

class AI85motion(nn.Module):
    def __init__(
            self,
            num_classes=3,
            num_channels=3,
            dimensions=(12, 12),
            bias=False,
            **kwargs
    ):
        super().__init__()
        self.conv1 = ai8x.FusedConv2dBNReLU(num_channels, 16, 3, stride=1, padding=1, bias=bias, **kwargs)
        self.conv2 = ai8x.FusedMaxPoolConv2dBNReLU(16, 9, 3, pool_size=2, pool_stride=2, stride=1, padding=0, bias=bias, **kwargs)

    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0), -1)
        return x

def ai85motion(pretrained=False, **kwargs):
    assert not pretrained
    return AI85motion(**kwargs)

models = [
    {
        'name': 'ai85motion',
        'min_input': 1,
        'dim': 2,
    },
]

训练使用Maxim官方提供的PyTorch训练框架。配置训练策略与量化感知训练(QAT)策略后,启动训练:

python train.py --epochs 40 --optimizer Adam --lr 0.001 --wd 0 \
--compress policies/schedule-motion.yaml --model ai85motion \
--dataset motion --device MAX78000 --batch-size 128 --print-freq 10 \
--validation-split 0 --qat-policy policies/qat_motion.yaml \
--use-bias "$@" --data ./data/motion --enable-tensorboard

最终训练结果优异:

  • 训练集: Top1准确率 91.341%, Top5准确率 97.067%
  • 测试集: Top1准确率 91.201%, Top5准确率 96.648%
    训练集与测试集表现接近,表明模型无明显过拟合或欠拟合问题。

3. 模型量化与部署

MAX78000硬件要求权重为8位,需对训练好的FP32模型进行量化。使用Maxim的synthesis工具,并编写motion.yaml网络描述文件完成量化与C代码生成。

量化命令:

python quantize.py trained/best_without_bn.pth.tar trained/motion-q.pth.tar \
--device MAX78000 -v -c networks/motion.yaml "$@"

量化后模型在测试集上准确率依然保持在91.34%,混淆矩阵显示分类效果良好。

生成部署至MAX78000的C语言工程:

python ai8xize.py --test-dir "sdk/Examples/MAX78000/CNN" --prefix motion \
--checkpoint-file trained/motion-q.pth.tar --config-file networks/motion.yaml \
--overwrite --device MAX78000 --timer 0 --display-checkpoint --verbose \
--compact-data --mexpress --sample-input 'motion.npy' --boost 2.5 "$@"

生成的工程可直接编译并烧录至MAX78000进行推理测试,实现毫秒级识别。

4. 系统逻辑与功能实现

系统上电后,电脑连接ESP32蓝牙(可自动重连)。为使用聚光灯和数字激光功能,需在电脑端运行一个用C#编写的便携式上位机程序。该程序后台运行,通过接收遥控笔模拟的特定快捷键来触发功能。

C#上位机核心代码片段(实现鼠标钩子与光点绘制):

public MouseForm()
{
    // ... 窗体初始化代码
    const int WH_MOUSE_LL = 14;
    using (Process process = Process.GetCurrentProcess())
    using (ProcessModule module = process.MainModule)
    {
        Hook = SetWindowsHookEx(WH_MOUSE_LL, Proc, GetModuleHandle(module.ModuleName), 0);
    }
    // ... 创建DispatcherQueue
}

private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    const int WM_MOUSEMOVE = 0x0200;
    if (nCode >= 0 && (int)wParam == WM_MOUSEMOVE)
    {
        Point position = PointToClient(Cursor.Position);
        MouseVisual.Offset = new Vector3(position.X, position.Y, 0);
    }
    return CallNextHookEx(Hook, nCode, wParam, lParam);
}

MAX78000检测到按钮或开关动作后,编码为控制指令,通过UART发送给ESP32。ESP32内实现了蓝牙HID协议栈,模拟键盘或鼠标向电脑发送对应指令,从而完成所有可通过键鼠触发的操作。

此外,还实现了飞鼠模式,通过摆动遥控笔控制光标移动。飞鼠模式与手势识别模式通过快速下摆手势切换。当关闭飞鼠模式且IMU检测到较大动作时,系统开始采集0.9秒(36个点)的IMU数据,送入CNN进行手势分类。

MAX78000主控流程图:
系统工作流程图

遇到的问题与优化方向

目前存在偶尔误触发(将随意动作识别为手势)或漏识别的问题。未来优化方向包括:

  1. 改进触发条件:考虑增加触摸感应按键,仅在触碰时激活手势识别,避免无意触发。
  2. 优化数据集与模型:增加“空闲状态”负样本的数据量,提升模型对无效动作的区分能力。

由于开发周期所限,当前仅训练了9种手势(包括数字、字母及空闲状态)。未来若能收集更多字符(字母、汉字)数据,将能充分发挥MAX78000的潜能,实现更丰富的空中输入功能。

项目总结

本项目完整实践了从数据采集、模型训练、量化到边缘端部署的AI应用全流程。Maxim提供的完善开发工具链极大便利了开发。MAX78000毫秒级的神经网络推理速度令人印象深刻,为神经网络在实时控制系统的应用展示了广阔前景。基于此类AI微控制器,未来可探索更多嵌入式智能应用。




上一篇:货拉拉HBase存储架构演进:跨云混合云部署、成本优化与稳定性保障实践
下一篇:Kubernetes Pod调度指南:NodeSelector、NodeAffinity、PodAffinity机制详解与生产环境实战
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 18:48 , Processed in 0.129955 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表