Tuesday, April 30, 2019

[Discuss-gnuradio] Announcing GNU Radio and RFNoC Workshops in Columbia, Maryland

======================================================================
         *** Announcing GNU Radio and RFNoC Workshops ***

     Ettus Research will be running a series of free, hands-on,
        technical workshops, and you are welcome to attend!

Location:
National Instruments
7125 Thomas Edison Drive, Suite 200
Columbia, Maryland, 21046, USA

Dates:
Tuesday May 14 -- GNU Radio Workshop
Wednesday May 15 -- RFNoC Workshop

Workshops will run from 09:00 to 17:00
Coffee and donuts will be provided at 08:00
Lunch will be provided at around 12:00

Registration is required in advance, but is completely free:
https://events.ni.com/profile/form/index.cfm?PKformID=0x380818abcd

======================================================================
GNU Radio Workshop Description:

Full Title:
Introduction to the USRP, UHD, and GNU Radio (Open-Source Toolchain)

Abstract:
This workshop will provide a thorough and practical introduction to
the USRP hardware and the open-source software toolchain (UHD and
GNU Radio). We will examine the hardware and architecture of the
entire USRP family of software-defined radios. We will discuss topics
such as how to get started using a new USRP device, how to install and
configure the open-source software toolchain, programming the USRP
using the UHD API from C++, using GNU Radio with the USRP and creating
and running flowgraphs, using GNU Radio from both GRC and Python, and
various debugging techniques. Several exercises will be performed,
such as implementing an FM transmitter and receiver. Various
demonstrations of wireless systems will be shown. A discussion of the
embedded E310 radio and using embedded SDR will be included. Several
other open-source tools will be discussed, such as GQRX, Fosphor,
Inspectrum, and several Out-of-Tree (OOT) modules. A discussion of
cellular applications, including OpenBTS and LTE stacks, as well as
GPS/GNSS applications will be presented. Several other miscellaneous
topics such as 10 Gigabit Ethernet networking, host system performance
tuning, X300/X310 device recovery, and some best practices will be
discussed. Attendees should come away with a solid foundation and
practical understanding of how to configure, program, and use the USRP
to implement a wide range range of wireless systems.

======================================================================
RFNoC Workshop Description:

Full Title:
FPGA Programming on the USRP with the RFNoC Framework

Abstract:
Ettus Research's RFNoC (RF Network-on-Chip) software framework is
designed to decrease the development time for experienced FPGA
engineers seeking to integrate IP into the USRP FPGA signal
processing chain. RFNoC is the framework for USRP devices that use
Xilinx 7-series FPGAs (E310, E312, X300, X310). RFNoC is built around
a packetized network infrastructure in the FPGA that handles the
transport of control and sample data between the host CPU and the
radio. Users target their custom algorithms to the FPGA in the form
of Computation Engines (CE), which are processing blocks that attach
to this network. CEs act as independent nodes on the network that can
receive and transmit data to any other node (e.g., another CE, the
radio block, or the host CPU).  Users can create modular,
FPGA-accelerated SDR applications by chaining CEs into a flow graph.
RFNoC is supported in UHD and GNU Radio. In this workshop, we will
present an interactive hands-on tutorial on RFNoC, including a
discussion on its design and capabilities, demonstrations of several
existing examples, and a walk-through on implementing a user-defined
CE and integrating the CE into GNU Radio.

======================================================================
Details and Logistics:

* The workshops are free, technical, and hands-on.

* Laptop computers and USRP radios will be provided in the workshop.
  Attendees do not need to bring or prepare anything.

* Attendees may optionally bring their own equipment.
  Contact "support@ettus.com" for specific setup requirements.

* For the USRP/GNU Radio Workshop, attendees should have some previous
experience with Linux and using the Linux command line, and basic
familiarity with a programming language such as C, C++, or Python,
and basic fundamental concepts in DSP and RF. For the RFNoC Workshop,
attendees should also have some basic familiarity with Verilog.
Extensive or deep experience with these topics is not necessary.

* Space is limited and will be allocated
  on a first-come,first-serve basis.

* Registration is required in advance, but is completely free.
https://events.ni.com/profile/form/index.cfm?PKformID=0x380818abcd

======================================================================
              We look forward to seeing you there!!

======================================================================


[Discuss-gnuradio] How to get precise time tag from blocks_meta_data_sink

Hi,

I'm trying to use blocks_file_meta_sink to record data with tags, and then use gr_read_file_metadata.py to read .hdr file, and I got this output:
" " "
HEADER 30
Version Number: 0
Sample Rate: 20000000.00 sps
Seconds: 1556652948.179670
Item size: 8
Data Type: float (5)
Complex? True
Header Length: 171 bytes
Extra Length:  22
Extra Header?  True
Size of Data: 8000000 bytes
              1000000 items

Extra Header:
rx_freq: 2.4205e+09
" " "
It looks like the time in seconds only has 6 floating points, however, it supposes to be double. 
I thought it was caused by string formatting so I went to parse_file_metadata.py and modified line 94 from "print "Seconds: {0:6f}".format(t)" to "print "Seconds: {0:20f}".format(t)", then I got: 
" " "
Seconds: 1556652948.17966961860656738281
" " "
Is this the correct way to solve this problem? Is GNUradio's time tag actually precise to nanosecond? I want to use a PC with GPS time module and sync a B200mini with it, can I actually get the correct GPS time tag in this way?

 Thanks

Best regards,
Ziang

Re: [Discuss-gnuradio] Question on PMT boolean messages

Hello,

Thank you for the advice. I went back to the tutorials and now I have a better grasp of what is going on.

