GNU RADIO软件无线电benchmark程序发送接收文件测试笔记

GNU RADIO软件无线电benchmark程序发送接收文件测试笔记
 
 GNU RADIO软件无线电benchmark程序发送接收文件测试笔记
    在GNU RADIO软件无线电程序中,benchmark程序可以发射900MHZ,接收900MHZ的无线电信号。具体做法是,把两台装有Basic子板的USRP1母板分别连上两台电脑的USB端口上,接通电源,在ubuntu操作系统下,在其中一台电脑的终端提示符下键入:
 “ cd /usr/local/share/gnuradio/example/digital/"
进入benchmark程序的目录, 再键入:
“./benchmark_tx.py -f 900M"
这时候,和这台电脑USB端口连接的USRP母板上的LFTX子板通过电线就会发送一个900MHZ的无线电信号,电脑显示器显示:
".................."
表示正在发射无线电信号。这时,在另外的一台电脑上的终端提示符下键入:
“ cd /usr/locaul/share/gnuradio/example/digital/"
进入benchmark程序的目录, 再键入:
“./benchmark_rx.py -f 900M"
这时候,和这台电脑USB端口连接的USRP母板上的LFTX子板通过电线就会收到一个900MHZ的无线电信号,电脑显示器显示:
ok=True pktno=1202 n_rcvd=1 n_right=0
表明接收信号正常。
    现在的问题是要从这个电脑发送一个文件到另外一个电脑,我查找了相关资料发现,benchmark具有发送文件的功能,但是开源程序里没有这项功能,需要用户根据自己的需要修改程序来达到发送接收文件的功能。我通过研究发现,修改程序后,可以把这台电脑的aa.txt文件的“hello“字符发送到另外一台 电脑的tt.txt文件中。具体做法是,在发送端电脑的"/usr/local/share/gnuradio/example/digital"目录下新建aa.txt,tt.txt两个文本文件,在aa.txt中输入"hello"并保存,然后在终端下输入:
“vi benchmark_tx.py"
在vi编辑器下打开benchmark_tx.py程序,在第124行
" tb.start()                       # start flow graph",
后输入
    “f=open("/usr/local/share/gnuradio/examples/digital/aa.txt","r")”
    “lines=f.readlines()”
两行新程序,第一行程序是以只读方式打开aa.txt文件,第二行程序的作用是以每行阅读的方式读出aa.txt中的文本内容,然后再赋值给"lines"数组,接着把第140行程序
 "payload = struct.pack('!H', pktno & 0xffff) + data "
改为
 " payload = str(options.num ) + str(lines) "
这步的作用是,去掉了打包发送pkno函数的功能,而加入发送lines函数和options.num函数的功能。
    现在说一下options.num函数是从哪来的。首先把程序的第95行至第100行,改为
    parser.add_option("-E","--discontinuous", action="store_true", default=False,
                      help="enable discontinous transmission (bursts of 5 packets)")
 
    parser.add_option("-W","--from_file",dest="from_file", default=None,
                      help="use intput file for packet contents")
 
    parser.add_option("-T","--to_file",dest="to_file", default=None,
                      help="Output file for modulated samples")
 
    parser.add_option("-n","--num",type="int",dest="num",default=1000,
                      help="send message")
 
    parser.add_option("-e", "--file",dest="filename", 
                      help="write report to FILE",metavar="FILE")
 
    parser.add_option("-p", "--pdbk", action="store_true", 
                      dest="pdcl", 
                      default=False, 
                      help="write pdbk data to oracle db") 
   
     parser.add_option("-z", "--zdbk", action="store_true", 
                      dest="zdcl", 
                      default=False, 
                      help="write zdbk data to oracle db") 
 
 
简单说一下,在终端输入“benchmark_tx -f 900M -n 1500”时,程序以900MHZ的频率发送数组options.num中的数字1500和lines数组,因为
 parser.add_option("-n","--num",type="int",dest="num",default=1000,
                      help="send message")
定义了一个属性是num的option.num函数通过提示符"-n xxx"来返回一个值给option.num数组, 上面其他程序的作用是定义了在终端提示符下发送文件"-W",接收文件"-T",写入给数据库"-p",读取数据库"-z", 其他功能这里暂时不讨论。修改完成后保存文件,退出vi编辑器。
    下来在接收端的电脑上的"/usr/local/share/gnuradio/example/digital/narrowband"目录下新建aa.txt,tt.txt两个空白文本文件,然后在终端下输入:
