Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error during 'make' step for gr-sparsdr #12

Open
tkpudgy opened this issue Oct 18, 2021 · 28 comments
Open

Error during 'make' step for gr-sparsdr #12

tkpudgy opened this issue Oct 18, 2021 · 28 comments

Comments

@tkpudgy
Copy link

tkpudgy commented Oct 18, 2021

Hello,

I've followed the steps in this link sequentially. All went smooth until the 'make' step for gr-sparsdr:

https://github.com/ucsdsysnet/sparsdr/blob/pluto/doc/getting_started.md

Any help or workaround would be appreciated.

Thank you,

Jae

[ 37%] Building CXX object lib/CMakeFiles/test-sparsdr.dir/test-sparsdr_autogen/mocs_compilation.cpp.o
[ 40%] Building CXX object lib/CMakeFiles/test-sparsdr.dir/test_sparsdr.cc.o
[ 42%] Building CXX object lib/CMakeFiles/test-sparsdr.dir/qa_sparsdr.cc.o
[ 45%] Linking CXX executable test-sparsdr
/usr/bin/ld: libgnuradio-sparsdr-1.0.0git.so.0.0.0: undefined reference to `gr::filter::rational_resampler_base_ccf::make(unsigned int, unsigned int, std::vector<float, std::allocator > const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [lib/CMakeFiles/test-sparsdr.dir/build.make:157: lib/test-sparsdr] Error 1
make[1]: *** [CMakeFiles/Makefile2:285: lib/CMakeFiles/test-sparsdr.dir/all] Error 2
make: *** [Makefile:160: all] Error 2

@samcrow
Copy link
Collaborator

samcrow commented Oct 18, 2021

To help diagnose this, please let me know what version of GNU Radio you have and how you installed it (system package manager, PyBOMBS, or some other way). Also, please post the full output from the CMake configuration step.

@tkpudgy
Copy link
Author

tkpudgy commented Oct 18, 2021

To help diagnose this, please let me know what version of GNU Radio you have and how you installed it (system package manager, PyBOMBS, or some other way). Also, please post the full output from the CMake configuration step.

Below is the info. Also, I did have some warning messages which I ignored during the installation of 'sparsdr_reconstruct'. If it may be related to 'gr-sparsdr' installation, I can post the warning messages from that as well. Let me know. Thank you.

  • GNUradio version: 3.8.2.0 (Python 3.7.3)
  • How GNUradio was installed: It came installed with the Raspbian OS image called PiSDR (https://github.com/luigifcruz/pisdr-image)
  • Full output from cmake:
    pi@raspberrypi:~/sparsdr/gr-sparsdr/build $ make
    Scanning dependencies of target gnuradio-sparsdr_autogen
    [ 2%] Automatic MOC for target gnuradio-sparsdr
    [ 2%] Built target gnuradio-sparsdr_autogen
    Scanning dependencies of target gnuradio-sparsdr
    [ 5%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/gnuradio-sparsdr_autogen/mocs_compilation.cpp.o
    [ 7%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/average_detector_impl.cc.o
    [ 10%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/real_time_receiver_impl.cc.o
    [ 12%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/multi_sniffer_impl.cc.o
    [ 15%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/reconstruct_impl.cc.o
    [ 17%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/compressing_usrp_source_impl.cc.o
    [ 20%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/gui/average_waterfall_impl.cc.o
    [ 22%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/gui/stream_average_model.cc.o
    [ 25%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/gui/average_model.cpp.o
    [ 27%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/gui/average_waterfall_view.cpp.o
    [ 30%] Building CXX object lib/CMakeFiles/gnuradio-sparsdr.dir/sample_distributor_impl.cc.o
    [ 32%] Linking CXX shared library libgnuradio-sparsdr-1.0.0git.so
    [ 32%] Built target gnuradio-sparsdr
    Scanning dependencies of target test-sparsdr_autogen
    [ 35%] Automatic MOC for target test-sparsdr
    [ 35%] Built target test-sparsdr_autogen
    Scanning dependencies of target test-sparsdr
    [ 37%] Building CXX object lib/CMakeFiles/test-sparsdr.dir/test-sparsdr_autogen/mocs_compilation.cpp.o
    [ 40%] Building CXX object lib/CMakeFiles/test-sparsdr.dir/test_sparsdr.cc.o
    [ 42%] Building CXX object lib/CMakeFiles/test-sparsdr.dir/qa_sparsdr.cc.o
    [ 45%] Linking CXX executable test-sparsdr
    /usr/bin/ld: libgnuradio-sparsdr-1.0.0git.so.0.0.0: undefined reference to `gr::filter::rational_resampler_base_ccf::make(unsigned int, unsigned int, std::vector<float, std::allocator > const&)'
    collect2: error: ld returned 1 exit status
    make[2]: *** [lib/CMakeFiles/test-sparsdr.dir/build.make:157: lib/test-sparsdr] Error 1
    make[1]: *** [CMakeFiles/Makefile2:285: lib/CMakeFiles/test-sparsdr.dir/all] Error 2
    make: *** [Makefile:160: all] Error 2