Regarding 'work' vs 'handle_msg', which situations fit each of these?

Is 'handle_msg' supposed to be for passing messages through multiple internal msg ports?

Is 'work' for dealing with streams or can I do message related things in 'work'?

It appears that handle_msg is for passing from inputs to outputs (which I do not need as I want a block with only a message out).


In short, if one wants to make a block with a single msg output and nothing else, should s/he use a message handler (and leave work empty with a pass) or use work? If so, what should work return, given there are no data-streams involved?

Thank you for your time,

Ali

On Mon, Apr 29, 2019 at 2:49 PM Marcus Müller <mmueller@gnuradio.org> wrote:
Hi Ali,
causality, our old foe, strikes again!

You're trying to emit a message in the constructor.  Messages will be
delivered to all message acceptors connected to that message port.
However, you can't possibly connect the block before the block-holding
object exists, i.e. before the constructor returns.

So, necessarily, the messages are sent before anything is connected to
the msg_out port, and thus into the void and simply get dropped by the
scheduler.

Best regards,
Marcus

PS: I'd strongly recommend having a `self.port = pmt.intern('msg_out')`
in the constructor and using that whenever you need the port if you're
doing that within the work() function often. Constructing PMT interns
is relatively expensive.

On Mon, 2019-04-29 at 14:39 -0700, Ali Dormiani wrote:
> Hello everyone,
>
> I have been attempting to make my own block that sends out a boolean
> message if certain time related conditions are met.
>
> I am unable to figure out why my block does not work. This seems to
> be the line of interest:
>
> self.message_port_pub(pmt.intern('msg_out'), pmt.PMT_T)
>
> This line should cause the block to output a PMT true through port
> msg_out right?
>
> My full block is attached bellow. Any help would be greatly
> appreciated.
>
> Thank you all for your time,
>
> Ali
>
> ======================
> import numpy as np
> from gnuradio import gr
> import pmt
> import datetime
>
> class msg_block(gr.basic_block):  # other base classes are
> basic_block, decim_block, interp_block
>     """This block checks time and sends true or false if capture
> period is desired"""
>
>     def __init__(self, minutes=15, seconds=10):  # only default
> arguments here
>         """arguments to this function show up as parameters in GRC"""
>         gr.basic_block.__init__(
>             self,
>             name='Time Enable',   # will show up in GRC
>             in_sig=None,
>             out_sig=None
>         )
>         self.message_port_register_out(pmt.intern('msg_out'))
>         now = datetime.datetime.now()
>         #P_true = pmt.PMT_T
>         #P_false = pmt.PMT_F
>         if ((now.minute % minutes) == 0): #check if minute is ok
>             if (now.second < seconds): #check if capture period is ok
>                 self.message_port_pub(pmt.intern('msg_out'),
> pmt.PMT_T)
>             else:
>                 self.message_port_pub(pmt.intern('msg_out'),
> pmt.PMT_F)
>         else:
>             self.message_port_pub(pmt.intern('msg_out'), pmt.PMT_F)

>     def work(self, input_items, output_items):
>         pass
> =====================================
> _______________________________________________
> Discuss-gnuradio mailing list
> Discuss-gnuradio@gnu.org
> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Re: [Discuss-gnuradio] Recurring memory leak problems with iterative decoding [ GNU Radio 3.7.11.1]

Hi Moses - You're doing some very interesting work here! I think you're more likely to get some assistance if you can provide a repo/archive that we can download / clone, then do the usual to configure, build & do testing on to verify your issue. Once verified, there are a variety of ways to try to track down memory issues && the GNU Radio community has many talented programmers / hackers who could help do so. You did a great job writing up what you're doing & the issue, but the barrier to entry / testing / debugging is still a little high. Hope this is useful! - MLD

On Mon, Apr 29, 2019, at 3:32 PM, Moses Browne Mwakyanjala wrote:
Hello everyone,
I have finished writing a C++ LDPC decoder for the standard CCSDS C2 (8160,7136) LDPC code. In order to avoid memory allocation issues, I have decided to use std::vector<> vectors throughout the program, as opposed to the c-style mallocs. I am able to run the program and simulate the BER on my laptop (8 Gig ram) without any problems. The simulation is able to run for hours without any issues. However, the code experiences severe memory leaks when imported to GNU Radio. 


The LDPC class files [ldpc.cc and ldpc.h] as well as the GNU Radio wrapper files [decodeLDPC_impl.h and decodeLDPC_impl.cc]   are attached to this email. The wrapper class constructor initializes the LDPC decoder variable by specifying an "alist" file. It also initializes the message handler function called "decode" which use the LDPC codec to carry out LDPC decoding. 

//Constructor
set_msg_handler(d_in_port, boost::bind(&decodeLDPC_impl::decode, this ,_1) );
ccsdsLDPC = new ldpc(d_file);

The decode message handler receives soft bits from the recoverCADUSoft block, which are float values as shown in the code below. The soft bits are decoded by a wrapper function "decodeLDPC::decode" which use the function ldpc->decode(softbits,iterations,sigma). Iterative decoding requires a number of iterations to successful converge. I use 20 iterations. 



