如何利用gr_modtool创建自己的模块(以创建python模块为例)

创建新模块:

gr_modtool newmod multiusrp

进入新模块所在文件夹:

cd gr-multiusrp/

添加一个source block:

gr_modtool add -t source -l python multiusrp_source

-t:为模块模式,有以下几种可选:‘sink’, ‘source’, ‘sync’, ‘decimator’, ‘interpolator’, ‘general’, ‘tagged_stream’, ‘hier’, ‘noblock’
-l:语言,有以下两种可选:cpp/python
修改文件./python/multiusrp_source.py:

import numpy
from gnuradio import gr
from gnuradio import blocks
import uhd
import numpy as np
import argparse
from datetime import datetime, timedelta
import sys
import time
import threading
import logging
from uhd import libpyuhd as lib


INIT_DELAY = 0.05

class multiusrp_source(gr.sync_block):
    """
    docstring for block multiusrp_source
    """
    def __init__(self, samp_rate, center_freq, gain, sources, duration):
        gr.sync_block.__init__(self,
            name="Multi Usrp Source",
            in_sig=None,
            out_sig=[numpy.complex64,numpy.complex64])
        
        ##################################################
        # Parameters
        ##################################################
        self.samp_rate = samp_rate
        self.center_freq = center_freq
        self.gain = gain
        self.sources = sources
        self.duration = duration
        self.addresses = "addr=192.168.10.2"
        self.subdev="A:0 B:0"
        self.recvFile_0="../misc/rx00"
        self.recvFile_1 = "../misc/rx01"

        ##################################################
        # Blocks
        ##################################################
        self.parameter = self.parse_args(self.addresses, center_freq, samp_rate, sources, gain, self.subdev)
        self.usrp = uhd.usrp.MultiUSRP(self.parameter.args)
        #self.num_samps = int(np.ceil(self.duration * self.samp_rate))
        self.usrp.set_rx_subdev_spec(uhd.usrp.SubdevSpec(self.subdev))
        self.usrp.set_clock_source("internal")
        self.usrp.set_rx_dc_offset(0, 0)
        self.usrp.set_rx_dc_offset(0, 1)

        for chan in range(self.sources):
            self.usrp.set_rx_rate(self.samp_rate,chan)
            self.usrp.set_rx_freq(lib.types.tune_request(self.center_freq),chan)
            self.usrp.set_rx_gain(self.gain,chan)

        st_args=lib.usrp.stream_args("fc32","sc16")
        st_args.channels=range(self.sources)
        self.metadata=lib.types.rx_metadata()
        self.streamer=self.usrp.get_rx_stream(st_args)

        buffer_samps = self.streamer.get_max_num_samps()
        self.recv_buffer = np.zeros((self.sources, buffer_samps), dtype=np.complex64)
        stream_cmd = lib.types.stream_cmd(lib.types.stream_mode.start_cont)
        stream_cmd.stream_now = False
        stream_cmd.time_spec = uhd.types.TimeSpec(self.usrp.get_time_now().get_real_secs() + INIT_DELAY)
        self.streamer.issue_stream_cmd(stream_cmd)

        self.samps=np.array([],dtype=np.complex64)

    def work(self, input_items, output_items):

        out_0= output_items[0]
        out_1 = output_items[1]

        self.samps = self.streamer.recv(self.recv_buffer, self.metadata)
        length=min(self.samps,len(out_0))
        out_0[0:length] = self.recv_buffer[0, 0:length]
        out_1[0:length] = self.recv_buffer[1, 0:length]

        return length

    def parse_args(self, addresses, center_freq, samp_rate, sources, gain, subdev):
        parser = argparse.ArgumentParser()
        parser.add_argument("-a", "--args", default=addresses, type=str)
        parser.add_argument("-f", "--freq", default=center_freq, type=int)
        parser.add_argument("-r", "--rate", default=samp_rate, type=int)
        parser.add_argument("-c", "--channels", default=range(sources), nargs="+", type=int)
        parser.add_argument("--rx_cpu", type=str, default="fc32",
                                             help="specify the host/cpu sample mode for RX")
        parser.add_argument("--rx_otw", type=str, default="sc16",
                             help="specify the over-the-wire sample mode for RX")
        parser.add_argument("-g", "--gain", type=int, default=gain)
        return parser.parse_args()

修改./grc/multiusrp_multiusrp_source.xml:

<?xml version="1.0"?>
<block>
  <name>multiusrp_source</name>
  <key>multiusrp_multiusrp_source</key>
  <category>multiusrp</category>
  <import>import multiusrp</import>
  <make>multiusrp.multiusrp_source($samp_rate, $center_freq, $gain, $sources, $duration)</make>
  <!-- Make one 'param' node for every Parameter you want settable from the GUI.
       Sub-nodes:
       * name
       * key (makes the value accessible as $keyname, e.g. in the make node)
       * type -->
  <param>
    <name>samp_rate</name>
    <key>samp_rate</key>
    <type>float</type>
  </param>

  <param>
    <name>center_freq</name>
    <key>center_freq</key>
    <type>float</type>
  </param>

  <param>
    <name>gain</name>
    <key>gain</key>
    <type>int</type>
  </param>

  <param>
    <name>sources</name>
    <key>sources</key>
    <type>int</type>
  </param>

  <param>
    <name>duration</name>
    <key>duration</key>
    <type>int</type>
  </param>

  <!-- Make one 'source' node per output. Sub-nodes:
       * name (an identifier for the GUI)
       * type
       * vlen
       * optional (set to 1 for optional inputs) -->
  <source>
    <name>out_0</name>
    <type>complex</type>
  </source>
  
  <source>
    <name>out_1</name>
    <type>complex</type>
  </source>
</block>

添加一个sink block:

gr_modtool add -t sink -l python multiusrp_sink

修改文件./python/multiusrp_sink.py:

import numpy
from gnuradio import gr
import uhd
import numpy as np
import argparse
from datetime import datetime, timedelta
import sys
import time
import threading
import logging
from uhd import libpyuhd as lib

INIT_DELAY =1

