用Arduino Nano 33 BLE Sense实现投篮运动手柄设计 - Funpack8项目分享一

电子森林 2021-05-25 21:50
从Funpack8 Arduino上线到现在,快两个月过去了,也迎来了落幕时刻,但活动的落幕不代表板卡的积灰,大家后期还是可以使用这个板卡来研究机器学习。

而我们第一个分享的项目,作者使用TinyML完成设计,模拟制作了投篮运动手柄,其中还模拟机器学习通过声音控制不同颜色LED灯亮起,真切感受到机器学习带来的快乐。大家也通过参加Funpack第八期活动体会到Arduino的易用性和庞大的生态圈,简约而不简单。

项目链接:https://www.eetree.cn/project/detail/324

大家感兴趣的也可以联系我们工作人员,帮你们“搭桥牵线”,更进一步交流机器学习。接下来请欣赏aramy的投篮运动手柄项目制作。





项目介绍:Funpack第八期开发板Arduino Nano 33 BLE Sense。这是一款非常小巧的开发板,集成了非常多的传感器,尤其吸引我的是,TinyML在这个开发板上得到了支持。

这里我选择任务一:投篮运动手柄。利用NANO-33 BLE的加速度及角速度感应器,设计一款用于虚拟练习投篮的手柄。投篮者可通过手持手柄(开发板)模拟投篮动作,而手柄会根据初始物理参数(可由用户设定或者系统默认值),对投篮者的命中率作出预判,并且可以将改进建议的信息反馈给投篮者。优秀的模拟投篮手柄的确可以帮助用户提高投篮命中率。作为作业去完成。
  
解决问题思路:这里绘制了个简单的投篮示意图(灵魂画手,请勿介意)。人手给篮球一个力,这个力持续一段时间,使篮球速度产生变化。然后篮球脱离手,仅仅受到重力影响,做自由落体运动。篮球到篮筐的水平距离、垂直距离都是已知的,那么求出篮球脱手时的速度,和速度方向即可。篮球脱手的速度可以由篮球受到的加速度和时间的积分获得,而这个开发板带有加速度传感器的,通过加速度传感器就可以测量出三轴的加速度,再乘以时间,就可以获得累加起来的速度了。至于说速度方向,自然是和加速度方向一致。用加速度和角速度可以算出开发板的四元数,拿到开发板在空间中的仰角就知道加速度与水平面的夹角了。有了夹角,计算水平加速度和垂直加速度。水平加速度可以计算水平方向的速度,垂直方向加速度,累加上重力加速度,就可以计算竖直方向的速度了。
#include . // this is for IMU on BLE 33#include#include "SensorFusion.h" //SFSF fusion;
float gx, gy, gz, ax, ay, az, mx, my, mz;float pitch, roll, yaw;float deltat;
void setup() { Serial.begin(115200); if (!IMU.begin()) { Serial.println("Failed to initialize IMU!"); while (1); }
if (!BLE.begin()) { Serial.println("starting BLE failed!"); while (1); } delay(3000);
}
void loop() { if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable() && IMU.magneticFieldAvailable()) { IMU.readAcceleration(ax, ay, az); IMU.readGyroscope(gx, gy, gz); IMU.readMagneticField(mx, my, mz); gx = gx - 1.77; //校零 gy = gy + 0.521; gz = gz + 0.431; float gyroScale = 3.1415926f / 180; gx = gx * gyroScale; gy = gy * gyroScale; gz = gz * gyroScale;
deltat = fusion.deltatUpdate(); //this have to be done before calling the fusion update //choose only one of these two: // fusion.MahonyUpdate(gx, gy, gz, ax, ay, az, deltat); //mahony is suggested if there isn't the mag and the mcu is slow fusion.MadgwickUpdate(gx, gy, gz, ax, ay, az, mx, my, mz, deltat); //else use the magwick, it is slower but more accurate
pitch = fusion.getPitchRadians(); roll = -fusion.getRollRadians(); //you could also use getRollRadians() etc yaw = fusion.getYawRadians();
Serial.print(pitch); Serial.print("\t"); Serial.print(roll); Serial.print("\t"); Serial.print(yaw); Serial.print("\t");
Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.print(az); Serial.print("\t");
Serial.print(gx); Serial.print("\t"); Serial.print(gy); Serial.print("\t"); Serial.println(gz); }}

将四元数的姿态信息用processing做可视化后,才发现现实的残酷。四元数能够很好地反映开发板的姿态信息,通过仰角也是能够获得开发板与水平面的夹角,可是这个仰角数据滞后严重啊!尝试旋转开发板,然后水平放置在桌面上,图中的立方体,是缓慢恢复到水平态的!而用手投球,发力时长是按毫秒计算的。这样的滞后,感觉没法算了。