//Decode message handler
void
    decodeLDPC_impl::decode(pmt::pmt_t msg)
    {
        pmt::pmt_t meta(pmt::car(msg));
        pmt::pmt_t bits(pmt::cdr(msg));

        std::vector<float> softBits = pmt::f32vector_elements(bits);

        // LDPC Decoding
        std::vector<unsigned char> decodedBits = (*this.*ldpcDecode)(softBits);

        if(d_pack)
        {
            uint8_t *decoded_u8 = (uint8_t *)malloc(sizeof(uint8_t)*decodedBits.size()/8);
            for(int i=0; i<decodedBits.size()/8; i++)
            {
                decoded_u8[i] = 0;
                for(int j=0; j<8; j++)
                {
                    decoded_u8[i] |= decodedBits[i*8+j]?(0x80>>j):0;
                }
            }
            // Publishing data
            pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL,pmt::make_blob(decoded_u8,decodedBits.size()/8)));
            message_port_pub(d_out_port, pdu);
            free(decoded_u8);
        }
        else
        {
        // Publishing data
        pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL,pmt::make_blob(decodedBits.data(),decodedBits.size())));
                    message_port_pub(d_out_port, pdu);
        }
        decodedBits.clear();
        softBits.clear();
    }

My question is what could possibly be the cause of the memory leak I experience? There are no memory leaks when the class is used outside GNU Radio. To add more confusion, I experienced the same situation when I was working with another iterative decoder for Turbo code (only 10 iterations). The code was able to run smoothly in a C++ application but experienced memory leaks in GNU Radio.

I also have one question regarding buffering in GNU Radio. Since iterative decoding with a large number of iterations and large block sizes takes time to complete, the input pmt data that is not consumed immediately will have to be stored somewhere. Is that the case? Could that be the reason for the memory leak?

Regards,
Moses. 
_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio


Attachments:
  • image.png
  • decodeLDPC_impl.cc
  • decodeLDPC_impl.h
  • ldpc.h
  • ldpc.cpp

Monday, April 29, 2019

Re: [Discuss-gnuradio] Bursty transmission in GNURadio 3.7.13.4

Hi Martin,

We are using the X310 USRPs, and each of them has two channels. The configurations for those two channels are the same except for the center frequency (kind of like an FDMA system).

Best regards,
Jonathan

Martin Braun <martin.braun@ettus.com> 于2019年4月30日周二 上午8:44写道:
On Thu, Apr 25, 2019 at 02:28:35PM +0800, Jiaxin Liang wrote:
>    Hi,
>    I have been using the bursty transmission (see here) in GNURadio for USRP
>    transmission for a while. And we have a stable program running on GNURadio
>    3.7.10.2 with UHD 3.9.7.
>    Recently, we are trying to upgrade the GNURadio to 3.7.13.4 and the UHD to
>    3.15.0 (rfnoc version). But we kept receiving "L" from the very beginning
>    to the end.
>    May I ask whether the bursty transmission is still available in the above
>    version? If yes, is there any changes I should notice?
>    Best regards,
>    Jonathan

Jonathan,

can you provide some more info? How many channels are you using, which
device, etc.?

Thanks,

M
_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Re: [Discuss-gnuradio] Bursty transmission in GNURadio 3.7.13.4

On Thu, Apr 25, 2019 at 02:28:35PM +0800, Jiaxin Liang wrote:
> Hi,
> I have been using the bursty transmission (see here) in GNURadio for USRP
> transmission for a while. And we have a stable program running on GNURadio
> 3.7.10.2 with UHD 3.9.7.
> Recently, we are trying to upgrade the GNURadio to 3.7.13.4 and the UHD to
> 3.15.0 (rfnoc version). But we kept receiving "L" from the very beginning
> to the end.
> May I ask whether the bursty transmission is still available in the above
> version? If yes, is there any changes I should notice?
> Best regards,
> Jonathan

Jonathan,

can you provide some more info? How many channels are you using, which
device, etc.?

Thanks,

M

Re: [Discuss-gnuradio] Shared resource for source and sink blocks

On Fri, Apr 26, 2019 at 09:41:00AM +0000, N. Benes wrote:
> So this seems to be a suitable pattern for my case.

Nicolas,

thanks for responding to your own email! It's a little thing, but it
keeps our archives complete, and if someone else runs into this issue,
it'll be useful for them.

-- M

Re: [Discuss-gnuradio] Question on PMT boolean messages

Hi Ali,
causality, our old foe, strikes again!

You're trying to emit a message in the constructor. Messages will be
delivered to all message acceptors connected to that message port.
However, you can't possibly connect the block before the block-holding
object exists, i.e. before the constructor returns.

So, necessarily, the messages are sent before anything is connected to
the msg_out port, and thus into the void and simply get dropped by the
scheduler.

Best regards,
Marcus

PS: I'd strongly recommend having a `self.port = pmt.intern('msg_out')`
in the constructor and using that whenever you need the port if you're
doing that within the work() function often. Constructing PMT interns
is relatively expensive.

On Mon, 2019-04-29 at 14:39 -0700, Ali Dormiani wrote:
> Hello everyone,
>
> I have been attempting to make my own block that sends out a boolean
> message if certain time related conditions are met.
>
> I am unable to figure out why my block does not work. This seems to
> be the line of interest:
>
> self.message_port_pub(pmt.intern('msg_out'), pmt.PMT_T)
>
> This line should cause the block to output a PMT true through port
> msg_out right?
>
> My full block is attached bellow. Any help would be greatly
> appreciated.
>
> Thank you all for your time,
>
> Ali
>
> ======================
> import numpy as np
> from gnuradio import gr
> import pmt
> import datetime
>
> class msg_block(gr.basic_block): # other base classes are
> basic_block, decim_block, interp_block
> """This block checks time and sends true or false if capture
> period is desired"""
>
> def __init__(self, minutes=15, seconds=10): # only default
> arguments here
> """arguments to this function show up as parameters in GRC"""
> gr.basic_block.__init__(
> self,
> name='Time Enable', # will show up in GRC
> in_sig=None,
> out_sig=None
> )
> self.message_port_register_out(pmt.intern('msg_out'))
> now = datetime.datetime.now()
> #P_true = pmt.PMT_T
> #P_false = pmt.PMT_F
> if ((now.minute % minutes) == 0): #check if minute is ok
> if (now.second < seconds): #check if capture period is ok
> self.message_port_pub(pmt.intern('msg_out'),
> pmt.PMT_T)
> else:
> self.message_port_pub(pmt.intern('msg_out'),
> pmt.PMT_F)
> else:
> self.message_port_pub(pmt.intern('msg_out'), pmt.PMT_F)
>
> def work(self, input_items, output_items):
> pass
> =====================================
> _______________________________________________
> Discuss-gnuradio mailing list
> Discuss-gnuradio@gnu.org
> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio


_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

[Discuss-gnuradio] Question on PMT boolean messages

Hello everyone,

I have been attempting to make my own block that sends out a boolean message if certain time related conditions are met.

I am unable to figure out why my block does not work. This seems to be the line of interest:

self.message_port_pub(pmt.intern('msg_out'), pmt.PMT_T)

This line should cause the block to output a PMT true through port msg_out right?

My full block is attached bellow. Any help would be greatly appreciated.

Thank you all for your time,

Ali

======================
import numpy as np
from gnuradio import gr
import pmt
import datetime

class msg_block(gr.basic_block):  # other base classes are basic_block, decim_block, interp_block
    """This block checks time and sends true or false if capture period is desired"""

    def __init__(self, minutes=15, seconds=10):  # only default arguments here
        """arguments to this function show up as parameters in GRC"""
        gr.basic_block.__init__(
            self,
            name='Time Enable',   # will show up in GRC
            in_sig=None,
            out_sig=None
        )
        self.message_port_register_out(pmt.intern('msg_out'))
        now = datetime.datetime.now()
        #P_true = pmt.PMT_T
        #P_false = pmt.PMT_F
        if ((now.minute % minutes) == 0): #check if minute is ok
            if (now.second < seconds): #check if capture period is ok
                self.message_port_pub(pmt.intern('msg_out'), pmt.PMT_T)
            else:
                self.message_port_pub(pmt.intern('msg_out'), pmt.PMT_F)
        else:
            self.message_port_pub(pmt.intern('msg_out'), pmt.PMT_F)
 
    def work(self, input_items, output_items):
        pass
=====================================

[Discuss-gnuradio] Recurring memory leak problems with iterative decoding [ GNU Radio 3.7.11.1]

/* -*- c++ -*- */
/*
* Copyright 2019 <+YOU OR YOUR COMPANY+>.
*
* This 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.
*
* This software 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 this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "decodeLDPC_impl.h"
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>

#define N 8176
#define K 7154
#define P 1022
using namespace std;
namespace gr {
namespace ccsds {

decodeLDPC::sptr
decodeLDPC::make(std::string alist_file, int code_type,int iterations, float sigma, int update_sigma, int pack)
{
return gnuradio::get_initial_sptr
(new decodeLDPC_impl(alist_file,code_type,iterations, sigma, update_sigma,pack));
}

/*
* The private constructor
*/
decodeLDPC_impl::decodeLDPC_impl(std::string alist_file, int code_type,int iterations, float sigma, int update_sigma,int pack)
: gr::sync_block("decodeLDPC",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)),
d_iterations(iterations),d_sigma(sigma),d_update_sigma(update_sigma),
d_file(alist_file),d_code_type(code_type), d_pack(pack)
{
//Initializing input and output ports
d_in_port = pmt::mp("in");
message_port_register_in(d_in_port);

d_out_port = pmt::mp("out");
message_port_register_out(d_out_port);

//Setting callback
set_msg_handler(d_in_port, boost::bind(&decodeLDPC_impl::decode, this ,_1) );

//Packing bits into bytes
d_pack_8 = new blocks::kernel::pack_k_bits(8);


switch(code_type)
{
case 0:
ldpcDecode = &decodeLDPC_impl::decodeFullC2;
d_file = "/home/mbkitine/Dropbox/Lulea/GRC/DeepSpace/gr-ccsds/lib/fec/ldpc/alist/C2_Alist.a";
break;
case 1:
ldpcDecode = &decodeLDPC_impl::decodeExpC2;
d_file = "/home/mbkitine/Dropbox/Lulea/GRC/DeepSpace/gr-ccsds/lib/fec/ldpc/alist/C2_Alist.a";
break;
case 2:
ldpcDecode = &decodeLDPC_impl::decodeAR4JA;
punct = 512;
d_file = "/home/mbkitine/Dropbox/Lulea/GRC/DeepSpace/gr-ccsds/lib/fec/ldpc/alist/AR4JA_r12_k1024n.a";
break;
}

//LDPC codec object
ccsdsLDPC = new ldpc(d_file);

//Printing properties of the LDPC codec
std::cout << "LDPC Decoder Initialized .." << std::endl;
std::cout << "Code rate : " << ccsdsLDPC->getCodeRate() << std::endl;
std::cout << "Check nodes: " << ccsdsLDPC->getnumCheckNodes() << std::endl;
std::cout << "Variable nodes : " << ccsdsLDPC->getnumVarNodes() << std::endl;

set_output_multiple(N);
}
std::vector<unsigned char>
decodeLDPC_impl::decodeFullC2(std::vector<float> softBits)
{
std::vector<float> logapp = ccsdsLDPC->decode(softBits,d_iterations,d_sigma);
std::vector<unsigned char> decodedBits = slice(logapp);

return decodedBits;
}

