OFDM GRC block attempt

Hello all,

I’m trying to write an OFDM mod/demod for the gnuradio companion and
I’m running into a problem. I’m following the (now deprecated?) packet
modulator code that was in GRC very closely. I have an OFDMDemod block
which creates the following class when its used:


class OFDMDemodHelper(gr.hier_block2):
“”“Forward data from ofdm demod to the gr data stream.”""
def init(self, item_size, options):
#create hier block
gr.hier_block2.init(
self, ‘ofdm_demod’,
gr.io_signature(1, 1, Complex().get_num_bytes()),
gr.io_signature(1, 1, item_size)
)
#the message source (handles the output data stream)
msg_source = gr.message_source(item_size, DEFAULT_QUEUE_LIMIT)
msgq = msg_source.msgq()
def callback(ok, payload):
if ok: msgq.insert_tail(gr.message_from_string(payload, 0,
item_size,
len(payload)/item_size))
ofdm_demod = blks.ofdm_demod(
fg=self,
options=options,
callback=callback,
)
#connections
self.connect(msg_source, self)
self.connect(self, ofdm_demod.head)


This is basically the same as the old packet demod code, with a few
small changes for OFDM. Unfortunately, I get the following error:


File “/home/dramudit/work/gnuradio/grc/src/SignalBlockDefs/Packet.py”,
line 337, in init
callback=callback,
File
“/usr/local/lib/python2.4/site-packages/gnuradio/blksimpl/ofdm.py”, line
218, in init
options.log)
File
“/usr/local/lib/python2.4/site-packages/gnuradio/blksimpl/ofdm_receiver.py”,
line 56, in init
self.fg.connect(self.chan_filt, self.ofdm_sync)
File
“/usr/local/lib/python2.4/site-packages/gnuradio/gr/hier_block2.py”,
line 46, in connect
self._connect(points[i-1], points[i])
File
“/usr/local/lib/python2.4/site-packages/gnuradio/gr/hier_block2.py”,
line 50, in _connect
(dst_block, dst_port) = self._coerce_endpoint(dst)
File
“/usr/local/lib/python2.4/site-packages/gnuradio/gr/hier_block2.py”,
line 61, in _coerce_endpoint
raise ValueError(“unable to coerce endpoint”)
ValueError: unable to coerce endpoint


Any suggestions as far as fixing this error, or another approach?

Thanks,
Dev

In short, the GRC code for the packet modulator was no good after the
“incompatible trunk check in”. So, I just deleted the packet mod/demod
code in GRC.

To restore the functionality of the packet mod/demod (in grc), i would
have to cannibalize the current blks.pkt code. I will be glad to do
this, especially if someone is using the blocks.

The only thing about the packet mod/demod blocks is that they are
implemented poorly. For example, to implement a packet modulation block,
you have to sample the gnuradio stream with a message sink and a thread,
the error coding/packetizing is done in python with packet utils, and
then the data is pushed back into the gnuradio stream with a message
source. Not too efficient. Any suggestions before I go ahead with the
message source/sink idea?

Anyway, it would be great to get ofdm working with GRC.

-Josh

Its not quite that. I should explain. The packet modulator block in blks
is weird for another reason, it takes another gnuradio block (a
modulator) as an argument in the constructor. The problem being that
this does not fit into GRC too well.

My “old” solution was to feed the constructor a dummy block (just to
forward data). And then, to connect the actual modulator block to the
output of the packet modulator. Something like: gr data stream ->
message sink -> packet modulator w/ dummy (byte out) -> dpsk_mod
(complex out) -> data sink

However, the “new” blks2 packet modulator has an io signature that
requires a byte input and a complex output. The io signature will not
allow a dummy block (one that just forwards data) because the data types
will not match. I think it is best to just make my own packet modulator
block that uses the code from the blks2.

This implementation of the packet modulator will take a data stream (of
any type), read data from a message sink, packetize, write data to a
message source. Then, a modulator (like dpsk) could be connected to the
output of this packet modulator using top_block.connect.

…Similar story for the packet demodulator.

Maybe it would be useful to have a packet modulator/demodulator that
fits into the typical gnuradio block model? Also, I was under the
impression that the mblocks will eventually implement this kind of
functionality (packets, error encoding, recovery…).

Thoughts?

-Josh

Josh B. wrote:

Thanks! GRC has been a huge help for our development/testing efforts.

be used with the ofdm_mod block). Again: similar story with ofdm demod.

I’m still not entirely sure what the difference between the hier and
hier2 versions are? Is there anywhere that discusses this? I’ve checked
the wiki and the mailing list with no results.

Thanks,
Dev

I’m still not entirely sure what the difference between the hier and
hier2 versions are? Is there anywhere that discusses this? I’ve checked
the wiki and the mailing list with no results.

The hier blocks were a way to hide a linear chain of blocks inside a
“macro block”, and all blocks ultimately reside in one top level flow
graph. However, this method of doing things is being phased out of
gnuradio in favor of the hier2 blocks.

hier2 blocks offer a fully hierarchical approach. A hier2 block can
contain any number of gr blocks and hier2 blocks. These blocks may
connect to any number of input and output ports. A hier2 block is
itself, a flow graph. And the highest level hier2 block is nothing
more than a hier2 block with no IO ports, this is called gr.top_block.

hier2 blocks should offer everything that hier blocks offer, but also,
can do a lot more. The gnuradio trunk is towards the end of switching
from hier to hier2. Currently, both types of blocks work in the
gnuradio trunk, but are incompatible with one another. Also, the blks2
package is still missing some blocks that you would find in blks.

GRC uses the hier2 format, but continued to support the hier blocks
(due to some hackery) until the “incompatible trunk check in”. Just
another week or so, and all the GRC blocks should be functional again.

-Josh

Josh B. wrote:

Its not quite that. I should explain. The packet modulator block in
blks is weird for another reason, it takes another gnuradio block (a
modulator) as an argument in the constructor. The problem being that
this does not fit into GRC too well.

OFDM is itself a modulation format, but each of the sub-carriers has
their own channel modulation scheme. So we have to pass a modulator
into the OFDM block so it knows what to use to map incoming bits into
channel symbols for each sub-carrier. This isn’t weird; it’s how OFDM
works.

However, the “new” blks2 packet modulator has an io signature that
requires a byte input and a complex output.

If you are referring to blks2.mod_pkts, it’s signature takes no inputs,
and outputs complex baseband. You send it a payload via send_pkt().

If you are referring to the various digital modulator blocks, like
blks2.dqpsk_mod(…), then these all take a stream of bytes and output
complex baseband. So the io signature you describe is the correct one.

I think it is best to just make my own packet modulator block that
uses the code from the blks2.

This implementation of the packet modulator will take a data stream
(of any type), read data from a message sink, packetize, write data
to a message source. Then, a modulator (like dpsk) could be connected
to the output of this packet modulator using top_block.connect.

This would work, to take an arbitrary data stream and break it up into
packets for transmission. But…

Maybe it would be useful to have a packet modulator/demodulator that
fits into the typical gnuradio block model?

The “typical gnuradio block model” is that of a stream-based data flow,
with no boundaries. Digital packet data has boundaries by definition.
Up until now we deal with this by turning specific lengths of bytes in a
stream into a “message” that gets sent to the packetizer, which then
formats the header, CRC, whitening, FEC (future), etc.

Also, I was under the impression that the mblocks will eventually
implement this kind of functionality (packets, error encoding,
recovery…).

Yes. The message block (m-block) data model is passing defined lengths
of data between I/O ports in a flow graph of blocks. It was entirely
motivated by this more natural method of dealing with packet data and
meta-data.

So, once the m-block infrastructure is more mature, we’ll be able to
re-write all the packet handling code in such a way that the
modulation/demodulation functions occur in the gr-block data flow model
and the packet handling, MAC layer, etc., occur in the m-block world.

Conceptually, a digital modulator will be a hybrid block that accepts
raw frame data as m-block messages and outputs a complex baseband data
stream. A digital demodulator will accept a complex baseband data
stream and emit m-block messages containing raw frame data. This is
very similar to the existing blocks except today we use gr_message’s
instead of m-block messages.

The basic m-block code and infrastructure is in the trunk, but it is
undocumented and incomplete. If you look through the QA code you can
see how to create your own m-blocks and wire them up much in the same
way you do with gr-blocks.

As an aside, the “in-band signaling” feature that is slated for release
3.2 depends upon m-block code, so you’ll see it in use then.


Johnathan C.
Corgan Enterprises LLC
http://corganenterprises.com

The conversion of all the example code and blks code on the trunk to the
new 3.1 flow graph code is nearly complete.

This is being done in the jcorgan/t162 developer branch if you want to
take a look.

Once this is merged into the trunk, you’ll be able to restore GRC
functionality.

Sent via BlackBerry by AT&T

I reimplemented the packet modulator/demodulator in GRC, and updated the
packet_mod_demod.grc.xml example. The packet modulator can be used
interchangeably with the gmsk, psk, and qam modulators (same for demod).

See PacketModHelper and PacketDemodHelper in
http://gnuradio.org/trac/browser/grc/trunk/src/SignalBlockDefs/Packet.py

Here is a screen shot of the example that may help explain what I was
talking about, and why:


I suppose that until m-blocks come around, these packet blocks in grc
are the only way a user can actually use a gmsk, psk, or qam
de/modulator.


I will add the ofdm mod/demod, once its hier2 version is merged. The
ofdm modulator will be implemented in a similar manner: GRC will have a
ofdm wrapper block that reads from a message source and calls
ofdm_mod.send_pkt. (I do this so that the output of any block in grc can
be used with the ofdm_mod block). Again: similar story with ofdm demod.

-Josh

Dev R. wrote:

I’m still not entirely sure what the difference between the hier and
hier2 versions are? Is there anywhere that discusses this? I’ve checked
the wiki and the mailing list with no results.

This will get documented as we release 3.1.

Release 3.1 will have entirely rewritten flow graph construction and
handling code, and will support arbitrarily nested flow graphs. (We’re
leaving in the old way of doing things until release 3.2 to give people
time to convert their code.)

Instead of deriving your own flow graph class from gr.flow_graph, you
now derive your own ‘top block’ class from gr.top_block.

You wire up gr-blocks in the usual way, with self.connect.

Hierarchical blocks can now have arbitrary numbers of input and output
ports. You derive them from gr.hier_block2 (instead of the old
gr.hier_block), then and in their init function, you tell the parent
class how many ports of each there will be.

Hierarchical blocks can be connected into a flowgraph the same way you’d
connect a gr-block. Internal to the hierarchical block, you wire the
inputs and outputs to an internally defined flow graph, which can itself
contain hierarchical blocks, etc.

So simple, flat flow graphs work almost identically–substitute
gr.top_block for gr.flow_graph and you’re done.

For complex flow graphs, you can now encapsulate a portion of a flow
graph in to a hierarchical block definition, wire the inputs and outputs
to the internal blocks, and use this composite block wherever you’d use
a gr-block. This kind of nested, hierarchical design allows modularity
and reuse.

As an aside, all the new flow graph code is written in C++. This allows
compiling pure C++ GNU Radio apps. But it won’t be until release 3.2
that the C++ code for the USRP daughterboards, audio handling, build
infrastructure, and C++ only example applications will be completed.


Johnathan C.
Corgan Enterprises LLC
http://corganenterprises.com