更换思路:放弃通过加速度去计算速度的方法,换种思考角度,尝试通过机器学习来解决这个问题。传感器获得的信息是条件,计算出篮球脱手的速度和角度是方法,是否命中篮筐是结果。既然方法这块弄起来有困难,那么就给足够多的条件和结果,用机器学习的方式去推算方法。

  

首先,收集几组投篮的数据,来明确条件的边界。上图中图像是将三个轴的加速度做了平方和的结果。可以看出平时的运动,三个轴加速度和基本为1,投篮时,加速度会变大,图像上有明显的突变。这里每个点之间是50ms(这里应该是串口影响,每次取样时间间隔近50ms,传感器的频率应该是110HZ,间隔应该在10ms才对),一次投篮的加速度差不多350ms左右。取加速度和为35作为阈值。开始训练,通过串口记录训练样本值。

这里保留影响投篮的相关参数:三轴加速度,三轴角速度。其它传感器信息都不要。以加速度和超过35的点作为中心点,前后一共取32个点的数据。当出现符合条件的情况,就通过串口把数据传送给电脑,记录下来作为训练数据。实际测量时发现有投完球后也会有数据出现,就再从时间上限定,出现符合条件的数据后1秒内不再接受数据。    

因为需要接电脑收集数据,不方便使用篮球场收集数据(就是因为宅,且不会打篮球,而且也没有篮球)。就改用孩子的米奇玩偶,在室内的墙上做一个标记位,每次击中标记位即为投中。将开发板绑在手背上,用usb延长线与电脑连接。米奇每击中标记位,就记录一次数据,每组数据均是32*6=192位的数据。应该记录100次以上的,但是为了测试(宅男属性,体力不支)收集到了62组数据就停止了。
2.38      -3.86      3.05      109.99      -37.11      29.54      2.42      -4      3.15      119.2      -33.75      38.09      2.26      -4      2.83      119.51      -17.82      69.82      2.22      -3.68      2.02      107.6      -6.71      116.46      2.27      -3.05      1.59      89.66      8.48      171.02      1.95      -2.83      1.54      58.29      30.58      244.2      1.38      -2.61      1.4      2.14      63.96      316.47      1.44      -1.88      1.55      -91.19      105.35      365.23      1.13      -2.08      1.97      -211.43      149.72      428.16      0.98      -2.13      2.57      -268.55      260.19      506.71      -0.88      -2.48      2.99      -222.29      360.23      612.37      -3.98      -1.05      1.76      -105.83      356.38      700.93      -4      1.42      0.04      -56.15      430.66      745.18      -4      3.43      -0.39      -177.98      635.07      672.24      -4      4      -1.42      -141.91      619.14      616.46      -4      4      -3.21      -288.51      595.58      332.7      -4      4      -4      -406.19      628.66      125.49      -4      4      -4      -522.77      520.69      56.21      -4      0.99      -4      -439.39      152.71      -34.48      -3.48      -0.33      -3.64      -139.1      -85.88      -300.78      -2.19      -1.99      -3.22      127.01      -62.5      -454.53      -1.21      -3.13      -2.13      189.27      -53.65      -430.85      -0.34      -3.99      -0.93      112.3      -162.72      -322.51      0.73      -4      -0.11      41.26      -242.37      -220.83      0.38      -3.58      -0.02      43.4      -222.53      -187.74      0.73      -3.5      0.26      86      -164.92      -133.06      0.79      -2.52      -0.04      78.37      -105.16      -90.64      1.02      -2.03      0.01      19.78      -78.06      -57.62      0.88      -1.59      0.17      -48.77      -58.78      -32.35      0.68      -1.51      0.28      -69.15      -47.24      -1.16      0.37      -1.23      0.37      -62.87      -32.04      5.86      0.55      -0.65      0.19      -43.46      -17.09      0.851.79      -3.44      3.57      128.72      -54.99      59.2      1.82      -3.52      3.43      130.62      -53.96      81.91      1.94      -3.5      3.45      115.05      -29.79      125.55      1.9      -3.65      3.4      61.77      12.21      194.64      1.87      -4      3.33      -20.75      73.36      280.46      1.53      -3.98      3.38      -89.05      135.44      368.29      1.42      -3.27      3.48      -136.35      213.2      437.19      0.76      -2.55      3.62      -207.34      332.76      481.26      -0.45      -2.58      3.97      -256.71      486.88      517.33      -2.33      -2.91      3.57      -205.2      605.41      559.94      -3.98      -2.39      2.84      -46.57      654.91      608.52      -4      0.12      1.42      178.59      715.09      603.09      -4      2.68      1.49      338.62      791.2      533.69      -4      4      0.2      280.09      792.97      479.37      -4      4      0.35      21.12      810.55      411.07      -4      4      -2.11      -226.87      810.73      325.99      -4      4      -2.85      -437.19      638.37      226.56      -4      3.81      -3.64      -456.73      539.25      193.05      -4      1.9      -4      -234.99      430.18      76.11      -3.3      1.32      -3.99      54.44      220.95      -187.19      -2.56      1.23      -3.42      192.75      78.49      -420.78      -2.06      -0.63      -3      201.29      -2.93      -438.6      -1.68      -1.91      -2.19      77.45      -41.56      -441.47      -0.6      -1.38      -1.06      -57.92      -40.95      -428.16      -0.6      -3.58      -0.57      -74.04      -61.77      -305.85      0.2      -2.99      -0.15      -86.43      -70.31      -247.68      0.61      -2.22      -0.05      -79.71      -80.69      -155.76      0.66      -2.09      0.04      -70.31      -90.27      -47.12      0.71      -1.51      -0.1      -83.68      -91.13      -2.38      0.8      -1.3      -0.23      -98.75      -86.55      20.51      0.74      -1.21      -0.36      -106.75      -86.67      50.66      0.76      -0.95      -0.25      -119.08      -52.61      60.972.62      -2.9      2.84      88.93      -42.24      47.3      2.69      -3.39      3.11      126.16      -76.9      21.73      3.18      -3.64      3.33      138.73      -68.54      -17.03      3.22      -4      3.3      120.42      -40.16      -19.29      3.09      -4      2.79      92.1      -30.03      31.13      3.16      -4      2.08      70.19      0.79      73.97      2.97      -3.94      2.03      57.13      47.49      137.33      2.68      -3.6      1.6      51.57      85.14      225.22      2      -3.15      1.17      -6.29      139.1      323.67      1.16      -2.27      0.9      -102.48      206.42      446.66      -0.19      -1.81      0.85      -209.66      259.64      559.69      -3.03      0.16      0.19      -266.17      277.34      693.79      -4      1.68      0.02      -266.54      327.45      801.7      -4      3.24      -0.46      -89.54      438.35      758.73      -4      4      -0.79      94.42      535.64      518.8      -4      4      -1.78      134.22      605.1      240.84      -4      4      -2.27      13.67      581.97      -32.35      -4      4      -3.57      -206.18      424.5      -214.17      -4      2.76      -2.58      -392.88      258.06      -284.48      -3.9      -1.8      -2.07      -330.2      86.43      -265.81      -2.04      -3.35      -2.45      -90.52      -12.15      -273.56      -1.13      -2.71      -2.49      96.19      24.6      -300.72      -0.69      -2.12      -2.23      146      32.78      -275.51      -0.13      -1.81      -1.6      102.97      -58.96      -230.96      0.07      -1.88      -0.93      51.15      -168.15      -180.24      0.38      -2.19      -0.32      26.25      -198.18      -147.22      0.57      -2.25      0.07      2.14      -167.18      -141.48      1.04      -2.07      0.34      -25.94      -129.09      -122.62      1.33      -1.93      0.56      -45.41      -96.5      -54.81      0.65      -2.34      0.93      -58.96      -63.05      31.98      0.98      -1.52      0.9      -80.99      -45.78      56.4      0.83      -1.08      0.66      -90.64      -24.11      71.17

