智能车声标定位相关算法优化
相關(guān)
相關(guān)部分比較簡單,相關(guān)的意義和實(shí)現(xiàn)有需要可以參考下面兩篇博文,
https://blog.csdn.net/jbb0523/article/details/6669883?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4
https://blog.csdn.net/LiuXF93/article/details/88956643?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-5&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-5
相關(guān)函數(shù)優(yōu)化
將相關(guān)部分轉(zhuǎn)化成代碼
/*!* @brief 互相關(guān)** @param acor: 互相關(guān)結(jié)果* @param x : 互相關(guān)數(shù)據(jù) x* @param y : 互相關(guān)數(shù)據(jù) y* @param len : 互相關(guān)數(shù)據(jù)長度** @return 無** @note 無** @see** @date 2020/4/28*/ void xcorr(float *acor, int16_t *x, int16_t *y, uint16 len) {double sum = 0;int delay, i, j;for(delay = -len + 1; delay < 0; delay++){sum = 0;for(i = 0; i < len; i++){j = i + delay;if((j < 0)){sum += 0.00001f * x[j + len] * y[i]; //防止溢出,縮小一定倍數(shù)}else if(j >= len){sum += 0.00001f * x[j - len] * y[i]; //防止溢出,縮小一定倍數(shù)}else{sum += 0.00001f * x[j] * y[i]; //防止溢出,縮小一定倍數(shù)}}acor[delay + len - 1] = (float)sum;} }運(yùn)行時間巨慢,簡直無法使用,但是這個和fft加速相比,占用內(nèi)存比較小,TC264官方的FFT庫需要輸入輸出都是float32的復(fù)數(shù),在做相關(guān)的時候還需要把2048點(diǎn)的原始數(shù)據(jù)補(bǔ)零變成4096點(diǎn)的復(fù)數(shù),兩組數(shù)據(jù)進(jìn)行相關(guān)就需要 4 x 2 x 4096 x 3 字節(jié),也就是96KB。而TC264雙核架構(gòu),CPU0的dsram只有72KB,CPU1的dsram只有120KB,嗯,也就是只可以用CPU1的內(nèi)存了,但是這只是一個麥克風(fēng)和FM做相關(guān)計算,一般確定位置最少也要三個麥克風(fēng),內(nèi)存不夠用了!怎么降低內(nèi)存消耗?
1.可以降低采樣率,以5KHz的頻率進(jìn)行采樣,這樣1024點(diǎn)就可以采集到一個周期,缺點(diǎn)就是原始數(shù)據(jù)粒度下降了,可能會影響相關(guān)結(jié)果,實(shí)測的時候發(fā)現(xiàn)相關(guān)峰值位置不會變,沒有發(fā)現(xiàn)和原始結(jié)果有太大區(qū)別(也可能是測的不太久)。2.可以使用TC264DA版芯片,DA芯片多了512K的EMEM內(nèi)存,可以在CPU0中進(jìn)行使用,缺點(diǎn)EMEM速度比常規(guī)的RAM要慢一些。使用FFT加速相關(guān)運(yùn)算的步驟比較簡單
1.將ADC采集到FM信號1和9814信號2從2048點(diǎn)補(bǔ)零成4096點(diǎn)
2.對信號1和信號2進(jìn)行FFT變換
3.對信號2求共軛
4.(信號1FFT結(jié)果)* (信號2FFT結(jié)果的共軛)
5.對上述結(jié)果進(jìn)行IFFT變換
6.求出IFFT變換結(jié)果的幅值
7.找出最大幅值的下標(biāo)
8.兩個信號之間的時延 = 最大下標(biāo) * 1/采樣頻率
9.距離信息 = 時延 * 聲速
那么是否必須使用FFT加速呢?
我們可以上述直接相關(guān)函數(shù)進(jìn)行優(yōu)化,直接相關(guān)函數(shù)一樣可以得到最大下標(biāo)(也就是FFT加速的第7個步驟),賽場大小是固定的,因此距離信息其實(shí)有最大值的,而距離信息 = 時延 * 聲速,聲速固定,因此時延其實(shí)有最大值,時延和最大下標(biāo)又有關(guān)系,因此最大下標(biāo)其實(shí)在一個范圍內(nèi),我們直接進(jìn)行相關(guān)的時候,可以只求最大下標(biāo)范圍內(nèi)的相關(guān)值,因此相關(guān)函數(shù)可以改成如下
/*!* @brief 互相關(guān)** @param acor: 互相關(guān)結(jié)果* @param x : 互相關(guān)數(shù)據(jù) x* @param y : 互相關(guān)數(shù)據(jù) y* @param len : 互相關(guān)數(shù)據(jù)長度** @return 無** @note 無** @see** @date 2020/4/28*/ void xcorr(float *acor, int16_t *x, int16_t *y, uint16 len) {double sum = 0;int delay, i, j;for(delay = -300; delay < 0; delay++) //300 * 100us * 0.0346 cm/us (聲速) 可以檢測最遠(yuǎn)距離 10.38m // for(delay = -len + 1; delay < len; delay++){sum = 0;for(i = 0; i < len; i++){j = i + delay;if((j < 0)){sum += 0.00001f * x[j + len] * y[i]; //防止溢出,縮小一定倍數(shù)}else if(j >= len){sum += 0.00001f * x[j - len] * y[i]; //防止溢出,縮小一定倍數(shù)}else{sum += 0.00001f * x[j] * y[i]; //防止溢出,縮小一定倍數(shù)}}acor[delay + 300] = (float)sum;} }速度有所提升,將對應(yīng)的變量全部放到運(yùn)行CPU的dram中,大概需要50ms,50ms還是有點(diǎn)好長啊,是否可以接著優(yōu)化?
分析這個函數(shù),發(fā)現(xiàn)循環(huán)次數(shù)非常多,大部分資源都耗費(fèi)在循環(huán)上了,按一般最少使用3個4468模塊來算,一次循環(huán)做三組相關(guān),是否可以提高效率?
void xcorr(float *acor1, float *acor2, float *acor3, int16_t *x, int16_t *y, int16_t *y1, int16_t *y2, uint16 len) {float sum3 = 0;float sum1 = 0;float sum2 = 0;int delay, i, j;for(delay = -300; delay < 0; delay++) // for(delay = -len + 1; delay < len; delay++){sum1 = 0;sum2 = 0;sum3 = 0;for(i = 0; i < len; i++){j = i + delay;if((j < 0)){sum1 += 0.0001f * (float)x[j + len] * (float)y[i];sum2 += 0.0001f * (float)x[j + len] * (float)y1[i];sum3 += 0.0001f * (float)x[j + len] * (float)y2[i];} // else if ((j >= len)) // { // sum1 += 0.0001f * (float)x[j - len] * (float)y[i]; // sum2 += 0.0001f * (float)x[j - len] * (float)y1[i]; // sum3 += 0.0001f * (float)x[j - len] * (float)y2[i]; // }else{sum1 += 0.0001f * (float)x[j] * (float)y[i];sum2 += 0.0001f * (float)x[j] * (float)y1[i];sum3 += 0.0001f * (float)x[j] * (float)y2[i];}}/* 相關(guān)結(jié)果存放在 300長度數(shù)組中 */acor1[300 + delay] = (float)sum1;acor2[300 + delay] = (float)sum2;acor3[300 + delay] = (float)sum3;} }實(shí)測發(fā)現(xiàn),三組相關(guān)時間上大概需要70ms左右,這樣子就和用FFT加速效果差不多,如果使用更多9814模塊,速度上就可能超過FFT加速,而且內(nèi)存消耗相比FFT減少的不要太多。
思考
小車在運(yùn)動過程中采集數(shù)據(jù)是否會影響距離信息精確度?該如何減小該方面誤差?
可以在滅燈后原地靜止,當(dāng)下一個信標(biāo)燈響起,采集到一幀靜止?fàn)顟B(tài)的數(shù)據(jù),獲取精確的距離信息,根據(jù)此距離信息和編碼器信息,在空間位置上進(jìn)行控制。不過這樣有個問題,計算的距離信息必須準(zhǔn)確,編碼器距離積分必須精確(脈輪車估計不行)。
可以運(yùn)動過程中進(jìn)行采集計算,計算大概方位,然后橫沖直撞莽過去,個人覺得這種比較靠譜。
總結(jié)
以上是生活随笔為你收集整理的智能车声标定位相关算法优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。