完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
概述
硬件上使用STM32F4+MPU9150实现的神经网络识别手势,不过没有用IMU的地磁数据,只用了三轴加速度计和三轴陀螺仪的数据,板子是自己画的主要参照了意法官方的开发板的原理图(人生画的第一个板子还没有错误哈,容小逗比高兴一下。。。)。MPU9150的驱动是用的InvenSense提供的eMPL硬件抽象层,虽然这个driver配置imu内置DMP比较方便,但感觉这个bias矫正和姿态解算做的并不是很好,而且源码没公开不好改。不过识别部分用的是原始数据没用融合出的姿态数据,(姿态用在另一个功能上了)。考虑到单片机的计算性能不高(其实是训练部分不好移植^_^)于是把网络的训练部分放在在matlab上做的,然后把训练完的网络的阈值和权值导出来,放到单片机里。这里涉及到了单片机采集的数据怎么发给matlab的问题,幸好高版本的matlab对硬件的支持有大幅提升,可以通过串口来收数据。网络在单片机上的识别过程计算量还是挺大的,原始的imu数据(6Dof)经过一个巴特沃斯低通滤波器后放到一个类似于FIFO的数据结构中,从这个FIFO中首先进行间隔取数(间隔根据手势动作时间计算),并对取出的数进行归一化,然后将这些数据传给网络进行识别。过程中的滤波、归一化和网络计算都要进行大量的浮点运算,于是把logsig函数由泰勒展开改成了查表,还开了FPU,用了CMSIS-DSP。 Matlab串口接收 下面是创建串口obj的脚本 try try obj=serial(‘COM15’,‘baudrate’,115200,‘parity’,‘none’,‘databits’,8,‘stopbits’,1); flag_fetch=1; catch fprintf(‘Create Obj Error’); end obj.BytesAvailableFcnMode = ‘terminator’; obj.Terminator = ‘c’; obj.BytesAvailableFcn =@serial_nn_callback; try fopen(obj); catch fprintf(‘Open Errorn’); break; end pause; flag_fetch=0; catch fprintf(‘Serial Read Error!n’); end fclose(obj); delete(obj); clear obj; 下位机将imu数据以数据帧的形式发送上来,数据帧自定义协议,帧以字符’c’结尾,这里将串口配置为terminator模式,设置terminator=’c’,这样该模式下接收到字符’c’就调用一次回调函数”serial_nn_callback” 下面是回调函数的框架: function [c]= serial_nn_callback(obj, ~) % var start 。.. % var end try n = get(obj, ‘BytesAvailable’); if n》20&& (flag_fetch==1) a = fread(obj, 29, ‘uchar’);%数据帧长度 if a(1)~=‘A’ fscanf(obj) ; end % 协议解析 start % 协议解析 end end catch end 这里读取之后要首先判断数据帧头是否吻合,如果不吻合立即调用 fscanf(obj) 清除串口的缓存,否则的话接收到的数据都是串的。这样就可以成功的接收到下位机发送的数据。 网络训练 这个部分比较简单,用的单S激活函数,mse能到的最小值有限,后来试了下双S激活函数,mse可以很小。不过实际测试时单S激活函数的识别率已经够用了 input=input‘; net = newff( minmax(input) , [mid_layer,output_layer] , { ’logsig‘ ’logsig‘ } ,’traingdx‘) ; net.trainparam.show = 50 ; net.trainparam.epochs = 500 ; net.trainparam.goal = 0.00001 ; net.trainParam.lr = 0.001 ; 网络导出 w_i2l=net.IW{1,1};%输入层到中间层的权值 b_i2l=net.b{1,1};%输入层到中间层的阈值 w_l2o=net.LW{2,1};%中间层到输出层的权值 b_l2o=net.b{2,1};%中间层到输出层的阈值 % 导出函数 start 。.. % 导出函数 end 单片机上网络计算函数 void layer_to_layer( int lin_num, int lout_num, float32_t* input, float32_t* output, float32_t* w, float32_t* b ) { float32_t *temp; memset(output, 0, lout_num * sizeof(float32_t)); temp = (float32_t *)malloc(lin_num * sizeof(float32_t)); for (int i=0;i《lout_num;i++) { #ifdef ARM_M4 arm_mult_f32(input,w+i*lin_num,temp,lin_num); //CMSIS-DSP库 向量相乘 #else for (int i=0;i《lin_num;i++) //非DSP指令 { *(temp+i)=*(input)*(*(w+i*lin_num)) } #endif for (int j=0;j《lin_num;j++) { *(output+i)=*(output+i)+*(temp+j); } *(output+i)=*(output+i)+*(b+i); *(output+i)=logsig_fun(*(output+i)); } free(temp); } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1125 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1149 浏览 1 评论
581 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
436 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1041 浏览 2 评论
1627浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
290浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
297浏览 3评论
290浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
262浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-22 15:57 , Processed in 0.671313 second(s), Total 45, Slave 39 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号