再在屋顶标记一个目标点,做为用力过猛的点,继续收集数据,收集到了60组数据。
0.09      0.99      -0.73      -2.26      37.78      51.51      0.08      0.99      -0.78      0.85      37.41      42.3      0.07      0.97      -0.81      1.1      33.69      35.58      0      1.05      -0.85      0.12      28.87      31.49      -0.1      1.07      -0.88      -0.49      24.54      29.54      -0.2      1.12      -0.88      0.67      23.44      31.13      -0.27      1.15      -0.9      1.34      28.14      36.01      -0.3      1.18      -0.95      -3.66      34.06      44.19      -0.34      1.34      -1.02      -13.49      38.76      50.17      -0.4      1.54      -1.13      -18.98      43.95      51.45      -0.54      1.76      -1.22      -10.68      50.17      47.55      -0.78      1.97      -1.36      4.27      59.14      35.83      -1.16      2.49      -1.54      11.17      67.26      22.46      -1.88      2.92      -1.63      14.89      69.09      10.19      -2.71      3.44      -2.27      8.24      85.33      7.39      -2.96      4      -3.38      -43.33      114.75      8.06      -2.57      4      -4      -68.3      140.93      -1.59      -1.87      4      -4      -39.18      125.18      -47.61      -1.21      3.75      -4      -9.7      71.72      -102.11      -0.84      3.41      -4      -19.78      -32.1      -191.41      -1.33      3.02      -3.61      -10.44      -113.77      -261.78      -0.43      2.38      -3.81      -47.73      -158.75      -331.85      0.03      2.24      -3.86      -142.21      -238.83      -362.61      0.19      1.6      -3.75      -218.08      -355.65      -402.53      0.25      1.03      -3.3      -304.38      -483.89      -446.17      0.36      -0.14      -2.38      -379.7      -635.99      -511.47      -1.18      -0.94      -0.63      -407.04      -847.29      -627.81      -4      -0.38      1.99      -304.02      -1102.17      -790.1      -4      -1.76      4      -14.89      -1289.79      -969.79      -4      -4      4      558.23      -1196.35      -800.78      -4      -4      3.84      759.03      -510.93      -295.84      -3.82      -4      2.76      575.32      -178.83      13.18-0.72      0.84      -1.08      -0.18      18.19      27.22      -0.69      0.9      -1.11      -1.89      22.64      19.53      -0.7      0.93      -1.11      0.37      27.22      8.36      -0.75      0.94      -1.15      5.55      29.24      -3.17      -0.79      0.91      -1.19      9.22      32.23      -13.31      -0.87      0.88      -1.22      12.08      35.89      -21.42      -0.91      0.88      -1.29      12.94      39.98      -27.95      -1      0.91      -1.37      9.46      44.43      -33.14      -1.11      1.01      -1.47      4.39      48.4      -37.29      -1.33      1.14      -1.57      0.61      45.47      -42.36      -1.71      1.37      -1.74      -0.98      36.93      -48.28      -2.15      1.59      -2.02      1.1      30.58      -53.71      -2.54      1.83      -2.48      0.12      39.43      -61.1      -3.02      2.22      -3.16      -0.92      60.42      -81.79      -3.54      2.64      -3.94      5.92      85.02      -117      -3.67      2.63      -4      16.48      111.27      -156.01      -3.39      2.76      -4      11.84      125.18      -198.43      -2.85      2.68      -4      17.21      108.28      -254.03      -2.21      2.35      -4      26.31      46.57      -322.88      -1.67      2.28      -4      13.98      -37.17      -381.04      -1.61      2.65      -3.99      -20.45      -147.34      -417.48      -1.35      2.3      -3.78      -51.03      -281.56      -453.86      -1.38      3.13      -3.15      -74.46      -424.8      -493.29      -0.88      1.09      -2.76      -58.53      -599.06      -550.11      -1.33      -0.3      -1.79      -76.72      -798.03      -646.42      -2.64      -0.94      -0.48      -171.94      -1031.07      -834.41      -4      -1.61      0.28      -188.78      -1302.12      -975.34      -4      -3.12      0.64      -229.37      -1593.69      -1125.61      -4      -4      4      -267.7      -1458.44      -1121.4      -4      -4      4      -254.15      -523.25      -570.13      -4      -4      4      128.48      -244.81      -61.16      -4      -4      4      302.8      -152.77      280.52-0.75      1.02      -0.99      -14.83      15.14      41.38      -0.85      1      -0.99      -11.05      13.31      33.63      -0.85      0.99      -0.99      -10.25      18.74      23.19      -0.81      1.01      -1      -9.52      23.25      12.45      -0.86      1.01      -1      -7.81      25.15      3.54      -0.92      1.04      -1.01      -6.9      27.89      -3.36      -0.99      1.06      -1.03      -6.84      31.25      -9.58      -1.05      1.07      -1.06      -7.87      36.32      -15.63      -1.07      1.1      -1.12      -11.54      43.09      -18.92      -1.1      1.16      -1.17      -17.64      50.05      -21.61      -1.25      1.28      -1.24      -19.1      55.79      -26.73      -1.55      1.47      -1.36      -17.33      58.35      -35.52      -2.09      1.91      -1.63      -14.4      59.69      -47.55      -2.89      2.5      -2      -10.01      60.85      -57.5      -3.58      2.87      -2.73      -10.86      64.33      -65.25      -3.8      2.92      -3.47      -22.64      72.2      -84.96      -3.44      2.8      -3.99      -34.97      83.01      -130.25      -2.96      2.74      -4      -35.58      77.76      -202.15      -2.7      2.19      -4      -29.72      34.85      -296.2      -2.42      2.44      -4      -40.65      -40.65      -396.67      -2.21      1.92      -3.96      -38.15      -138.12      -465.76      -2.3      2.57      -3.42      -43.88      -248.9      -514.59      -1.83      2.2      -2.91      -85.33      -356.81      -558.17      -1.44      1.93      -2      -168.4      -484.5      -619.63      -1.27      1.28      -1.42      -253.05      -636.84      -660.16      -1.2      2.03      -0.7      -346.37      -820.8      -734.37      -3.96      -0.65      -0.56      -350.52      -1091.98      -888.18      -4      -0.75      0.63      -308.84      -1445.92      -942.63      -4      0.85      2.89      -228.33      -1602.97      -1137.27      -4      -4      4      60.24      -1350.28      -1002.2      -4      -4      4      185.12      -460.94      -569.82      -4      -4      4      348.94      -176.76      -164.79