“vi benchmark_rx.py"
在vi编辑器下打开benchmark_rx.py程序,把第79行到第98行的内容改为
global n_rcvd, n_right
global n_data
def main():
    global n_rcvd, n_right
    global n_data
    n_rcvd = 0
    n_right = 0
    n_data = str()
    def rx_callback(ok, payload):
        global n_rcvd, n_right
        global n_data
        (pktno,) = struct.unpack('!H', payload[0:2])
        n_data = payload[0:4096]
        f=open("/usr/local/share/gnuradio/examples/digital/tt.txt","w")
        f.write(payload)
        n_rcvd += 1
        if ok:
            n_right += 1
 
        print "ok = %5s  pktno = %4d  n_rcvd = %4d  n_right = %4d n_data = %5s" % (
            ok, pktno, n_rcvd, n_right, n_data)
其中,
n_data = payload[0:4096]
定义变量n_data用来显示接收的options.num数组和lines数组。 还有上述
        f=open("/usr/local/share/gnuradio/examples/digital/narrowband/tt.txt","w")
        f.write(payload)
两行程序实现了以写入方式打开tt.txt文本文件,然后把接收的payload数组写入tt.txt中。
保存修改退出vi编辑器后,在发送端的电脑/usr/local/share/gnuradio/example/digital的目录下键入
./benchmark_tx.py -f 900M -n 1900
后,电脑显示
".................."
表示发送正常,然后在接收端电脑/usr/local/share/gnuradio/example/digital的目录下键入
./benchmark_tx.py -f 900M 
电脑显示
ok =  True  pktno = 12598  n_rcvd =  458  n_right =  458 n_data = 1900['hello\n']
表示接收正常。用“ctrl+c”键停止接收,打开接收端电脑/usr/local/share/gnuradio/example/digital/的目录下的tt.txt文件,发现原来是空文件的tt.txt,出现'['hello\n']显示,表示发送接收正常.说明发送端电脑上的aa.txt文件中的“hello”字符已经传送到接收端电脑的tt.txt文件中。
     给发送端电脑的aa.txt文件中添加字符,如把“hello”改为“hello python”,接收端点脑上的tt.txt文件中显示“['hello python\n']",表明接受正常,当aa.txt中字符的长度超过3571个字节时,接收端就会显示乱码,因为每次程序只能发送低于3571字节的 文本,一旦文本超过了3571字节,发送的信息量太大就会使程序读入数据出错,接收端就会收到乱码,要传送更多字节的文本就要修改程序,这个问题还在研究,现在不做讨论。
     下面测试一下能不能用其他子板正常发送接收文本。把上面的两个Basic子板换成两个WBX子板,WBX子板上都连有天线。测试后发现接收端的tt.txt就会显示乱码和误码。例如 原来发送aa.txt文本中的"hello",接收到的tt.txt文本却是为"\welp&*%"。造成这个结果的原因是WBX子板靠天线发送 信号,而LFRX子板是通过屏蔽线传输信号。WBX子板发送无线电后,由于空间中的干扰,无线电信号在传输中会产生衰减和变化,另外的WBX子板接收到的 无线电信号就会和发送的无线电信号不同。要想传输的内容不发生变化,就要修改程序,使每次只发送一个数据,这样接收就不容易产生误码和乱码。修改程序后,把benchmark_tx.py中的
 "payload = data + str(lines) + chr(options.num & 0xff) "
改为 
"payload = str(lines) “
作用是只把 lines的值赋给发送函数paload,相当于只发送了lines数组。同时把发送端电脑的aa.txt文件里的“hello”改为“h”,只发送一个字符"h",减少了传送的数据量,此时运行接收
./benchmark_rx.py -f 900M 
和发送
./benchmark_tx.py -f 900M
发现接收端电脑的tt.txt文本显示\'h';表明接收成功
附件:benchmark_rx.py源码
#!/usr/bin/python
#!/usr/bin/env python
#
# Copyright 2010,2011,2013 Free Software Foundation, Inc.
# This file is part of GNU Radio
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
 
from gnuradio import gr, gru
from gnuradio import blocks
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
from optparse import OptionParser
 
# From gr-digital
from gnuradio import digital
 
# from current dir
from receive_path import receive_path
from uhd_interface import uhd_receiver
 
import struct
import sys
 
#import os
#print os.getpid()
#raw_input('Attach and press enter: ')
 
class my_top_block(gr.top_block):
    def __init__(self, demodulator, rx_callback, options):
        gr.top_block.__init__(self)
 
        if(options.rx_freq is not None):
            # Work-around to get the modulation's bits_per_symbol
            args = demodulator.extract_kwargs_from_options(options)
            symbol_rate = options.bitrate / demodulator(**args).bits_per_symbol()
 
            self.source = uhd_receiver(options.args, symbol_rate,
                                       options.samples_per_symbol, options.rx_freq, 
                                       options.lo_offset, options.rx_gain,
                                       options.spec, options.antenna,
                                       options.clock_source, options.verbose)
            options.samples_per_symbol = self.source._sps
 
        elif(options.from_file is not None):
            sys.stderr.write(("Reading samples from '%s'.\n\n" % (options.from_file)))
            self.source = blocks.file_source(gr.sizeof_gr_complex, options.from_file)
        else:
            sys.stderr.write("No source defined, pulling samples from null source.\n\n")
            self.source = blocks.null_source(gr.sizeof_gr_complex)
 
        # Set up receive path
        # do this after for any adjustments to the options that may
        # occur in the sinks (specifically the UHD sink)
        self.rxpath = receive_path(demodulator, rx_callback, options) 
 
        self.connect(self.source, self.rxpath)
 
 
# /////////////////////////////////////////////////////////////////////////////
#                                   main
# /////////////////////////////////////////////////////////////////////////////
 
global n_rcvd, n_right
 
def main():
    global n_rcvd, n_right
    global c_rev
    n_rcvd = 0
    n_right = 0
    
    def rx_callback(ok, payload):#dingyi rx_callback hanshu ,zuoyong shi xianshi jieshoushujubao
        global n_rcvd, n_right
        global c_rev   #dingyi c_rev wei jieshou hanshu
        (pktno,) = struct.unpack('!H', payload[0:2])
        (c_rev,) = struct.unpack('H', payload[0:2])#c_rev jieshou xinhao
        n_rcvd += 1
        if ok:
            n_right += 1
        print "ok = %5s  pktno = %4d  n_rcvd = %4d  n_right = %4d c_rev = %4d" % (
            ok, pktno, n_rcvd, n_right,c_rev)
 
    demods = digital.modulation_utils.type_1_demods()
 
    # Create Options Parser:
    parser = OptionParser (option_class=eng_option, conflict_handler="resolve")
    expert_grp = parser.add_option_group("Expert")
 
    parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), 
                      default='psk',
                      help="Select modulation from: %s [default=%%default]"
                            % (', '.join(demods.keys()),))
    parser.add_option("","--from-file", default=None,
                      help="input file of samples to demod")
 
    receive_path.add_options(parser, expert_grp)
    uhd_receiver.add_options(parser)
 
    for mod in demods.values():
        mod.add_options(expert_grp)
 
    (options, args) = parser.parse_args ()
 
    if len(args) != 0:
        parser.print_help(sys.stderr)
        sys.exit(1)
 
    if options.from_file is None:
        if options.rx_freq is None:
            sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
            parser.print_help(sys.stderr)
            sys.exit(1)
 
 
    # build the graph
    tb = my_top_block(demods[options.modulation], rx_callback, options)
 
    r = gr.enable_realtime_scheduling()
    if r != gr.RT_OK:
        print "Warning: Failed to enable realtime scheduling."
 
    tb.start()        # start flow graph
    tb.wait()         # wait for it to finish
 
if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass
 
benchmark_tx.py源码
#!/usr/bin/python
#!/usr/bin/env python
#
# Copyright 2010,2011,2013 Free Software Foundation, Inc.
# This file is part of GNU Radio
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
 
from gnuradio import gr
from gnuradio import blocks
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
from optparse import OptionParser#diaoyong minglinghang chuli canshu
 
# From gr-digital
from gnuradio import digital
 
# from current dir
from transmit_path import transmit_path
from uhd_interface import uhd_transmitter
 
import time, struct, sys
 
#import os 
#print os.getpid()
#raw_input('Attach and press enter')
 
