Trouble creating simple custom Sink (Python): Unable to coerce endpoint

I’d like to implement a simple custom sink block in Python.

AFAIK, a sink is a 1:0 basic block, with one input port, and no output
port.

I define it as a class:

class MySink(gr.basic_block):
def init(self, src_block):
gr.basic_block.init(self, name=‘MySink’,
in_sig=[numpy.float32],
out_sig=None)
gr.top_block().connect(src_block, self)

Then, in the top block constructor:
# …
self.gsm_fcch_detector_0 = grgsm.fcch_detector(4)
# Line bellow raises an ‘Unable to coerce endpoint’ exception
self.my_sink = MySink(self.gsm_fcch_detector_0)

As you may already have guessed, I’m a newcomer here, and I’m sure I
miss something obvious.
I thought the connect line should wire the FCCH detector output port to
my custom sink input port, but instead it raises an exception.

I will really appreciate any direction, as I’m a bit stuck here: could
someone point me toward what I clearly misunderstand ?

Thanks in advance.

Hi M4RL0V,

a sink is typically built as a sync block, simply because it’s easier
(and still works), since you don’t have to implement a general_work (and
a forecast).

So your problem here is that logically, connecting happens in the
top_block, not in the block itself; have a look at python code that the
GNU Radio Companion generates when connecting two blocks. It simply
happens outside any constructor as tb.connect(source,sink).

Generally, I don’t know whether that actually is the problem here. You
forgot to actually include information on what goes wrong, and any
relevant errors (if any). It’s hard to help you like this :slight_smile: Here’s a
link having a few tips on how to ask good questions on the mailing list:
https://gnuradio.org/redmine/projects/gnuradio/wiki/ReportingErrors

Best regards,
Marcus

Marcus, Thank you for your answer.

a sink is typically built as a sync block, simply because it’s easier
(and still works), since you don’t have to implement a general_work (and
a forecast).

Actually, I do not override general_work() neither forecast(), but only
work(), with signature:
work(self, input_items, output_items)

Though the default forecast() implementation (1 input -> 1 output) may
be wrong for me (as I don’t have any output), and my work function does
not call consume(), I do not think this may cause the error, since the
ValueError(“Unable to coerce endpoint”) exception raises at:
self.connect((self.gsm_fcch_detector_0,0) , (self.my_sink, 0))

I assume self.gsm_fcch_detector_0 is properly initialized, as when I
substitute the code bellow, it works as expected:
self.connect((self.gsm_fcch_detector_0, 0), (self.blocks_tag_debug_0,
0))
where blocks_tag_debug_0 is of type gr.blocks.tag_debug.

Following your suggestion, I updated my code to inherit from sync_block
rather than basic_block:
class MySink(gr.sync_block):
def init(self) gr.sync_block.init(self, name=‘MySink’,
in_sig=[numpy.float32], out_sig=None)

In my understanding, this should define a sink block with a single input
port with item size float32, and no output port. But still the same
error.

< So your problem here is that logically, connecting happens in the
< top_block, not in the block itself; have a look at python code that
the
< GNU Radio Companion generates when connecting two blocks. It simply
< happens outside any constructor as tb.connect(source,sink).

I use GNU radio 3.7, and companion generates Python scripts which
initialize the whole flow graph in the top block constructor, that
contains sections for Parameters and Variables, then Blocks, and then
Connections. The main() function only instantiates and
starts/stops/waits the top block (no connection happen here for me).
I still tried to call connect() from the main() function rather than
from the top block constructor, the error is identical.

< Generally, I don’t know whether that actually is the problem here. You
< forgot to actually include information on what goes wrong, and any
< relevant errors (if any). It’s hard to help you like this :slight_smile:

I’m not sure I can tell you more that this: connecting an input to my
stupid sink raises ValueError(“Unable to coerce endpoint”).
Bellow is the console output:

gr-osmosdr v0.1.4-48-g86ad5842 (0.1.5git) gnuradio 3.7.7.1
built-in source types: file fcd rtl_tcp bladerf rfspace
Opening nuand bladeRF with device identifier string: “*:instance=0”
Serial # 23a1…fec4
FW v1.8.0 FPGA v0.3.3
[INFO @ bladerf.c:648] Clamping bandwidth to 1500000Hz
Using Volk machine: avx_64_mmx_orc
Traceback (most recent call last):
File “./fcch_block.py”, line 101, in
tb = fcch_block(ppm=options.ppm, fc=options.fc)
File “./fcch_block.py”, line 65, in init
self.connect((self.gsm_fcch_detector_0,0) , (self.my_sink, 0))
File
“/rand/platform/gnuradio-3.7.7.1/lib/python2.7/dist-packages/gnuradio/gr/hier_block2.py”,
line 48, in wrapped
raise ValueError(“Unable to coerce endpoint”)
ValueError: Unable to coerce endpoint

I understand the runtime complains that the (self.my_sink,0) port is not
defined (can not be coerced), and thus can’t connect to the source
output port, though I assumed providing the appropriate input I/O
signature to the sink block’s constructor should achieve its input
port’s “registration”.

Thanks again for your kind help.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs