diff options
author | Johnathan Corgan <johnathan@corganlabs.com> | 2015-04-29 15:46:26 -0700 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2015-04-29 15:46:26 -0700 |
commit | 4bf227c02c6f4ae59f285510b8faaa1686163894 (patch) | |
tree | 210a130a3a897832450886da6822486ac90c256f | |
parent | 70fecd437b264984569f6a4531dd3b424aced781 (diff) | |
parent | efd2116fdf27892b93078be5b019b0d9bf3943aa (diff) |
Merge branch 'master' into next
-rw-r--r-- | cmake/Modules/GrSwig.cmake | 41 | ||||
-rw-r--r-- | docs/doxygen/other/msg_passing.dox | 40 | ||||
-rw-r--r-- | gnuradio-runtime/swig/gr_types.i | 20 | ||||
-rw-r--r-- | gr-blocks/include/gnuradio/blocks/peak_detector2_fb.h | 24 | ||||
-rw-r--r-- | grc/base/Block.py | 2 | ||||
-rw-r--r-- | grc/base/FlowGraph.py | 18 |
6 files changed, 108 insertions, 37 deletions
diff --git a/cmake/Modules/GrSwig.cmake b/cmake/Modules/GrSwig.cmake index abf4dc4612..ef3a76eb4c 100644 --- a/cmake/Modules/GrSwig.cmake +++ b/cmake/Modules/GrSwig.cmake @@ -105,17 +105,36 @@ endfunction(GR_SWIG_MAKE_DOCS) macro(GR_SWIG_MAKE name) set(ifiles ${ARGN}) - # Shimming this in here to take care of a SWIG bug with handling - # vector<size_t> and vector<unsigned int> (on 32-bit machines) and - # vector<long unsigned int> (on 64-bit machines). Use this to test - # the size of size_t, then set SIZE_T_32 if it's a 32-bit machine - # or not if it's 64-bit. The logic in gr_type.i handles the rest. - INCLUDE(CheckTypeSize) - CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T) - CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT) - if(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT}) - list(APPEND GR_SWIG_FLAGS -DSIZE_T_32) - endif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT}) + # Take care of a SWIG < 3.0 bug with handling std::vector<size_t>, + # by mapping to the correct sized type on the runtime system, one + # of "unsigned int", "unsigned long", or "unsigned long long". + # Compare the sizeof(size_t) with the sizeof the other types, and + # pick the first one in the list with the same sizeof. The logic + # in gnuradio-runtime/swig/gr_types.i handles the rest. It is + # probably not necessary to do this assignment all of the time, + # but it's easier to do it this way than to figure out the + # conditions when it is necessary -- and doing it this way won't + # hurt. This bug seems to have been fixed with SWIG >= 3.0, and + # mostly happens when not doing a native build (e.g., on Mac OS X + # when using a 64-bit CPU but building for 32-bit). + + if(SWIG_VERSION VERSION_LESS "3.0.0") + include(CheckTypeSize) + check_type_size("size_t" SIZEOF_SIZE_T) + check_type_size("unsigned int" SIZEOF_UINT) + check_type_size("unsigned long" SIZEOF_UL) + check_type_size("unsigned long long" SIZEOF_ULL) + + if(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT}) + list(APPEND GR_SWIG_FLAGS -DSIZE_T_UINT) + elseif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UL}) + list(APPEND GR_SWIG_FLAGS -DSIZE_T_UL) + elseif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_ULL}) + list(APPEND GR_SWIG_FLAGS -DSIZE_T_ULL) + else() + message(FATAL_ERROR "GrSwig: Unable to find replace for std::vector<size_t>; this should never happen!") + endif() + endif() #do swig doc generation if specified if(GR_SWIG_DOC_FILE) diff --git a/docs/doxygen/other/msg_passing.dox b/docs/doxygen/other/msg_passing.dox index df116c2ba1..494ca03921 100644 --- a/docs/doxygen/other/msg_passing.dox +++ b/docs/doxygen/other/msg_passing.dox @@ -311,4 +311,44 @@ file qa_pdu.py. There are some examples of using the message passing infrastructure through GRC in gr-blocks/examples/msg_passing. +\section msg_passing_commands Using messages as commands + +Messages can be used to send commands to blocks. Examples for this include: + +- gr::qtgui::freq_sink_c: The scaling of the frequency axis can be changed by messages +- gr::uhd::usrp_source and gr::uhd::usrp_sink: Many transceiver-related settings can + be manipulated through command messages, such as frequency, gain and LO offset +- gr::digital::header_payload_demux, which receives an acknowledgement from a header parser + block on how many payload items there are to process + +There is no special PMT type to encode commands, however, it is strongly recommended +to use one of the following formats: + +- pmt::cons(KEY, VALUE): This format is useful for commands that take a single value. + Think of KEY and VALUE as the argument name and value, respectively. For the case of + the QT GUI Frequency Sink, KEY would be "freq" and VALUE would be the new center frequency + in Hz. +- pmt::dict((KEY1: VALUE1), (KEY2: VALUE2), ...): This is basically the same as the + previous format, but you can provide multiple key/value pairs. This is particularly + useful when a single command takes multiple arguments which can't be broken into + multiple command messages (e.g., the USRP blocks might have both a timestamp and a + center frequency in a command message, which are closely associated). + +In both cases, all KEYs should be pmt::symbols (i.e. strings). VALUEs can be +whatever the block requires. + +It might be tempting to deviate from this format, e.g. the QT Frequency sink could +simply take a float value as a command message, and it would still work fine. +However, there are some very good reasons to stick to this format: + +- Interoperability: The more people use the standard format, the more likely it + is that blocks from different sources can work together +- Inspectability: A message debug block will display more useful information about + a message if its containing both a value and a key +- Intuition: This format is pretty versatile and unlikely to create situations + where it is not sufficient (especially considering that values are PMTs themselves). + As a counterexample, using positional arguments (something like "the first argument + is the frequency, the second the gain") is easily forgotten, or changed in one place + and not another, etc. + */ diff --git a/gnuradio-runtime/swig/gr_types.i b/gnuradio-runtime/swig/gr_types.i index 8ae953b904..e329a4ce9f 100644 --- a/gnuradio-runtime/swig/gr_types.i +++ b/gnuradio-runtime/swig/gr_types.i @@ -80,15 +80,19 @@ namespace std { %template(gr_vector_vector_complexf) std::vector< std::vector< std::complex<float> > >; %template(gr_vector_vector_complexd) std::vector< std::vector< std::complex<double> > >; -// Fix for Issue #529 -#ifdef SIZE_T_32 - // On 32-bit systems, whenever we see std::vector<size_t>, replace it - // with vector<unsigned int> +// Fix for Issue #529: replace std::vector<size_t> with its equivalent +// in element size, one of "unsigned int", "unsigned long", or +// "unsigned long long". The replacement depends on the sizeof each +// type, as determined in GrSwig.cmake GR_SWIG_MAKE. For SWIG >= +// 3.0.0, none of these will be defined because this issue seems to +// have been fixed. + +#if defined(SIZE_T_UINT) %apply std::vector<unsigned int> { std::vector<size_t> }; -#else - // On 64-bit systems, whenever we see std::vector<size_t>, replace it - // with vector<long unsigned int> - %apply std::vector<long unsigned int> { std::vector<size_t> }; +#elif defined(SIZE_T_UL) + %apply std::vector<unsigned long> { std::vector<size_t> }; +#elif defined(SIZE_T_ULL) + %apply std::vector<unsigned long long> { std::vector<size_t> }; #endif #endif /* SWIG_GR_TYPES_I */ diff --git a/gr-blocks/include/gnuradio/blocks/peak_detector2_fb.h b/gr-blocks/include/gnuradio/blocks/peak_detector2_fb.h index da2d9fc740..541dd8aa09 100644 --- a/gr-blocks/include/gnuradio/blocks/peak_detector2_fb.h +++ b/gr-blocks/include/gnuradio/blocks/peak_detector2_fb.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007,2013 Free Software Foundation, Inc. + * Copyright 2007,2013,2015 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -36,7 +36,7 @@ namespace gr { * \details * If a peak is detected, this block outputs a 1, or it outputs * 0's. A separate debug output may be connected, to view the - * internal EWMA described below. + * internal estimated mean described below. */ class BLOCKS_API peak_detector2_fb : virtual public sync_block { @@ -47,13 +47,21 @@ namespace gr { /*! * Build a peak detector block with float in, byte out. * - * \param threshold_factor_rise The threshold factor determins - * when a peak is present. An EWMA average of the signal is - * calculated and when the value of the signal goes over - * threshold_factor_rise*average, we call the peak. + * \param threshold_factor_rise The threshold factor determines + * when a peak is present. An average of the input signal + * is calculated (through a single-pole autoregressive + * filter) and when the value of the input signal goes + * over threshold_factor_rise*average, we assume we are + * in the neighborhood of a peak. The block will then + * find the position of the maximum within a window of + * look_ahead samples starting at the point where the + * threshold was crossed upwards. * \param look_ahead The look-ahead value is used when the - * threshold is found to locate the peak within this range. - * \param alpha The gain value of a single-pole moving average filter. + * threshold is crossed upwards to locate the peak within + * this range. + * \param alpha One minus the pole of a single-pole + * autoregressive filter that evaluates the average of + * the input signal. */ static sptr make(float threshold_factor_rise=7, int look_ahead=1000, float alpha=0.001); diff --git a/grc/base/Block.py b/grc/base/Block.py index afe326bbf4..b367e60e69 100644 --- a/grc/base/Block.py +++ b/grc/base/Block.py @@ -414,7 +414,7 @@ class Block(Element): """ n = odict() n['key'] = self.get_key() - n['param'] = map(lambda p: p.export_data(), self.get_params()) + n['param'] = map(lambda p: p.export_data(), sorted(self.get_params(), key=str)) if 'bus' in map(lambda a: a.get_type(), self.get_sinks()): n['bus_sink'] = str(1); if 'bus' in map(lambda a: a.get_type(), self.get_sources()): diff --git a/grc/base/FlowGraph.py b/grc/base/FlowGraph.py index fb25b46821..790aed07f6 100644 --- a/grc/base/FlowGraph.py +++ b/grc/base/FlowGraph.py @@ -126,13 +126,13 @@ class FlowGraph(Element): def get_block(self, id): return filter(lambda b: b.get_id() == id, self.get_blocks())[0] def get_blocks_unordered(self): return filter(lambda e: e.is_block(), self.get_elements()) def get_blocks(self): - blocks = self.get_blocks_unordered(); - for i in range(len(blocks)): - if blocks[i].get_key() == 'variable': - blk = blocks[i]; - blocks.remove(blk); - blocks.insert(1, blk); - return blocks; + # refactored the slow, ugly version + # don't know why we need this here, using it for sorted export_data() + return sorted(self.get_blocks_unordered(), key=lambda b: ( + b.get_key() != 'options', # options to the front + not b.get_key().startswith('variable'), # then vars + str(b) + )) def get_connections(self): return filter(lambda e: e.is_connection(), self.get_elements()) def get_children(self): return self.get_elements() def get_elements(self): @@ -250,8 +250,8 @@ class FlowGraph(Element): """ n = odict() n['timestamp'] = self._timestamp - n['block'] = [block.export_data() for block in self.get_blocks()] - n['connection'] = [connection.export_data() for connection in self.get_connections()] + n['block'] = [b.export_data() for b in self.get_blocks()] # already sorted + n['connection'] = [c.export_data() for c in sorted(self.get_connections(), key=str)] instructions = odict({ 'created': self.get_parent().get_version_short(), 'format': FLOW_GRAPH_FILE_FORMAT_VERSION, |