Peak_Detector2 stalls simulation

Stephan,

We have worked with this block and realized it has a bug (not just an
inefficient functionality).
This is easy to see if you consider what happens when the first time
work
is called, the threshold is passed,
a peak is found in item “i” and so “d_peak_ind” is set to “i”,
but there are less that d_lookahead_items to be processed.
Then suppose the second time the work is called, no other peak is found
and
d_lookahead_remaining goes to 0.
Then the output buffer will be accessed at:
“optr[d_peak_ind] = 1” which may not even be a valid access since the
value
of d_peak_ind was set to “i”
in the previous work call!

Anyway, I attach a fix to this (we were supposed to post it sooner on
the
list but got delayed by some other issues).
Please note that in this current form the functionality is a bit
different
than the one suggested in the manual, ie,
the peak finder ONLY looks ahead d_lookahead items from the point the
threshold is crossed, but it does not
reset this window every time a new peak is found within the window.
It should be pretty easy to do this as well…

Please let us know if you have any comments.

best
Achilleas

Hello Achilleas,

Thank you for your comments as well as your implementation. I very much
like the clear separation that in every call of work(.) only one state
is active.

Sorry, but I cannot follow your bug description. In line 110 (actual git
version, which do you use?), d_peak_ind = 1 is set in the case you
describe, right? During the first call, the function does not return
noutput_items as amount of processed samples, but only the amount up to
the peak’s index (-1). From my understanding of the scheduler, this
leaves the (noutput_items - d_peak_ind + 1) remaining samples in the
input buffer, and thus the first sample (index 0) in the next
work(.)-call should the one before the d_peak_ind of the previous call.
Since all output items are held back up to this sample, the optr[.]=1
should come at the right position. But I am not sure about that,
especially not about how the scheduler handle the case, if the output
vector is longer than the return value of work(.). Hence my question
about the (to me) unknown behavior of the scheduler in my original post.

But I think, it is even worse! In the case you describe (look_ahed does
not count down to 0 in the very same run of work(.) like the peak), in a
second call of work(.) all samples from the triggering value on (“old
values”) are reconsidered. The old values decreased
d_look_ahead_remaining in the first call and now decrease this variable
again, hence twice.

And there is another bug in the original: If you have a single value
above the threshold (within look_ahead), the very next sample is
indicated being the peak. This is because d_peak_ind is not set in the
if-case// above threshold. Your code circumvents this bug, because
triggering value is reconsidered in work(.), if in look_ahead mode.

Meanwhile, I implemented another peak_search (attached), which also has
a period of being quiet after a detected peak. I.e., if look_ahead
passed, no peak is searched until a given amount of samples passed. This
is quite handy, if you have a fixed preamble/data structure. I think, I
will combine both of our approaches.

Just in case other users might want to use your block, I add some notes
on the behavior of your code:

  1. The average is updated with the first sample above the threshold

  2. As with the original, the average value is not updated during the
    look_ahead phase

  3. The threshold is as given in the documentation as
    avgthreshold_factor_rise (the original is inconsistent with doc as
    avg
    (1+threshold_factor_rise) )
    @Martin/Tom/Marcus: How should we handle this? I prefer changing code,
    since this parallels my intuition of a threshold_factor, but this will
    change behavior. Else adapt doc to actual code.

  4. Concerning your (@Achilleas) comment on look_ahead not being reset on
    finding a new max value: The original does not reset look_ahead in such
    a case either. But in which documentation did you find a comment on
    that? I only have
    GNU Radio Manual and C++ API Reference: gr::blocks::peak_detector2_fb Class Reference

PS: Thanks for your great book, Achilleas. It helped me a lot with my
PhD on CPM comm. over non-coherent doubly-selective fading channels. The
first chapters show a very clear and concise general concept of
detection. I wish, I had found that earlier.

Best regards

Stephan Ludwig

Robert Bosch GmbH
Corporate Sector Research & Advance Engineering, Communication
Technology (CR/AEH4)
Renningen
70465 Stuttgart
GERMANY

Tel. +49(711)811-8809
Fax +49(711)811-1052
Mobile +49(172)5630639
[email protected]

Registered Office: Stuttgart, Registration Court: Amtsgericht Stuttgart,
HRB 14000;
Chairman of the Supervisory Board: Franz Fehrenbach; Managing Directors:
Dr. Volkmar Denner,
Dr. Stefan Asenkerschbaumer, Dr. Rolf Bulander, Dr. Stefan Hartung, Dr.
Dirk Hoheisel, Christoph Kübel,
Uwe Raschke, Wolf-Henning Scheider, Dr. Werner Struth, Peter Tyroller
Von: [email protected]
[mailto:[email protected]] Im Auftrag von Achilleas
Anastasopoulos
Gesendet: Samstag, 3. Januar 2015 00:35
An: Ludwig Stephan (CR/AEH4); [email protected]
Betreff: [Discuss-gnuradio] Peak_Detector2 stalls simulation

Stephan,
We have worked with this block and realized it has a bug (not just an
inefficient functionality).
This is easy to see if you consider what happens when the first time
work is called, the threshold is passed,
a peak is found in item “i” and so “d_peak_ind” is set to “i”,
but there are less that d_lookahead_items to be processed.
Then suppose the second time the work is called, no other peak is found
and d_lookahead_remaining goes to 0.
Then the output buffer will be accessed at:
“optr[d_peak_ind] = 1” which may not even be a valid access since the
value of d_peak_ind was set to “i”
in the previous work call!
Anyway, I attach a fix to this (we were supposed to post it sooner on
the list but got delayed by some other issues).
Please note that in this current form the functionality is a bit
different than the one suggested in the manual, ie,
the peak finder ONLY looks ahead d_lookahead items from the point the
threshold is crossed, but it does not
reset this window every time a new peak is found within the window.
It should be pretty easy to do this as well…
Please let us know if you have any comments.

best
Achilleas