科学的办法应该是将传感器固定在手上,然后真实地去场地投篮,记录成功与失败的数据,要想细分,失败的数据还要进一步对失败原因进行标记,将每种情况进行分类。这里就先在屋中用测试数据代替了。仅仅分为投中和用力过猛两类。

收集到这些数据条件后,对数据对应的结果进行标记。投中的标记为0,用力过猛的标记为1.数据标记后,做归一处理,通过查询,可以得知,加速度的量程为【-4,4】,角速度为【-2000,2000】,所以引入这样一个矩阵 dealzero=(4,4,4,2000,2000,2000)*32,所有的数据都与它除,就能将数据点,归到【-1,1】之间了。这里还发现一个问题,少量的加速度到了4这个值了,也就是说投球过程中,已经超出量程了,感觉【-4,4】这个量程不是太合适了。
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time    : 2021/04/21 14:25# @Author  : aramy# @File    : nano33    deal_trandate.py#处理训练数据import numpy as npimport pandas as pdimport tensorflow as tfimport tensorflow.keras as kerasdealzero=(4,4,4,2000,2000,2000)*32def processDate(file,y_val):    openD = pd.read_csv(file, header=None)    dataX = np.array(openD)    if dataX.shape[1]>192:        dataX=dataX[:,:-1]    dataX=dataX/dealzero    dataY=np.ones((dataX.shape[0],))*y_val    return dataX,dataY
def loaddata(): dataX0,dataY0 = processDate('../res/succ.csv',0) dataX1,dataY1 = processDate('../res/fail.csv', 1)
dataX = np.concatenate((dataX0, dataX1), axis=0) dataY=np.append(dataY0,dataY1) # print(dataX,dataY) permutationTrain = np.random.permutation(dataX.shape[0]) # # print(permutationTrain) dataX = dataX[permutationTrain] dataY = dataY[permutationTrain] vfoldSize = int(dataX.shape[0] / 100 * 20) xTest = dataX[0:vfoldSize] yTest = dataY[0:vfoldSize] xTrain = dataX[vfoldSize:dataX.shape[0]] yTrain = dataY[vfoldSize:dataY.shape[0]]
return xTest,yTest,xTrain,yTrain

