gr-dvbs2rx
gr-dvbs2rx copied to clipboard
the plutosdr integer check is errorneous
Problem
Passing 2e5
as sampling rate does not convert the float
to an int
, thus failing to initialize the plutosdr source:
$ dvbs2-rx --samp-rate 2e5 --source plutosdr --plutosdr-addr 192.168.2.1
log :info: Starting DVB-S2 Rx
Traceback (most recent call last):
File "/nix/store/ndymc3sszvcnsps8p1skmj7ww88izg17-gr-dvbs2rx-1.4.0/bin/.dvbs2-rx-wrapped", line 1631, in <module>
main()
File "/nix/store/ndymc3sszvcnsps8p1skmj7ww88izg17-gr-dvbs2rx-1.4.0/bin/.dvbs2-rx-wrapped", line 1587, in main
tb = DVBS2RxTopBlock(options)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/ndymc3sszvcnsps8p1skmj7ww88izg17-gr-dvbs2rx-1.4.0/bin/.dvbs2-rx-wrapped", line 156, in __init__
source_block = self.connect_source()
^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/ndymc3sszvcnsps8p1skmj7ww88izg17-gr-dvbs2rx-1.4.0/bin/.dvbs2-rx-wrapped", line 755, in connect_source
source = self.setup_plutosdr_source()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/ndymc3sszvcnsps8p1skmj7ww88izg17-gr-dvbs2rx-1.4.0/bin/.dvbs2-rx-wrapped", line 665, in setup_plutosdr_source
iio_pluto_source.set_samplerate(self.samp_rate)
TypeError: set_samplerate(): incompatible function arguments. The following argument types are supported:
1. (self: gnuradio.iio.iio_python.fmcomms2_source_fc32, samplerate: int) -> None
Invoked with: <gnuradio.iio.iio_python.fmcomms2_source_fc32 object at 0x7f1abfe218f0>, 200000.0
However, using an actual floating point value as sampling rate does trigger the plutosdr float to integer magic:
$ dvbs2-rx --samp-rate 200000.5 --source plutosdr --plutosdr-addr 192.168.2.1
log :info: Starting DVB-S2 Rx
log :warning: An integer sample rate is required by the PlutoSDR. Setting rate to 200000 samples/sec.
log :warning: The OOT symbol synchronizer requires an even integer sps >= 2 (current sps=0.2000005)
log :info: Switching to the in-tree symbol synchronizer
Traceback (most recent call last):
File "/nix/store/ndymc3sszvcnsps8p1skmj7ww88izg17-gr-dvbs2rx-1.4.0/bin/.dvbs2-rx-wrapped", line 1631, in <module>
main()
File "/nix/store/ndymc3sszvcnsps8p1skmj7ww88izg17-gr-dvbs2rx-1.4.0/bin/.dvbs2-rx-wrapped", line 1587, in main
tb = DVBS2RxTopBlock(options)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/ndymc3sszvcnsps8p1skmj7ww88izg17-gr-dvbs2rx-1.4.0/bin/.dvbs2-rx-wrapped", line 160, in __init__
self.connect_dvbs2rx(source_block, sink_block)
File "/nix/store/ndymc3sszvcnsps8p1skmj7ww88izg17-gr-dvbs2rx-1.4.0/bin/.dvbs2-rx-wrapped", line 912, in connect_dvbs2rx
symbol_sync = digital.symbol_sync_cc(
^^^^^^^^^^^^^^^^^^^^^^^
IndexError: nominal samples per symbol must be > 1
(Ignore the following crash, this is likely related to having a weird sampling rate)
Cause
The reason for this is an error in the business logic. The conditional responsible for the conversion
https://github.com/igorauad/gr-dvbs2rx/blob/c22b350912f31d87e397ef3ff470ac81cef943e0/apps/dvbs2-rx#L146
uses pythons float.is_integer()
method to check, if the sampling rate is already and integer value, and only converts if it is not integer. However, aforementioned function does not check the value type, but rather if the float has no digits other than 0
behind the decimal:
Return True if the float instance is finite with integral value, and False otherwise:
Therefore, the float
2e5
will not be converted to an integer type, because it already is re-presentable as an integer type (having no relevant decimal digits). However, the plutosdr checks the actual data type to be int.
Solutions
Solution one: fix conditional to check value type
Actually check the type: http://docs.python.org/library/functions.html#isinstance
if self.source == 'plutosdr' and isinstance(self.samp_rate, float):
# ...
Solution two: just omit the type check
Let's be real; converting one float to an integer when running on the plutosdr is not such a costly operation that one should make it conditional/on demand. Doing such micro-optimizations is prone to introduce bugs, like, it just did! So ditch the secondary check, always convert to int
if running on plutosdr
:
if self.source == 'plutosdr':
# ...
Thanks
Thanks to @C4H6O6U for helping me discover and understand this bug!