@samcrow
Copy link
Collaborator

samcrow commented Oct 19, 2021

It looks like the problem is a version mismatch. The gr-bluetooth module in the pluto branch currently works with GNU Radio 3.7 and needs a few changes to support GNU Radio 3.8.

I made a version that should work with GNU Radio 3.8, which is in the pluto-3.8 branch. Please try that and let me know if there are other problems.

@tkpudgy
Copy link
Author

tkpudgy commented Oct 19, 2021

Success at the make and install steps. I see that GNURadio has the blocks available. I opened the SparSDR.grc file in the example folder and tried to execute. I get the following error:
"
Executing: /usr/bin/python3 -u /home/pi/sparsdr/examples/top_block.py

Traceback (most recent call last):
File "/home/pi/sparsdr/examples/top_block.py", line 33, in
import sparsdr
ModuleNotFoundError: No module named 'sparsdr'

Done (return code 1)
"
Also, I noticed that there was string of errors when GNURadio started. I copy the messages below. It looks like I'm getting close. Much appreciate your help.

Jae

<<< Welcome to GNU Radio Companion 3.8.2.0 >>>

Block paths:
/usr/local/share/gnuradio/grc/blocks

Loading: "/home/pi/sparsdr/examples/SparSDR.grc"
ERROR:gnuradio.grc.core.FlowGraph:Failed to evaluate variable block variable_sparsdr_reconstruct_0
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gnuradio/grc/core/FlowGraph.py", line 268, in renew_namespace
value = eval(variable_block.value, namespace, variable_block.namespace)
File "", line 1, in
NameError: name 'value' is not defined
ERROR:gnuradio.grc.core.FlowGraph:Failed to evaluate variable block variable_sparsdr_reconstruct_0
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gnuradio/grc/core/FlowGraph.py", line 268, in renew_namespace
value = eval(variable_block.value, namespace, variable_block.namespace)
File "", line 1, in
NameError: name 'value' is not defined

Done
ERROR:gnuradio.grc.core.FlowGraph:Failed to evaluate variable block variable_sparsdr_reconstruct_0
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gnuradio/grc/core/FlowGraph.py", line 268, in renew_namespace
value = eval(variable_block.value, namespace, variable_block.namespace)
File "", line 1, in
NameError: name 'value' is not defined
ERROR:gnuradio.grc.core.FlowGraph:Failed to evaluate variable block variable_sparsdr_reconstruct_0
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gnuradio/grc/core/FlowGraph.py", line 268, in renew_namespace
value = eval(variable_block.value, namespace, variable_block.namespace)
File "", line 1, in
NameError: name 'value' is not defined
ERROR:gnuradio.grc.core.FlowGraph:Failed to evaluate variable block variable_sparsdr_reconstruct_0
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gnuradio/grc/core/FlowGraph.py", line 268, in renew_namespace
value = eval(variable_block.value, namespace, variable_block.namespace)
File "", line 1, in
NameError: name 'value' is not defined
ERROR:gnuradio.grc.core.FlowGraph:Failed to evaluate variable block variable_sparsdr_reconstruct_0
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gnuradio/grc/core/FlowGraph.py", line 268, in renew_namespace
value = eval(variable_block.value, namespace, variable_block.namespace)
File "", line 1, in
NameError: name 'value' is not defined
ERROR:gnuradio.grc.core.FlowGraph:Failed to evaluate variable block variable_sparsdr_reconstruct_0
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gnuradio/grc/core/FlowGraph.py", line 268, in renew_namespace
value = eval(variable_block.value, namespace, variable_block.namespace)
File "", line 1, in
NameError: name 'value' is not defined
ERROR:gnuradio.grc.core.FlowGraph:Failed to evaluate variable block variable_sparsdr_reconstruct_0
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gnuradio/grc/core/FlowGraph.py", line 268, in renew_namespace
value = eval(variable_block.value, namespace, variable_block.namespace)
File "", line 1, in
NameError: name 'value' is not defined

