|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
# D* L2 s' x! \
文章目录
! b p" D* U. \2 f写在前面
# x% f! C3 F5 ^- @1 设计目标与问题分解
7 ?* ^7 I9 B- S2 K; B% W3 ~1.1 设计目标- X. u$ n" z. B$ c3 v" q) C
1.2 问题分解6 o, i2 a5 S# Q: |+ M) U( Z* B" f
2 解决思路: q8 y+ [0 }. ~! [7 J$ m: m
2.1 信源编码和解码部分
! ]+ m/ i0 ]9 D% u6 P. e2 V( l9 A2.2 信道编码和解码部分
4 ^& B- n: y# e( o9 B% ~% }9 G& y2.3 噪声信道部分
5 F! \4 v8 Q5 u2.4 声音信号识别部分
: N8 Z0 Q0 p9 D* h% o; y0 s6 H2.5 控制器部分
, e4 J/ H- ?2 W W# R. U+ I3 实现过程及每步实现结果, } ~" u' ]; M* z% y+ x
3.1 信源和信道编码模块
8 e0 R2 ?' C, ]3.2 调制解调模块
4 h# e* z+ s' e3.3 噪声模块" g- c! y4 z+ n8 r; a
3.4 声音信号处理模块
: ~; h+ w' f1 s0 _4 e3.5 控制模块
B3 g. a6 @$ k: n" r4 |; E- K! P3.6 系统整体实现$ z" g! e3 Y) q' x) }
X L7 W: v% [7 Q1 J! A+ H2 w写在前面# R k- k5 s; k g# f8 ?% t2 a
在本篇中将利用MATLAB设计一个远程声控小车系统并仿真,整体难度并不大,关键要理清信息的传输过程,理解信源和信道编码的意义等等,在课堂上学到的香农信息论等内容都是偏向于理论方面且比较抽象,亲自动手进行设计对这些理论的理解还是有蛮大的帮助的。
5 R* H$ ~) P7 K- D P+ D8 _4 s% J* x% ?$ L% K
; E6 [, b$ f c1 设计目标与问题分解
2 ?) P- ^. ]- n/ _6 f1.1 设计目标
: V9 A1 M) {. d* {完成远程声控小车系统设计与实现,需要采集语音控制信号并在适当压缩后发出,通过噪声信道传输,在小车接收端进行接收识别,进而控制小车在平面上运动。
$ q% M" w9 r; f+ x# L% F" k" u6 a/ s/ P# r# z$ @# \
1.2 问题分解. F; x3 N i+ o
该目标可以分为以下几步进行设计:" z" E6 D5 y8 M8 T
% |6 i/ U) s) _4 r4 O- 采集声音信号,并对声音指示信号进行一定的压缩,即选择合适的编码方式进行信源编码;
- 为了减小传输过程中噪声的影响,需要选择合适的编码方式进行信道编码并进行调制;
- 需要设计噪声信道,在调制后的信息内加入噪声;
- 需要在接收端接收信号并进行解调、信道解码、信源解码,重新将其转换成声音指示信号;
- 需要进行声音控制信号类型的识别,并将声音控制信号转换为相应的数字指示信号;
- 需要设计小车的控制系统,能根据指示信号做出反应并且保证系统具有可观能控性;
$ O6 P/ b5 E! Z* Z
2 ~( A, h8 s4 ?2 M& L1 A3 Z2 \6 a" C W7 u2 e7 o8 Q
2 解决思路
( F* L4 J. Q8 t' ?* }根据问题分解,可设计流程图如下,7 i- D/ I/ V2 a
" q$ l* \1 b& o: i2 z$ _
接下去将使用MATLAB软件进行实现,进行分步处理。) b0 h9 z0 G% S, L+ U o
% w/ o! f& J* o" |4 {$ D* T: W9 O
P& u0 ^; d3 M! m5 J/ L+ x9 W2.1 信源编码和解码部分
0 z: [* p0 \" B+ b! {为了对输入的消息进行适当压缩,要选用合适的编码方式,本次设计中对信号采用PCM的A律13折线法。* K) f: B/ {6 Q3 b# ]+ z8 l7 B
PCM(Pulse Code Modulation)脉冲编码调制是数字通信的编码方式之一。主要过程是对语音等模拟信号采样使其离散化后将抽样值按分层单位四舍五入取整量化,同时将抽样值按一组二进制码来表示抽样脉冲的幅值。A律13折线法即为将y轴等分成8份,而x轴按1/2比逐次缩小化取值,总共连成8个转折点,由于第一个点斜率不需要考虑,因此只考虑7点,算上y轴左侧就有14点。同时最左侧和最右侧的线段斜率相同,因此只需考虑13点为量化标准。
G/ K- f* ?, G+ S) b1 O1 l由于采用电脑仿真,因此在读取文件时已经完成了语音信号的采样,只需要进行幅值量化即可,同时对信号的幅值进行量化的这一过程也可以看作是对源信息的压缩,因为量化后表示某个小数所需要的二进制码比特数大概率会减小很多。
. I) ~; Y' i+ {- J0 I2 r. D2 T* E3 C/ h& O1 _3 k
! `3 q, ~$ X9 d! Q2.2 信道编码和解码部分
6 S- F2 N0 l+ u! E) _为了方便,本次设计采用3位重复编码,即1->111,0->000,此时可计算得编码速率为1/3,可以对1bit进行纠错。' ?4 l4 g9 _- w& W. y' h2 h) L
信道解码如下表,' S2 ?4 b5 ^' _0 H8 Y' c
, O, D- q5 t- L4 I
) b r9 ^2 W8 N可见此信道编码方式只能检测一位错误,当三位中有两位或以上产生错误时结果将出错,会影响最终解码。
* x& m* t+ M; v Q7 w2 v7 F3 [( q, L- s$ v- n
+ T6 I0 M- x9 _ D
& J& O h* X$ W2.3 噪声信道部分
2 L: ?6 S0 h2 n) o对于噪声信道部分,由于缺乏相应的设备,只能通过MATLAB来仿真噪声信道,通过将白噪声加入传输信号来模拟;
2 ` w* a' o# g$ I- Y/ Z! s( E0 |) P B. G* O% s4 Q
2.4 声音信号识别部分; D- J0 }% T3 f5 w( _
对于输入的音频信号,可以利用MATLAB内部函数来计算声音特征,并与先前存储的标准音频进行比对,将相似度最高的一项作为配对结果,将其转化为该项所对应的消息,完成声音控制信号到数字控制信号的转换。其中语音消息和数字信号对照表如下,
( G+ w' ]! p1 Z+ O. \' q
0 M5 R* z7 E* U. |$ V
& d+ D, y2 `) j- d5 l8 W% }4 y
- T) E- J+ k$ @! J" B& [( H2.5 控制器部分! n8 Y& Z; r$ V8 A/ \
控制系统也由MATLAB模拟,通过输出相应的结果来查看控制效果,用平面内的所有整数坐标点作为小车的活动区域,小车当前所处状态即为当前坐标,可以设计声控小车的语音消息和对应执行命令如下,# ~( f& R% [3 \2 P
% P$ \4 M7 y% J" b6 S6 p! S* a4 d- z; |5 a8 z
能控性证明
% A% b( P0 \& z$ f. V显然,由以上的命令表可知,小车可以前往平面内任意整数坐标位置,也可以从任意初始位置经过一系列操作后仍能回到原位置,即证明了该系统是能控的。
2 k4 k( O5 `- ~" v( o能观性证明0 i2 Y& {- [5 N1 g' G
输入将以规定运动轨迹的方式来控制小车运动,因此可以通过当前输入以及小车最终所处位置来反推出初始状态,即根据输入从终点开始反向绘制运动轨迹就可以找到初始位置,故该系统为能观的。
9 U. T) P3 y0 ?2 b/ k# f6 A7 N) U7 \, J( t8 U; B
; ]8 N7 T; X4 e# o5 Y } ]! z
3 实现过程及每步实现结果
9 p! Y1 R( i+ T: Z4 j3.1 信源和信道编码模块
8 d+ Q7 o. H9 k& d# t1 {按照解决思路内的原理可完成PCM编码的MATLAB代码,如果觉得比较困难的话可以参考这篇文章《基于 MATLAB 的 PCM 编码解码实现》。信道编码的实现则相对比较简单,在输入的信号中添加冗余项即重复三位,解码时每隔三位识别和是否大于2即可。9 d0 _6 D4 R* _$ R* g
考虑到音频文件在MATLAB内读取时会自动被采样为离散的数字信号,因此在测试时的输入设置为:xm4a=2*rand(1,100)-1;%随机产生(-1,1)的数字序列。部分测试代码和结果截图如下,7 m! C. U* ~9 ?
2 ^0 h) I) P4 E& S: W, Q- P% X
6 S/ N* {. H) {' ?" i# `4 k可见信源和信道的编码和解码均正常进行,其中miss代表信源和解码信号的欧氏距离,从中可见前后信号差距不大,体现该编码方式失真度较低,并且由对信号的幅度值进行了量化,因此起到了很好的压缩效果,便于传输。信源和信道的编码解码设计成功。
3 J1 L* [: R* z/ ~* ~9 d
9 ~; T6 D: H+ ]* I1 v9 ?3.2 调制解调模块0 `! |0 S6 p5 @( ^- [
此处将采用QPSK调制,由于信道编码后的序列为二进制,为充分发挥QPSK效果,需要将其进行两两分组从而转为四进制,此时可以利用reshape函数将信道编码后的序列的维度从1*n转为(n/2)*2,再利用bi2de函数将每一行的两个二进制码转为10进制,即可完成二-四进制间的转换,之后使用pskmod和pskdemod函数进行QPSK调制与解调,再转回二进制码序列。
+ u% ^" q% J3 D0 D& N具体模块的MATLAB代码如下," ^. V0 f; t5 G! f. z
/ V# Q3 U. Q3 S: r# ]
- %QPSK调制
- x=bi2de((reshape(xch,2,length(xch)/2))');
- yout = pskmod(x,4);
- %QPSK解调
- yin=pskdemod(yout,4);
- ydein=reshape(de2bi(yin,2)',1,length(yin)*2);, T/ _& F9 `& n3 o! L1 ~
, z* i% j( B7 U6 F) b4 ^( m0 X, P/ B. G6 g2 j& \6 l5 J
测试结果如下,左图为星座图,右图为调制和解调调制信号的对比,可见调制与解调过程正常进行,结果正确。3 ~+ N2 S: A3 m9 w
* {9 h9 u6 Y) a. ?/ r
& @9 Y- S) o3 f% p8 r" J: `
+ m* `, e. z9 b0 _9 o
3.3 噪声模块2 O$ | a$ {3 @
该部分可以直接采用MATLAB内部awgn函数来模拟,此时即可将噪声加入进行测试,测试代码和结果如下,
# o9 o5 K9 G" d7 K8 ?4 [; h y
- H) m6 K4 f* r( Q
7 t8 h M! h6 }& Z; e9 }4 P: Y% Z5 z+ e
图中左侧工作区的M代表误码数,R代表误码率,从中可以看出,对于随机生成的这10000个消息,经过信源和信道编码后变为24000bits的二进制信号,该二进制在通过信噪比为3dB的噪声信道后,有26967bits受噪声影响出错了,因此错误率为11.24%,会对最后的解码有一定影响。可见大多数信号在经过该噪声信道后仍能保持正确的信息。* @; A0 r: ]. W6 w
同时针对不同信噪比进行分析,作出如下图象,可见随着信噪比的提升,错误率逐渐下降至趋于0,与理论情况相符合,并且在信噪比10dB时已经几乎不会出错。
' g% m0 k0 \0 ~( {7 r7 S* M, r+ \) Q1 j
( M. ^7 h, o5 G' B0 n6 O
8 `, n: g6 s. T6 Y. i I4 j% X- j
* I( _1 J2 d1 H& q" f至此,对信息传输过程的设计与实现部分已成功完成,接下来是处理。- H. y; U+ I1 `3 i
# p& Y0 k- V3 Z4 t: F) P5 N" c9 N" Q: [- K0 C
3.4 声音信号处理模块* ]" c; ` a, P: c- E1 h- S
该部分最关键的是要进行语音识别,具体实现如下。
4 M9 |, B: F! n# b/ y* o先录制几段标准声音文件作为对输入音频进行配对用的音频信号,并存储在电脑内。2 f9 Z2 p! X# }5 Z% a
采集声音信号为m4a文件,利用MATLAB内部audioread()函数来进行声音-数字信号的转换,其后利用MATLAB的工具箱voicebox内的melcepst函数来计算输入音频的语音特征梅尔频率倒谱系数(MFCC),此处voicebox不是MATLAB安装时自带的,需要另行下载。$ F) t1 }$ p$ z" \2 V
当输入为单个音频控制信号时,用dtw函数来计算输入信号MFCC与先前存储的标准声音文件的MFCC的差距,将两者作为dtw函数的两个输入,输出的值越小则说明匹配度越高,并选择能使得dtw输出最小的一个标准声音文件与输入配对,至此,语音识别完成。需要注意的是,dtw的输入必须维度相同,因此要对音频进行长度上的对齐。
, F- R- o7 J- Q' l在完成语音识别后,即可将输入音频转化为与所匹配的标准音频所对应的消息。 i2 |' i: B; ^- Q+ b, p$ [
当输入为多个音频控制信号时,只需将其在时域上进行一段段的划分,分别进行MFCC的计算和与标准音频的匹配,即可完成对多个音频控制信号的转化。, _ j2 {; z' C" R9 e J4 ^
下面以“东”,“南”,“西”,“北”的音频为例演示语音识别模块:
) I; \( k# n. f6 \+ c" f6 A文件2为“东”,文件1为“东”的标准声音文件,文件4为“西”,文件3为“西”的标准声音文件,文件6为“南”,文件5为“南”的标准声音文件,文件8为“北”,文件7为“北”的标准声音文件,MATLAB主体代码如下,
- l. `# C7 { |& n
; H: Z8 S" c: S% ?* P5 Z1 Q
4 J# O# L% r4 C/ C
, p7 @5 f% }* x: G6 p
7 D Y1 e; e c7 A+ y, H9 _( B运行后结果如下,可以看出,与文件2匹配度最高的为文件1,与文件4匹配度最高的为文件3,与文件6匹配度最高的为文件5,与文件8匹配度最高的为文件7,即“东”,“南”,“西”,“北”的音频均识别正确。0 @/ s$ \* b' R4 x {
+ H5 M5 p( X2 c: y8 c+ E5 m
1 M4 U. A+ M' ?0 u; ~9 U/ F( l
0 Z- }$ H' w% Y* D0 G6 V% }6 e; D, r6 m
在此基础上稍作修改即可完成音频信息与数字控制消息间的转化。, y! T# {2 j* [) a# q6 C2 L
$ c, x% ~( C6 H0 S: j X$ A9 L* c( a4 f( ~9 u c
3.5 控制模块
/ X% x3 {1 L* b6 R8 ` P/ a& L在仿真中假设地图满足上北下南左西右东的规则,设计控制器MATLAB代码mov.m定义为:function [destination,line] = mov(decode,start)%返回目的地和路径1 I4 i: e% s9 Z. i# W
因为此处只涉及平移的操作,实现起来较为简单,直接利用case语句写即可,所以不再赘述。
1 r. {2 Z# g- H# S6 C3 L4 G6 O0 c/ n( ]9 y# l8 U5 r5 Y
3.6 系统整体实现
9 [4 c7 Q3 t; o; v! w+ E$ W) a根据前面的分析可以来撰写整体的代码。对输入设置如下,0 F1 \4 N4 s8 F7 d' M
: [) n2 m" E, k
- %输入声音文件,内部每2s一个声音信号,每个信号有效长度在0.5s以内,顺序为北-东北-东-东南-南-西南-西-西北,旋转一圈
- xdig=m4a2xdig('C:\Users\46817\Desktop\m4a\序列.m4a');
7 e+ P1 `3 w: K+ i' C! c& k
* P( B9 X7 t) D P运行结果如下,+ D; W& z* w& M- S8 d) S8 o
1 F1 ?5 S0 Y) G$ u; a3 b5 i2 { [' y+ y7 S) k
% E$ Y. N& w/ E( O; p$ g, q$ M# G从结果可见小车成功按照语音控制信号的指示路径转了一圈,回到了起点。远程声音控制系统设计成功。
! M' k( I; [$ W7 h" m/ A- H由于收集大量音频信号工作量比较大,此处在MATLAB内随机挑选八个方向的音频信号共100次并将结果整合成一个向量来作为输入进行整体系统性能的测试,实现代码如下,
1 s8 [: ^) ?) p |& x8 a8 h0 [; H. D" t2 G6 @. A$ b1 }
- for i=1:100
- j=randi([1 8]);
- tem(i,:)=orim4a(j,:);%orim4a内为各音频信号
- end
- xm4a=reshape(tem',1,100*length(orim4a));- f3 `+ C, I% I% h
- r) W l* I4 h8 H% ~: }4 j) G
- T \3 t0 R+ m
仿真结果如下所示,从图中可见此小车路径中没有出现红色箭头,并且实际终点与正确终点相重合,因此远端消息对小车进行了准确的控制操作,因此所设计系统对大量输入也能正确进行远程控制,设计成功。8 |& ~: \% T; |! B1 S: Q0 S
" M4 E, | p% [: ~- H8 X" j; M8 A8 [
& X% @3 B( }# P! I. _4 ~
I- n9 k1 r4 S! \* K" B5 [当信噪比较小例如1dB时,控制信号在传输时可能会受噪声影响而出错,造成如下结果,可见有很多路径出现了红色箭头,即识别出错,最后的终点也与正确终点不同,因此该系统对信道的噪声有一定要求。
$ l0 m+ Z9 g( @
# {2 s5 ^ @' D& V8 U* _1 W' U2 B' A! I3 g. P5 c
9 ~* \; t) r6 V- W
至此,远程声音控制系统仿真完成。
* F2 Q' B8 J! a. Z此处附上整体实现代码
8 v0 |8 m" z# h+ c( n9 e
) |! X/ b6 k" `1 _; b4 ~+ h3 vclc;clear;close all;, k" |1 e1 p7 k3 A8 d; O# C7 N
%%输入7 V9 {* x7 v/ r: v
%输入声音文件,内部每2s一个声音信号,每个信号有效长度在0.5s以内,顺序为北-东北-东-东南-南-西南-西-西北,旋转一圈2 M8 D/ M- C. E) t4 B* ?
[xm4a,fs]=audioread('');& K" V) l. Q7 v
%%
2 ~$ x; x0 m# V# o: B%编码和调制模块
9 x, V1 Q* k0 L. |%信源PCM编码/ D, L+ }9 B$ @6 J2 q4 ^! l2 y
xso=soencodePCM(xm4a);8 l* b5 Q) G: t
%信道编码
7 n( T5 Z- N2 e# O1 `len=3;+ s% U% D1 @+ ]5 J
xch=chencode(xso,len);8 T2 L. z( j: r3 Q( P1 p6 Q
%QPSK调制
( v, |$ D# O- a v) {3 ?+ p6 G& ?x=bi2de((reshape(xch,2,length(xch)/2))');
$ s0 [, o$ P4 G+ J4 N7 @6 ]# Nyout=pskmod(x,4);
& l. U6 R, p. d; R) q! b" \8 u9 ^%%) B O5 j. L4 f" e* l
%噪声模块
& T8 B/ B" n2 B/ \% CSNR=10;. U6 a/ a t6 S5 d. z
yn=awgn(yout,SNR);
1 G3 I7 p" q, U- Y" y9 S' S%%
. [# X( D/ T7 s%解调和解码模块
3 K6 z: j' u0 y/ p2 W* `%解调
! S, R0 {! j5 o" x3 lyin=pskdemod(yn,4);+ z: G$ {5 C0 A& `
ydein=reshape(de2bi(yin,2)',1,length(yin)*2);/ h! E5 T9 a7 H, s4 m
%信道解码
# E, V( `) O7 k/ O. r- h; R+ jych=chdecode(ydein,len);
+ V L) I* X2 x- _* { A) x%信源PCM解码4 J* L8 j: g* ^% j8 S
yso=sodecodePCM(ych);/ C" ]& B0 P- u* `
%% A* v* z& A7 O1 G7 {% F
%音频信号处理模块7 H3 i9 a' M; W# P4 F
ydig=m4a2xdig(yso);
$ Q( A) @7 L* K+ Y6 }) r" k: C3 J! i%%+ ?5 p8 ^9 u! g2 R, { r
%控制系统
- a8 D# r. L, Y) e# h%起始点. o2 Y: B- q& ~" _! y6 r8 u
start=[1 2];9 a9 K# ?5 q& [+ M, r
%控制器解析传入信号
3 K" a$ G( t7 p2 y[outy,liney]=mov(ydig,start);
* H& |6 O8 V$ N" d1 d# `' Q+ y3 A. `& Y%控制器解析原始信号
* ?! S3 Y6 A0 `5 ?3 n6 e1 Rxdig=m4a2xdig(xm4a);
; r6 ?' a+ p9 Z[outx,linex]=mov(xdig,start);
% k: R+ ^6 u& |, w# q%绘制小车路径的有向图、起点、正确终点、实际终点
7 b0 U k2 z# r( G& x6 e- Kplot(liney(:,1),liney(:,2),'Color','b');hold on;8 R/ P) A4 V; \; a' w
for i = 1:length(ydig)
; q" H/ W) B3 H if ydig(i)==xdig(i)%信息传递正确则蓝色箭头
, P, s4 e/ t H* H1 q8 v ay = annotation('arrow','HeadLength',4,'HeadWidth',3,'Color','b');; M2 p& H! ]' I9 |0 a
else%信息传递错误则红色箭头# U& A$ ~& t/ i- A i" O; d- A3 ~
ay = annotation('arrow','HeadLength',6,'HeadWidth',5,'Color','r');6 h* h& \( {) p7 m% N
end% |7 ~" G! \- l& G3 X
set(ay,'parent',gca); ) s; k$ x; m7 X- M$ n% Y
set(ay,'position',[liney(i+1,1) liney(i+1,2) 0.05*(liney(i+1,1)-liney(i,1)) 0.05*(liney(i+1,2)-liney(i,2))]);, x! v# }1 ^- s$ P* x- a9 ~: z
hold on;
- [6 q% o# B) `2 B$ ?6 | Gend
& V9 p# S# {% \' p* |( ~plot(start(1),start(2),'g.','MarkerSize',20);hold on;
. n8 j- v6 G: t4 p: Eplot(outy(1),outy(2),'r.','MarkerSize',15);hold on;
g; |- A- l) }8 R. N, eplot(outx(1),outx(2),'b.','MarkerSize',10);hold on;2 z# m3 t/ C, Q: D" ?5 B- B9 k u! l
legend('实际路径','起点','实际终点','正确终点');
' ?, r% T+ {6 K. U% g
* h4 \4 H2 H: l) _2 z; r
% |7 Z; K, o" F( b4 t/ J3 M' h5 k/ d% \) d* f
$ G) q( G C* M/ z |
|