std::vector<unsigned char>
decodeLDPC_impl::decodeExpC2(std::vector<float> softBits)
{
// Removing the last two LLRs
softBits.pop_back();
softBits.pop_back();

// Insert LLRs for the first 18 elements
std::vector<float> codeword(18,-1000.00);
codeword.insert(codeword.end(),softBits.begin(),softBits.end());

// LDPC Decoding
std::vector<float> logapp = ccsdsLDPC->decode(codeword,d_iterations,d_sigma);

// Slicing log-APP ratios into hard bits
std::vector<unsigned char> decodedBits = slice(logapp);

// Remove the prefixed zero bits
decodedBits.erase(decodedBits.begin(),decodedBits.begin() + 18);

return decodedBits;
}

std::vector<unsigned char>
decodeLDPC_impl::decodeAR4JA(std::vector<float> softBits)
{
for(int i = 0; i < punct; i++)
softBits.push_back(0.0);
std::vector<float> logapp = ccsdsLDPC->decode(softBits,d_iterations,d_sigma);
std::vector<unsigned char> decodedBits = slice(logapp);
return decodedBits;
}


std::vector<unsigned char>
decodeLDPC_impl::slice(std::vector<float> logapp)
{
std::vector<unsigned char> bits;
unsigned char bit;
for(int i = 0; i < logapp.size(); i++)
bits.push_back( (logapp[i] > 0) ? 0x01 : 0x00);
return bits;
}

void
decodeLDPC_impl::decode(pmt::pmt_t msg)
{
pmt::pmt_t meta(pmt::car(msg));
pmt::pmt_t bits(pmt::cdr(msg));

std::vector<float> softBits = pmt::f32vector_elements(bits);

// LDPC Decoding
std::vector<unsigned char> decodedBits = (*this.*ldpcDecode)(softBits);

if(d_pack)
{
uint8_t *decoded_u8 = (uint8_t *)malloc(sizeof(uint8_t)*decodedBits.size()/8);
for(int i=0; i<decodedBits.size()/8; i++)
{
decoded_u8[i] = 0;
for(int j=0; j<8; j++)
{
decoded_u8[i] |= decodedBits[i*8+j]?(0x80>>j):0;
}
}
// Publishing data
pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL,pmt::make_blob(decoded_u8,decodedBits.size()/8)));
message_port_pub(d_out_port, pdu);
free(decoded_u8);
}
else
{
// Publishing data
pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL,pmt::make_blob(decodedBits.data(),decodedBits.size())));
message_port_pub(d_out_port, pdu);
}
decodedBits.clear();
softBits.clear();

}

/*
* Our virtual destructor.
*/
decodeLDPC_impl::~decodeLDPC_impl()
{
}

int
decodeLDPC_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
// const float *in = (const float *) input_items[0];
// //<+OTYPE+> *out = (<+OTYPE+> *) output_items[0];

// std::vector<double> softBits;
// for(int i = 0; i < N; i++)
// softBits.push_back(in[i]);

// LDPC Decoding
//ldpc decoderLDPC = ldpc(d_file);
//std::vector<unsigned char> decodedBits = (*this.*ldpcDecode)(softBits);
//std::vector<double> decodedBits = decoderLDPC.decode(softBits,d_iterations,d_sigma);
// Do <+signal processing+>
//softBits.clear();
// Tell runtime system how many output items we produced.
return noutput_items;
}

} /* namespace ccsds */
} /* namespace gr */

/* -*- c++ -*- */
/*
* Copyright 2019 <+YOU OR YOUR COMPANY+>.
*
* This 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.
*
* This software 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 this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/

#ifndef INCLUDED_CCSDS_DECODELDPC_IMPL_H
#define INCLUDED_CCSDS_DECODELDPC_IMPL_H

#include <ccsds/decodeLDPC.h>
//#include "fec/ldpc/soft_decoder.h"
#include "fec/ldpc/checknode.h"
#include "fec/ldpc/variablenode.h"
#include "fec/ldpc/ldpc.h"
#include <cassert>
#include <gnuradio/blocks/pack_k_bits.h>
namespace gr {
namespace ccsds {

class decodeLDPC_impl : public decodeLDPC
{
private:
int d_iterations;
float d_sigma;
int d_update_sigma;
int d_code_type;
bool d_pack;
blocks::kernel::pack_k_bits *d_pack_8;
int punct;
string d_file;
pmt::pmt_t d_in_port;
pmt::pmt_t d_out_port;
int** H; //Parity matrix
//double *inputData;
ldpc *ccsdsLDPC;
std::vector<unsigned char> decodeFullC2(std::vector<float> softBits);
std::vector<unsigned char> decodeExpC2(std::vector<float> softBits);
std::vector<unsigned char> decodeAR4JA(std::vector<float> softBits);
std::vector<unsigned char> (decodeLDPC_impl::*ldpcDecode)(std::vector<float> input);
std::vector<unsigned char> slice(std::vector<float> logapp);

public:
decodeLDPC_impl(std::string alist_file, int code_type, int iterations, float sigma, int update_sigma,int pack);
~decodeLDPC_impl();
void decode(pmt::pmt_t msg);

// Where all the action really happens
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
};

} // namespace ccsds
} // namespace gr

#endif /* INCLUDED_CCSDS_DECODELDPC_IMPL_H */

#ifndef LDPC_H
#define LDPC_H
#include <vector>
#include <algorithm>
#include <string>
#include <cassert>
#include "checknode.h"
#include "variablenode.h"
#include "alist.h"
using namespace std;
class ldpc
{
private:
std::vector<checkNode> checkNodes;
std::vector<variableNode> varNodes;
int numCheckNodes;
int numVarNodes;
float codeRate;
public:
ldpc(string filename);
void readAlist(string filename, std::vector< std::vector<int> > &m_list,std::vector< std::vector<int> > &n_list);
std::vector<float> decode(std::vector<float> softBits, int iterations, float sigma);
float getCodeRate() { return codeRate;}
int getnumCheckNodes() { return numCheckNodes;}
int getnumVarNodes() { return numVarNodes;}

};

