当前位置:   article > 正文

2022 电赛陕西省赛_sipeed麦克风阵列

sipeed麦克风阵列

一:题目:

声源定位跟踪系统(E题)

设计制作一个声源定位跟踪系统,能够实时显示及指示声源的位置,当声源移动时能够用激光笔动态跟踪声源

在这里插入图片描述

  • 设计并制作声音发生装置——“声源”,装置最大边长或直径不超过10cm,声源中心点B用红色或其他醒目颜色标识,并在B点所在的平面以B点为圆心,直径为5cm画圆圈,用醒目线条标识,该平面面向检测指示装置(图中A点)。(4分)
  • 设计并制作一个声源定位检测装置,传感器安装在图1的 C区范围内,高度不超过1m,系统采用的拾音器或麦克风传感器数量不超过10个;在装置上标记测试参考点A,作为位置坐标的原点;装置上有显示电路实时显示D区域内声源的位置显示A、B两点直线距离γ和以A点为原点,AB在地面的投影与图1中心线的夹角θ,测量时间不超过5s,距离γ和角度θ的测值误差越小越好。(36分)
  • 设计并制作一个声源指示控制装置,此装置和上述声源定位检测装置可以合为一体。也放置在图1的 C区,安装有激光笔和二维电动云台,能控制激光笔指向声源,定位计算过程中时,激光笔关闭,定位运算完成时激光笔开启。定位指示声源时,动作反应时间不超过10s,光点与B点偏差越小越好。(30分)
  • 声源移动动态追踪:当声源摆放在地面,用细绳牵引,以0.2m/s左右的速度在D区移动时,激光笔光点指向B点,光点与B点偏差越小好,跟踪反应时间越短越好。(20分)

二:方案计划

2.1【硬件选型】

Sipeed Maix Dock k210开发板:

在这里插入图片描述

Sipeed麦克风阵列模块:

在这里插入图片描述

飞特串口舵机:
在这里插入图片描述

激光模块:

在这里插入图片描述

按键:

在这里插入图片描述

2.2【基础架构】

刚开始将麦克风阵列模块平面放置进行尝试,但出来的声音数据处于整个屏幕的最下方,有一半数据被遮挡不见,所以放弃此方法。

在这里插入图片描述

后面将麦克风阵列垂直放置后发现接收到的数据偶尔会有偏移现象导致不准,所以开始尝试增加麦克风阵列的收音能力。

在这里插入图片描述

尝试通过增加桶装结构来增加收音功能,但由于桶太小,3m距离的两头顶点数据很少收到,所以最终还是使用垂直放置的方式。

在这里插入图片描述

2.3【各模块软件设计】

2.3.1 麦克风阵列软件设计:

依据官方给出的声源定位历程如下所示:

#导入MIC_ARRAY和LCD模块
from Maix import MIC_ARRAY as mic
import lcd

#初始化模块
lcd.init()
mic.init()

while True:

    #获取原始的声源黑白位图,尺寸 16*16
    imga = mic.get_map()

    #获取声源方向并设置LED显示
    b = mic.get_dir(imga)
    a = mic.set_led(b,(0,0,255))

    #将声源地图重置成正方形,彩虹色
    imgb = imga.resize(160,160)
    imgc = imgb.to_rainbow(1)

    #显示声源图
    lcd.display(imgc)

mic.deinit()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

问题:依据官方给的结果只能得出一张声场图,通过调用 get_dir 函数可以得到12个灯珠的强度。但是得不到具体的位置,只能令相应位置的灯珠亮。

通过在网上搜寻发现了一位大神所写的依据官方声源定位做处理得到相应X坐标,Y坐标,强度,角度的具体实现如下所示:

def get_mic_dir():
    AngleX=0
    AngleY=0
    AngleR=0
    Angle=0
    AngleAddPi=0
    mic_list=[]
    imga = mic.get_map()    # 获取声音源分布图像
    imgb = imga.resize(160,160)
    imgc = imgb.to_rainbow(1)
    lcd.display(imgc)
    b = mic.get_dir(imga)   # 计算、获取声源方向
    for i in range(len(b)):
        if b[i]>=2:
            AngleX+= b[i]*math.sin(i*math.pi/6)
            AngleY+= b[i]*math.cos(i*math.pi/6)
    AngleX=round(AngleX,6) #计算坐标转换值
    AngleY=round(AngleY,6)
    if AngleY<0:AngleAddPi=180
    if AngleX<0 and AngleY > 0:AngleAddPi=360
    if AngleX!=0 or AngleY!=0: #参数修正
        if AngleY==0:
            Angle=90 if AngleX>0 else 270 #填补X轴角度
        else:
            Angle=AngleAddPi+round(math.degrees(math.atan(AngleX/AngleY)),4) #计算角度
        AngleR=round(math.sqrt(AngleY*AngleY+AngleX*AngleX),4) #计算强度
        mic_list.append(AngleX)
        mic_list.append(AngleY)
        mic_list.append(AngleR)
        mic_list.append(Angle)
    a = mic.set_led(b,(0,0,255))# 配置 RGB LED 颜色值
    return mic_list #返回列表,X坐标,Y坐标,强度,角度
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

经过测试,发现数据非常NICE,但是还是有些达不到本次赛题的具体要求(只能说我也是非常头疼了)。于是开始尝试追寻源头,获取最底层的数据,尽量往题目de要求靠近了:(。

与麦克风阵列有关的函数库为MIC_ARRAY:MaixPy/components/micropython/port/src/Maix at master · sipeed/MaixPy (github.com)

  1. 通过查看发现我们所使用的 get_map() 函数内部只是把数据进行了一个拷贝,真正的数据来自 thermal_map_data ,定义如下:STATIC uint8_t thermal_map_data[256]; ,是一个静态变量。

    000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 093 191 000 000 000 000 000 000 000 000 000 000 
     000 000 000 204 243 109 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 255 146 146 000 000 000 000 000 000 000 000 000 
     000 000 000 000 122 219 076 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     ====================
    000 000 000 016 122 206 168 068 000 000 000 000 000 000 000 000 
     000 000 000 000 078 255 208 120 003 000 000 000 000 000 000 000 
     000 000 000 000 096 164 201 204 042 000 000 000 000 000 000 000 
     000 000 000 000 010 043 139 149 028 000 000 000 000 000 000 000 
     000 000 000 000 000 000 021 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
     000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  2. 这个变量只使用过两次,一次是初始化的时候进行读取,一次是在调用 get_map() 这个函数的时候进行处理。接下来就瞅瞅到底是如何调用数据的。

  3. Maix_mic_array_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) 函数中最后一行代码显示 int ret = lib_mic_init(DMAC_CHANNEL4, lib_mic_cb, thermal_map_data); 所以最原始的数据来自 lib_mic_init 这个函数,而这个函数在 #include "lib_mic.h" 函数库中。

  4. lib_mic.h 地址如下所示:https://github.com/sipeed/MaixPy/blob/master/components/kendryte_sdk/include/lib_mic.h,最终发现官方只给了 lib_mic.a 静态链接库。所以我们目前所能够获得的最原始的数据便是 thermal_map_data 这256个数据也就是16x16在屏幕上所能看到的音场图像

    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/879971
推荐阅读
相关标签