-
Notifications
You must be signed in to change notification settings - Fork 11
Home
This wiki captures some additional ERA development efforts that we consider worth being documented. This is "live" text that will keep evolving with new contributions.
(work in progress)
One alternative to profile GNU Radio flowgraphs is through its built-in performance counters. To enable them, GNU Radio has to be built from sources (including some additional dependencies) as explained below. These instruction build and install GNU Radio 3.7.9.3, which looks like a stable "pre-3.8" version. We initially tried GNU Radio 3.8, but there are some major changes between 3.7 and 3.8 (for example, the use of YAML instead of XML) that complicate the installation of other GNU Radio projects.
-
Install UHD (to be able to use USRP devices):
sudo apt-get install libuhd-dev libuhd003 uhd-host
-
Install Boost 1.57 from sources:
cd ~/gnuradio/ wget http://sourceforge.net/projects/boost/files/boost/1.57.0/boost_1_57_0.tar.bz2 tar xjvf boost_1_57_0.tar.bz2 cd boost_1_57_0/ sudo apt-get update sudo apt-get install build-essential g++ python-dev autotools-dev libicu-dev build-essential libbz2-dev libboost-all-dev ./bootstrap.sh --prefix=/usr/ ./b2 sudo ./b2 install
-
Install GMP (GNU Multiple Precision Arithmetic Library):
sudo apt-get install libgmp3-dev
-
Install Apache Thrift 0.9.2 (the exact version 0.9.2 is required):
cd ~/gnuradio/ git clone https://github.com/apache/thrift.git thrift cd thrift git checkout 0.9.2 ./bootstrap ./configure --prefix=/usr --with-cpp --with-python make -j8 sudo make install thrift --version
-
Install GNU Radio:
cd ~/gnuradio/ wget https://www.gnuradio.org/releases/gnuradio/gnuradio-3.7.9.3.tar.gz tar xzvf gnuradio-3.7.9.3.tar.gz cd gnuradio-3.7.9.3/ mkdir build cd build/ cmake -DENABLE_PERFORMANCE_COUNTERS=True -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/opt/gnuradio/ -DPYTHON_EXECUTABLE=/usr/bin/python ../ make -j8 && make test sudo make install
-
Add the custom installation directories to the environment settings:
export PATH=/opt/gnuradio/bin:$PATH export LD_LIBRARY_PATH=/opt/gnuradio/lib:$LD_LIBRARY_PATH export PKG_CONFIG_PATH=/opt/gnuradio/lib/pkgconfig:$PKG_CONFIG_PATH export PYTHONPATH=/opt/gnuradio/lib/python2.7/dist-packages:$PYTHONPATH
-
Adjust GNU Radio Companion's configuration file (
~/.gnuradio/config.conf
) to allow it to find our out-of-tree modules (usually, this step is only needed when GNU Radio is installed in a user-defined location with theCMAKE_INSTALL_PREFIX
switch):[grc] global_blocks_path = /opt/gnuradio/share/gnuradio/grc/blocks local_blocks_path = /usr/local/share/gnuradio/grc/blocks
Note 1: At present, we have not managed to enable Volk when GNU Radio is built from sources. In other words, Volk is only enabled when GNU Radio is compiled with apt
.
Note 2: Ensure that gnuradio-companion
(GRC) is among the Gnuradio enabled components at the end of the cmake
output. GRC will not be installed if any of the required components are missing!
Note 3: Ensure that thrift
is among the Gnuradio enabled components at the end of the cmake
output. This is required to access GNU Radio's performance counters using ControlPort. In case of any problems, verify that gr-ctrlport
is properly configured during the execution of cmake
:
-- Configuring gr-ctrlport support...
-- Dependency Boost_FOUND = 1
-- Dependency SWIG_FOUND = TRUE
-- Dependency SWIG_VERSION_CHECK = TRUE
-- Dependency ENABLE_GNURADIO_RUNTIME = ON
-- Enabling gr-ctrlport support.
-- Override with -DENABLE_GR_CTRLPORT=ON/OFF
-- Loading build date Fri, 30 Nov 2018 15:36:58 into constants...
-- Loading version 3.7.9.3 into constants...
--
-- Python checking for Thrift
-- Python checking for Thrift - found
-- Found THRIFT: /usr/lib/libthrift.so
-- Found and enabling Thrift backend to ControlPort
-- Running thrift to build C++ bindings
-- TRY_SHM_VMCIRCBUF set to ON.
If Python cannot find thrift
, check the PYTHONPATH
environment variable – it should look like this:
PYTHONPATH=/usr/local/lib/python2.7/dist-packages:/usr/lib/python2.7/site-packages
Note 4: If the following error appears when the GNU Radio Companion (GRC) is launched:
dconf-WARNING **: failed to commit changes to dconf: Could not connect: Connection refused
then try to first remove the following folders (which are likely locked by root):
~/.cache/dconf
~/.dbus
During the creation of the ros-interface
out-of-tree (OOT) module, we found difficulties to link this new module against the external ROS libraries. Actually, the compilation process run just fine; the problem appeared at run-time with the following Python message: AttributeError: 'module' object has no attribute 'ros_interface'
The problem is due to improper linking against ROS libraries, which is fixed with appropriate directives in the CMakeLists.txt
file in the root of the module as well as in the CMakeLists.txt
file under lib/
:
target_link_libraries(gnuradio-ros_interface ${roscpp_LIBRARIES} ... )
Similarly, we had to explicitly define the linking against the LZ4 compression library by creating a proper FindLZ4.cmake
file under cmake/Modules/
and adding ${LZ4_LIBRARY}
to target_link_libraries
:
target_link_libraries(gnuradio-ros_interface ${roscpp_LIBRARIES} ${LZ4_LIBRARY} ... )
When we converted the ros-interface
OOT block into a ROS node, we found that the callback function to process incoming ROS messages was never called. This was because the ROS spin()
or spinOnce()
functions were never called since the ros-interface
instance is not a standalone program with a main
function to call them. We solved this by using an alternative version of spin()
, called AsyncSpinner
. Then, when the ros-interface
block is instantiated, the asynchronous spinner is started in the background.
It turns out that the mapper looks for any updates on its input port and if it doesn't have any, returns immediately. Since the following block is waiting for data, the mapper work function is called again. Thus, when the packet period is low, the mapper function takes 100% of the CPU. Replacing delete_head_nowait(pmt::intern("in"))
with delete_head_blocking(pmt::intern("in"), 100)
solved the problem