#endif // LDPC_H
/*
* The Turbo codec class implementation
* -------------------------------------------
* This class implements CCSDS LDPC decoder as specified by the
* CCSDS TM SYNCHRONIZATION AND CHANNEL CODING blue book standard (August 2011).
* It can also work generically with any LDPC code specified by an alist file.
* Author : Moses Browne Mwakyanjala
* Date : March 18th, 2019
* Institue : Lulea University of Technology
* E-mail : moses.browne.mwakyanjala@ltu.se
*/

#include "ldpc.h"
#define DEBUG false
ldpc::ldpc(string filename)
{
//Reading alist file
std::vector< std::vector<int> > m_list, n_list;
readAlist(filename,m_list,n_list);
codeRate = (n_list.size()*1.0 - m_list.size()*1.0)/(n_list.size()*1.0);

//Initializing check nodes
for(unsigned int i = 0; i < m_list.size(); i++)
checkNodes.push_back(checkNode(m_list[i]));

// Initializing variable nodes
for(unsigned int i = 0; i < n_list.size(); i++)
{
varNodes.push_back(variableNode(n_list[i]));
}

// Deriving code properties
numCheckNodes = m_list.size();
numVarNodes = n_list.size();
}

void
ldpc::readAlist(string filename, std::vector< std::vector<int> > &m_list,std::vector< std::vector<int> > &n_list)
{
alist myAlist(filename.c_str());
m_list = myAlist.get_mlist();
n_list = myAlist.get_nlist();
}

std::vector<float>
ldpc::decode(std::vector<float> softBits, int iterations, float sigma)
{
// ##############################################
// Initializing variable nodes
for(unsigned int i = 0; i < softBits.size(); i++)
varNodes[i].setLx(2*softBits[i]/(sigma*sigma));

// ###############################################
for(int z = 0; z < iterations; z++)
{
// ##########################################
// Pass Lq from variable nodes to check nodes
for(unsigned int v = 0; v < varNodes.size();v++)
{
std::vector<int> indicies = varNodes[v].getCheckNodes();
std::vector<double> lq = varNodes[v].getLq();
assert(lq.size() == indicies.size());
for(unsigned int c = 0; c < indicies.size();c++)
checkNodes[indicies[c]].updateLq(lq[c]);
}

// ##########################################
// Updating Checknode Lrs
for(unsigned int i = 0; i < checkNodes.size(); i++)
{
checkNodes[i].updateLr();
}


// ##########################################
for(unsigned int c = 0; c < checkNodes.size();c++)
{
std::vector<int> indicies = checkNodes[c].getVarNodes();
std::vector<double> lr = checkNodes[c].getLr();
assert(lr.size() == indicies.size());
for(unsigned int r = 0; r < indicies.size();r++)
varNodes[indicies[r]].updateLr(lr[r]);
}

// #########################################
// Update Lqs
for(unsigned int i = 0; i < varNodes.size(); i++)
varNodes[i].updateLq();

// ##########################################
// Updating logAPP
for(unsigned int v = 0; v < varNodes.size(); v++)
varNodes[v].updatelogAPP();
}
//std::cout << "Size of varNodes : " << varNodes.size() << std::endl;
std::vector<float> logAPP;
for(unsigned int i = 0; i <(varNodes.size() - getnumCheckNodes()); i++)
{
logAPP.push_back(varNodes[i].getlogAPP());
}
if (DEBUG)
{
std::cout << "Size of checknode Lq vector : " << std::endl;
std::cout << "Size of checknode Lr vector : " << std::endl;
}
//std::cout << "Size of logAPP vector : " << logAPP.size() << std::endl;
return logAPP;
}

Hello everyone,
I have finished writing a C++ LDPC decoder for the standard CCSDS C2 (8160,7136) LDPC code. In order to avoid memory allocation issues, I have decided to use std::vector<> vectors throughout the program, as opposed to the c-style mallocs. I am able to run the program and simulate the BER on my laptop (8 Gig ram) without any problems. The simulation is able to run for hours without any issues. However, the code experiences severe memory leaks when imported to GNU Radio. 


The LDPC class files [ldpc.cc and ldpc.h] as well as the GNU Radio wrapper files [decodeLDPC_impl.h and decodeLDPC_impl.cc]   are attached to this email. The wrapper class constructor initializes the LDPC decoder variable by specifying an "alist" file. It also initializes the message handler function called "decode" which use the LDPC codec to carry out LDPC decoding. 

//Constructor
set_msg_handler(d_in_port, boost::bind(&decodeLDPC_impl::decode, this ,_1) );
ccsdsLDPC = new ldpc(d_file);

The decode message handler receives soft bits from the recoverCADUSoft block, which are float values as shown in the code below. The soft bits are decoded by a wrapper function "decodeLDPC::decode" which use the function ldpc->decode(softbits,iterations,sigma). Iterative decoding requires a number of iterations to successful converge. I use 20 iterations. 



