Posterous theme by Cory Watilo

How to easily write a GNU Radio Signal Processing Block and understand the architecture

Windows and Linux

GNU Radio these days works on Windows and Linux systems. So I started using the new cmake based build system on both systems. You can use VisualStudio to write Signal Processing blocks. Alternatively of course you can use cmake to generate Code::Blocks or CodeLite projects. So from a developer's perspective this means freedom: use what you like best.

In the following this is about how to utilize cmake after a Windows installation to bring a Signal Block into VisualStudio 2010 (setting variables to let cmake track all the necessary dependencies). Also it's about understanding the architecture of GR. I keep is very concise here, but hopefully not to short. The next part will be about working with the block-template.

 GR architecture

Gr_architecture
GR has a Layers architecture.

  • You have a radio peripheral device, let's say a USRP2. In that case these days you use the UHD device drivers which utilize UDP/IP. Otherwise a USRP1 uses USB.
  • Either way these radios pass vectors (discrete values, bytes) to the GR Scheduler which keeps a ringbuffer of vectors accessible to your signal processing logics
  • the signal processing logic which remains with the GR Blocks.
  • the illustration names Vn as vector n, and mentions that the ringbuffer might increment n to remove vectors that are unnessary - to push them out of the buffer's ring. At the blocks you iterate over a continous stream of vectors via (Boost) Shared Pointers that refer to Vn. Concretely this is in[i] or out[i]. Where i iterates over the Vn, Vn+1 sequence within the stream.
  • Vn is controlled by the ringbuffer, but depending on your inherited Block class the ringbuffer changes. You can either just rewrite some vectors and apply your math in sync, decimate or interpolate, or just consume. You tell the GR Scheduler what you want by inheriting from the appropriate C++ class.
  • the GR Top Block connects Block instances into a Flow-Graph. This means your Signal Processing Scheme consists of multiple blocks, connected, and some parameters (sample-rate, USRP IP, interpolation and what not).
  • the language interoperability (data-types need to be rewritten e.g.) is done with SWIG. You can also implement entire new blocks in Python. But this is not jet as fast as the C++ stuff with Boost'ed coolness. And this not just the Python vs. C++ prejudice.
  • in short this is like a clockwork: imagine the GR Scheduler like a cog-wheel that is transporting the bytes (vectors) into the Blocks. These blocks are cog-wheels again, which are build with more, less or equal prongs (faster, slower - consume, produce, in sync). While all cog-wheels are instances of a whole greater logic that is the Flow-Graph in the Top Block. 
  • for the vocabulary: an item in GR is a "vector" that is passed between the Blocks. 

Writing a new block therefore has a number of issues:

  1. language interoperability: SWIG interfaces need to be written
  2. GR has a load of dependencies, but I mentioned Windows & Linux (GNU stuff on Windows)
  3. there's some performance impact. That in short means no Cygwin or something.
  4. It needs a concrete example. DSP for software developers is a challenge. Since we are not accustomed to think of these low-level interactions. Modelling these in OOP is pretty amazing though.
  5. While we are at it: the GNU Radio companion is a Model Driven Development environment. We will write a block that extends the GRC library. This needs XML. The GRC abstracts the Top Block again by letting you design a transmission scheme (Flow-Graph) in a UML like manner. It generates an XML file to hold the connections and parameters and uses this XML file for Python code-generation.
  6. We need some C++ (Boost libs, OOP, inheritance), Python (OOP, special APIs, SWIG interface operability), XML (just some definitions on an XML scheme), basic networking skills (static IP setup on Windows, maybe some network analysis) and last but not least cmake and your IDE - in my case VisualStudio 2010. In short: some awesome developer who knows his stuff.

Dependency tracking- Oh my ...

Please take your time here to read carefully what is in the readmes. This is not easy. Remember to restart cmake if you change your PATH variable.

  • Josh Blum has a GNU Radio installation manual for Windows. There's a port in MacPorts and your favorite Linux distribution (Fedora, Ubuntu, Arch AUR, gentoo), too. You may want to build it manually. On Windows I cannot recommend this - although is is possible.
  • make sure you have at least GR 3.4 anyway
  • install Git (on Windows mysysgit and SmartGit(r) (free for non-commercial use))
  • set your PYTHONPATH with the Rapid Environment Editor or on Linux/Mac via Terminal to meet the gnuradio/lib/site-packages. You can also use Powershell on Windows.
  • LXML and Cheetah are harder to build on Windows, even with easy_install. This fails sometimes... but here are setup files. Use the base and lxml pack and you're done.
  • fire up your Terminal and start gnuradio-companion(.py)
  • if that worked you have all the runtime dependencies. That doesn't mean you have all the developer dependencies.
  • install cppunit. I don't know why, but the distribution of cppunit is inadequate to say the least... Use the SVN, because the developer chose not to distribute his work and just threw it on the internet. Anyhow, this happens from time to time. Just as a hint: there will be build errors. Don't mind that. It's dead code anyway.
  • install Boost stuff cmake asks for. Unit test stuff etc. Yes, it may be 1 GB or so.
  • just in case you compile more than just the howto block: make sure you manually link the MinGW cross-compiled libfftw libs with the mentioned lib command (lib /def:libfftw3-3.de, lib /def:libfftw3f-3.def, lib /def:libfftw3l-3.def). Same thing with GSL. This is important because we are using VisualStudio here later with its native compiler. It's recommended to stay x86 here.
  • if that worked install SWIG (from here). It needs to be put into PATH.
  • git clone the current master and copy the gr-how-to-write-a-block-cmake
  • fire up cmake-gui, source folder is the mentioned block-howto folder. build is a new sub-directory build.
  • and take a look at the screen-shot. I build most stuff into ~/Documents and that's where I made cmake resolve the dependencies mentioned.

Now that was fun, wasn't it? Yes... this is it. You never need to touch these dependencies again for a while. cmake generated a VisualStudio project file. We open it and voilà:

 

(download)

Quadrature Demodulator - a DSP example

The Quadrature Demodulator is used to demodulate FM, GMSK or oQPSK for example. - So to receive Bluetooth (802.15.1) or Zigbee (802.15.4) signals. With GR you can implement the entire protocol stacks in Python, after receiving the bits. It's not restricted to signal level.

Take a look at this Flow-Graph on GRC (doesn't need a USRP btw.):

Quaddemod
The Quadrature Demod Block at the bottom is equivalent with the Multiplication and Complex-conjugation above. This is one way to represent this. Here's the same in C++:

int

gr_quadrature_demod_cf::work (int noutput_items,

gr_vector_const_void_star &input_items,

gr_vector_void_star &output_items)

{

gr_complex *in = (gr_complex *) input_items[0];

float *out = (float *) output_items[0];

in++; // ensure that in[-1] is valid

for (int i = 0; i < noutput_items; i++){

gr_complex product = in[i] * conj (in[i-1]);

// out[i] = d_gain * arg (product);

out[i] = d_gain * gr_fast_atan2f(imag(product), real(product));

}

return noutput_items;

}

This is a sync block. The number of items it outputs are equal with the input's. So the GR scheduler doesn't need to remove or add any space for vectors in the sequence.

Let's say for research purposes we now want a higher delay. And for performance reasons we don't want to set this via the Flow-Graph above but embed this in one C++ block file. We need to rename the block, change the work method, and delete some of the clutter around the howto-came block. You can easily do this from within the VS project-explorer now. Ensure that you add the GR source as dependency to resolve the headers.

 

To be continued: the next part very soon will cover renaming blocks using the cmake-howto file form the current GR master.

Have fun,

wishi

Explorer and Finder Commandline-KungFu

Annoyed by file-navigation?

Terminal to File-Manager

The more data, the worse. Some file actions require GUI interactions.
But click based navigation is slow.


open -a Finder .

Opens the Finder at the current directory. open is a very handy tool to
invoke applications. -a defines which application you want to use.
open . would be sufficient in most cases. It has an index of installed
applications, therefore it doesn't require complete paths.


explorer .

Does the same for the Windows Explorer. Furthermore you can pass Setup
files to it that way, and it'll automatically raise the process within UAC.
You can start LNKs on your Desktop with the Explorer that way, instead
of clicking them. That's very practical if you don't show your symbols
on your Desktop. Just keep one Powershell Tab with Console2
(http://sourceforge.net/projects/console/) at %USERPROFILE%\Desktop.

And use the environment variables

%HOMEPATH% == ~
%WinDir% == \Windows
%SystemDrive% == C: in most cases

and so on...
cd %HOMEPATH% is much faster than cd \Users\mysuperlongname.
- Especially handy: explorer %programfiles%\Example\example_app.exe

File-Manager to Terminal

For the Finder there's cd-to.app:
http://code.google.com/p/cdto/

For the Explorer there's the infamous StEX toolbar:
http://tools.tortoisesvn.net/StExBar.html

Favorites

Adding Favorite folders to Finder is a drag & drop actions...

For our annoying stupid Windows Explorer there's FileBoxExtender:
http://www.hyperionics.com/files/

I don't keep favorites to cd to via my Shell, but I make heavy use on
ZSH completion. Try it in time. Speeds up standard Shell-tasks enormously.

Have fun,
wishi

No Flash within Safari on MacOS X 10.5.8

Java?

I had some hours of "fun" fixing the following error on my Mac system:

The nature of the problem

Firefox and Chrome had a working Flash-plugin.

But not Safari, and other tools utilizing its engine like OmniWeb or
Evernote. It seems Evernote uses Flash to display PDFs within the notes.

The solution

Possible (but not working) solutions are to manually apply the newest
10.5.8 combo update again, to delete related configs (plists), to delete
all SIMBL plugins, all Safari Extensions, reset everything. None of that
worked. But resetting Java to a 32bit version. Apple does not provide a
32bit Java6 implementation!
I think if you load a 64bit Java plugin, after switching to Java6, you
get a crap-ton of problems with interoperability.

So just in case you stumple upon the same problem (likely as a Java
developer), change the Java preferences back. It seems the "Internet
Plugins" (In ~/Library or /Library) for Safari will get a problem with
Adobe Flash Square (64bit). I don't recommend installing the 64bit Beta.

Have fun,
wishi

findjump in VS 2010

What?

findjump can help searching for opcodes through DLLs.

Patched, how?

Nothing fancy. Just some Visual Studio 2010 compiler flags:

  1. deactivated precompiled headers
  2. deactivated common language runtime support

Link

Seems to work for me at least ;)

Have fun,
wishi