@samcrow
Copy link
Collaborator

samcrow commented Oct 20, 2021

I had the same problem in my test virtual machine. The workaround for now is to set these environment variables: PYTHONPATH=/usr/local/lib/python3/dist-packages LD_LIBRARY_PATH=/usr/local/lib/x86_64-linux-gnu. (The first directory contains a sparsdr directory, which contains __init__.py, and the second contains libgnuradio-sparsdr.so.1.0.0git.) With those variables set, I was able to run a flow graph and receive some samples.

I'm not sure what was happening with the SparSDR.grc file. Because you are using a Pluto instead of a USRP, I would suggest making a new file in GNU Radio Companion and adding a Compressing Pluto Source block. The default settings of the block will produce some compressed samples that can show if it is working.

I recently pushed some small changes to the pluto-3.8 branch that make it possible to use the Compressing Pluto Source block with file sinks and other common blocks.

@tkpudgy
Copy link
Author

tkpudgy commented Oct 21, 2021

Ok. So I'm still getting the same set of errors. I can see through the 'echo' command that I've set the environment variables as you have instructed. I checked that 'int.py' is under '/usr/local/lib/python3/dist-packages/gnuradio' folder. However, I'm not seeing the 'x86_64-linux-gnu' folder under the path you have described. Have I skipped a step somewhere possibly? Thanks!

@samcrow
Copy link
Collaborator

samcrow commented Oct 22, 2021

It's possible that the files ended up installed in different places on your computer. When you run make install in the gr-sparsdr build folder, it will print the path to each installed file.

On my computer, that process installs the files /usr/local/lib/python3/dist-packages/sparsdr/__init__.py and /usr/local/lib/x86_64-linux-gnu/libgnuradio-sparsdr.so.1.0.0git (as well as various other files). If those files are in different places on your computer, you will need to change the environment variables to point there.

As you can tell, I barely spent any time testing gr-sparsdr with GNU Radio 3.8 on other computers. This process is not going very smoothly, but we will get through it and make the system work.

@tkpudgy
Copy link
Author

tkpudgy commented Oct 26, 2021

Before I switched to GNURadio 3.7, I decided to look for the 'libgnuradio-sparsdr.so.1.0.0git' file. Mine was installed in '/usr/local/lib' folder. I changed the environment accordingly, but I ended up running into the same error. At this point I decided to downgrade the GNURadio version.

Per Moein's instruction, I reimaged my SD card with the version of PiSDR that came with the 3.7 version of GNURadio. I proceeded with the setup instruction on your getting started guide. To note in detail as much as possible, here are two points to note that deviated a bit from your instruction:

  1. From this command 'sudo apt install build-essential cmake gnuradio libuhd-dev libfftw3-3 swig', 'cmake' and 'gnuradio' were omitted since they were already installed
  2. There were set of warnings at the cmake step for 'gr-sparsdr that I ignored. Subsequent commands went through fine.

GNURadio opened without the errors that I ran into with the version 3.8. Hooray! I opened 'SparSDR.grc' in the example folder. Per your instruction, I deleted the USRP block and substituted in the 'Compressing Pluto Source' without any parameter changes. When I hit the execute button, I ran into the following errors:

Generating: '/home/pi/sparsdr/examples/top_block.py'

Executing: /usr/bin/python -u /home/pi/sparsdr/examples/top_block.py

Traceback (most recent call last):
File "/home/pi/sparsdr/examples/top_block.py", line 199, in
main()
File "/home/pi/sparsdr/examples/top_block.py", line 187, in main
tb = top_block_cls()
File "/home/pi/sparsdr/examples/top_block.py", line 64, in init
variable_sparsdr_reconstruct_0_bands = sparsdr.band_spec_vector()
AttributeError: 'module' object has no attribute 'band_spec_vector'

Done

One step closer than before! Please advise. Thank you!

@samcrow
Copy link
Collaborator

samcrow commented Oct 26, 2021

I'm working on setting up a Raspberry Pi so I can test with the same setup you're using. Until that is ready, please try this:

