Hi Jeff,
Thank you very much, all this time I didn't realize.
Now I have the following error:/Warning: failed to XInitThreads()//
//thread[thread-per-block[0]: <block sig_source(5)>]: *pmt_car:
wrong_type : ampl",*/
there is something bad with the red marked line (below) , but according
to what is explained in the wiki that' s how commands should be encoded.
And the doc said that the key for the amplitude is "ampl"
Please could you review the line marked in red and tell me what is wrong?
class messageGenerator(gr.sync_block):
def __init__(self, msg=1):
gr.sync_block.__init__(
self,
name="message generator",
in_sig=None,
out_sig=None
)
self.message_port_register_out(pmt.intern('out_port'))
self.msg = msg
self.finished = False
self.thread = None
def start(self):
self.finished = False
self.thread = Thread(target=self.run, args=(self.msg, ),
daemon=True)
self.thread.start()
return True
def stop(self):
self.finished = True
self.thread.stop()
self.thread.join()
return True
def run(self, data):
while(self.finished == False):
msgToSend = pmt.cons(pmt.intern("ampl"), pmt.from_double(data))
self.message_port_pub(pmt.intern('out_port'), msgToSend)
time.sleep (1)
return (1)
m=messageGenerator(3)
m.start()
On 2021-12-06 5:14 p.m., Jeff Long wrote:
It is message_port_pub, not msg_port_pub, if that helps.
On Mon, Dec 6, 2021 at 4:48 PM Michelle <[email protected]
<mailto:[email protected]>> wrote:
Good evening,
I wonder where the function *msg_port_pub* is defined, I do not
find it anywhere.
I ask because the error "/can't interpret source code:
'messageGenerator' object has no attribute 'msg_port_pub'/**"
persists. I have implemented a handler that calls the function
but it doesn't fix the issue. So I would like to try 2 things:
1) define the original function in my embedded python block and
invoke it. And if it doesn't work,
2) invoke the original C++ function with pybinds.
Thanks you and have a nice evening.
On 2021-12-01 11:26 a.m., Michelle wrote:
Good morning Jeff,
I didn't write you yesterday because the code doesn't work yet as
I want and I was trying to understand why. I don't have any error
message but when I execute my flowgraph the value of the
amplitude doesn't change and I have the warning "failed to
XInitThreads()".I have almost always this warning in gnuradio so
it does not worry me for the moment. below is my code:
from gnuradio import gr, blocks
from threading import Thread
import pmt
import numpy
import time
class messageGenerator(gr.sync_block):
def __init__(self, msg=1, period=1):
# calling init of a parent class
gr.sync_block.__init__(
self,
name="message generator",
in_sig=None,
out_sig=None
)
d_port =
self.message_port_register_out(pmt.intern('out_port'))
self.msg = msg
self.period = period
self.finished = False
def start(self):
self.finished = False
a_thread = Thread(target = self.run, args =(self.msg, ))
return True
def stop(self):
self.finished = True
#a_thread.stop()
#a_thread.join()
return True
def run(self, data):
msgToSend = pmt.cons(pmt.intern("ampl"),
pmt.from_double(data))
self.msg_port_pub(d_port, msgToSend)
time.sleep (period)
return (1)
m = messageGenerator(3,1)
m.start()
m.stop()
When I compare your code with mine I realize some of my mistakes:
1) in the start() function I don't start the thread. It is
necessary to add thread.start()
2) same error in the stop function.
3) thread must be an attribute. This answers a problem I had when
I tried to stop and join the thread in the stop function.
I'll try it all and get back to you.
thank you!
On 2021-11-30 4:14 p.m., Jeff Long wrote:
Ha! No, not emailing myself, just a user who was replying
directly. But to continue my conversation (hopefully with the
OP), here is some working code. It does a print() because I
didn't get around to actually sending a pmt as a message, but
you get the idea. Picture of flowgraph attached.
import threading
import time
import numpy as np
from gnuradio import gr
import pmt
class blk(gr.sync_block):
def __init__(self, val=0):
gr.sync_block.__init__(
self,
name='Show Value',
in_sig=[],
out_sig=[]
)
self.message_port_register_out(pmt.intern("msgout"))
self.val = val
self.thread = None
print('init')
def start(self):
print('start')
self.stopit = False
self.thread = threading.Thread(target=self.run, daemon=True)
self.thread.start()
return True
def stop(self):
print('stop')
self.stopit = True
self.thread.join()
return True
def set_val(self, val):
self.val = val
def run(self):
while(not self.stopit):
print(f'val={self.val} (would send as message)')
time.sleep(1)
On Tue, Nov 30, 2021 at 2:13 AM Marcin Puchlik
<[email protected] <mailto:[email protected]>>
wrote:
Jeff,
Are you mailing with yourself?
wt., 30 lis 2021 o 00:46 Jeff Long <[email protected]
<mailto:[email protected]>> napisał(a):
Sounds good. Only look at the C++ to figure out the
general idea. I'd learn Python threading first in a
standalone program so you're not learning (debugging) GR
and python threading at the same time. Good luck - let
us know how it goes.
Also, please respond to the mailing list so everyone can
benefit from the conversation.
On Mon, Nov 29, 2021 at 5:11 PM Michelle
<[email protected]
<mailto:[email protected]>> wrote:
Hi Jeff,
thank you for your help and sorry for the delay, I
was in class.
it is now that I start to work on it. My first step
is to master how the c++ code of the strobe message
block work, specially the functions:
-bool message_strobe_impl::start()
-bool message_strobe_impl::stop()
-void message_strobe_impl::run()
Then I will implement the python version following
your advice. I will write to you to show you the result.
Once again thank you, I was really lost.
Have a good afternoon.
OK, it does work, as long as there is a message
port defined and connected in a flowgraph. I was
trying too simple an example. You would do your
thread management in the start() and stop() functions.
"""
Embedded Python Blocks:
Each time this file is saved, GRC will instantiate
the first class it finds
to get ports and parameters of your block. The
arguments to __init__ will
be the parameters. All of them are required to have
default values!
"""
import numpy as np
from gnuradio import gr
import pmt
class blk(gr.sync_block): # other base classes are
basic_block, decim_block, interp_block
"""Embedded Python Block example - a simple
multiply const"""
def __init__(self): # only default arguments here
"""arguments to this function show up as
parameters in GRC"""
gr.sync_block.__init__(
self,
name='Embedded Python Block', # will
show up in GRC
in_sig=[],
out_sig=[]
)
self.message_port_register_out(pmt.intern("msgout"))
print('init')
def start(self):
print('start')
return True
def stop(self):
print('stop')
return True
On Mon, Nov 29, 2021 at 2:13 PM Jeff Long
<[email protected] <mailto:[email protected]>>
wrote:
Issue submitted:
https://github.com/gnuradio/gnuradio/issues/5358
<https://github.com/gnuradio/gnuradio/issues/5358>
On Mon, Nov 29, 2021 at 1:58 PM Jeff Long
<[email protected]
<mailto:[email protected]>> wrote:
It does not seem that python blocks can
override start() and stop(), which they
should be able to do. So, don't go too far
down that path. I do not see anywhere in
the code where this is used or would have
been caught.
The embedded blocks are easier, be beware
that GRC calls the init function to learn
about the block. Therefore, you don't want
any action taken as a result of a call to
init, for instance spawning a thread and
starting to send messages. Embedded python
block are sort of a toy that turned out to
be useful. In general, an OOT is a better
idea, but an embedded block can work if
it's simple enough.
Maybe someone else has figured this out.
With just a quick look, I don't see how a
Message Strobe kind of block can be
implemented in python without start() and
stop().
Here's kind of a hack: make a python block
with a message handler that gets a periodic
strobe from the existing Message Strobe
block. In the handler, send out the message
that you would have sent in the thread.