class my_top_block(gr.top_block):
    def __init__(self, modulator, options):
        gr.top_block.__init__(self)
 
        if(options.tx_freq is not None):
            # Work-around to get the modulation's bits_per_symbol
            args = modulator.extract_kwargs_from_options(options)
            symbol_rate = options.bitrate / modulator(**args).bits_per_symbol()
 
            self.sink = uhd_transmitter(options.args, symbol_rate,
                                        options.samples_per_symbol, options.tx_freq,
                                        options.lo_offset, options.tx_gain,
                                        options.spec, options.antenna,
                                        options.clock_source, options.verbose)
            options.samples_per_symbol = self.sink._sps
            
        elif(options.to_file is not None):
            sys.stderr.write(("Saving samples to '%s'.\n\n" % (options.to_file)))
            self.sink = blocks.file_sink(gr.sizeof_gr_complex, options.to_file)
        else:
            sys.stderr.write("No sink defined, dumping samples to null sink.\n\n")
            self.sink = blocks.null_sink(gr.sizeof_gr_complex)
 
        # do this after for any adjustments to the options that may
        # occur in the sinks (specifically the UHD sink)
        self.txpath = transmit_path(modulator, options)
 
        self.connect(self.txpath, self.sink)
 
# /////////////////////////////////////////////////////////////////////////////
#                                   main
# /////////////////////////////////////////////////////////////////////////////
 
def main():
 
    def send_pkt(payload='', eof=False):#dingyi fasong hanshu
        return tb.txpath.send_pkt(payload, eof)
 
    mods = digital.modulation_utils.type_1_mods()
 
    parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
    expert_grp = parser.add_option_group("Expert")
 
    parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
                      default='psk',
                      help="Select modulation from: %s [default=%%default]"
                            % (', '.join(mods.keys()),))
 
    parser.add_option("-s", "--size", type="eng_float", default=1500,
                      help="set packet size [default=%default]")
    parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
                      help="set megabytes to transmit [default=%default]")
    parser.add_option("-E","--discontinuous", action="store_true", default=False,
                      help="enable discontinous transmission (bursts of 5 packets)")
    parser.add_option("-W","--from_file",dest='from_file', default=None,
                      help="use intput file for packet contents")
    parser.add_option("-T","--to_file",dest='to_file', default=None,
                      help="Output file for modulated samples")
    parser.add_option("-n","--num",type="int",dest="num",default=1000,
                      help="send message")
 
    parser.add_option("-p", "--pdbk", action="store_true", 
                      dest="pdcl", 
                      default=False, 
                      help="write pdbk data to oracle db") 
    parser.add_option("-z", "--zdbk", action="store_true", 
                      dest="zdcl", 
                      default=False, 
                      help="write zdbk data to oracle db") 
 
    transmit_path.add_options(parser, expert_grp)
    uhd_transmitter.add_options(parser)
 
    for mod in mods.values():
        mod.add_options(expert_grp)
 
    (options, args) = parser.parse_args ()
   # if options.pdcl==True: 
    #    print 'pdcl is true' 
   # if options.zdcl==True: 
    #    print 'zdcl is true' 
    if len(args) != 0:
        parser.print_help()
        sys.exit(1)
           
    if options.from_file is not None:
        source_file = open(options.from_file, 'r')
 
    # build the graph
    tb = my_top_block(mods[options.modulation], options)
 
    r = gr.enable_realtime_scheduling()
    if r != gr.RT_OK:
        print "Warning: failed to enable realtime scheduling"
 
    tb.start()                       # start flow graph
        
    # generate and send packets
    nbytes = int(1e6 * options.megabytes)
    n = 0
    pktno = 0
    pkt_size = int(options.size)
 
    while n < nbytes:
        if options.from_file is None:
            data =(pkt_size - 2) * chr(pktno & 0xff) 
        else:
            data = source_file.read(pkt_size - 2)
            if data == '':
                break;
 
        payload = struct.pack('!H', pktno & 0xffff) + data# + open(options.data)
       # payload=data#+struct.pack('!H',pktno & 0xffff)
        send_pkt(payload)
        n += len(payload)
        sys.stderr.write('.')
        if options.discontinuous and pktno % 5 == 4:
            time.sleep(1)
        pktno += 1
        
    send_pkt(eof=True)
 
    tb.wait()                       # wait for it to finish
 
if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        pass
 

猜你喜欢

转载自www.cnblogs.com/zgdcnyhl/p/12344377.html
GNU
今日推荐