Modify the file /usr/local/lib/python2.7/dist-packages/sparsdr/__init__.py (the python2.7 part may be different if it used a different version of Python).

The file should contain this:

# import swig generated symbols into the sparsdr namespace
try:
	# this might fail if the module is python-only
	from sparsdr_swig import *
except ImportError:
	pass

Replace that block with this:

from sparsdr_swig import *

Now, when you run GNU Radio, it should show errors involved in loading the library instead of suppressing them, and we can investigate that.

@tkpudgy
Copy link
Author

tkpudgy commented Oct 28, 2021

The file was in the same directory as the one you specified. I didn't have the file permission to write, so I had to activate a root account on my RaspberryPi first. Using root, I made changes to init.py as you suggested above. Below is the error message when I run the gnuradio code now:

Done

Generating: '/home/pi/sparsdr/examples/top_block.py'

Executing: /usr/bin/python -u /home/pi/sparsdr/examples/top_block.py

Traceback (most recent call last):
File "/home/pi/sparsdr/examples/top_block.py", line 28, in
import sparsdr
File "/usr/local/lib/python2.7/dist-packages/sparsdr/init.py", line 33, in
from sparsdr_swig import *
File "/usr/local/lib/python2.7/dist-packages/sparsdr/sparsdr_swig.py", line 17, in
_sparsdr_swig = swig_import_helper()
File "/usr/local/lib/python2.7/dist-packages/sparsdr/sparsdr_swig.py", line 16, in swig_import_helper
return importlib.import_module('_sparsdr_swig')
File "/usr/lib/python2.7/importlib/init.py", line 37, in import_module
import(name)
ImportError: No module named _sparsdr_swig

Done

I checked that I have swig version 3.0.12 installed.

Thank you so much for trying to replicate my error on a raspberryPi!

@samcrow
Copy link
Collaborator

samcrow commented Oct 29, 2021

I reproduced the problem on a Raspberry Pi with the same image you're using. I found that the fix was to run the command sudo ldconfig after installing gr-sparsdr, before opening GNU Radio Companion.

Apparently the library loader does not look in /usr/local/lib by default, until you run ldconfig to make it update the paths.

After running ldconfig, I was able to run Python scripts that loaded some gr-sparsdr blocks and ran their constructor code.

@tkpudgy
Copy link
Author

tkpudgy commented Oct 29, 2021

Thank you! I just tried the 'sudo ldconfig' command. GNURadio runs fine now. When I executed the example code, I'm getting the following error. This may be due to my unfamiliarity with gnuradio. I'll play with it more but I'd thought I let you know of the progress. Thank you.

Generating: '/home/pi/sparsdr/examples/top_block.py'

Executing: /usr/bin/python -u /home/pi/sparsdr/examples/top_block.py

WARN: WARNING: File will not be fully consumed with the current output type
WARN: WARNING: File will not be fully consumed with the current output type
03:45:01 [INFO] Setup: compressed bandwidth 61440000
03:45:01 [INFO] Band: 1024 bins, center frequency -25000000
03:45:01 [INFO] Band: 1024 bins, center frequency 25000000
thread 'main' panicked at 'Range end too large', sparsdr_bin_mask/src/lib.rs:88:9
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
/home/pi/.gnuradio/prefs/vmcircbuf_default_factory: No such file or directory
vmcircbuf_createfilemapping: createfilemapping is not available
gr::vmcircbuf_sysv_shm: shmat (3): Invalid argument
gr::vmcircbuf_sysv_shm: shmat (3): Invalid argument
gr::vmcircbuf_sysv_shm: shmat (3): Invalid argument
thread[thread-per-block[1]: <block file_sink (2)>]: file_sink write failed with error 9

@samcrow
Copy link
Collaborator

samcrow commented Oct 29, 2021

03:45:01 [INFO] Setup: compressed bandwidth 61440000
03:45:01 [INFO] Band: 1024 bins, center frequency -25000000
03:45:01 [INFO] Band: 1024 bins, center frequency 25000000
thread 'main' panicked at 'Range end too large', sparsdr_bin_mask/src/lib.rs:88:9
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

This is a problem with the default reconstruction settings. The defaults make sense for the N210 but not the Pluto, which has only 1024 FFT bins that span 61.44 MHz of frequency. Some of the requested FFT bins extend beyond the frequency range that the Pluto can receive.