//Decode message handler
void
    decodeLDPC_impl::decode(pmt::pmt_t msg)
    {
        pmt::pmt_t meta(pmt::car(msg));
        pmt::pmt_t bits(pmt::cdr(msg));

        std::vector<float> softBits = pmt::f32vector_elements(bits);

        // LDPC Decoding
        std::vector<unsigned char> decodedBits = (*this.*ldpcDecode)(softBits);

        if(d_pack)
        {
            uint8_t *decoded_u8 = (uint8_t *)malloc(sizeof(uint8_t)*decodedBits.size()/8);
            for(int i=0; i<decodedBits.size()/8; i++)
            {
                decoded_u8[i] = 0;
                for(int j=0; j<8; j++)
                {
                    decoded_u8[i] |= decodedBits[i*8+j]?(0x80>>j):0;
                }
            }
            // Publishing data
            pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL,pmt::make_blob(decoded_u8,decodedBits.size()/8)));
            message_port_pub(d_out_port, pdu);
            free(decoded_u8);
        }
        else
        {
        // Publishing data
        pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL,pmt::make_blob(decodedBits.data(),decodedBits.size())));
                    message_port_pub(d_out_port, pdu);
        }
        decodedBits.clear();
        softBits.clear();
    }

My question is what could possibly be the cause of the memory leak I experience? There are no memory leaks when the class is used outside GNU Radio. To add more confusion, I experienced the same situation when I was working with another iterative decoder for Turbo code (only 10 iterations). The code was able to run smoothly in a C++ application but experienced memory leaks in GNU Radio.

I also have one question regarding buffering in GNU Radio. Since iterative decoding with a large number of iterations and large block sizes takes time to complete, the input pmt data that is not consumed immediately will have to be stored somewhere. Is that the case? Could that be the reason for the memory leak?

Regards,
Moses. 

Re: [Discuss-gnuradio] Need to install PyQt4.Qwt5

Folks,

 

Never mind. I found some site that has download & installation instructions.

 

Do any of you have any documentation on the "trigger rising edge event" block?

 

Thanks,

 

Aaron

 

From: Chesir, Aaron M.
Sent: Monday, April 29, 2019 12:59 PM
To: discuss-gnuradio@gnu.org
Subject: Need to install PyQt4.Qwt5

 

Folks,

 

I am running CentOS, and am trying to run a flowgraph containing a "trigger rising edge event" block. In my attempt to understand this block, the Internet  directed me to the only descriptive page available: An attempt at a tutorial by the inventor of the block, at the following URL:

 

https://oshearesearch.com/index.php/2015/03/15/a-simple-eventstream-based-burst-plotter-example/

 

The page points to a flowgraph. In this flowgraph is a block "PyQT Complex Time Block" When I click on the "Go" icon of the GRC toolbar, I get the following error message:

 

"plotter_base.py", line 26, in <module>
    from PyQt4 import Qt, QtCore, QtGui, Qwt5
ImportError: cannot import name Qwt5

 

When I type $sudo yum install PyQt4, I am assured that I have the latest version of PyQt4 installed.

When I type $sudo yum install python-qwt5-qt4, I am told that there is no such package available.

When I type $sudo yum install python-qwt5, I am told that there is no such package available.

 

What can I do?

Help.

 

Thanks,

 

Aaron

[Discuss-gnuradio] Need to install PyQt4.Qwt5

Folks,

 

I am running CentOS, and am trying to run a flowgraph containing a "trigger rising edge event" block. In my attempt to understand this block, the Internet  directed me to the only descriptive page available: An attempt at a tutorial by the inventor of the block, at the following URL:

 

https://oshearesearch.com/index.php/2015/03/15/a-simple-eventstream-based-burst-plotter-example/

 

The page points to a flowgraph. In this flowgraph is a block "PyQT Complex Time Block" When I click on the "Go" icon of the GRC toolbar, I get the following error message:

 

"plotter_base.py", line 26, in <module>
    from PyQt4 import Qt, QtCore, QtGui, Qwt5
ImportError: cannot import name Qwt5

 

When I type $sudo yum install PyQt4, I am assured that I have the latest version of PyQt4 installed.

When I type $sudo yum install python-qwt5-qt4, I am told that there is no such package available.

When I type $sudo yum install python-qwt5, I am told that there is no such package available.

 

What can I do?

Help.

 

Thanks,

 

Aaron

[Discuss-gnuradio] [OT] Old world magic

I had to share this wonderful video,
Student Short Film: "Shortwave":
https://www.youtube.com/watch?v=jK2iKtjrYOU

A great attempt at an experiment in the
"Philosophy of Everyday Life".

--
--gv

_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Sunday, April 28, 2019

[Discuss-gnuradio] Introducing Theseus Cores: Open source FPGA cores for DSP and SDR

Hi all,

I'm very happy to announce the (very modest) release of the Theseus Cores project: https://gitlab.com/theseus-cores/theseus-cores

Theseus Cores is designed to provide open source FPGA cores for digital signal processing and software defined radio, plus the means to *use* the FPGA cores in real life.... In practice, that mostly means FPGA code propagates up through RFNoC blocks which have both UHD and Gnuradio software hooks for users to attach to. In the future it would be great to support other FPGA platforms if there's interest too.

So far, Theseus Cores provides the following RFNoC FPGA blocks and corresponding software:
- Polyphase M/2 Channelizer: A polyphase channelizer where each channel outputs 2x sample rate and is compatible with perfect-reconstruction. Thanks to Phil Vallance for re-implementing the channelizer described in his GRCon 2017 presentation-- it works!
- "1-to-N" DDC Chain: Parameterized instantiations of "N" independent DDCs, where each DDC is connected to the *first* input (a very basic, brute force channelizer). Note I've seen several mailing list discussions in the past year about 1-to-4 or 1-to-8 DDC channelizers -- this block provides the generalized version of that scenario.
- DUC + DDC Rational Resampler: A "hacked" rational resampler, consisting of a DUC and a DDC back-to-back. It's not pretty, but it can occasionally be helpful.

Furthermore, in an effort to TRY to create an open source FPGA project that doesnt catastrophically break on a regular basis, we've set up continuous integration tests for both software and FPGA. Dockerfiles are provided here (https://gitlab.com/theseus-cores/theseus-docker). Theseus Cores also pushes tagged docker images for various versions of UHD and Gnuradio, where the branches for UHD-3.13, UHD-3.14, UHD's master, and gnuradio's maint-3.7 are rebuilt weekly. This may be of auxiliary use to people building UHD and gnuradio in a CI scenario: https://hub.docker.com/u/theseuscores

What's next?? It's a modest list of features so far, but I'm sure we can all sympathize that things move slowly when developing FPGA code. Here's a quick rundown of a few ideas on the horizon:
- Arbitrary resampling
- Channel downselection for the M/2 channelizer (currently all channels must be output... it's far more useful to select a subset of channels to return and just grab those)
- Channel reconsonstruction *after* the M/2 channelizer (maybe)
- OFDM receiver (maybe)

We need more ideas and contributors! Now that this thing exists, I would LOVE to see Theseus Cores fill itself out with some of the more common DSP utilities that really should be available as open-source... it would be absolutely amazing to provide a library of components and applications for FPGA developers in a similar way that gnuradio provides for the software community. Please reach out with suggestions for relevant FPGA utilities or applications you'd like to see -- or even better, if you have ideas or code you're willing to share with the project! If you are interested in getting involved in any way, I would be happy to hear from you.

Cheers,
EJ

Saturday, April 27, 2019

Re: [Discuss-gnuradio] Two channel receiver

Hi Wu,

Thanks for the info. I do not have experience in FPGA programming. I am planning to use bladerf as it seems to be easier to synchronize two SDRs via the driver.



On Sat, Apr 27, 2019, 03:05 wu jo <john.wu.888@hotmail.com> wrote:
Hi YENDstudio,
if you have ability to modify the fpga code you can use 2 b210 or 2 LIMESDR to achieve that. the synchronized receive need same phase clock that is easy to get from a clock buffer from a clock source. and need the same timestamp of the sample at the same time. that need to modify the fpga to reset timestamp and output an start signal from the GPIO then another sdr receive this signal reset the timestamp. I think HACKRF use the same way to do synchronize. but HACKRF use usb 2.0 i don't know if it support LTE bandwitdh.


provide SDR, LNA, PA

发件人: Discuss-gnuradio <discuss-gnuradio-bounces+john.wu.888=hotmail.com@gnu.org> 代表 YENDstudio <yend19@gmail.com>
发送时间: 2019年4月26日 11:54
收件人: Kyeong Su Shin
抄送: discuss-gnuradio@gnu.org
主题: Re: [Discuss-gnuradio] Two channel receiver
 
Hello Kyeong,

Thanks for the info; I will check more. It seems that some hardware modifications are required.

Regards


On Fri, Apr 26, 2019, 06:01 Kyeong Su Shin <ksshin@postech.ac.kr> wrote:
Hello YENDstudio,

I know that USRP 1 can take two RF daughterboards, but the effective sampling rate of the device in this configuration is a bit limited (probably too slow for LTE applications).

You can probably use two SDR boards with synchronization capabilities (or synchronization hacks) and a suitable clock generator. I know that my HackRF boards can do this ( https://github.com/mossmann/hackrf/wiki/Multiple-device-hardware-level-synchronization ), but I never tried this by myself (and the sample alignments can be off by ~50 samples, according to the wiki, so you have to correct that for the perfect alignment). I also know that there are a few cheap SDRs with synchronization capabilities,like AirSpy, but I never used them.

You can make your own RF frontend and add that to one of the antenna ports of a LimeSDR-like SDR by using a mixer and a clock generator (available on RF components stores, or on eBay/AliExpress, if you are willing to deal with dodgey sources). You may have to add an additional LNA (LNA4ALL? ) and/or a filter before the mixer to improve the noise figure (but you need to make sure that you are not overloading your SDR by doing so). All of these parts are available as SMA-type plug-in modules, and are in reasonable price, if you are okay with cheapo eBay/AliExpress parts.

Regards,
Kyeong Su Shin

보낸 사람: YENDstudio <yend19@gmail.com>
보낸 날짜: 2019년 4월 26일 금요일 오전 1:43
받는 사람: Kyeong Su Shin
참조: discuss-gnuradio@gnu.org
제목: Re: [Discuss-gnuradio] Two channel receiver
 
I just wanted to receive time-synchronized channels. 

On Wed, Apr 24, 2019, 15:15 Kyeong Su Shin <ksshin@postech.ac.kr> wrote:
Hello YENDstudio,

Do you actually need a two-channel receiver? Maybe you can get away by using two separate SDRs (possibly synchronized with PPS and 10MHz clock) and a splitter (or two antennas). 

An another alternative would be adding a custom mixer (and a filter, if needed) between the SDR and the antenna.

Regards,
Kyeong Su Shin

보낸 사람: YENDstudio <yend19@gmail.com> 대신 Discuss-gnuradio <discuss-gnuradio-bounces+ksshin=postech.ac.kr@gnu.org>
보낸 날짜: 2019년 4월 24일 수요일 오후 8:03
받는 사람: discuss-gnuradio@gnu.org
제목: [Discuss-gnuradio] Two channel receiver
 
Hi,

Does anyone know any affordable (not thousands) SDR which can receive two frequencies separately. I want to receive LTE UL and DL channels which can be more than 100 MHz appart. The LO offset in USRP B210 and Limesdr is not enough to cover the two frequencies with a shared frequency synthesizer.

Regards