if __name__ == '__main__': xTest,yTest,xTrain,yTrain=loaddata() print( xTest,yTest,xTrain,yTrain)
model = keras.Sequential() model.add(keras.layers.Dense(32, input_shape=(6*32,), activation='relu')) model.add(keras.layers.Dense(16, activation='relu')) model.add(keras.layers.Dense(2, activation='softmax'))
adam = keras.optimizers.Adam(0.000005) model.compile(loss='sparse_categorical_crossentropy', optimizer=adam, metrics=['sparse_categorical_accuracy']) model.summary()
history = model.fit(xTrain, yTrain, batch_size=1, validation_data=(xTest, yTest), epochs=3000, verbose=1) converter = tf.lite.TFLiteConverter.from_keras_model(model) tflite_model = converter.convert()
open("model", "wb").write(tflite_model)

训练模型:将归一后的数据用随机数的方式打乱,保证成功和用力过猛的数据均匀混合,取80%做为训练数据,20%做为验证数据。

我们使用的是Sequential模型,Sequential模型形象地解释就是一个漏斗,数据只能从上层往下层流动,我们可以在这个漏斗中堆叠各种计算的层,以丰富这个模型的结构。这里使用了三层的神经网络。使用softmax激活函数。这部分自己还不是太懂,只能是照猫画虎。使用0.000005做为损失函数,训练3000次。在我的电脑上,大概是5分钟,训练完成,得到一个model的文件。使用命令:xxd -i model >> model.h 就生成了Arduino下能用的model.h文件了。