I would suggest using a simpler setup that should work with the Pluto:

  • Open the SparSDR reconstruct block properties
  • In the "General" tab, change "Bands" to 1
  • In the "Bands" tab, change "Band 0 frequency" to 10e6
  • Also in the "Bands" tab, change "Band 0 bins" to 64

This will give you one stream of reconstructed samples centered 10 MHz above the Pluto's center frequency, with a sample rate of 64 / 1024 * 61.44 MHz = 3.84 MHz.

The other warnings are all either spurious or caused by the above error.

@tkpudgy
Copy link
Author

tkpudgy commented Oct 30, 2021

Those warnings and errors disappeared once I made changes to the reconstruct block. I'm not seeing anything in the waterfall graph but I suppose it's because there is no real-world signal that it's capturing that meets the threshold? I do need to to familiarize myself with gnuradio and the sparsdr blocks. Any suggestion on setting up a quick demo to show end-to-end capability would be great. Thank you so much for all your help!

@samcrow
Copy link
Collaborator

samcrow commented Nov 1, 2021

We were missing an actual working example for the Pluto version. I added a flow graph file SparSDR Pluto single channel.grc and some documentation to the new examples folder. That flow graph receives one BLE advertising channel, reconstructs the signals, and displays them in a waterfall view.

Let me know if you have any problems with that, or if you would like help adapting it to do something else.

@tkpudgy
Copy link
Author

tkpudgy commented Nov 2, 2021

Thank you so much for the example. I just downloaded the file and tried to open it on gnuradio. However, there's a long list of errors and doesn't open. I couldn't capture the beginning of the error. I just took a snapshot and pasted below. Any help would be appreciated.

/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2063:13:FATAL:PARSER:ERR_GT_REQUIRED: Couldn't find end of Start Tag a line 2060
/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2065:11:FATAL:PARSER:ERR_TAG_NAME_MISMATCH: Opening and ending tag mismatch: div line 1904 and a
/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2141:145:FATAL:PARSER:ERR_ATTRIBUTE_WITHOUT_VALUE: Specification mandate value for attribute data-pjax
/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2145:24:FATAL:PARSER:ERR_ATTRIBUTE_WITHOUT_VALUE: Specification mandate value for attribute data-pjax
/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2145:24:FATAL:PARSER:ERR_SPACE_REQUIRED: attributes construct error
/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2145:24:FATAL:PARSER:ERR_GT_REQUIRED: Couldn't find end of Start Tag a line 2145
/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2152:15:FATAL:PARSER:ERR_TAG_NAME_MISMATCH: Opening and ending tag mismatch: div line 2138 and a
/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2171:160:FATAL:PARSER:ERR_ATTRIBUTE_WITHOUT_VALUE: Specification mandate value for attribute preload
/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2173:124:FATAL:PARSER:ERR_ATTRIBUTE_WITHOUT_VALUE: Specification mandate value for attribute data-close-dialog
/home/pi/sparsdr/gr-sparsdr/examples/SparSDR Pluto single channel.grc:2241:14:FATAL:PARSER:ERR_ATTRIBUTE_WITHOUT_VALUE: Specification mandate value for attribute disabled
/home/pi/sp

@samcrow
Copy link
Collaborator

samcrow commented Nov 2, 2021

Those errors look like the software was parsing HTML when it expected flow graph XML. You may have downloaded the GItHub web page that displays the .grc file, instead of downloading just the .grc file. Does something different happen if you download the file from this raw link: https://github.com/ucsdsysnet/sparsdr/raw/b9ed92a73a3193f381d38258d1d656d8ff03d99d/gr-sparsdr/examples/SparSDR%20Pluto%20single%20channel.grc ?

@tkpudgy
Copy link
Author

tkpudgy commented Nov 8, 2021

Thank you for all your help so far. I was able to get the waterfall graphs to display. I think at this point I just need to familiarize myself with SparSDR capability. Thank you!

@tkpudgy
Copy link
Author

tkpudgy commented Dec 4, 2021

Some questions about the "Bin specification" parameter on the "Compressing Pluto Source" block:

In the example grc file, this is set to 416..450:12800. 1) How do you calculate which frequency bins 416 through 450 are? 2) All other frequency bins other than 416..450 are masked off meaning turned off, correct?

Thank you.

@samcrow
Copy link
Collaborator

samcrow commented Dec 4, 2021

Bin to frequency conversion