class multiusrp_sink(gr.sync_block):
    """
    docstring for block multiusrp_sink
    """
    def __init__(self, samp_rate, center_freq, gain, sinks):
        gr.sync_block.__init__(self,
            name="Multi Usrp Sink",
            in_sig=[numpy.complex64,numpy.complex64],
            out_sig=None)

        ##################################################
        # Parameters
        ##################################################
        self.samp_rate = samp_rate
        self.center_freq = center_freq
        self.gain = gain
        self.sink = sinks
        self.addresses = "addr=192.168.10.2"
        self.subdev="A:0 B:0"
        self.tranFile_0="../misc/tran00"

        ##################################################
        # Blocks
        ##################################################
        self.parameter = self.parse_args(self.addresses, center_freq, samp_rate, sinks, gain, self.subdev)
        self.usrp = uhd.usrp.MultiUSRP(self.parameter.args)
        self.usrp.set_tx_subdev_spec(uhd.usrp.SubdevSpec(self.subdev))
        self.usrp.set_clock_source("internal")
        self.usrp.set_time_unknown_pps(uhd.types.TimeSpec(0.1))

        for chan in range(self.sink):
            self.usrp.set_tx_rate(self.samp_rate,chan)
            self.usrp.set_tx_freq(lib.types.tune_request(self.center_freq),chan)
            self.usrp.set_tx_gain(self.gain,chan)

        st_args = uhd.usrp.StreamArgs("fc32","sc16")
        st_args.channels = range(self.sink)

        self.tx_streamer = self.usrp.get_tx_stream(st_args)
        self.metadata = uhd.types.TXMetadata()

        # Set false to send immediately.
        # Set true to send at the time specified by time spec.
        # self.metadata.has_time_spec = bool(num_channels)
        self.metadata.time_spec = uhd.types.TimeSpec(self.usrp.get_time_now().get_real_secs() + INIT_DELAY)
        self.metadata.has_time_spec = bool(self.sink)
        # self.metadata.has_time_spec = True

        # print("time:",self.usrp.get_time_now().get_real_secs() + INIT_DELAY)
        self.tx_buffer_samps = self.tx_streamer.get_max_num_samps()
        self.tx_buffer = np.zeros((self.sink, self.tx_buffer_samps), dtype=np.complex64)
        # print(self.tx_buffer_samps)
        # self.samps=np.array([],dtype=np.complex64)


    def work(self, input_items, output_items):
        # length=min(len(input_items[0]),len(input_items[1]))
        # self.tx_buffer[0,0:self.tx_buffer_samps] = input_items[0,0:self.tx_buffer_samps]
        # self.tx_buffer[1,0:self.tx_buffer_samps] = input_items[1,0:self.tx_buffer_samps]
        self.samps= self.tx_streamer.send(input_items, self.metadata)
        # self.metadata.time_spec = uhd.types.TimeSpec(self.usrp.get_time_now().get_real_secs()+0.05)
        # print("time:", self.usrp.get_time_now().get_real_secs()+INIT_DELAY)
        # with open(self.tranFile_0, 'wb') as f0:
        #     np.save(f0, in0[:], allow_pickle=False, fix_imports=False)
        # print("samp:",self.samps)
        return len(input_items[0])

    def parse_args(self, addresses, center_freq, samp_rate, sinks, gain, subdev):
        parser = argparse.ArgumentParser()
        parser.add_argument("-a", "--args", default=addresses, type=str)
        parser.add_argument("-f", "--freq", default=center_freq, type=int)
        parser.add_argument("-r", "--rate", default=samp_rate, type=int)
        parser.add_argument("--tx_cpu", type=str, default="fc32",
                                             help="specify the host/cpu sample mode for TX")
        parser.add_argument("--tx_otw", type=str, default="sc16",
                             help="specify the over-the-wire sample mode for TX")
        parser.add_argument("-g", "--gain", type=int, default=gain)
        return parser.parse_args()

修改./grc/multiusrp_multiusrp_sink.xml:

<?xml version="1.0"?>
<block>
  <name>multiusrp_sink</name>
  <key>multiusrp_multiusrp_sink</key>
  <category>multiusrp</category>
  <import>import multiusrp</import>
  <make>multiusrp.multiusrp_sink($samp_rate, $center_freq, $gain, $sinks)</make>
  <!-- Make one 'param' node for every Parameter you want settable from the GUI.
       Sub-nodes:
       * name
       * key (makes the value accessible as $keyname, e.g. in the make node)
       * type -->
  <param>
    <name>samp_rate</name>
    <key>samp_rate</key>
    <type>float</type>
  </param>

  <param>
    <name>center_freq</name>
    <key>center_freq</key>
    <type>float</type>
  </param>

  <param>
    <name>gain</name>
    <key>gain</key>
    <type>int</type>
  </param>

  <param>
    <name>sinks</name>
    <key>sinks</key>
    <type>int</type>
  </param>


  <!-- Make one 'sink' node per input. Sub-nodes:
       * name (an identifier for the GUI)
       * type
       * vlen
       * optional (set to 1 for optional inputs) -->
  <sink>
    <name>in_0</name>
    <type>complex</type>
  </sink>

  <sink>
    <name>in_1</name>
    <type>complex</type>
  </sink>
</block>

build:

mkdir build
cd build
sudo cmake ../
sudo make -j4
sudo make install
sudo ldconfig

此时在gnuradio中已经出现了multiusrp模块以及其下面的两个block。
那么如果模块不用了,如何卸载呢:

cd build
sudo make uninstall
sudo ldconfig

over!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值