使用训练结果:训练完成后,得到的model.h文件就要需要的模型了。我的理解是在Arudino收集到的运动数据来和模型作比较,看动作数据与之前训练中的特征值相似程度,用来判断当前动作的属性。在Arduino中增加tensor处理的框架,保证每次三轴加速度和超过35就触发tensor的判断,判断当前动作投篮是否成功。若投篮成功概率超过0.8,则在oled屏幕上显示“success”。若投篮用力过大的概率超过0.8,则显示“Too Hard”。将投篮次数、各自的概率显示在oled屏幕上。
#include#include "Buff.h"#include#include#include#include#include#include#include "model.h"#includeAdafruit_SSD1306 display(128, 64, &Wire, NULL);

float ax, ay, az, gx, gy, gz;float buff[actionnumber * 6];uint32_t tim[actionnumber];uint32_t rectime = 0;const float zero[3] = {0.12620776, -0.360400501, -0.518010013}; //归零Buff actionBuf;
tflite::MicroErrorReporter tflErrorReporter;tflite::AllOpsResolver tflOpsResolver;const tflite::Model* tflModel = nullptr;tflite::MicroInterpreter* tflInterpreter = nullptr;TfLiteTensor* tflInputTensor = nullptr;TfLiteTensor* tflOutputTensor = nullptr;constexpr int tensorArenaSize = 8 * 1024;byte tensorArena[tensorArenaSize];const char* ACTION[] = { "SUCCESS", "TOO HARD"};#define ACT_NUM (sizeof(ACTION) / sizeof(ACTION[0]))float answer[sizeof(ACTION) / sizeof(ACTION[0])];int action_num=0; //投篮次数
void setup() { Serial.begin(115200); tflModel = tflite::GetModel(model); if (tflModel->version() != TFLITE_SCHEMA_VERSION) { Serial.println("Model schema mismatch!"); while (1); } tflInterpreter = new tflite::MicroInterpreter(tflModel, tflOpsResolver, tensorArena, tensorArenaSize, &tflErrorReporter); tflInterpreter->AllocateTensors(); tflInputTensor = tflInterpreter->input(0); tflOutputTensor = tflInterpreter->output(0); delay(1000); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //初始化oled display.clearDisplay(); display.display(); if (!IMU.begin()) { Serial.println("Failed to initialize IMU!"); while (1); } delay(3000);
}
void loop() { if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable() ) { IMU.readAcceleration(ax, ay, az); IMU.readGyroscope(gx, gy, gz); actionBuf.insertnode(gx, gy, gz, ax, ay, az, millis()); if (actionBuf.isavailable()) { actionBuf.getActionVal(buff, tim); if (millis() - rectime > 1000) { rectime = millis(); judgeAcion(); //判断是否投中 action_num++; dispactioninfo(); //显示信息 } } }}//将收到的数据作推理,判断是否能进球void judgeAcion() { float max = 0; char pos; //数据归一 for (int i = 0; i << span=""> actionnumber; i++) { tflInputTensor->data.f[i * 6 + 0] = buff[i * 6 + 0] / 4; tflInputTensor->data.f[i * 6 + 1] = buff[i * 6 + 1] / 4; tflInputTensor->data.f[i * 6 + 2] = buff[i * 6 + 2] / 4; tflInputTensor->data.f[i * 6 + 3] = buff[i * 6 + 3] / 2000; tflInputTensor->data.f[i * 6 + 4] = buff[i * 6 + 4] / 2000; tflInputTensor->data.f[i * 6 + 5] = buff[i * 6 + 5] / 2000; } TfLiteStatus invokeStatus = tflInterpreter->Invoke(); if (invokeStatus != kTfLiteOk) { Serial.println("Invoke failed!"); while (1); return; } for (int i = 0; i << span=""> ACT_NUM; i++) { if (max << span=""> tflOutputTensor->data.f[i]) { max = tflOutputTensor->data.f[i]; pos = i; } Serial.print(ACTION[i]); Serial.print(": "); Serial.print(tflOutputTensor->data.f[i], 6); Serial.print(" "); answer[i]=tflOutputTensor->data.f[i]; } Serial.println();}
//显示结果信息void dispactioninfo(){ display.clearDisplay(); //清空屏幕 display.setCursor(0, 0); //设置起点 display.setTextSize(2); //设置字体 display.setTextColor(SSD1306_WHITE); //设置字体颜色 display.println(F("NO.")); display.setCursor(60, 0); //设置起点 display.println(action_num); //显示次数 display.setTextSize(3); //设置字体 display.setCursor(0, 24); //设置起点 if(answer[0]>0.8){//投篮成功 display.println("SUCCESS"); }else if(answer[1]>0.8){ display.println("TOO HARD"); }else{ display.println("FAIL"); } display.setTextSize(1); //设置字体 display.setCursor(0, 48); //设置起点 display.print(answer[0],3); display.print(" , "); display.print(answer[1],3); display.display(); //刷新屏幕 delay(3000);}

在实际测试中,效果并不理想,很多动作都会被判断为投篮成功。对整个过程复盘,感觉几个地方会有问题:
  1. 加速度量程应该有点偏小,用到【-8g,8g】不知道效果会不会好点。

  2. 采集动作时间长度不够,使用32个动作点,每个动作点之间按9ms计算,才不到300ms。感觉偏小。

  3. 需要更多的训练样本,而且最好是实际中产生的训练样本。但是采集样本成本不低,如果大量采集数据,还走串口感觉很不方便,需要学习蓝牙传输数据。

  4. 准备还是不够充分。测试中出现了很多问题,USB线松动,魔术贴粘住米奇,开发板脱落……还是需要做好准备。


这次活动学习到了时下最流行的机器学习,这个方法对解决问题换了个全新的视角。自己水平实在有限,希望活动能继续,能够了解更多的机器学习的知识。

END


硬禾学堂

硬禾团队一直致力于给电子工程师和相关专业的同学,带来规范的核心技能课程,帮助大家在学习和工作的各个阶段,都能有效地提升自己的职业能力。

硬禾学堂

我们一起在电子领域探索前进

关注硬禾公众号,随时直达课堂


    

点击阅读原文查看最新一期Funpack

电子森林 讲述电子工程师需要掌握的重要技能: PCB设计、FPGA应用、模拟信号链路、电源管理等等;不断刷新的行业新技术 - 树莓派、ESP32、Arduino等开源系统;随时代演进的热点应用 - 物联网、无人驾驶、人工智能....
评论
  •   在信号处理过程中,由于信号的时域截断会导致频谱扩展泄露现象。那么导致频谱泄露发生的根本原因是什么?又该采取什么样的改善方法。本文以ADC性能指标的测试场景为例,探讨了对ADC的输出结果进行非周期截断所带来的影响及问题总结。 两个点   为了更好的分析或处理信号,实际应用时需要从频域而非时域的角度观察原信号。但物理意义上只能直接获取信号的时域信息,为了得到信号的频域信息需要利用傅里叶变换这个工具计算出原信号的频谱函数。但对于计算机来说实现这种计算需要面对两个问题: 1.
    TIAN301 2025-01-14 14:15 48浏览
  • PNT、GNSS、GPS均是卫星定位和导航相关领域中的常见缩写词,他们经常会被用到,且在很多情况下会被等同使用或替换使用。我们会把定位导航功能测试叫做PNT性能测试,也会叫做GNSS性能测试。我们会把定位导航终端叫做GNSS模块,也会叫做GPS模块。但是实际上他们之间是有一些重要的区别。伴随着技术发展与越发深入,我们有必要对这三个词汇做以清晰的区分。一、什么是GPS?GPS是Global Positioning System(全球定位系统)的缩写,它是美国建立的全球卫星定位导航系统,是GNSS概
    德思特测试测量 2025-01-13 15:42 412浏览
  • 根据Global Info Research(环洋市场咨询)项目团队最新调研,预计2030年全球无人机电池和电源产值达到2834百万美元,2024-2030年期间年复合增长率CAGR为10.1%。 无人机电池是为无人机提供动力并使其飞行的关键。无人机使用的电池类型因无人机的大小和型号而异。一些常见的无人机电池类型包括锂聚合物(LiPo)电池、锂离子电池和镍氢(NiMH)电池。锂聚合物电池是最常用的无人机电池类型,因为其能量密度高、设计轻巧。这些电池以输出功率大、飞行时间长而著称。不过,它们需要
    GIRtina 2025-01-13 10:49 130浏览
  • 随着通信技术的迅速发展,现代通信设备需要更高效、可靠且紧凑的解决方案来应对日益复杂的系统。中国自主研发和制造的国产接口芯片,正逐渐成为通信设备(从5G基站到工业通信模块)中的重要基石。这些芯片凭借卓越性能、成本效益及灵活性,满足了现代通信基础设施的多样化需求。 1. 接口芯片在通信设备中的关键作用接口芯片作为数据交互的桥梁,是通信设备中不可或缺的核心组件。它们在设备内的各种子系统之间实现无缝数据传输,支持高速数据交换、协议转换和信号调节等功能。无论是5G基站中的数据处理,还是物联网网关
    克里雅半导体科技 2025-01-10 16:20 410浏览
  • 新年伊始,又到了对去年做总结,对今年做展望的时刻 不知道你在2024年初立的Flag都实现了吗? 2025年对自己又有什么新的期待呢? 2024年注定是不平凡的一年, 一年里我测评了50余块开发板, 写出了很多科普文章, 从一个小小的工作室成长为科工公司。 展望2025年, 中国香河英茂科工, 会继续深耕于,具身机器人、飞行器、物联网等方面的研发, 我觉得,要向未来学习未来, 未来是什么? 是掌握在孩子们生活中的发现,和精历, 把最好的技术带给孩子,
    丙丁先生 2025-01-11 11:35 410浏览
  • 流量传感器是实现对燃气、废气、生活用水、污水、冷却液、石油等各种流体流量精准计量的关键手段。但随着工业自动化、数字化、智能化与低碳化进程的不断加速,采用传统机械式检测方式的流量传感器已不能满足当代流体计量行业对于测量精度、测量范围、使用寿命与维护成本等方面的精细需求。流量传感器的应用场景(部分)超声波流量传感器,是一种利用超声波技术测量流体流量的新型传感器,其主要通过发射超声波信号并接收反射回来的信号,根据超声波在流体中传播的时间、幅度或相位变化等参数,间接计算流体的流量,具有非侵入式测量、高精
    华普微HOPERF 2025-01-13 14:18 419浏览
  • ARMv8-A是ARM公司为满足新需求而重新设计的一个架构,是近20年来ARM架构变动最大的一次。以下是对ARMv8-A的详细介绍: 1. 背景介绍    ARM公司最初并未涉足PC市场,其产品主要针对功耗敏感的移动设备。     随着技术的发展和市场需求的变化,ARM开始扩展到企业设备、服务器等领域,这要求其架构能够支持更大的内存和更复杂的计算任务。 2. 架构特点    ARMv8-A引入了Execution State(执行状
    丙丁先生 2025-01-12 10:30 408浏览
  • 随着数字化的不断推进,LED显示屏行业对4K、8K等超高清画质的需求日益提升。与此同时,Mini及Micro LED技术的日益成熟,推动了间距小于1.2 Pitch的Mini、Micro LED显示屏的快速发展。这类显示屏不仅画质卓越,而且尺寸适中,通常在110至1000英寸之间,非常适合应用于电影院、监控中心、大型会议、以及电影拍摄等多种室内场景。鉴于室内LED显示屏与用户距离较近,因此对于噪音控制、体积小型化、冗余备份能力及电气安全性的要求尤为严格。为满足这一市场需求,开关电源技术推出了专为
    晶台光耦 2025-01-13 10:42 436浏览
  • 01. 什么是过程能力分析?过程能力研究利用生产过程中初始一批产品的数据,预测制造过程是否能够稳定地生产符合规格的产品。可以把它想象成一种预测。通过历史数据的分析,推断未来是否可以依赖该工艺持续生产高质量产品。客户可能会要求将过程能力研究作为生产件批准程序 (PPAP) 的一部分。这是为了确保制造过程能够持续稳定地生产合格的产品。02. 基本概念在定义制造过程时,目标是确保生产的零件符合上下规格限 (USL 和 LSL)。过程能力衡量制造过程能多大程度上稳定地生产符合规格的产品。核心概念很简单:
    优思学院 2025-01-12 15:43 450浏览
  • 随着全球向绿色能源转型的加速,对高效、可靠和环保元件的需求从未如此强烈。在这种背景下,国产固态继电器(SSR)在实现太阳能逆变器、风力涡轮机和储能系统等关键技术方面发挥着关键作用。本文探讨了绿色能源系统背景下中国固态继电器行业的前景,并强调了2025年的前景。 1.对绿色能源解决方案日益增长的需求绿色能源系统依靠先进的电源管理技术来最大限度地提高效率并最大限度地减少损失。固态继电器以其耐用性、快速开关速度和抗机械磨损而闻名,正日益成为传统机电继电器的首选。可再生能源(尤其是太阳能和风能
    克里雅半导体科技 2025-01-10 16:18 314浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