There are two steps to find the corresponding frequency range:

  1. Convert bin numbers from FFT order to frequency order

In the bin specification, bin numbers use the order produced by the FFT. Bins 0 through 511 correspond to the upper half of the frequency range, and bins 512 through 1023 correspond to the lower half of the frequency range. Bin 0 is the center frequency, and bin 1023 is just below the center frequency.

To do the conversion: for each bin number that is less than 512, add 512. If the bin number is greater than or equal to 512, subtract 512.

This will give bin numbers that are proportional to frequency. Some contiguous ranges in FFT order will be split into two separate ranges in frequency order.

In this example, bins 416..450 are all less than 512. Adding 512 to each gives the bin range 928..962 .

  1. Convert bin numbers to frequency

SparSDR on the Pluto uses 1024 bins that span 61.44 MHz of frequency. First calculate the frequency of bin 0: bin_0_frequency = center_frequency - 61.44 MHz / 2

Then, use that to find the frequency of each bin: bin_frequency = bin_0_frequency + bin_number * 61.44 MHz / 1024

In this example, the center frequency is 2.4 GHz, so bin_0_frequency is 2.36928 GHz. Bin 928 corresponds to 2.42496 GHz, and bin 962 corresponds to 2.427 GHz. This is range of approximately 2 MHz centered at 2.426 GHz, one of the BLE advertising channels.

I know this is not very user-friendly, but we are working on a simpler way to configure these settings.

Other bins

Yes, all bins that are not mentioned in the bin specification are masked, so the FPGA will not send any samples for those bins.

@mkhazraee
Copy link
Collaborator

mkhazraee commented Dec 4, 2021

Actually there is a python script that does this computation:
https://github.com/ucsdsysnet/sparsdr/blob/universal/examples/uhd_rx_compressed_cfile/fft_bin_calculator.py

Just update the 3 values for Pluto as mentioned in line 7. The input to the script is
capture center freq - band center - freq bandwidth
The idea is you give it the capture center frequency, and the center frequency of the band you want, with the width of the band. It will output the FFT bin ranges, and the actually frequencies that are going to be captured (after proper rounding).

If you want multiple bands, simply run it for different bands, and use them all for capture. (For reconstruct they should be processed separately).

We will soon incorporate this script into our GnuRadio module.

@tkpudgy
Copy link
Author

tkpudgy commented Dec 4, 2021

Thank you Sam and mkhazree. I understand the bin number to frequency translation now. Would you please elaborate on the "Shift amount" parameter and on what circumstances this needs to be adjusted? Another questions about the "Band x bins" parameter on the "SparSDR Reconstruct" block: Is my understanding correct in that this number is bigger than the number of bins specified in the Source block (i.e. 34) to ensure entire coverage of the bandwidth being captured? Thank you.

@mkhazraee
Copy link
Collaborator

mkhazraee commented Dec 5, 2021

  1. You can think of shift amount as a knob for digital gain.

When we do 1024 point FFT on 13-bit inputs, the output will be 13+10+1=24 bits. 13 bits assuming there is IQ imbalance correction causing one additional bit to 12-bit DAC, that 10 comes from stages and there is a corner overflow case that adds another bit. On the other hand we backhaul 16-bit values from Pluto. So we have to shift the outputs by 24-16=8 bits to the right keeping the most significant bits, which is the default shift value.

However this is the most conservative value possible. In practice that overflow never happens, as it requires perfect sine. Also the implementation on Pluto actually doesn't add any bits in the IQ imbalance step, so it stays at 12 bits (just wanted to be conservative for future designs as it barely changed the resource utilization). So choosing 6 instead of 8 is safe too. Now if you want to get digital gain, you can go for lower values. For example, if the receive antenna is not that close to the the transmitter the value 4-5 worked really nice for us, aka 2-4 times digital gain, on top of 4 times safe gain.

Note that the threshold is applied after the shift, on 16-bit values, so you should update the thresholds accordingly.

  1. In reconstruction we can decide the time-domain sample rate, irrespective on number of active bins.

One beauty of being in the frequency domain is that we can decide on the time-domain sample rate later. For example, each bin is 60KHz, and if I have 10 bins active, I'm not obliged to get an 600KHz time domain signal. Instead I can assume 40 bins of zero, and get 3MHz time domain signal. Generally we benefit from frequency domain sparsity, so based on the desired sample rate, we fill the rest of the non-active bins with 0 and then we perform the IFFT.

If there is a single band, number of reconstruct bins should be at least number of capture bins, not to lose any information, and can be more to get a nice time-domain sample rate to be fed to the decoder. If there are adjacent bins, let's say capturing 2 adjacent Bluetooth bands, actually we can give each 2MHz to a different reconstruct path, and fill each of them with extra zeros if we want a different sample rate, let's say that 3MHz as example above.

@tkpudgy
Copy link
Author

tkpudgy commented Dec 10, 2021

Thank you mkhazrazee. I have a better understanding of the shift amount and the flexibility to resample at a different rate going into time-domain.

As a first order demo, I would like to show my colleagues the advantage of using SparSDR by making the comparison of file size of saved data between SparSDR vs stock Pluto. Before heading in that direction, I thought I would experiment with SparSDR alone and show the file size difference when choosing a different threshold. This will demonstrate how SparSDR essentially chooses to keep signals that are significant, dictated by a threshold parameter. So for the BLE band we've been discussing so far, I varied the threshold from 100 to 50000. If my understanding is correct in that lower number for this parameter means lower threshold, I would expect to see a bigger file size for the saved data as more signals would be deemed significant. In fact for roughly about 25 seconds of data collection for each threshold, I saw 150 MB (100) vs 60 MB (50000). What puzzled me was the waterfall plot that I was seeing. Please see the snapshot I took in the attachment. I was expecting to see more sparse and muted plot for the threshold of 50000, and more noisy and intense plot for the 100. But it was the opposite. Any explanation you can provide would be helpful. Also, if you have a better and simple way to do setup a quick demo to show advantage of using SparSDR, I would much appreciate it. Thank you!
Threshold = 50000
threshold_50000

Threshold = 100
threshold_100

@samcrow
Copy link
Collaborator

samcrow commented Dec 11, 2021

Your understanding about the threshold is correct. The reason the waterfall graphs look like that is that when there is a time period with no signals, the reconstruction application does not produce any samples.

Let's look at an example: We capture a signal with a strong Bluetooth signal, a gap of 1 second where there are weak signals and background noise, and finally another strong Bluetooth signal at the end.

With a low threshold, the radio will receive and store the strong Bluetooth signals and the weak signals during the gap. When we reconstruct the signals, we will get approximately one second of weak signals in the gap between the two Bluetooth signals.

With a high threshold, the radio will receive and store the strong Bluetooth signals but ignore the weak signals between them. When we reconstruct the signals, the reconstruction software sees the first Bluetooth signal, a 1-second gap with nothing, and the second Bluetooth signal. Instead of filling the gap with 0 samples, the reconstruction software skips that time period. It reconstructs the two Bluetooth signals with no gap between them, so they look like they are consecutive in time.

In your example with the low threshold, the gaps between the strong signals are periods where there were weak signals. By increasing the threshold, you eliminated those weak-signal periods and the strong signals ended up compressed together in time. That makes the waterfall diagram more crowded, but if you look at the number of samples in your reconstructed files you should see significantly more samples from the lower threshold.

Let me know if you have other questions.

@mkhazraee
Copy link
Collaborator

Actually overlap-gaps branch is exactly to add filling zeros for such examples. Right now it only supports N210, but soon we will port it to Pluto too. Will let you know when it's done, shouldn't take long.

@samcrow
Copy link
Collaborator

samcrow commented Dec 11, 2021

The sparsdr_reconstruct application from the pluto-overlap-gaps branch now produces zero samples in the gaps, so it should work more like you expect.

@stevewillson
Copy link
Contributor

stevewillson commented Mar 9, 2023

I wanted to document this here for those that are setting the bin specification.

"Bin specification" parsing is done in compressing_source.cc

The string format in the "Bin specification" field is as follows:

BIN_1:THRESHOLD_VALUE_1,BIN_2:THRESHOLD_VALUE_2,...

Ex:
2:1000,44:500

This backhauls bin 2 with threshold value 1000 and bin 44 with threshold value 500.

or:

START_BIN_1..END_BIN_1:THRESHOLD_VALUE_1,START_BIN_1..END_BIN_1:THRESHOLD_VALUE_1,...

Ex:
2..4:1000,44..55:500

This backhauls bins 2-4 (inclusive) with threshold value 1000 and bins 44-55 (inclusive) with threshold value 500.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants