From d6a0093973eea5994346d939e6ea74c90c887217 Mon Sep 17 00:00:00 2001 From: caoziyi Date: Wed, 10 Apr 2024 23:05:09 +0800 Subject: [PATCH 1/4] Changes to be committed: modified: CMakeLists.txt modified: README.md modified: cmake/Modules/gnuradio-radarConfig.cmake modified: lib/CMakeLists.txt modified: lib/scatter_plot.h modified: python/radar/CMakeLists.txt modified: python/radar/__init__.py modified: python/radar/bindings/CMakeLists.txt new file: python/radar/bindings/bind_oot_file.py modified: python/radar/bindings/python_bindings.cc --- CMakeLists.txt | 6 +- README.md | 4 +- cmake/Modules/gnuradio-radarConfig.cmake | 17 +- .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1983 bytes .../doxyxml/__pycache__/base.cpython-310.pyc | Bin 0 -> 6048 bytes .../__pycache__/doxyindex.cpython-310.pyc | Bin 0 -> 8496 bytes .../doxyxml/__pycache__/text.cpython-310.pyc | Bin 0 -> 1257 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 395 bytes .../__pycache__/compound.cpython-310.pyc | Bin 0 -> 21004 bytes .../__pycache__/compoundsuper.cpython-310.pyc | Bin 0 -> 245705 bytes .../__pycache__/index.cpython-310.pyc | Bin 0 -> 2346 bytes .../__pycache__/indexsuper.cpython-310.pyc | Bin 0 -> 17798 bytes examples/tests/test_find_max_peak_c.py | 193 ++++++++++++++++++ include/gnuradio/radar/CMakeLists.txt | 56 +++++ include/gnuradio/radar/api.h | 34 +++ include/gnuradio/radar/crop_matrix_vcvc.h | 66 ++++++ include/gnuradio/radar/estimator_cw.h | 60 ++++++ include/gnuradio/radar/estimator_fmcw.h | 73 +++++++ include/gnuradio/radar/estimator_fsk.h | 64 ++++++ include/gnuradio/radar/estimator_ofdm.h | 79 +++++++ include/gnuradio/radar/estimator_rcs.h | 95 +++++++++ .../gnuradio/radar/estimator_sync_pulse_c.h | 66 ++++++ include/gnuradio/radar/find_max_peak_c.h | 79 +++++++ include/gnuradio/radar/msg_gate.h | 65 ++++++ include/gnuradio/radar/msg_manipulator.h | 67 ++++++ .../radar/ofdm_cyclic_prefix_remover_cvc.h | 63 ++++++ include/gnuradio/radar/ofdm_divide_vcvc.h | 70 +++++++ include/gnuradio/radar/os_cfar_2d_vc.h | 83 ++++++++ include/gnuradio/radar/os_cfar_c.h | 82 ++++++++ include/gnuradio/radar/print_results.h | 61 ++++++ include/gnuradio/radar/qtgui_scatter_plot.h | 72 +++++++ .../gnuradio/radar/qtgui_spectrogram_plot.h | 79 +++++++ include/gnuradio/radar/qtgui_time_plot.h | 69 +++++++ .../gnuradio/radar/signal_generator_cw_c.h | 66 ++++++ .../gnuradio/radar/signal_generator_fmcw_c.h | 75 +++++++ .../gnuradio/radar/signal_generator_fsk_c.h | 72 +++++++ .../radar/signal_generator_sync_pulse_c.h | 72 +++++++ include/gnuradio/radar/split_cc.h | 64 ++++++ include/gnuradio/radar/split_fsk_cc.h | 63 ++++++ .../radar/static_target_simulator_cc.h | 143 +++++++++++++ .../gnuradio/radar/tracking_singletarget.h | 79 +++++++ .../gnuradio/radar/transpose_matrix_vcvc.h | 63 ++++++ include/gnuradio/radar/trigger_command.h | 69 +++++++ include/gnuradio/radar/ts_fft_cc.h | 60 ++++++ include/gnuradio/radar/usrp_echotimer_cc.h | 79 +++++++ lib/CMakeLists.txt | 7 +- lib/scatter_plot.h | 1 + python/radar/CMakeLists.txt | 2 +- python/radar/__init__.py | 3 +- python/radar/bindings/CMakeLists.txt | 8 + python/radar/bindings/bind_oot_file.py | 58 ++++++ python/radar/bindings/python_bindings.cc | 68 +++--- 52 files changed, 2606 insertions(+), 49 deletions(-) create mode 100644 docs/doxygen/doxyxml/__pycache__/__init__.cpython-310.pyc create mode 100644 docs/doxygen/doxyxml/__pycache__/base.cpython-310.pyc create mode 100644 docs/doxygen/doxyxml/__pycache__/doxyindex.cpython-310.pyc create mode 100644 docs/doxygen/doxyxml/__pycache__/text.cpython-310.pyc create mode 100644 docs/doxygen/doxyxml/generated/__pycache__/__init__.cpython-310.pyc create mode 100644 docs/doxygen/doxyxml/generated/__pycache__/compound.cpython-310.pyc create mode 100644 docs/doxygen/doxyxml/generated/__pycache__/compoundsuper.cpython-310.pyc create mode 100644 docs/doxygen/doxyxml/generated/__pycache__/index.cpython-310.pyc create mode 100644 docs/doxygen/doxyxml/generated/__pycache__/indexsuper.cpython-310.pyc create mode 100755 examples/tests/test_find_max_peak_c.py create mode 100644 include/gnuradio/radar/CMakeLists.txt create mode 100644 include/gnuradio/radar/api.h create mode 100644 include/gnuradio/radar/crop_matrix_vcvc.h create mode 100644 include/gnuradio/radar/estimator_cw.h create mode 100644 include/gnuradio/radar/estimator_fmcw.h create mode 100644 include/gnuradio/radar/estimator_fsk.h create mode 100644 include/gnuradio/radar/estimator_ofdm.h create mode 100644 include/gnuradio/radar/estimator_rcs.h create mode 100644 include/gnuradio/radar/estimator_sync_pulse_c.h create mode 100644 include/gnuradio/radar/find_max_peak_c.h create mode 100644 include/gnuradio/radar/msg_gate.h create mode 100644 include/gnuradio/radar/msg_manipulator.h create mode 100644 include/gnuradio/radar/ofdm_cyclic_prefix_remover_cvc.h create mode 100644 include/gnuradio/radar/ofdm_divide_vcvc.h create mode 100644 include/gnuradio/radar/os_cfar_2d_vc.h create mode 100644 include/gnuradio/radar/os_cfar_c.h create mode 100644 include/gnuradio/radar/print_results.h create mode 100644 include/gnuradio/radar/qtgui_scatter_plot.h create mode 100644 include/gnuradio/radar/qtgui_spectrogram_plot.h create mode 100644 include/gnuradio/radar/qtgui_time_plot.h create mode 100644 include/gnuradio/radar/signal_generator_cw_c.h create mode 100644 include/gnuradio/radar/signal_generator_fmcw_c.h create mode 100644 include/gnuradio/radar/signal_generator_fsk_c.h create mode 100644 include/gnuradio/radar/signal_generator_sync_pulse_c.h create mode 100644 include/gnuradio/radar/split_cc.h create mode 100644 include/gnuradio/radar/split_fsk_cc.h create mode 100644 include/gnuradio/radar/static_target_simulator_cc.h create mode 100644 include/gnuradio/radar/tracking_singletarget.h create mode 100644 include/gnuradio/radar/transpose_matrix_vcvc.h create mode 100644 include/gnuradio/radar/trigger_command.h create mode 100644 include/gnuradio/radar/ts_fft_cc.h create mode 100644 include/gnuradio/radar/usrp_echotimer_cc.h create mode 100644 python/radar/bindings/bind_oot_file.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 86b11fb5..72175417 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") # Make sure our local CMake Modules path comes first list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) # Find gnuradio to get access to the cmake modules -find_package(Gnuradio REQUIRED) +find_package(Gnuradio "3.10" REQUIRED) # Set the version information here set(VERSION_MAJOR 1) @@ -74,7 +74,7 @@ if(NOT CMAKE_MODULES_DIR) set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) endif(NOT CMAKE_MODULES_DIR) -set(GR_INCLUDE_DIR include/radar) +set(GR_INCLUDE_DIR include/gnuradio/radar) set(GR_CMAKE_DIR ${CMAKE_MODULES_DIR}/gnuradio-radar) set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME}) set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME}) @@ -132,7 +132,7 @@ add_custom_target(uninstall ######################################################################## # Add subdirectories ######################################################################## -add_subdirectory(include/radar) +add_subdirectory(include/gnuradio/radar) add_subdirectory(lib) add_subdirectory(apps) add_subdirectory(docs) diff --git a/README.md b/README.md index 8805d2ae..9b3af93e 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,9 @@ For full documentation build the toolbox and open `build/docs/doxygen/html/index **Development platform** -GNU Radio maint-3.8 +GNU Radio maint-3.10 UHD 3.15 -Ubuntu 18.04 +Ubuntu 22.04 **Dependencies** Qt 5.10.1 diff --git a/cmake/Modules/gnuradio-radarConfig.cmake b/cmake/Modules/gnuradio-radarConfig.cmake index ab0f4354..6c3d2e7a 100644 --- a/cmake/Modules/gnuradio-radarConfig.cmake +++ b/cmake/Modules/gnuradio-radarConfig.cmake @@ -1,9 +1,10 @@ -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_RADAR radar) +find_package(PkgConfig) + +PKG_CHECK_MODULES(PC_GR_RADAR gnuradio-radar) FIND_PATH( - RADAR_INCLUDE_DIRS - NAMES radar/api.h + GR_RADAR_INCLUDE_DIRS + NAMES gnuradio/radar/api.h HINTS $ENV{RADAR_DIR}/include ${PC_RADAR_INCLUDEDIR} PATHS ${CMAKE_INSTALL_PREFIX}/include @@ -12,7 +13,7 @@ FIND_PATH( ) FIND_LIBRARY( - RADAR_LIBRARIES + GR_RADAR_LIBRARIES NAMES gnuradio-radar HINTS $ENV{RADAR_DIR}/lib ${PC_RADAR_LIBDIR} @@ -24,8 +25,8 @@ FIND_LIBRARY( /usr/lib64 ) -include("${CMAKE_CURRENT_LIST_DIR}/radarTarget.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/gnuradio-radarTarget.cmake") INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(RADAR DEFAULT_MSG RADAR_LIBRARIES RADAR_INCLUDE_DIRS) -MARK_AS_ADVANCED(RADAR_LIBRARIES RADAR_INCLUDE_DIRS) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GR_RADAR DEFAULT_MSG GR_RADAR_LIBRARIES GR_RADAR_INCLUDE_DIRS) +MARK_AS_ADVANCED(GR_RADAR_LIBRARIES GR_RADAR_INCLUDE_DIRS) diff --git a/docs/doxygen/doxyxml/__pycache__/__init__.cpython-310.pyc b/docs/doxygen/doxyxml/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1cc18f70a1552956bc12e338dff3c4fa68305acd GIT binary patch literal 1983 zcma)7O>ZML7@nDYO=epJ2nq3Vuoj_Y)NOL%1WQFJ+ttF7U8#FYRaws1N!*U@k?pA( zl%C2D=^pt5T)FcT=E`aR0vCAgne;;oh>7Cy$NTxbkKa+-+erY=&ab~Q(+h$>+~V#N z!QvbEn+XgwmlxZ|q+KV0R>>wg((%9bxA50U= zsP_aGDZ~Vl+-xj>!@a#d^ci|dw5fe|(f4 zOq1j(vxuOa8;E6&NS*_(#cs~dS&r1~lw}qI_BIL)*bk2d6C)p3>LG%q%b)TQ%w|kO zpb*`0IoK!koanQ`BUBDZJzrraRk>LDJwdn}oHPM|+j%K7SFZo-j!T?D85T;fhAy+i zM!#|YUoH=pEIUIS(v?k)2&z|TW`HwIwvf=07+fbcyiF%fUg?rGpxzfbJZvJ8%oxu*4}zaH*!a0a{I2AQuduUr zuNJj(`Zo4SIe1apq68pZFFEHHz;6s9;~J5%9Pa)gN#2CeBh!A>zqyaq)?EVE2hcl+ zsHX=xF{X;W3>2-}cC!ia$rR8BYni87l|_|!8Q_Ja_4W%0MrYvf=IO!=+G%hAfAc*I z(5ZtwxD3|8X?Pvk)>S~GkAm0XWw;J$>%-tOvh8(r6<)U1t?LeL!%2JHKJ7w>cACA* z&bo6QzYdOqv@>}F27@ZzG^(Gr@Aaap*FX;0N6J)f*SxA;)9I>S)9SSQnpDXx@YQ>7 zaUHZ&=9p6T+$a=HyZRmPeA5c6c+=*pi1Mlh)zBY+#4myV7+!yVFk5O;J&&yCS41`*av@S_yk0%_%R?* X=4{V#%WT2W?mrsEt#~U5+kgEHvqx-p literal 0 HcmV?d00001 diff --git a/docs/doxygen/doxyxml/__pycache__/base.cpython-310.pyc b/docs/doxygen/doxyxml/__pycache__/base.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7a12ec08e013d8b9dae373a39011e580df8421a GIT binary patch literal 6048 zcma)A&2!tv6~`_>5CkPzaxD2H{y-8t3GG;N;%U;RYMKu_owf;^sWVBVP6md#kVJ+g z=mq3h9IBIvoT+=rp{L$5QV*T+AJ86pXlHuqq5lD{J>{HRJ017;TaXl~*qxGthlkz8 z?!Nba?_-h7&iWR9m;UtE`05GE`X?VIe-0jA$CZ*OYt2$Z$+lP%<}TMH?snVmIBSlu zl%q=RQpa6$h4mv#xvG56Qsub3Yp;1q-mq$3|11BE;8v8zL8Bd|Y0ylAhK{2wR?EKs z7MtSK^s8X2mvn<{6C)xW2U}^Zf-DI-(I;`xNs1PId0jW-u4-=w&2AR!^{5f2K1OAm zaiEgB+Z%B=xZ7!iZ=`69IAI*1HP&3S*aTMW>EupR#moNJkkYExMDAa|+l#X6S||Ez zfi^UGjil2{wz{gpL6g6+lAr@CwxAqqO+o=s6%-(28wzmnY%2%Pj(INOxuje?yXM(d zFDXw|?uoT>?1A@H^`6)jYZdb}qh`&MujbT|d)8WY!&;kB^J)S7tU9Wmz072Hp&E9ynu&!{pCeKmL9gq6RgDXQ{y zT;I%qj5MVL-jMw{zOj65tJiKeV4eB{JNLq{8+GC^%>6LzBxmksJZ}KNos0(rL51VL71z^?e zHnT81PsvY#xMK3}312uiTYS-IX7Im{Gqf5fQcVAPaCN*Fy>$S?4aL3o5gYuAR*w!zGaA$Cp-Y$!)SNoZ+7 z8HJLlI-?|KIQ}BWIiVald$=2AIaF4?kmMW|foSE8IE%7O8_|m%BEMGBPvfS~kQgKc z?+4IB(_(2+(z@-{AmivUcahFxip zVYNg{4n)gdMMAw{u9_^wp(LA8Y9uk+r6r9xHK|X7&uy6d(AG62eFs;{u;h!Q!g<)A zF`FFPerj{v*w{wPcozeg(bw>{59{hfv0G84c*xYS91EdFH&)&C|kXSw!*lPd6 zHDIxuWWjo~tAc2R)I<-#7(90&eQp`TRN>U2$@FoWR~k{baQVD){ca=fWzD3Ud$61d z^1y8&A>JvhcF01sF(ylYPEi>;1eBM9yRh=q@S2!%LSW^Z2=)(%pAznYZ>&My4-L+c~hamV?U zQ&^PTr{YuOh>h1>&SYNRFt5aU%N20Xd7M|zgm>^9n4Doz!*!&!YfjH;uaZ>=jZ%2<1&mZ12~EK8i*JRiphw zSab^@w=trSNc5{lnMM1QJQRTlGz;AVL+tIty{JtDK%rk~B6*?}QDI-e6_Yoh;WKN$YrhF@+p@1PVOrO_Y?m}B97kw)p9 zBD-W;x(jG_qF#?lrAWpBODq)5$#|}!9q3(W63WIiE(ZaZ8IETUi*_}t<%s#%^kTJx z$*@>a)z_0Qito{eYo&Z1pj>b2PS{O~YC#jmd3CZDaJZT&)N0N!bU?t|>&Bm&5~A>! zLxx)j86YMrj06*>G_~h4!ObDm&xv`-;L=|zYWDf1FT_V7xtff^0J9k~s#n4&(nQ*b;-Tz^a)L;53b$Hm#fYE!CY9P)4(RlWeG??VZULP+tfN>{~g{m5Rlj~Gm(q@J*+7Y zMomF~GERTPv_D3G@hg25P1uuxBEDc)`el+sZtw7r@fA9X6CRfBR}9A4{@CU8PdU}( z0tV}kTA)0PjKAj_?}7{~uwnDm62vr(VGO}^wPEcr20)&cMEEZw8SnsMzk>GL<;>YY zi~!D=8cy#3$$Ka}48EO~J8)X%b%X1Hjp*_s5`{N#O~GQdDtrE*ME>?73zI^WYJLO- zeugh6cVbnXr%*H$pEgvC(-Y3^%njr##s0x+hBo~Y39X%1!lJOldE7>sX`(>xGNO0Y z5afBOqp}odGfbG5x4O;STX9+-dk)JO z7UZPzGw0v^`38mCdb1q|7t;4@)m$bi z<LsnMxmANb%hBahkt1xm93h5!Hn literal 0 HcmV?d00001 diff --git a/docs/doxygen/doxyxml/__pycache__/doxyindex.cpython-310.pyc b/docs/doxygen/doxyxml/__pycache__/doxyindex.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02a55b2f24940077c722d7954b2328a435abae00 GIT binary patch literal 8496 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 literal 0 HcmV?d00001 diff --git a/docs/doxygen/doxyxml/__pycache__/text.cpython-310.pyc b/docs/doxygen/doxyxml/__pycache__/text.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1dd9da7b776bf2280aa6c10c5913f43cb91cfb4 GIT binary patch literal 1257 zcmZ`(&2G~`5Z+xoj^m`XqAeiA!2*G>fTo-(p{hcHBK49>K!{2xa=qKs#j(Tgh9*&R zA$d7ytS2TQ^L4i z%%IrXwfv{T11M9y;C&Yi3avgcsZm)4^%4^Y47eQ zmDpTI%&?_pKz=iy;Sdn zr}3YjDJ}G|0AZ}5VYYf&7&nIjFm5-N@sI^UR59h9SmAqF!-(!~k>+v{8DP02wzX|w zQ(5mP!uFuN4aUfkc!!*)t&Asy>Sg+BMhFwavUf>9=b#VIWQ}59G6r*Uvf!X@gEk`9 olv^#BzE;b|wtYM0gTs0yg7H^71@C2I4Q~*I@!X1E@~buPABIjC;s5{u literal 0 HcmV?d00001 diff --git a/docs/doxygen/doxyxml/generated/__pycache__/__init__.cpython-310.pyc b/docs/doxygen/doxyxml/generated/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9fdb43edffe2965d49285c45f648072ec93f9785 GIT binary patch literal 395 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 lu1RJ4QPL1)Dkb#J4b literal 0 HcmV?d00001 diff --git a/docs/doxygen/doxyxml/generated/__pycache__/compoundsuper.cpython-310.pyc b/docs/doxygen/doxyxml/generated/__pycache__/compoundsuper.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4790e9243ce1be115a4c67b65fe97d7548ddf035 GIT binary patch literal 245705 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ദ#7~_hiq*E_# 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 K_e)UE3;zq|xh9hU literal 0 HcmV?d00001 diff --git a/examples/tests/test_find_max_peak_c.py b/examples/tests/test_find_max_peak_c.py new file mode 100755 index 00000000..bd803cab --- /dev/null +++ b/examples/tests/test_find_max_peak_c.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# +# SPDX-License-Identifier: GPL-3.0 +# +# GNU Radio Python Flow Graph +# Title: Test Find Max Peak C +# GNU Radio version: 3.10.1.1 + +from packaging.version import Version as StrictVersion + +if __name__ == '__main__': + import ctypes + import sys + if sys.platform.startswith('linux'): + try: + x11 = ctypes.cdll.LoadLibrary('libX11.so') + x11.XInitThreads() + except: + print("Warning: failed to XInitThreads()") + +from PyQt5 import Qt +from gnuradio import qtgui +from gnuradio.filter import firdes +import sip +from gnuradio import analog +from gnuradio import blocks +from gnuradio import gr +from gnuradio.fft import window +import sys +import signal +from argparse import ArgumentParser +from gnuradio.eng_arg import eng_float, intx +from gnuradio import eng_notation +from gnuradio import radar +from gnuradio.qtgui import Range, RangeWidget +from PyQt5 import QtCore + + + +from gnuradio import qtgui + +class test_find_max_peak_c(gr.top_block, Qt.QWidget): + + def __init__(self): + gr.top_block.__init__(self, "Test Find Max Peak C", catch_exceptions=True) + Qt.QWidget.__init__(self) + self.setWindowTitle("Test Find Max Peak C") + qtgui.util.check_set_qss() + try: + self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) + except: + pass + self.top_scroll_layout = Qt.QVBoxLayout() + self.setLayout(self.top_scroll_layout) + self.top_scroll = Qt.QScrollArea() + self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) + self.top_scroll_layout.addWidget(self.top_scroll) + self.top_scroll.setWidgetResizable(True) + self.top_widget = Qt.QWidget() + self.top_scroll.setWidget(self.top_widget) + self.top_layout = Qt.QVBoxLayout(self.top_widget) + self.top_grid_layout = Qt.QGridLayout() + self.top_layout.addLayout(self.top_grid_layout) + + self.settings = Qt.QSettings("GNU Radio", "test_find_max_peak_c") + + try: + if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"): + self.restoreGeometry(self.settings.value("geometry").toByteArray()) + else: + self.restoreGeometry(self.settings.value("geometry")) + except: + pass + + ################################################## + # Variables + ################################################## + self.threshold = threshold = -120 + self.samp_rate = samp_rate = 32000 + self.packet_len = packet_len = 2048 + + ################################################## + # Blocks + ################################################## + self._threshold_range = Range(-200, 100, 1, -120, 200) + self._threshold_win = RangeWidget(self._threshold_range, self.set_threshold, "'threshold'", "counter_slider", float, QtCore.Qt.Horizontal) + self.top_layout.addWidget(self._threshold_win) + self.radar_ts_fft_cc_0 = radar.ts_fft_cc(packet_len, "packet_len") + self.radar_ts_fft_cc_0.set_min_output_buffer(4096) + self.radar_print_results_0 = radar.print_results(False, "") + self.radar_find_max_peak_c_0 = radar.find_max_peak_c(samp_rate, threshold, 0, [], False, "packet_len") + self.qtgui_sink_x_0 = qtgui.sink_c( + packet_len, #fftsize + window.WIN_BLACKMAN_hARRIS, #wintype + 0, #fc + samp_rate, #bw + 'QT GUI Plot', #name + True, #plotfreq + True, #plotwaterfall + True, #plottime + True, #plotconst + None # parent + ) + self.qtgui_sink_x_0.set_update_time(1.0/10) + self._qtgui_sink_x_0_win = sip.wrapinstance(self.qtgui_sink_x_0.qwidget(), Qt.QWidget) + + self.qtgui_sink_x_0.enable_rf_freq(False) + + self.top_layout.addWidget(self._qtgui_sink_x_0_win) + self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True) + self.blocks_throttle_0.set_min_output_buffer(4096) + self.blocks_stream_to_tagged_stream_0 = blocks.stream_to_tagged_stream(gr.sizeof_gr_complex, 1, packet_len, "packet_len") + self.analog_sig_source_x_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, 5000, 1, 0, 0) + + + ################################################## + # Connections + ################################################## + self.msg_connect((self.radar_find_max_peak_c_0, 'Msg out'), (self.radar_print_results_0, 'Msg in')) + self.connect((self.analog_sig_source_x_0, 0), (self.blocks_throttle_0, 0)) + self.connect((self.blocks_stream_to_tagged_stream_0, 0), (self.qtgui_sink_x_0, 0)) + self.connect((self.blocks_stream_to_tagged_stream_0, 0), (self.radar_ts_fft_cc_0, 0)) + self.connect((self.blocks_throttle_0, 0), (self.blocks_stream_to_tagged_stream_0, 0)) + self.connect((self.radar_ts_fft_cc_0, 0), (self.radar_find_max_peak_c_0, 0)) + + + def closeEvent(self, event): + self.settings = Qt.QSettings("GNU Radio", "test_find_max_peak_c") + self.settings.setValue("geometry", self.saveGeometry()) + self.stop() + self.wait() + + event.accept() + + def get_threshold(self): + return self.threshold + + def set_threshold(self, threshold): + self.threshold = threshold + self.radar_find_max_peak_c_0.set_threshold(self.threshold) + + def get_samp_rate(self): + return self.samp_rate + + def set_samp_rate(self, samp_rate): + self.samp_rate = samp_rate + self.analog_sig_source_x_0.set_sampling_freq(self.samp_rate) + self.blocks_throttle_0.set_sample_rate(self.samp_rate) + self.qtgui_sink_x_0.set_frequency_range(0, self.samp_rate) + + def get_packet_len(self): + return self.packet_len + + def set_packet_len(self, packet_len): + self.packet_len = packet_len + self.blocks_stream_to_tagged_stream_0.set_packet_len(self.packet_len) + self.blocks_stream_to_tagged_stream_0.set_packet_len_pmt(self.packet_len) + + + + +def main(top_block_cls=test_find_max_peak_c, options=None): + + if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"): + style = gr.prefs().get_string('qtgui', 'style', 'raster') + Qt.QApplication.setGraphicsSystem(style) + qapp = Qt.QApplication(sys.argv) + + tb = top_block_cls() + + tb.start() + + tb.show() + + def sig_handler(sig=None, frame=None): + tb.stop() + tb.wait() + + Qt.QApplication.quit() + + signal.signal(signal.SIGINT, sig_handler) + signal.signal(signal.SIGTERM, sig_handler) + + timer = Qt.QTimer() + timer.start(500) + timer.timeout.connect(lambda: None) + + qapp.exec_() + +if __name__ == '__main__': + main() diff --git a/include/gnuradio/radar/CMakeLists.txt b/include/gnuradio/radar/CMakeLists.txt new file mode 100644 index 00000000..2aa90e16 --- /dev/null +++ b/include/gnuradio/radar/CMakeLists.txt @@ -0,0 +1,56 @@ +# Copyright 2011,2012 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-radar +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Install public header files +######################################################################## +install(FILES + api.h + signal_generator_cw_c.h + signal_generator_fmcw_c.h + split_cc.h + os_cfar_c.h + ts_fft_cc.h + estimator_cw.h + print_results.h + static_target_simulator_cc.h + signal_generator_fsk_c.h + split_fsk_cc.h + estimator_fsk.h + usrp_echotimer_cc.h + estimator_fmcw.h + signal_generator_sync_pulse_c.h + estimator_sync_pulse_c.h + find_max_peak_c.h + qtgui_scatter_plot.h + qtgui_time_plot.h + tracking_singletarget.h + msg_gate.h + msg_manipulator.h + ofdm_cyclic_prefix_remover_cvc.h + transpose_matrix_vcvc.h + qtgui_spectrogram_plot.h + crop_matrix_vcvc.h + ofdm_divide_vcvc.h + os_cfar_2d_vc.h + estimator_ofdm.h + estimator_rcs.h + trigger_command.h DESTINATION include/gnuradio/radar +) diff --git a/include/gnuradio/radar/api.h b/include/gnuradio/radar/api.h new file mode 100644 index 00000000..5369014f --- /dev/null +++ b/include/gnuradio/radar/api.h @@ -0,0 +1,34 @@ +/* + * Copyright 2011 Free Software Foundation, Inc. + * + * This file was generated by gr_modtool, a tool from the GNU Radio framework + * This file is a part of gr-radar + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_API_H +#define INCLUDED_RADAR_API_H + +#include + +#ifdef gnuradio_radar_EXPORTS +#define RADAR_API __GR_ATTR_EXPORT +#else +#define RADAR_API __GR_ATTR_IMPORT +#endif + +#endif /* INCLUDED_RADAR_API_H */ diff --git a/include/gnuradio/radar/crop_matrix_vcvc.h b/include/gnuradio/radar/crop_matrix_vcvc.h new file mode 100644 index 00000000..e7c55a20 --- /dev/null +++ b/include/gnuradio/radar/crop_matrix_vcvc.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_CROP_MATRIX_VCVC_H +#define INCLUDED_RADAR_CROP_MATRIX_VCVC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This matrix crops a data matrix. A tagged stream combined with vectors as items + * represent a matrix. crop_x and crop_y gives the ranges which shall be pushed through. + * Rest of the matrix is lost. + * + * \param vlen Vector length + * \param crop_x Index range on x axis to crop matrix + * \param crop_y Index range on y axis to crop matrix + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API crop_matrix_vcvc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::crop_matrix_vcvc. + * + * To avoid accidental use of raw pointers, radar::crop_matrix_vcvc's + * constructor is in a private implementation + * class. radar::crop_matrix_vcvc::make is the public interface for + * creating new instances. + */ + static sptr make(int vlen, + std::vector crop_x, + std::vector crop_y, + std::string len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_CROP_MATRIX_VCVC_H */ diff --git a/include/gnuradio/radar/estimator_cw.h b/include/gnuradio/radar/estimator_cw.h new file mode 100644 index 00000000..a262926b --- /dev/null +++ b/include/gnuradio/radar/estimator_cw.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_ESTIMATOR_CW_H +#define INCLUDED_RADAR_ESTIMATOR_CW_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block estimates the velocity from given peaks of a CW spectrum. The + * estimator looks for a f32vector tagged with a 'frequency' identifier (symbol) and + * calculates the velocity with the doppler formula. The identifier (symbol) of the output + * data is 'velocity'. Needed identifier (symbols) of the input are 'frequency'. + * + * \param center_freq Center frequency + * + * \ingroup radar + * + */ +class RADAR_API estimator_cw : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::estimator_cw. + * + * To avoid accidental use of raw pointers, radar::estimator_cw's + * constructor is in a private implementation + * class. radar::estimator_cw::make is the public interface for + * creating new instances. + */ + static sptr make(float center_freq); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_ESTIMATOR_CW_H */ diff --git a/include/gnuradio/radar/estimator_fmcw.h b/include/gnuradio/radar/estimator_fmcw.h new file mode 100644 index 00000000..928e3a77 --- /dev/null +++ b/include/gnuradio/radar/estimator_fmcw.h @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_ESTIMATOR_FMCW_H +#define INCLUDED_RADAR_ESTIMATOR_FMCW_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block estimates range and veloicty from peaks of a FMCW spectrum. Input + * messages are data with the identifier 'frequency' of the up-chirp, down-chirp and CW + * part. If data is available on all three message ports the estimation starts. The + * velocity is estimated with the frequency information of the CW block and the range is + * estimated with the up and down chirp. If multiple frequencies are given, the velocity + * is estimated first and associated with the most likely range from the up- and + * down-chirp. The output identifiers are 'range' and 'velocity'. + * + * \param samp_rate Sample rate + * \param center_freq Center frequency + * \param sweep_freq Sweep frequency + * \param samp_up Samples of up-chirp + * \param samp_down Samples of down-chirp + * \param push_power Push through power of peak + * + * \ingroup radar + * + */ +class RADAR_API estimator_fmcw : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::estimator_fmcw. + * + * To avoid accidental use of raw pointers, radar::estimator_fmcw's + * constructor is in a private implementation + * class. radar::estimator_fmcw::make is the public interface for + * creating new instances. + */ + static sptr make(int samp_rate, + float center_freq, + float sweep_freq, + int samp_up, + int samp_down, + bool push_power); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_ESTIMATOR_FMCW_H */ diff --git a/include/gnuradio/radar/estimator_fsk.h b/include/gnuradio/radar/estimator_fsk.h new file mode 100644 index 00000000..b4bca36e --- /dev/null +++ b/include/gnuradio/radar/estimator_fsk.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_ESTIMATOR_FSK_H +#define INCLUDED_RADAR_ESTIMATOR_FSK_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block estimates the range with peaks given from a FSK spectrum. Needed + * identifiers (symbols) are 'frequency' and 'phase'. The velocity is calculated with the + * 'frequency' information and the doppler formula. The phase of the doppler peaks are + * used to estimate the range. Output identifier are 'range' and 'velocity'. If push_power + * is true the information about the power of the peaks is pushed through. This can be + * used for estimating the RCS of an object. + * + * \param center_freq Center frequency + * \param delta_freq Frequency difference of high and low frequency + * \param push_power Toggle pushing through information about power of peaks + * + * \ingroup radar + * + */ +class RADAR_API estimator_fsk : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::estimator_fsk. + * + * To avoid accidental use of raw pointers, radar::estimator_fsk's + * constructor is in a private implementation + * class. radar::estimator_fsk::make is the public interface for + * creating new instances. + */ + static sptr make(float center_freq, float delta_freq, bool push_power = false); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_ESTIMATOR_FSK_H */ diff --git a/include/gnuradio/radar/estimator_ofdm.h b/include/gnuradio/radar/estimator_ofdm.h new file mode 100644 index 00000000..bdaeb089 --- /dev/null +++ b/include/gnuradio/radar/estimator_ofdm.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_ESTIMATOR_OFDM_H +#define INCLUDED_RADAR_ESTIMATOR_OFDM_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block evaluates the peaks given from a OFDM matrix. Input are the bins of + * the peaks with the identifiers 'axis_x' and 'axis_y'. The parameters of the block + * axis_x and axis_y are vectors which define the mapping of the axis. If two values are + * given it is assumed a linear progression in between. If four values are given the + * middle values are set on half of the axis and it is interpolated linear in between. + * len_x and len_y gives the length of the axis in number of bins. symbol_x and symbol_y + * defines the identifier (symbols) for the output data. merge_consecutive toggles merging + * consecutive peaks. Each peak is compared with peaks in a range of one bin. If there is + * a peak with a higher power the actual bin is not used for evaluations. If + * merge_consecutive is true data with identifier 'power' is needed. + * + * \param symbol_x Identifier (symbol) for information on x axis + * \param len_x Length of x axis in bins + * \param axis_x Axis x + * \param symbol_y Identifier (symbol) for information on y axis + * \param len_y Length of y axis in bins + * \param axis_y Axis y + * \param merge_consecutive Merge consecutive peaks + * + * \ingroup radar + * + */ +class RADAR_API estimator_ofdm : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::estimator_ofdm. + * + * To avoid accidental use of raw pointers, radar::estimator_ofdm's + * constructor is in a private implementation + * class. radar::estimator_ofdm::make is the public interface for + * creating new instances. + */ + static sptr make(std::string symbol_x, + int len_x, + std::vector axis_x, + std::string symbol_y, + int len_y, + std::vector axis_y, + bool merge_consecutive = true); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_ESTIMATOR_OFDM_H */ diff --git a/include/gnuradio/radar/estimator_rcs.h b/include/gnuradio/radar/estimator_rcs.h new file mode 100644 index 00000000..7b34a794 --- /dev/null +++ b/include/gnuradio/radar/estimator_rcs.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_ESTIMATOR_RCS_H +#define INCLUDED_RADAR_ESTIMATOR_RCS_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief Basic RCS block for estimating the RCS of a single target. Some hardware specs + need to be known for calculating RCS values, see parameters for details. The radar + equation is used to calculate the RCS: RCS = Pr*(4pi)^3*R^4/(Pt*Gt*Gr*lamda^2). The Rx + power (Pr) and the distance (R) are being estimated, while the other parameters are given + in the flowgraph. It is possible to average a number of samples by setting the num_mean + value > 1. The RCS will be 0 until enough samples are collected to calculate the mean + value (be patient). The Tx power (Pt) needs to be calibrated with external hardware. I + recommend to calibrate for the wanted power and not to change the parameters in the + flowgraph on the Tx side after that. The RCS block needs the Rx power, to estimate the + RCS. For that, the input power of the block needs to be determined analytically and + altered via the corr_factor and exponent values, to fit the following equation: Pr = + P_input ^ (exponent) * corr_factor / Pt. In addition, the FFTs need to be normalized for + correct power calculation. + * + * \param num_mean Number of samples taken into account for calculating mean value (1 for + no mean calculation) + * \param center_freq Center frequency of radar + * \param antenna_gain_tx Antenna Gain of the Tx antenna + * \param antenna_gain_rx Antenna Gain of the Rx antenna + * \param usrp_gain_rx Rx gain of USRP set in flowgraph + * \param power_tx Tx power of radar signal. Needs to be measured one time! + * \param corr_factor Correction factor for the RCS to calibrate system to a known target + or special signal paths + * \param exponent Exponent of the input power to calculate Rx power, depends on signal + path (calculate analytically) + * + * \ingroup radar + * + */ +class RADAR_API estimator_rcs : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::estimator_rcs. + * + * To avoid accidental use of raw pointers, radar::estimator_rcs's + * constructor is in a private implementation + * class. radar::estimator_rcs::make is the public interface for + * creating new instances. + */ + static sptr make(int num_mean, + float center_freq, + float antenna_gain_tx, + float antenna_gain_rx, + float usrp_gain_rx, + float power_tx, + float corr_factor, + float exponent = 1); + // callbacks + virtual void set_num_mean(int val) = 0; + virtual void set_center_freq(float val) = 0; + virtual void set_antenna_gain_tx(float val) = 0; + virtual void set_antenna_gain_rx(float val) = 0; + virtual void set_usrp_gain_rx(float val) = 0; + virtual void set_power_tx(float val) = 0; + virtual void set_corr_factor(float val) = 0; +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_ESTIMATOR_RCS_H */ diff --git a/include/gnuradio/radar/estimator_sync_pulse_c.h b/include/gnuradio/radar/estimator_sync_pulse_c.h new file mode 100644 index 00000000..91794db5 --- /dev/null +++ b/include/gnuradio/radar/estimator_sync_pulse_c.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_ESTIMATOR_SYNC_PULSE_C_H +#define INCLUDED_RADAR_ESTIMATOR_SYNC_PULSE_C_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block can be used to estimate the shift of a signal on input 1 in relation + * to another on input 2. For example the constant number of delay samples due to + * hardware effect from a signal source can be estimated. The calculation of the shift is + * done by a cross correlation of the input signals. The number of correlations in samples + * is given with num_xcorr. The output message is the number of delay samples with the + * identifier (symbol) 'sync_pulse'. This can be displayed with the 'Print Results' block. + * + * \param num_xcorr Number of cross correlations + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API estimator_sync_pulse_c : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::estimator_sync_pulse_c. + * + * To avoid accidental use of raw pointers, radar::estimator_sync_pulse_c's + * constructor is in a private implementation + * class. radar::estimator_sync_pulse_c::make is the public interface for + * creating new instances. + */ + static sptr make(int num_xcorr, const std::string len_key = "packet_len"); + + virtual void set_num_xcorr(int num) = 0; +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_ESTIMATOR_SYNC_PULSE_C_H */ diff --git a/include/gnuradio/radar/find_max_peak_c.h b/include/gnuradio/radar/find_max_peak_c.h new file mode 100644 index 00000000..0df3ecbe --- /dev/null +++ b/include/gnuradio/radar/find_max_peak_c.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_FIND_MAX_PEAK_C_H +#define INCLUDED_RADAR_FIND_MAX_PEAK_C_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block estimates a single peak of a given FFT spectrum as tagged stream. + * Output is a message with the information of frequency, phase and power of the peak as a + * f32vector with a single item. All data is tagged with the identifiers (symbols) + * 'frequency', 'phase' and 'power'. The peak is estimated on the whole spectrum or on the + * range max_freq if cut_max_freq is true. Furthermore a threshold of the spectrum + * amplitude can be given with threshold. The DC peak can be cut out with the protected + * samples samp_protect. This value do not evaluate samp_protect samples around the DC + * peak. If no suitable peak is found the block returns empty vectors with the + * identifiers. + * + * \param samp_rate Sample rate + * \param threshold Threshold for detection of the spectrum amplitude + * \param samp_protect Protected samples for cutting DC peak + * \param max_freq Frequency range for cutting spectrum + * \param cut_max_freq Toggle cutting the spectrum for peak estimation + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API find_max_peak_c : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::find_max_peak_c. + * + * To avoid accidental use of raw pointers, radar::find_max_peak_c's + * constructor is in a private implementation + * class. radar::find_max_peak_c::make is the public interface for + * creating new instances. + */ + static sptr make(int samp_rate, + float threshold, + int samp_protect, + std::vector max_freq, + bool cut_max_freq, + const std::string& len_key = "packet_len"); + virtual void set_threshold(float threshold) = 0; + virtual void set_samp_protect(int samp) = 0; + virtual void set_max_freq(std::vector freq) = 0; +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_FIND_MAX_PEAK_C_H */ diff --git a/include/gnuradio/radar/msg_gate.h b/include/gnuradio/radar/msg_gate.h new file mode 100644 index 00000000..c44df729 --- /dev/null +++ b/include/gnuradio/radar/msg_gate.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_MSG_GATE_H +#define INCLUDED_RADAR_MSG_GATE_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block blocks messages whose data is not in range of val_min to val_max. All + * parameters are given as vectors. Each index represents a dataset with given identifier + * (symbol) which should be tested on valid data in given range. All other data is pushed + * through. + * + * \param keys Identifiers (symbols) of the data as vector + * \param val_min Lower limit of the gate as vector + * \param val_max Higher limit of the gate as vector + * + * \ingroup radar + * + */ +class RADAR_API msg_gate : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::msg_gate. + * + * To avoid accidental use of raw pointers, radar::msg_gate's + * constructor is in a private implementation + * class. radar::msg_gate::make is the public interface for + * creating new instances. + */ + static sptr make(std::vector keys, + std::vector val_min, + std::vector val_max); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_MSG_GATE_H */ diff --git a/include/gnuradio/radar/msg_manipulator.h b/include/gnuradio/radar/msg_manipulator.h new file mode 100644 index 00000000..e49f3b43 --- /dev/null +++ b/include/gnuradio/radar/msg_manipulator.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_MSG_MANIPULATOR_H +#define INCLUDED_RADAR_MSG_MANIPULATOR_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block manipulates data in a msg with given identifier (symbol). All data + * are given as vectors and each index represents a dataset with identifier which should + * be processed. All other data is pushed through. The addition is performed before the + * multiplication. + * + * \param symbols Identifier (symbols) of data as vector + * \param const_add Value to add on the data + * \param const_mult Value to multiply on the data + * + * \ingroup radar + * + */ +class RADAR_API msg_manipulator : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::msg_manipulator. + * + * To avoid accidental use of raw pointers, radar::msg_manipulator's + * constructor is in a private implementation + * class. radar::msg_manipulator::make is the public interface for + * creating new instances. + */ + static sptr make(std::vector symbols, + std::vector const_add, + std::vector const_mult); + virtual void set_const_add(std::vector val) = 0; + virtual void set_const_mult(std::vector val) = 0; +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_MSG_MANIPULATOR_H */ diff --git a/include/gnuradio/radar/ofdm_cyclic_prefix_remover_cvc.h b/include/gnuradio/radar/ofdm_cyclic_prefix_remover_cvc.h new file mode 100644 index 00000000..c3047c1a --- /dev/null +++ b/include/gnuradio/radar/ofdm_cyclic_prefix_remover_cvc.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_OFDM_CYCLIC_PREFIX_REMOVER_CVC_H +#define INCLUDED_RADAR_OFDM_CYCLIC_PREFIX_REMOVER_CVC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block removes the cyclic prefix of a OFDM signal by cut away the cyclic + * prefix data. cp_len gives the length of the cyclic prefix. fft_len represents the + * length of the data before the cyclic prefix. + * + * \param fft_len Length of FFT + * \param cp_len Length of cyclic prefix + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API ofdm_cyclic_prefix_remover_cvc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of + * radar::ofdm_cyclic_prefix_remover_cvc. + * + * To avoid accidental use of raw pointers, radar::ofdm_cyclic_prefix_remover_cvc's + * constructor is in a private implementation + * class. radar::ofdm_cyclic_prefix_remover_cvc::make is the public interface for + * creating new instances. + */ + static sptr make(int fft_len, int cp_len, std::string len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_OFDM_CYCLIC_PREFIX_REMOVER_CVC_H */ diff --git a/include/gnuradio/radar/ofdm_divide_vcvc.h b/include/gnuradio/radar/ofdm_divide_vcvc.h new file mode 100644 index 00000000..dfcf6a4c --- /dev/null +++ b/include/gnuradio/radar/ofdm_divide_vcvc.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_OFDM_DIVIDE_VCVC_H +#define INCLUDED_RADAR_OFDM_DIVIDE_VCVC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block performs a complex complex division with in0/in1. If vlen_out > + * vlen_in the additional space is filled with zeros. This can be used for zeropadding. + * discarded_carriers is a vector of the carriers which should be not used and set zero as + * division result. num_sync_words gives the number of sync words on which the + * discarded_carriers rule is not applied. + * + * \param vlen_in Input vector length + * \param vlen_out Output vector length + * \param discarded_carriers Discarded carriers + * \param num_sync_words Number of sync words + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API ofdm_divide_vcvc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::ofdm_divide_vcvc. + * + * To avoid accidental use of raw pointers, radar::ofdm_divide_vcvc's + * constructor is in a private implementation + * class. radar::ofdm_divide_vcvc::make is the public interface for + * creating new instances. + */ + static sptr make(int vlen_in, + int vlen_out, + std::vector discarded_carriers, + int num_sync_words, + std::string len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_OFDM_DIVIDE_VCVC_H */ diff --git a/include/gnuradio/radar/os_cfar_2d_vc.h b/include/gnuradio/radar/os_cfar_2d_vc.h new file mode 100644 index 00000000..a9d72dee --- /dev/null +++ b/include/gnuradio/radar/os_cfar_2d_vc.h @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_OS_CFAR_2D_VC_H +#define INCLUDED_RADAR_OS_CFAR_2D_VC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block estimates peaks of a given matrix. A matrix can be represented as a + * combination of vectors and tagged streams. Input has to be a matrix with linear scaled + * values (NOT logarithmic scaled!). Used algorithm is a 2D OS-CFAR algorithm. The + * algorithm uses around the cell under test (CUT) on each side samp_compare samples to + * estimate the noise floor. samp_protect is a protected are around the CUT which is not + * used for acquiring compare samples. Index 0 of a input vector refers to x axis + * properties and index 1 refers to y axis properties. The relative threshold is defined + * by the bin of the vector within the sorted samp_compare samples. A standard value is + * rel_threshold = 0.78. The value of this bin is multiplied by mult_threshold and + * compared with the CUT. If the magnitude square of the CUT is greater than the threshold + * the matrix item is accepted. Used identifiers (symbols) for data are 'axis_x', 'axis_y' + * and 'power'. + * + * \param vlen Input vector length + * \param samp_compare Compare samples (vector index refers to axis) + * \param samp_protect Protected samples (vector index refers to axis) + * \param rel_threshold Relative threshold + * \param mult_threshold Multiplier threshold + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API os_cfar_2d_vc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::os_cfar_2d_vc. + * + * To avoid accidental use of raw pointers, radar::os_cfar_2d_vc's + * constructor is in a private implementation + * class. radar::os_cfar_2d_vc::make is the public interface for + * creating new instances. + */ + static sptr make(int vlen, + std::vector samp_compare, + std::vector samp_protect, + float rel_threshold, + float mult_threshold, + const std::string& len_key = "packet_len"); + virtual void set_rel_threshold(float inp) = 0; + virtual void set_mult_threshold(float inp) = 0; + virtual void set_samp_compare(std::vector inp) = 0; + virtual void set_samp_protect(std::vector inp) = 0; +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_OS_CFAR_2D_VC_H */ diff --git a/include/gnuradio/radar/os_cfar_c.h b/include/gnuradio/radar/os_cfar_c.h new file mode 100644 index 00000000..297bae6e --- /dev/null +++ b/include/gnuradio/radar/os_cfar_c.h @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_OS_CFAR_C_H +#define INCLUDED_RADAR_OS_CFAR_C_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block estimates peaks of a given FFT spectrum as tagged stream. Multi peak + * detection is implemented with the OS-CFAR algorithm. The algorithm uses around the cell + * under test (CUT) on each side samp_compare samples to estimate the noise floor. This + * relative threshold is defined by the bin of the vector within the sorted samp_compare + * samples. A standard value is rel_threshold = 0.78. The value of this bin is multiplied + * by mult_threshold and compared with the CUT. samp_protect samples are a protected are + * which is not used for acquiring compare samples. If consecutive bins are detected as + * valid peaks it is possible to merge these detections with merge_consecutive = true. + * Output data are f32vectors with the information of frequency, power and phase. The + * identifiers (symbols) are 'frequency', 'power' and 'phase'. + * + * \param samp_rate Sample rate + * \param samp_compare Sample to be compared with each other + * \param samp_protect Samples which are protected and not used for peak detection + * \param rel_threshold Relative threshold + * \param mult_threshold Multiplier threshold + * \param merge_consectuive Toggle merging consecutive detected peaks + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API os_cfar_c : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::os_cfar_c. + * + * To avoid accidental use of raw pointers, radar::os_cfar_c's + * constructor is in a private implementation + * class. radar::os_cfar_c::make is the public interface for + * creating new instances. + */ + static sptr make(int samp_rate, + int samp_compare, + int samp_protect, + float rel_threshold, + float mult_threshold, + bool merge_consecutive = true, + const std::string& len_key = "packet_len"); + virtual void set_rel_threshold(float inp) = 0; + virtual void set_mult_threshold(float inp) = 0; + virtual void set_samp_compare(int inp) = 0; + virtual void set_samp_protect(int inp) = 0; +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_OS_CFAR_C_H */ diff --git a/include/gnuradio/radar/print_results.h b/include/gnuradio/radar/print_results.h new file mode 100644 index 00000000..152e7454 --- /dev/null +++ b/include/gnuradio/radar/print_results.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_PRINT_RESULTS_H +#define INCLUDED_RADAR_PRINT_RESULTS_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block prints data of messages filled with data of the structure [ + * [[symbol_0],[data_0]], [[symbol_1],[data_1]], ...] on the command line. Only data of + * the datatypes f32vector and long, and rx_time tuples are displayed. The output can also + * be stored in a text file. + * + * \param store_msg Toggle save output to file + * \param filename Filename of the output file + * + * \ingroup radar + * + */ +class RADAR_API print_results : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::print_results. + * + * To avoid accidental use of raw pointers, radar::print_results's + * constructor is in a private implementation + * class. radar::print_results::make is the public interface for + * creating new instances. + */ + static sptr make(bool store_msg = false, const std::string filename = ""); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_PRINT_RESULTS_H */ diff --git a/include/gnuradio/radar/qtgui_scatter_plot.h b/include/gnuradio/radar/qtgui_scatter_plot.h new file mode 100644 index 00000000..20900938 --- /dev/null +++ b/include/gnuradio/radar/qtgui_scatter_plot.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_QTGUI_SCATTER_PLOT_H +#define INCLUDED_RADAR_QTGUI_SCATTER_PLOT_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block displays a scatter plot of two data sets. The identifiers (symbols) + * are given with label_x and label_y. The display range is given with axis_x and axis_y. + * Points that are not in range are simply not displayed (there are no errors or + * warnings). label gives an additional label to differ multiple scatter plots on the + * screen by the titles. The update interval is given in milliseconds. + * + * \param interval Update interval in milliseconds + * \param label_x Identifier (symbol) of first data set + * \param label_y Identifier (symbol) of second data set + * \param axis_x Display range on x axis + * \param axis_y Display range on y axis + * \param label Optional label for the title + * + * \ingroup radar + * + */ +class RADAR_API qtgui_scatter_plot : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::qtgui_scatter_plot. + * + * To avoid accidental use of raw pointers, radar::qtgui_scatter_plot's + * constructor is in a private implementation + * class. radar::qtgui_scatter_plot::make is the public interface for + * creating new instances. + */ + static sptr make(int interval, + std::string label_x, + std::string label_y, + std::vector axis_x, + std::vector axis_y, + std::string label = ""); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_QTGUI_SCATTER_PLOT_H */ diff --git a/include/gnuradio/radar/qtgui_spectrogram_plot.h b/include/gnuradio/radar/qtgui_spectrogram_plot.h new file mode 100644 index 00000000..9d04a1b8 --- /dev/null +++ b/include/gnuradio/radar/qtgui_spectrogram_plot.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_QTGUI_SPECTROGRAM_PLOT_H +#define INCLUDED_RADAR_QTGUI_SPECTROGRAM_PLOT_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block displays a spectrogram plot of a tagged stream with vectors. Tagged + * streams combined with vectors represent a matrix. The value of the matrix elements are + * displayed within a color plot. The colorbar can be scaled automatically or with a + * manual scale with axis_z. The axis of x and y are set with axis_x and axis_y. The + * update rate interval is given in milliseconds. + * + * \param vlen Vector length + * \param xlabel Label for x axis + * \param ylabel Label for y axis + * \param label Addition label for title + * \param axis_x Display range for x axis + * \param axis_y Display range for y axis + * \param axis_z Display range for z axis. This defines the colorbar if autoscale_z is + * disabled. \param autoscale_z Toggle automatic scale of the colorbar \param packet_len + * Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API qtgui_spectrogram_plot : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::qtgui_spectrogram_plot. + * + * To avoid accidental use of raw pointers, radar::qtgui_spectrogram_plot's + * constructor is in a private implementation + * class. radar::qtgui_spectrogram_plot::make is the public interface for + * creating new instances. + */ + static sptr make(int vlen, + int interval, + std::string xlabel, + std::string ylabel, + std::string label, + std::vector axis_x, + std::vector axis_y, + std::vector axis_z, + bool autoscale_z, + std::string len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_QTGUI_SPECTROGRAM_PLOT_H */ diff --git a/include/gnuradio/radar/qtgui_time_plot.h b/include/gnuradio/radar/qtgui_time_plot.h new file mode 100644 index 00000000..d1fb8e96 --- /dev/null +++ b/include/gnuradio/radar/qtgui_time_plot.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_QTGUI_TIME_PLOT_H +#define INCLUDED_RADAR_QTGUI_TIME_PLOT_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block displays a plot of a value with a given interval in milliseconds. + * label_y represents the identifier (symbol) of the data. The y axis is scaled with + * axis_y. range_time gives the shown range of the x axis in seconds. label is an + * additional label for the title. + * + * \param interval Update interval in milliseconds + * \param label_y Lable for y axis and identifier (symbol) for data + * \param axis_y Display range y axis + * \param range_time Display range for x axis in seconds + * \param label Additional label for the title + * + * \ingroup radar + * + */ +class RADAR_API qtgui_time_plot : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::qtgui_time_plot. + * + * To avoid accidental use of raw pointers, radar::qtgui_time_plot's + * constructor is in a private implementation + * class. radar::qtgui_time_plot::make is the public interface for + * creating new instances. + */ + static sptr make(int interval, + std::string label_y, + std::vector axis_y, + float range_time, + std::string label = ""); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_QTGUI_TIME_PLOT_H */ diff --git a/include/gnuradio/radar/signal_generator_cw_c.h b/include/gnuradio/radar/signal_generator_cw_c.h new file mode 100644 index 00000000..460ac9c0 --- /dev/null +++ b/include/gnuradio/radar/signal_generator_cw_c.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_SIGNAL_GENERATOR_CW_C_H +#define INCLUDED_RADAR_SIGNAL_GENERATOR_CW_C_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block generates a signal for CW radar in baseband. The waveform consists of + * one (or sometimes multiple) constant frequency. + * + * \param packet_len packet_len is the length of a single tagged stream package which will + * be processed in subsequent tagged stream blocks. \param samp_rate Signal sample rate + * \param frequency This parameter holds a vector of all constant frequencies in baseband. + * \param amplitude Signal amplitude + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API signal_generator_cw_c : virtual public gr::sync_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::signal_generator_cw_c. + * + * To avoid accidental use of raw pointers, radar::signal_generator_cw_c's + * constructor is in a private implementation + * class. radar::signal_generator_cw_c::make is the public interface for + * creating new instances. + */ + static sptr make(int packet_len, + int samp_rate, + std::vector frequency, + float amplitude, + const std::string& len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_SIGNAL_GENERATOR_CW_C_H */ diff --git a/include/gnuradio/radar/signal_generator_fmcw_c.h b/include/gnuradio/radar/signal_generator_fmcw_c.h new file mode 100644 index 00000000..4618d226 --- /dev/null +++ b/include/gnuradio/radar/signal_generator_fmcw_c.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_SIGNAL_GENERATOR_FMCW_C_H +#define INCLUDED_RADAR_SIGNAL_GENERATOR_FMCW_C_H + +#include +#include + +namespace gr { +namespace radar { + +/*! Generates a signal for FMCW radar in baseband. + * + * The generated signal consists of three parts, in this order: + * + * 1. CW part with constant frequency + * 2. Up-chirp + * 3. Down-chirp + * + * The up-chirp goes from CW frequency to CW frequency plus sweep frequency + * and the down-chirp goes in the opposite direction. All of these parts + * can be disabled by setting the corresponding length to zero. + * + * The packet length for subsequent tagged streams is calculated by the sum + * of the number of samples of the single modulations parts. + * + * \ingroup radar + */ +class RADAR_API signal_generator_fmcw_c : virtual public gr::sync_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \param samp_rate Signal sample rate (samples per second) + * \param samp_up Number samples of up-chirp part + * \param samp_down Number samples of down-chirp part + * \param samp_cw Number samples of CW part + * \param freq_cw CW signal frequency in baseband + * \param freq_sweep Sweep frequency of up- and down-chirp + * \param amplitude Signal amplitude + * \param len_key Packet length key for tagged stream + */ + static sptr make(const int samp_rate, + const int samp_up, + const int samp_down, + const int samp_cw, + const float freq_cw, + const float freq_sweep, + const float amplitude, + const std::string& len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_SIGNAL_GENERATOR_FMCW_C_H */ diff --git a/include/gnuradio/radar/signal_generator_fsk_c.h b/include/gnuradio/radar/signal_generator_fsk_c.h new file mode 100644 index 00000000..1dd03b2c --- /dev/null +++ b/include/gnuradio/radar/signal_generator_fsk_c.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_SIGNAL_GENERATOR_FSK_C_H +#define INCLUDED_RADAR_SIGNAL_GENERATOR_FSK_C_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block generates a signal for FSK radar in baseband. The waveform consists + * of a signal with an alternating frequency. The packet length for subsequent tagged + * streams is calculated with two times the samples per single frequency multiplied by the + * blocks per tag. + * + * \param samp_rate Signal sample rate + * \param samp_per_freq Number of samples per frequency until the frequency shifts + * \param blocks_per_tag A block contains samp_per_freq samples of the low frequency and + * samp_per_freq samples of the high frequency. The packet length for subsequent tagged + * stream blocks is calculated with 2*samp_per_freq*blocks_per_tag. \param freq_low Lower + * frequency in baseband \param freq_high Higher frequency in baseband \param amplitude + * Signal amplitude \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API signal_generator_fsk_c : virtual public gr::sync_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::signal_generator_fsk_c. + * + * To avoid accidental use of raw pointers, radar::signal_generator_fsk_c's + * constructor is in a private implementation + * class. radar::signal_generator_fsk_c::make is the public interface for + * creating new instances. + */ + static sptr make(int samp_rate, + int samp_per_freq, + int blocks_per_tag, + float freq_low, + float freq_high, + float amplitude, + const std::string& len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_SIGNAL_GENERATOR_FSK_C_H */ diff --git a/include/gnuradio/radar/signal_generator_sync_pulse_c.h b/include/gnuradio/radar/signal_generator_sync_pulse_c.h new file mode 100644 index 00000000..54b49a26 --- /dev/null +++ b/include/gnuradio/radar/signal_generator_sync_pulse_c.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_SIGNAL_GENERATOR_SYNC_PULSE_C_H +#define INCLUDED_RADAR_SIGNAL_GENERATOR_SYNC_PULSE_C_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block generates a signal for the synchronization of the USRP Echotimer in + * baseband. The signal is pulsed with a constant amplitude with various pulse length and + * wait samples in between. It is structured by alternating wait parts and burst parts and + * starting with the first wait part. The pulses are full real signals. + * + * \param packet_len The packet length has to be longer or equal than the sum of pulse_len + * and pulse_pause. \param pulse_len The length of the pulses are defined in a vector and + * given in number of samples. The pulses are generated alternating with the wait samples + * defined in pulse_pause. \param pulse_pause The wait samples between pulses are defined + * in a vector. The first segment of the whole signal is the first element in the + * pulse_pause vector. This element can be zero. \param pulse_amplitude Pulse amplitude of + * real signal \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API signal_generator_sync_pulse_c : virtual public gr::sync_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of + * radar::signal_generator_sync_pulse_c. + * + * To avoid accidental use of raw pointers, radar::signal_generator_sync_pulse_c's + * constructor is in a private implementation + * class. radar::signal_generator_sync_pulse_c::make is the public interface for + * creating new instances. + */ + static sptr make(int packet_len, + std::vector pulse_len, + std::vector pulse_pause, + float pulse_amplitude, + const std::string len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_SIGNAL_GENERATOR_SYNC_PULSE_C_H */ diff --git a/include/gnuradio/radar/split_cc.h b/include/gnuradio/radar/split_cc.h new file mode 100644 index 00000000..bbede847 --- /dev/null +++ b/include/gnuradio/radar/split_cc.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_SPLIT_CC_H +#define INCLUDED_RADAR_SPLIT_CC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block splits a tagged stream into segments. As packet_parts you give the + * structure of the packet, e.g. (10, 20, 5). With the packet number you can choose which + * packet shall be pushed to output. Counting begins on zero. E.g. packet_num=1 returns 20 + * items. + * + * \param packet_num Number of packet to push to output + * \param packet_parts Packet structure as vector of packet length + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API split_cc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::split_cc. + * + * To avoid accidental use of raw pointers, radar::split_cc's + * constructor is in a private implementation + * class. radar::split_cc::make is the public interface for + * creating new instances. + */ + static sptr make(int packet_num, + const std::vector packet_parts, + const std::string& len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_SPLIT_CC_H */ diff --git a/include/gnuradio/radar/split_fsk_cc.h b/include/gnuradio/radar/split_fsk_cc.h new file mode 100644 index 00000000..c785140b --- /dev/null +++ b/include/gnuradio/radar/split_fsk_cc.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_SPLIT_FSK_CC_H +#define INCLUDED_RADAR_SPLIT_FSK_CC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block splits a FSK signal consisting of two separate signals. samp_per_freq + * items are taken and pushed alternating to the outputs. Discarded samples are thrown + * away at the beginning of samp_per_freq samples and only samp_per_freq-samp_discard are + * pushed to output. + * + * \param samp_per_freq Samples per frequency + * \param samp_discard Discarded samples + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API split_fsk_cc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::split_fsk_cc. + * + * To avoid accidental use of raw pointers, radar::split_fsk_cc's + * constructor is in a private implementation + * class. radar::split_fsk_cc::make is the public interface for + * creating new instances. + */ + static sptr + make(int samp_per_freq, int samp_discard, const std::string& len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_SPLIT_FSK_CC_H */ diff --git a/include/gnuradio/radar/static_target_simulator_cc.h b/include/gnuradio/radar/static_target_simulator_cc.h new file mode 100644 index 00000000..ba08d500 --- /dev/null +++ b/include/gnuradio/radar/static_target_simulator_cc.h @@ -0,0 +1,143 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_STATIC_TARGET_SIMULATOR_CC_H +#define INCLUDED_RADAR_STATIC_TARGET_SIMULATOR_CC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! Simulates the backscattering of a given signal on point targets. + * + * Implements the point scatter model. The input signal is the transmitted + * signal. The output signal is the received, backscattered signal, and + * contains one output signal per receive antenna. + * + * \section radar_target_modeling Target modeling + * + * The targets are modeled by the vectors \p range, \p velocity, \p rcs, + * and \p azimuth. All these vectors need to be of length H, where H + * describes the number of reflecting targets. The backscattered signal + * can either have a zero phase, or a random phase (controlled by + * \p rndm_phaseshift). The received signal will be the linear + * superposition of H signals, each of which are derived from the input + * signal by the following equation: + * + * \f[ + * r_h(t) = b_h s(t - \tau_h) e^{j2\pi f_{D,h}} + * \f] + * + * The attenuation depends on the center frequency \f$f_C\f$, the radar + * cross section \f$\sigma_{\text{RCS},h}\f$, the distance of the target + * \f$d_h\f$ and the speed of light \f$c_0\f$: + * \f[ + * b_h = \sqrt{\frac{c_0^2 \sigma_{\text{RCS},h}}{(4\pi)^3 d_h^4 f_C^2}} + * \f] + * + * The delay \f$\tau_h\f$ depends on the distance of the target: + * \f[ + * \tau_h = 2\frac{d_h}{c_0} + * \f] + * + * The Doppler shift \f$f_{D,h}\f$ depends on the relative velocity and + * the center frequency: + * \f[ + * f_{D,h} = 2\frac{v_{\text{rel},h}{c_0} f_C + * \f] + * + * The signals are added up to produce the total sum signal: + * \f[ + * r(t) = \sum_{h=0}^{H-1} r_h(t) + * \f] + * + * \section radar_mimo_processing MIMO processing simulation + * + * This block has a limited capability of simulating multi-antenna + * reception. The \p position_rx vector determines the distance of every + * RX antenna from the origin (Note: The TX antenna is always in the + * origin). The length of the \p position_rx vector is thus also the number + * of output signals this block produces. For a simple, mono-static SISO + * radar, simply set position_rx to [0]. + * The RX antennas are always laid out in a straight line. When multiple + * antennas are given, the target azimuth plays a role; an azimuth of zero + * is perpendicular to the line in which the RX antennas are placed. + * + * \section radar_hw_impairments Self-coupling + * + * Self-coupling describes the amount of the TX signal that is directly + * coupled into the RX path. When \p self_coupling is set to true, + * effectively, a target with zero velocity and range is added. The + * parameter \p self_coupling_db describes the attenuation of the + * self-coupling, a value of -10 means that the transmit signal is + * attenuated by 10 dB on the receive signal. + * + * \ingroup radar + */ +class RADAR_API static_target_simulator_cc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \param range Target ranges as vector (length H) + * \param velocity Target velocities as vector (length H) + * \param rcs Target RCS as vector (length H) + * \param azimuth Target azimuth as vector (length H) + * \param position_rx Position RX antennas. A value of [0] means + * there is one antenna, located in the origin + * (simple monostatic case). + * \param samp_rate Sample rate (samples per second) + * \param center_freq Center frequency (Hz) + * \param self_coupling_db Self coupling attenuation (dB) + * \param rndm_phaseshift Toggle random phaseshift on targets + * \param self_coupling Toggle self coupling + * \param packet_len Packet length key for tagged stream + */ + static sptr make(std::vector range, + std::vector velocity, + std::vector rcs, + std::vector azimuth, + std::vector position_rx, + int samp_rate, + float center_freq, + float self_coupling_db, + bool rndm_phaseshift = true, + bool self_coupling = true, + const std::string& len_key = "packet_len"); + + virtual void setup_targets(std::vector range, + std::vector velocity, + std::vector rcs, + std::vector azimuth, + std::vector position_rx, + int samp_rate, + float center_freq, + float self_coupling_db, + bool rndm_phaseshift, + bool self_coupling) = 0; +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_STATIC_TARGET_SIMULATOR_CC_H */ diff --git a/include/gnuradio/radar/tracking_singletarget.h b/include/gnuradio/radar/tracking_singletarget.h new file mode 100644 index 00000000..4c8237f4 --- /dev/null +++ b/include/gnuradio/radar/tracking_singletarget.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_TRACKING_SINGLETARGET_H +#define INCLUDED_RADAR_TRACKING_SINGLETARGET_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block tracks a singletarget detection with a particle or kalman filter. As + * input values with identifiers 'range' and 'velocity' are needed and should hold a + * f32vector with only one element. All input variables tagged with std gives the standard + * deviation of the parameter. The threshold_track is a value which decides with the + * likelihood of the data if the new data is accepted as a track. A good starting value is + * threshold_track = 0.001. threshold_lost is the number of false tracks unitel the track + * is lost and the tracker begins with a new one. The string filter decides which tracking + * kernel should be used. 'kalman' or 'particle' are valid. If 'particle' is chosen + * num_particle gives the number of particles for the particle filter. If 'kalman' is + * chosen there is no effect on the tracker. + * + * \param num_particle Number of particles for particle filter. There is no effect if + * kalman filter is chosen. \param std_range_meas Standard deviation of the range + * measurement \param std_velocity_meas Standard deviation of the velocity measurement + * \param std_accel_sys Standard deviation of the system acceleration + * \param threshold_track Value to decide if data is valid for the track + * \param theshold_lost Number of false tracks until the current track is lost + * \param filter Filter kernel to be used. 'kalman' or 'particle' are valid. + * + * \ingroup radar + * + */ +class RADAR_API tracking_singletarget : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::tracking_singletarget. + * + * To avoid accidental use of raw pointers, radar::tracking_singletarget's + * constructor is in a private implementation + * class. radar::tracking_singletarget::make is the public interface for + * creating new instances. + */ + static sptr make(int num_particle, + float std_range_meas, + float std_velocity_meas, + float std_accel_sys, + float threshold_track, + int threshold_lost, + std::string filter); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_TRACKING_SINGLETARGET_H */ diff --git a/include/gnuradio/radar/transpose_matrix_vcvc.h b/include/gnuradio/radar/transpose_matrix_vcvc.h new file mode 100644 index 00000000..643ef0c5 --- /dev/null +++ b/include/gnuradio/radar/transpose_matrix_vcvc.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_TRANSPOSE_MATRIX_VCVC_H +#define INCLUDED_RADAR_TRANSPOSE_MATRIX_VCVC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block transposes a matrix. A tagged stream combined with vectors as items + * represent a matrix. vlen_in is the vector length of the input data and vlen_out the + * vector length of the output data. vlen_out is equal to the items (vectors) per tagged + * stream on the input stream. + * + * \param vlen_in Vector length input + * \param vlen_out Vector length output + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API transpose_matrix_vcvc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::transpose_matrix_vcvc. + * + * To avoid accidental use of raw pointers, radar::transpose_matrix_vcvc's + * constructor is in a private implementation + * class. radar::transpose_matrix_vcvc::make is the public interface for + * creating new instances. + */ + static sptr make(int vlen_in, int vlen_out, std::string len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_TRANSPOSE_MATRIX_VCVC_H */ diff --git a/include/gnuradio/radar/trigger_command.h b/include/gnuradio/radar/trigger_command.h new file mode 100644 index 00000000..f04fa35c --- /dev/null +++ b/include/gnuradio/radar/trigger_command.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef INCLUDED_RADAR_TRIGGER_COMMAND_H +#define INCLUDED_RADAR_TRIGGER_COMMAND_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This block executes a command with the std::system() command if a value from a + * f32vector with a given identifier (symbol) is in a given range. Each index of a vector + * refers to a identifier. The execution of a command can be blocked for block_time + * milliseconds after the last execution. + * + * \param command Command string + * \param identifiers Identifiers (symbols) as vector of strings + * \param vals_min Minimum values as f32vector + * \param vals_max Maximum values as f32vector + * \param block_time Block executing commands for block_time milliseconds + * + * \ingroup radar + * + */ +class RADAR_API trigger_command : virtual public gr::block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::trigger_command. + * + * To avoid accidental use of raw pointers, radar::trigger_command's + * constructor is in a private implementation + * class. radar::trigger_command::make is the public interface for + * creating new instances. + */ + static sptr make(std::string command, + std::vector identifiers, + std::vector vals_min, + std::vector vals_max, + int block_time); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_TRIGGER_COMMAND_H */ diff --git a/include/gnuradio/radar/ts_fft_cc.h b/include/gnuradio/radar/ts_fft_cc.h new file mode 100644 index 00000000..7508dacc --- /dev/null +++ b/include/gnuradio/radar/ts_fft_cc.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_TS_FFT_CC_H +#define INCLUDED_RADAR_TS_FFT_CC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief This blocks takes a tagged stream and returns a FFT of the length of the input + * stream. The output is NOT normalized on the number of input items and no window is + * used. + * + * \param packet_len Packet length of tagged stream + * \param len_key Packet length key for tagged stream + * + * \ingroup radar + * + */ +class RADAR_API ts_fft_cc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::ts_fft_cc. + * + * To avoid accidental use of raw pointers, radar::ts_fft_cc's + * constructor is in a private implementation + * class. radar::ts_fft_cc::make is the public interface for + * creating new instances. + */ + static sptr make(int packet_len, const std::string& len_key = "packet_len"); +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_TS_FFT_CC_H */ diff --git a/include/gnuradio/radar/usrp_echotimer_cc.h b/include/gnuradio/radar/usrp_echotimer_cc.h new file mode 100644 index 00000000..03048bc2 --- /dev/null +++ b/include/gnuradio/radar/usrp_echotimer_cc.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2014 Communications Engineering Lab, KIT. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RADAR_USRP_ECHOTIMER_CC_H +#define INCLUDED_RADAR_USRP_ECHOTIMER_CC_H + +#include +#include + +namespace gr { +namespace radar { + +/*! + * \brief <+description of block+> + * \ingroup radar + * + */ +class RADAR_API usrp_echotimer_cc : virtual public gr::tagged_stream_block +{ +public: + typedef std::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of radar::usrp_echotimer_cc. + * + * To avoid accidental use of raw pointers, radar::usrp_echotimer_cc's + * constructor is in a private implementation + * class. radar::usrp_echotimer_cc::make is the public interface for + * creating new instances. + */ + static sptr make(int samp_rate, + float center_freq, + int num_delay_samps, + std::string args_tx, + std::string wire_tx, + std::string clock_source_tx, + std::string time_source_tx, + std::string antenna_tx, + float gain_tx, + float timeout_tx, + float wait_tx, + float lo_offset_tx, + std::string args_rx, + std::string wire_rx, + std::string clock_source_rx, + std::string time_source_rx, + std::string antenna_rx, + float gain_rx, + float timeout_rx, + float wait_rx, + float lo_offset_rx, + const std::string& len_key = "packet_len"); + + virtual void set_num_delay_samps(int num_samps) = 0; + virtual void set_rx_gain(float gain) = 0; + virtual void set_tx_gain(float gain) = 0; +}; + +} // namespace radar +} // namespace gr + +#endif /* INCLUDED_RADAR_USRP_ECHOTIMER_CC_H */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d85b5590..cdbeaddb 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -25,7 +25,8 @@ set(QTGUI_MOC_HEADERS scatter_plot.h time_plot.h spectrogram_plot.h) -QT5_WRAP_CPP(QTGUI_MOC_OUTFILES ${QTGUI_MOC_HEADERS}) + +qt5_wrap_cpp(QTGUI_MOC_OUTFILES ${QTGUI_MOC_HEADERS}) ######################################################################## # Setup library @@ -77,7 +78,7 @@ endif(NOT radar_sources) add_library(gnuradio-radar SHARED ${radar_sources}) target_link_libraries(gnuradio-radar PUBLIC - gnuradio::gnuradio-runtime ${QT_LIBRARIES} fftw3f::fftw3f UHD::UHD qwt::qwt + gnuradio::gnuradio-runtime ${QT_LIBRARIES} fftw3f::fftw3f UHD::UHD qwt::qwt Qt5::Widgets ) target_include_directories(gnuradio-radar PUBLIC $ @@ -95,7 +96,7 @@ endif(APPLE) # Install built library files ######################################################################## include(GrMiscUtils) -GR_LIBRARY_FOO(gnuradio-radar) +GR_LIBRARY_FOO(gnuradio-radar Qwt Qt5Widgets) ######################################################################## # Print summary diff --git a/lib/scatter_plot.h b/lib/scatter_plot.h index a0c1e25f..d35d19a2 100644 --- a/lib/scatter_plot.h +++ b/lib/scatter_plot.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace gr { namespace radar { diff --git a/python/radar/CMakeLists.txt b/python/radar/CMakeLists.txt index de4dede2..7459a05c 100644 --- a/python/radar/CMakeLists.txt +++ b/python/radar/CMakeLists.txt @@ -31,7 +31,7 @@ GR_PYTHON_INSTALL( include(GrTest) set(GR_TEST_TARGET_DEPS gnuradio-radar) -set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}) +#set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}) # Create a package directory that tests can import. It includes everything # from `python/`. diff --git a/python/radar/__init__.py b/python/radar/__init__.py index 57e4216c..5b9ac5fd 100644 --- a/python/radar/__init__.py +++ b/python/radar/__init__.py @@ -27,9 +27,8 @@ # import pybind11 generated symbols into the radar namespace try: # this might fail if the module is python-only - from .bindings.radar_python import * -except ModuleNotFoundError: from .radar_python import * +except ModuleNotFoundError: pass # import any pure python here diff --git a/python/radar/bindings/CMakeLists.txt b/python/radar/bindings/CMakeLists.txt index 686b3fcb..919fa4ae 100644 --- a/python/radar/bindings/CMakeLists.txt +++ b/python/radar/bindings/CMakeLists.txt @@ -1,3 +1,11 @@ +######################################################################## +# Check if there is C++ code at all +######################################################################## +if(NOT radar_sources) + MESSAGE(STATUS "No C++ sources... skipping python bindings") + return() +endif(NOT radar_sources) + ######################################################################## # Check for pygccxml ######################################################################## diff --git a/python/radar/bindings/bind_oot_file.py b/python/radar/bindings/bind_oot_file.py new file mode 100644 index 00000000..5bc3ff63 --- /dev/null +++ b/python/radar/bindings/bind_oot_file.py @@ -0,0 +1,58 @@ +import warnings +import argparse +import os +from gnuradio.bindtool import BindingGenerator +import pathlib +import sys +import tempfile + +parser = argparse.ArgumentParser(description='Bind a GR Out of Tree Block') +parser.add_argument('--module', type=str, + help='Name of gr module containing file to bind (e.g. fft digital analog)') + +parser.add_argument('--output_dir', default=tempfile.gettempdir(), + help='Output directory of generated bindings') +parser.add_argument('--prefix', help='Prefix of Installed GNU Radio') +parser.add_argument('--src', help='Directory of gnuradio source tree', + default=os.path.dirname(os.path.abspath(__file__)) + '/../../..') + +parser.add_argument( + '--filename', help="File to be parsed") + +parser.add_argument( + '--defines', help='Set additional defines for precompiler', default=(), nargs='*') +parser.add_argument( + '--include', help='Additional Include Dirs, separated', default=(), nargs='*') + +parser.add_argument( + '--status', help='Location of output file for general status (used during cmake)', default=None +) +parser.add_argument( + '--flag_automatic', default='0' +) +parser.add_argument( + '--flag_pygccxml', default='0' +) + +args = parser.parse_args() + +prefix = args.prefix +output_dir = args.output_dir +defines = tuple(','.join(args.defines).split(',')) +includes = ','.join(args.include) +name = args.module + +namespace = ['gr', name] +prefix_include_root = name + + +with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + + bg = BindingGenerator(prefix, namespace, + prefix_include_root, output_dir, define_symbols=defines, addl_includes=includes, + catch_exceptions=False, write_json_output=False, status_output=args.status, + flag_automatic=True if args.flag_automatic.lower() in [ + '1', 'true'] else False, + flag_pygccxml=True if args.flag_pygccxml.lower() in ['1', 'true'] else False) + bg.gen_file_binding(args.filename) diff --git a/python/radar/bindings/python_bindings.cc b/python/radar/bindings/python_bindings.cc index 62ee3fc1..2d2e89c5 100644 --- a/python/radar/bindings/python_bindings.cc +++ b/python/radar/bindings/python_bindings.cc @@ -15,36 +15,44 @@ namespace py = pybind11; -void bind_crop_matrix_vcvc(py::module&); -void bind_estimator_cw(py::module&); -void bind_estimator_fmcw(py::module&); -void bind_estimator_fsk(py::module&); -void bind_estimator_ofdm(py::module&); -void bind_estimator_rcs(py::module&); -void bind_estimator_sync_pulse_c(py::module&); -void bind_find_max_peak_c(py::module&); -void bind_msg_gate(py::module&); -void bind_msg_manipulator(py::module&); -void bind_ofdm_cyclic_prefix_remover_cvc(py::module&); -void bind_ofdm_divide_vcvc(py::module&); -void bind_os_cfar_2d_vc(py::module&); -void bind_os_cfar_c(py::module&); -void bind_print_results(py::module&); -void bind_qtgui_scatter_plot(py::module&); -void bind_qtgui_spectrogram_plot(py::module&); -void bind_qtgui_time_plot(py::module&); -void bind_signal_generator_cw_c(py::module&); -void bind_signal_generator_fmcw_c(py::module&); -void bind_signal_generator_fsk_c(py::module&); -void bind_signal_generator_sync_pulse_c(py::module&); -void bind_split_cc(py::module&); -void bind_split_fsk_cc(py::module&); -void bind_static_target_simulator_cc(py::module&); -void bind_tracking_singletarget(py::module&); -void bind_transpose_matrix_vcvc(py::module&); -void bind_trigger_command(py::module&); -void bind_ts_fft_cc(py::module&); -void bind_usrp_echotimer_cc(py::module&); +// Headers for binding functions +/**************************************/ +// The following comment block is used for +// gr_modtool to insert function prototypes +// Please do not delete +/**************************************/ +// BINDING_FUNCTION_PROTOTYPES( +void bind_crop_matrix_vcvc(py::module& m); +void bind_estimator_cw(py::module& m); +void bind_estimator_fmcw(py::module& m); +void bind_estimator_fsk(py::module& m); +void bind_estimator_ofdm(py::module& m); +void bind_estimator_rcs(py::module& m); +void bind_estimator_sync_pulse_c(py::module& m); +void bind_find_max_peak_c(py::module& m); +void bind_msg_gate(py::module& m); +void bind_msg_manipulator(py::module& m); +void bind_ofdm_cyclic_prefix_remover_cvc(py::module& m); +void bind_ofdm_divide_vcvc(py::module& m); +void bind_os_cfar_2d_vc(py::module& m); +void bind_os_cfar_c(py::module& m); +void bind_print_results(py::module& m); +void bind_qtgui_scatter_plot(py::module& m); +void bind_qtgui_spectrogram_plot(py::module& m); +void bind_qtgui_time_plot(py::module& m); +void bind_signal_generator_cw_c(py::module& m); +void bind_signal_generator_fmcw_c(py::module& m); +void bind_signal_generator_fsk_c(py::module& m); +void bind_signal_generator_sync_pulse_c(py::module& m); +void bind_split_cc(py::module& m); +void bind_split_fsk_cc(py::module& m); +void bind_static_target_simulator_cc(py::module& m); +void bind_tracking_singletarget(py::module& m); +void bind_transpose_matrix_vcvc(py::module& m); +void bind_trigger_command(py::module& m); +void bind_ts_fft_cc(py::module& m); +void bind_usrp_echotimer_cc(py::module& m); +// ) END BINDING_FUNCTION_PROTOTYPES // We need this hack because import_array() returns NULL // for newer Python versions. From 3137e2acc0bd8298fc4acafb6702fa9f2c3f007b Mon Sep 17 00:00:00 2001 From: caoziyi Date: Sat, 20 Apr 2024 13:16:28 +0800 Subject: [PATCH 2/4] remove the __pycache__ directories and corresponding .pyc files --- .../doxyxml/__pycache__/__init__.cpython-310.pyc | Bin 1983 -> 0 bytes .../doxyxml/__pycache__/base.cpython-310.pyc | Bin 6048 -> 0 bytes .../__pycache__/doxyindex.cpython-310.pyc | Bin 8496 -> 0 bytes .../doxyxml/__pycache__/text.cpython-310.pyc | Bin 1257 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/doxygen/doxyxml/__pycache__/__init__.cpython-310.pyc delete mode 100644 docs/doxygen/doxyxml/__pycache__/base.cpython-310.pyc delete mode 100644 docs/doxygen/doxyxml/__pycache__/doxyindex.cpython-310.pyc delete mode 100644 docs/doxygen/doxyxml/__pycache__/text.cpython-310.pyc diff --git a/docs/doxygen/doxyxml/__pycache__/__init__.cpython-310.pyc b/docs/doxygen/doxyxml/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 1cc18f70a1552956bc12e338dff3c4fa68305acd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1983 zcma)7O>ZML7@nDYO=epJ2nq3Vuoj_Y)NOL%1WQFJ+ttF7U8#FYRaws1N!*U@k?pA( zl%C2D=^pt5T)FcT=E`aR0vCAgne;;oh>7Cy$NTxbkKa+-+erY=&ab~Q(+h$>+~V#N z!QvbEn+XgwmlxZ|q+KV0R>>wg((%9bxA50U= zsP_aGDZ~Vl+-xj>!@a#d^ci|dw5fe|(f4 zOq1j(vxuOa8;E6&NS*_(#cs~dS&r1~lw}qI_BIL)*bk2d6C)p3>LG%q%b)TQ%w|kO zpb*`0IoK!koanQ`BUBDZJzrraRk>LDJwdn}oHPM|+j%K7SFZo-j!T?D85T;fhAy+i zM!#|YUoH=pEIUIS(v?k)2&z|TW`HwIwvf=07+fbcyiF%fUg?rGpxzfbJZvJ8%oxu*4}zaH*!a0a{I2AQuduUr zuNJj(`Zo4SIe1apq68pZFFEHHz;6s9;~J5%9Pa)gN#2CeBh!A>zqyaq)?EVE2hcl+ zsHX=xF{X;W3>2-}cC!ia$rR8BYni87l|_|!8Q_Ja_4W%0MrYvf=IO!=+G%hAfAc*I z(5ZtwxD3|8X?Pvk)>S~GkAm0XWw;J$>%-tOvh8(r6<)U1t?LeL!%2JHKJ7w>cACA* z&bo6QzYdOqv@>}F27@ZzG^(Gr@Aaap*FX;0N6J)f*SxA;)9I>S)9SSQnpDXx@YQ>7 zaUHZ&=9p6T+$a=HyZRmPeA5c6c+=*pi1Mlh)zBY+#4myV7+!yVFk5O;J&&yCS41`*av@S_yk0%_%R?* X=4{V#%WT2W?mrsEt#~U5+kgEHvqx-p diff --git a/docs/doxygen/doxyxml/__pycache__/base.cpython-310.pyc b/docs/doxygen/doxyxml/__pycache__/base.cpython-310.pyc deleted file mode 100644 index e7a12ec08e013d8b9dae373a39011e580df8421a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6048 zcma)A&2!tv6~`_>5CkPzaxD2H{y-8t3GG;N;%U;RYMKu_owf;^sWVBVP6md#kVJ+g z=mq3h9IBIvoT+=rp{L$5QV*T+AJ86pXlHuqq5lD{J>{HRJ017;TaXl~*qxGthlkz8 z?!Nba?_-h7&iWR9m;UtE`05GE`X?VIe-0jA$CZ*OYt2$Z$+lP%<}TMH?snVmIBSlu zl%q=RQpa6$h4mv#xvG56Qsub3Yp;1q-mq$3|11BE;8v8zL8Bd|Y0ylAhK{2wR?EKs z7MtSK^s8X2mvn<{6C)xW2U}^Zf-DI-(I;`xNs1PId0jW-u4-=w&2AR!^{5f2K1OAm zaiEgB+Z%B=xZ7!iZ=`69IAI*1HP&3S*aTMW>EupR#moNJkkYExMDAa|+l#X6S||Ez zfi^UGjil2{wz{gpL6g6+lAr@CwxAqqO+o=s6%-(28wzmnY%2%Pj(INOxuje?yXM(d zFDXw|?uoT>?1A@H^`6)jYZdb}qh`&MujbT|d)8WY!&;kB^J)S7tU9Wmz072Hp&E9ynu&!{pCeKmL9gq6RgDXQ{y zT;I%qj5MVL-jMw{zOj65tJiKeV4eB{JNLq{8+GC^%>6LzBxmksJZ}KNos0(rL51VL71z^?e zHnT81PsvY#xMK3}312uiTYS-IX7Im{Gqf5fQcVAPaCN*Fy>$S?4aL3o5gYuAR*w!zGaA$Cp-Y$!)SNoZ+7 z8HJLlI-?|KIQ}BWIiVald$=2AIaF4?kmMW|foSE8IE%7O8_|m%BEMGBPvfS~kQgKc z?+4IB(_(2+(z@-{AmivUcahFxip zVYNg{4n)gdMMAw{u9_^wp(LA8Y9uk+r6r9xHK|X7&uy6d(AG62eFs;{u;h!Q!g<)A zF`FFPerj{v*w{wPcozeg(bw>{59{hfv0G84c*xYS91EdFH&)&C|kXSw!*lPd6 zHDIxuWWjo~tAc2R)I<-#7(90&eQp`TRN>U2$@FoWR~k{baQVD){ca=fWzD3Ud$61d z^1y8&A>JvhcF01sF(ylYPEi>;1eBM9yRh=q@S2!%LSW^Z2=)(%pAznYZ>&My4-L+c~hamV?U zQ&^PTr{YuOh>h1>&SYNRFt5aU%N20Xd7M|zgm>^9n4Doz!*!&!YfjH;uaZ>=jZ%2<1&mZ12~EK8i*JRiphw zSab^@w=trSNc5{lnMM1QJQRTlGz;AVL+tIty{JtDK%rk~B6*?}QDI-e6_Yoh;WKN$YrhF@+p@1PVOrO_Y?m}B97kw)p9 zBD-W;x(jG_qF#?lrAWpBODq)5$#|}!9q3(W63WIiE(ZaZ8IETUi*_}t<%s#%^kTJx z$*@>a)z_0Qito{eYo&Z1pj>b2PS{O~YC#jmd3CZDaJZT&)N0N!bU?t|>&Bm&5~A>! zLxx)j86YMrj06*>G_~h4!ObDm&xv`-;L=|zYWDf1FT_V7xtff^0J9k~s#n4&(nQ*b;-Tz^a)L;53b$Hm#fYE!CY9P)4(RlWeG??VZULP+tfN>{~g{m5Rlj~Gm(q@J*+7Y zMomF~GERTPv_D3G@hg25P1uuxBEDc)`el+sZtw7r@fA9X6CRfBR}9A4{@CU8PdU}( z0tV}kTA)0PjKAj_?}7{~uwnDm62vr(VGO}^wPEcr20)&cMEEZw8SnsMzk>GL<;>YY zi~!D=8cy#3$$Ka}48EO~J8)X%b%X1Hjp*_s5`{N#O~GQdDtrE*ME>?73zI^WYJLO- zeugh6cVbnXr%*H$pEgvC(-Y3^%njr##s0x+hBo~Y39X%1!lJOldE7>sX`(>xGNO0Y z5afBOqp}odGfbG5x4O;STX9+-dk)JO z7UZPzGw0v^`38mCdb1q|7t;4@)m$bi z<LsnMxmANb%hBahkt1xm93h5!Hn diff --git a/docs/doxygen/doxyxml/__pycache__/doxyindex.cpython-310.pyc b/docs/doxygen/doxyxml/__pycache__/doxyindex.cpython-310.pyc deleted file mode 100644 index 02a55b2f24940077c722d7954b2328a435abae00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8496 zcmb_hON<=HdG6;-Pw(t-cDYND6fKP&u{}<-avamLVOl0bT8a)?$(Ems7?atl-sKGE z#p>P_xt=v-F99DMDTo0BJ`QaG0R!afgOMNsa`M^8rF}Ad^2rCn7yBT8-(Nj5J^SJU zNdxuwU$4Ka{`y~4HCS8>Eqs6Z^Z$xIc-FFh%S`_BkhzW&f77-sWo=l>R!-O6u$8O4 zuG4cjT-yTfcfFp!;R{~q7J9{vqHVoysiF!VSSpD819u}pzNA9rL&=wrUr=S_%TWpS zA@Yl=f_z2t3&@{SRphJD0_w|=-&q`2qVhvqXfLT{)GbThIkY{mR*+wjd=>dsbpiPc zQHZ`vS>L6s?^Eg`>Mly%a#pvT)m>7TQFmGD&S!P!v%06%71Ujkx|OVMC9C_0dIojR z$oQ*S-D+0%tg4}|ChNYC)m>nna^AM;&+YZXo84v{M{#Ya2fJ<6?r+z610B_N;z+-= zrQ1t8S-$yRV{qK)kpPOak7lA|;B*EHnl)d39 zXT$!1wI!1AAlUGJV0qStkJb5U=@w@B21nVehc$d}H8t1T%um0j+B#|_1ATu@+Whgt zc7I1VReP|uleD|>8kdS?wm9v{$JrE+_>cb^U}SYH?JMhTE3p%2WF0tT_n~E5i8uC> zLZ>(m(4wU5ht5NLWHmzM!p_1i>)SW>ksp^w_CtFg{l<&LlFA)NUmw|>bK|N)5B5U1X-ncPmj&Y;~-OAQb~I~4d0Js2cu&>HlH zgPp!g7g~exqx^WtCt6pn&qtxp+dr=xd@ZxvcAP}(OW~Ae^I6(@{ z;SlxdB0H_4c|3${*4@;LqwZGfl5!~EBIIJisL=r zt8!{0dTWMX^#WGX;My9EG;B0_1GUp7UT!q*?likuO|j9yR2mH#E?vy#-HN(hlyPJO zo+0)e0r%trQXBvTmS=n3iX){h6wH0xF@EtifV>Kc`Z&s^`b56+l>fjwur~^-po$Ny z4H#2Z!aoqzDnVGnbb;%;i9P-MsJDJZHE6!iaiq%t2~>g#(Q!t0+Zs6^*zeN-LFgXY z>vdO`&_;g@fDCH)+exE=(x+MAHT8C!7Vf;mzm`SU*jiRz2lg4H*a5g~@2%vfv^JsC zV&&u`&U6zgE(1WrM04-J8tRXufY#^^w)~Nkx)e)yu-VD6o#R5XntijUpF{RB36`C` z)%@tw7IVXsD?XA8|5+fy85^$6I&cr5{#oA1^6m%*p@V(7W{q6IylcX@y1$-QH({K& zauzc^ucD+04O02SC27{k7p+X%6I_@i|ySs=M{>Vj(;(lS|j|v?R<^J7gP+lDQC_lF!B>pG>wbH0G zF3?_&isRy_BsTREqav6ds2S7ek0uyyyq`4E;_YV4P1e_0KI_#^U^tgJ=v$M4-awJqB7F&M^(z4N zFjGznNb2lDONLMtdl&z9oI1m9>M4V@vD#t#@M2UXesJyfKzXAe4y(V6S_~C(D41mU%XR%W%5rpT%nI?Z0sAI%96>X8gs_W3evkhSV74BF zUCxG^54Yeid{r?10(ddQi@<{npZSfF;l*n^{T72fT?Fwo*vhhV>ct7rBJm$<0O;be z5f&mJ4|P6u7I1Q}%sGD3%XaKZNe(|VWzBVT)l#w*J)@}ASRrA#Wa>mJ7#>q_wp0qe|Xx$)v40n|SGzqx4Lqq8n%I>mU z0h~@ue~ax-r9@c~N{@~=3S@B_;JAZ`Hn}gHF!Q^?jwf0K?)yI=JzfT&MW9V6FFH1M z=|eVlfLNdn}mI`i`SlvJyEDDSPbl97XfHzUPD?;uwm& zabhBkH0*W9c(QUnY&k5QG(rbR5-@sB0qV#U+D049(ko~UD#t9wZC3P9#{ zi=kZ(rdq}pEu^`RBEm0bOr6s*RT>9Iy-k;<>){Dh;>KA($ReXNBqQpbUgVK|+9@aab>C={&t8ZF`(4C>eI#|9 zm-{gY#yq$hYv74WRc+_Pid%6I?OmM8KI2`6p~qPWu5(VmpzlWJPW2H#<7!03B&ZY> zn+|g}RpUUy;8O?sU@{Pb@aKuYK=2~LUl1Hpl+)FNJNF|bF`|qK;eaYDw#aP@<#Qi} zkDvZJK)qz5kedvJP1NN}SUe}UWG1^Y#a{t9Np2Z($zciMlwPIGWr0_*6J%jn34Lcd z$f-H;n?rU!o{BM!upwR4QGzq=Ze)&`g$8b%2HJ#K=NgkrWomJYWbTtxv?Xy@x(t_& z3(7dVE<$;HqAU7$u8@x02wy-a&YK&%>>8IOj5?FRox!00f=iqkbVK`WQg#M|{vQ+S zNA_|~G0qS<{pW;|-Xd0;g4wx@4wLaKkWZ+NR^?lxu0C8Z{$3(O|KUY`-K@dPh=nG^lK!!T{G;% z352C5vyC?&r?D-6ju#dd850?|@wy)D3^TW}O?-}tJj63RAS2^{19-9`&fEsoaox3upjPNzI_JBz5TDCa!~0guI(k&!3C(MQpD2{(NVqL%gx z$ue3OPHg=JxT^CLb;qkm>L=}_%jYLI84T+yIo1Cz)?z%gsJ`g>O!c{B{VoAdJ!#nP z-z*P67P`Qp_M@VrlpfaQ9lk-2opaCV$*k%kzY6>zRxXgPnIl`E(Pp zfB+)r=M4FY0m1>2bIS!lGeMV=g3v!vg;Q+&WI80~u#@2y(qSYJqk-KK6gH}OtZh!efjN>YEPkF!Zy zfXuY}QCdvy4OYx+S~mmE@$KJAkpOc+?Bh70;Zcta@NfrN9Hp(h7fj9;+5flTN#BsC6MVfi)dlfS`w-{b2@DaM> h#8Y*vSE|ofy{cEf1pIP!mH+Z8(h}0MNJW&F{|t=Zm^=Ug diff --git a/docs/doxygen/doxyxml/__pycache__/text.cpython-310.pyc b/docs/doxygen/doxyxml/__pycache__/text.cpython-310.pyc deleted file mode 100644 index b1dd9da7b776bf2280aa6c10c5913f43cb91cfb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1257 zcmZ`(&2G~`5Z+xoj^m`XqAeiA!2*G>fTo-(p{hcHBK49>K!{2xa=qKs#j(Tgh9*&R zA$d7ytS2TQ^L4i z%%IrXwfv{T11M9y;C&Yi3avgcsZm)4^%4^Y47eQ zmDpTI%&?_pKz=iy;Sdn zr}3YjDJ}G|0AZ}5VYYf&7&nIjFm5-N@sI^UR59h9SmAqF!-(!~k>+v{8DP02wzX|w zQ(5mP!uFuN4aUfkc!!*)t&Asy>Sg+BMhFwavUf>9=b#VIWQ}59G6r*Uvf!X@gEk`9 olv^#BzE;b|wtYM0gTs0yg7H^71@C2I4Q~*I@!X1E@~buPABIjC;s5{u From df6758f9f0dcec44e9559cb09caa2282c037929d Mon Sep 17 00:00:00 2001 From: caoziyi Date: Sat, 20 Apr 2024 13:19:10 +0800 Subject: [PATCH 3/4] remove the __pycache__ directories and corresponding .pyc files --- .../__pycache__/__init__.cpython-310.pyc | Bin 395 -> 0 bytes .../__pycache__/compound.cpython-310.pyc | Bin 21004 -> 0 bytes .../__pycache__/compoundsuper.cpython-310.pyc | Bin 245705 -> 0 bytes .../__pycache__/index.cpython-310.pyc | Bin 2346 -> 0 bytes .../__pycache__/indexsuper.cpython-310.pyc | Bin 17798 -> 0 bytes 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/doxygen/doxyxml/generated/__pycache__/__init__.cpython-310.pyc delete mode 100644 docs/doxygen/doxyxml/generated/__pycache__/compound.cpython-310.pyc delete mode 100644 docs/doxygen/doxyxml/generated/__pycache__/compoundsuper.cpython-310.pyc delete mode 100644 docs/doxygen/doxyxml/generated/__pycache__/index.cpython-310.pyc delete mode 100644 docs/doxygen/doxyxml/generated/__pycache__/indexsuper.cpython-310.pyc diff --git a/docs/doxygen/doxyxml/generated/__pycache__/__init__.cpython-310.pyc b/docs/doxygen/doxyxml/generated/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 9fdb43edffe2965d49285c45f648072ec93f9785..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 395 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 lu1RJ4QPL1)Dkb#J4b diff --git a/docs/doxygen/doxyxml/generated/__pycache__/compoundsuper.cpython-310.pyc b/docs/doxygen/doxyxml/generated/__pycache__/compoundsuper.cpython-310.pyc deleted file mode 100644 index 4790e9243ce1be115a4c67b65fe97d7548ddf035..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 245705 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ദ#7~_hiq*E_# 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 K_e)UE3;zq|xh9hU From 86e80d535c1c80f9f2221459474160367faa0835 Mon Sep 17 00:00:00 2001 From: DBAA Date: Wed, 24 Apr 2024 13:44:15 +0800 Subject: [PATCH 4/4] Move include/radar include/gnuradio/radar --- include/radar/CMakeLists.txt | 57 ------- include/radar/api.h | 34 ----- include/radar/crop_matrix_vcvc.h | 66 -------- include/radar/estimator_cw.h | 60 -------- include/radar/estimator_fmcw.h | 73 --------- include/radar/estimator_fsk.h | 64 -------- include/radar/estimator_ofdm.h | 79 ---------- include/radar/estimator_rcs.h | 95 ------------ include/radar/estimator_sync_pulse_c.h | 66 -------- include/radar/find_max_peak_c.h | 79 ---------- include/radar/msg_gate.h | 65 -------- include/radar/msg_manipulator.h | 67 -------- .../radar/ofdm_cyclic_prefix_remover_cvc.h | 63 -------- include/radar/ofdm_divide_vcvc.h | 70 --------- include/radar/os_cfar_2d_vc.h | 83 ---------- include/radar/os_cfar_c.h | 82 ---------- include/radar/print_results.h | 61 -------- include/radar/qtgui_scatter_plot.h | 72 --------- include/radar/qtgui_spectrogram_plot.h | 79 ---------- include/radar/qtgui_time_plot.h | 69 --------- include/radar/signal_generator_cw_c.h | 66 -------- include/radar/signal_generator_fmcw_c.h | 75 --------- include/radar/signal_generator_fsk_c.h | 72 --------- include/radar/signal_generator_sync_pulse_c.h | 72 --------- include/radar/split_cc.h | 64 -------- include/radar/split_fsk_cc.h | 63 -------- include/radar/static_target_simulator_cc.h | 143 ------------------ include/radar/tracking_singletarget.h | 79 ---------- include/radar/transpose_matrix_vcvc.h | 63 -------- include/radar/trigger_command.h | 69 --------- include/radar/ts_fft_cc.h | 60 -------- include/radar/usrp_echotimer_cc.h | 79 ---------- 32 files changed, 2289 deletions(-) delete mode 100644 include/radar/CMakeLists.txt delete mode 100644 include/radar/api.h delete mode 100644 include/radar/crop_matrix_vcvc.h delete mode 100644 include/radar/estimator_cw.h delete mode 100644 include/radar/estimator_fmcw.h delete mode 100644 include/radar/estimator_fsk.h delete mode 100644 include/radar/estimator_ofdm.h delete mode 100644 include/radar/estimator_rcs.h delete mode 100644 include/radar/estimator_sync_pulse_c.h delete mode 100644 include/radar/find_max_peak_c.h delete mode 100644 include/radar/msg_gate.h delete mode 100644 include/radar/msg_manipulator.h delete mode 100644 include/radar/ofdm_cyclic_prefix_remover_cvc.h delete mode 100644 include/radar/ofdm_divide_vcvc.h delete mode 100644 include/radar/os_cfar_2d_vc.h delete mode 100644 include/radar/os_cfar_c.h delete mode 100644 include/radar/print_results.h delete mode 100644 include/radar/qtgui_scatter_plot.h delete mode 100644 include/radar/qtgui_spectrogram_plot.h delete mode 100644 include/radar/qtgui_time_plot.h delete mode 100644 include/radar/signal_generator_cw_c.h delete mode 100644 include/radar/signal_generator_fmcw_c.h delete mode 100644 include/radar/signal_generator_fsk_c.h delete mode 100644 include/radar/signal_generator_sync_pulse_c.h delete mode 100644 include/radar/split_cc.h delete mode 100644 include/radar/split_fsk_cc.h delete mode 100644 include/radar/static_target_simulator_cc.h delete mode 100644 include/radar/tracking_singletarget.h delete mode 100644 include/radar/transpose_matrix_vcvc.h delete mode 100644 include/radar/trigger_command.h delete mode 100644 include/radar/ts_fft_cc.h delete mode 100644 include/radar/usrp_echotimer_cc.h diff --git a/include/radar/CMakeLists.txt b/include/radar/CMakeLists.txt deleted file mode 100644 index 0385c145..00000000 --- a/include/radar/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2011,2012 Free Software Foundation, Inc. -# -# This file was generated by gr_modtool, a tool from the GNU Radio framework -# This file is a part of gr-radar -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. - -######################################################################## -# Install public header files -######################################################################## -install(FILES - api.h - signal_generator_cw_c.h - signal_generator_fmcw_c.h - split_cc.h - os_cfar_c.h - ts_fft_cc.h - estimator_cw.h - print_results.h - static_target_simulator_cc.h - signal_generator_fsk_c.h - split_fsk_cc.h - estimator_fsk.h - usrp_echotimer_cc.h - estimator_fmcw.h - signal_generator_sync_pulse_c.h - estimator_sync_pulse_c.h - find_max_peak_c.h - qtgui_scatter_plot.h - qtgui_time_plot.h - tracking_singletarget.h - msg_gate.h - msg_manipulator.h - ofdm_cyclic_prefix_remover_cvc.h - transpose_matrix_vcvc.h - qtgui_spectrogram_plot.h - crop_matrix_vcvc.h - ofdm_divide_vcvc.h - os_cfar_2d_vc.h - estimator_ofdm.h - estimator_rcs.h - trigger_command.h - DESTINATION include/radar -) diff --git a/include/radar/api.h b/include/radar/api.h deleted file mode 100644 index 5369014f..00000000 --- a/include/radar/api.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2011 Free Software Foundation, Inc. - * - * This file was generated by gr_modtool, a tool from the GNU Radio framework - * This file is a part of gr-radar - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_API_H -#define INCLUDED_RADAR_API_H - -#include - -#ifdef gnuradio_radar_EXPORTS -#define RADAR_API __GR_ATTR_EXPORT -#else -#define RADAR_API __GR_ATTR_IMPORT -#endif - -#endif /* INCLUDED_RADAR_API_H */ diff --git a/include/radar/crop_matrix_vcvc.h b/include/radar/crop_matrix_vcvc.h deleted file mode 100644 index e7c55a20..00000000 --- a/include/radar/crop_matrix_vcvc.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_CROP_MATRIX_VCVC_H -#define INCLUDED_RADAR_CROP_MATRIX_VCVC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This matrix crops a data matrix. A tagged stream combined with vectors as items - * represent a matrix. crop_x and crop_y gives the ranges which shall be pushed through. - * Rest of the matrix is lost. - * - * \param vlen Vector length - * \param crop_x Index range on x axis to crop matrix - * \param crop_y Index range on y axis to crop matrix - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API crop_matrix_vcvc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::crop_matrix_vcvc. - * - * To avoid accidental use of raw pointers, radar::crop_matrix_vcvc's - * constructor is in a private implementation - * class. radar::crop_matrix_vcvc::make is the public interface for - * creating new instances. - */ - static sptr make(int vlen, - std::vector crop_x, - std::vector crop_y, - std::string len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_CROP_MATRIX_VCVC_H */ diff --git a/include/radar/estimator_cw.h b/include/radar/estimator_cw.h deleted file mode 100644 index a262926b..00000000 --- a/include/radar/estimator_cw.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_ESTIMATOR_CW_H -#define INCLUDED_RADAR_ESTIMATOR_CW_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block estimates the velocity from given peaks of a CW spectrum. The - * estimator looks for a f32vector tagged with a 'frequency' identifier (symbol) and - * calculates the velocity with the doppler formula. The identifier (symbol) of the output - * data is 'velocity'. Needed identifier (symbols) of the input are 'frequency'. - * - * \param center_freq Center frequency - * - * \ingroup radar - * - */ -class RADAR_API estimator_cw : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::estimator_cw. - * - * To avoid accidental use of raw pointers, radar::estimator_cw's - * constructor is in a private implementation - * class. radar::estimator_cw::make is the public interface for - * creating new instances. - */ - static sptr make(float center_freq); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_ESTIMATOR_CW_H */ diff --git a/include/radar/estimator_fmcw.h b/include/radar/estimator_fmcw.h deleted file mode 100644 index 928e3a77..00000000 --- a/include/radar/estimator_fmcw.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_ESTIMATOR_FMCW_H -#define INCLUDED_RADAR_ESTIMATOR_FMCW_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block estimates range and veloicty from peaks of a FMCW spectrum. Input - * messages are data with the identifier 'frequency' of the up-chirp, down-chirp and CW - * part. If data is available on all three message ports the estimation starts. The - * velocity is estimated with the frequency information of the CW block and the range is - * estimated with the up and down chirp. If multiple frequencies are given, the velocity - * is estimated first and associated with the most likely range from the up- and - * down-chirp. The output identifiers are 'range' and 'velocity'. - * - * \param samp_rate Sample rate - * \param center_freq Center frequency - * \param sweep_freq Sweep frequency - * \param samp_up Samples of up-chirp - * \param samp_down Samples of down-chirp - * \param push_power Push through power of peak - * - * \ingroup radar - * - */ -class RADAR_API estimator_fmcw : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::estimator_fmcw. - * - * To avoid accidental use of raw pointers, radar::estimator_fmcw's - * constructor is in a private implementation - * class. radar::estimator_fmcw::make is the public interface for - * creating new instances. - */ - static sptr make(int samp_rate, - float center_freq, - float sweep_freq, - int samp_up, - int samp_down, - bool push_power); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_ESTIMATOR_FMCW_H */ diff --git a/include/radar/estimator_fsk.h b/include/radar/estimator_fsk.h deleted file mode 100644 index b4bca36e..00000000 --- a/include/radar/estimator_fsk.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_ESTIMATOR_FSK_H -#define INCLUDED_RADAR_ESTIMATOR_FSK_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block estimates the range with peaks given from a FSK spectrum. Needed - * identifiers (symbols) are 'frequency' and 'phase'. The velocity is calculated with the - * 'frequency' information and the doppler formula. The phase of the doppler peaks are - * used to estimate the range. Output identifier are 'range' and 'velocity'. If push_power - * is true the information about the power of the peaks is pushed through. This can be - * used for estimating the RCS of an object. - * - * \param center_freq Center frequency - * \param delta_freq Frequency difference of high and low frequency - * \param push_power Toggle pushing through information about power of peaks - * - * \ingroup radar - * - */ -class RADAR_API estimator_fsk : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::estimator_fsk. - * - * To avoid accidental use of raw pointers, radar::estimator_fsk's - * constructor is in a private implementation - * class. radar::estimator_fsk::make is the public interface for - * creating new instances. - */ - static sptr make(float center_freq, float delta_freq, bool push_power = false); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_ESTIMATOR_FSK_H */ diff --git a/include/radar/estimator_ofdm.h b/include/radar/estimator_ofdm.h deleted file mode 100644 index bdaeb089..00000000 --- a/include/radar/estimator_ofdm.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_ESTIMATOR_OFDM_H -#define INCLUDED_RADAR_ESTIMATOR_OFDM_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block evaluates the peaks given from a OFDM matrix. Input are the bins of - * the peaks with the identifiers 'axis_x' and 'axis_y'. The parameters of the block - * axis_x and axis_y are vectors which define the mapping of the axis. If two values are - * given it is assumed a linear progression in between. If four values are given the - * middle values are set on half of the axis and it is interpolated linear in between. - * len_x and len_y gives the length of the axis in number of bins. symbol_x and symbol_y - * defines the identifier (symbols) for the output data. merge_consecutive toggles merging - * consecutive peaks. Each peak is compared with peaks in a range of one bin. If there is - * a peak with a higher power the actual bin is not used for evaluations. If - * merge_consecutive is true data with identifier 'power' is needed. - * - * \param symbol_x Identifier (symbol) for information on x axis - * \param len_x Length of x axis in bins - * \param axis_x Axis x - * \param symbol_y Identifier (symbol) for information on y axis - * \param len_y Length of y axis in bins - * \param axis_y Axis y - * \param merge_consecutive Merge consecutive peaks - * - * \ingroup radar - * - */ -class RADAR_API estimator_ofdm : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::estimator_ofdm. - * - * To avoid accidental use of raw pointers, radar::estimator_ofdm's - * constructor is in a private implementation - * class. radar::estimator_ofdm::make is the public interface for - * creating new instances. - */ - static sptr make(std::string symbol_x, - int len_x, - std::vector axis_x, - std::string symbol_y, - int len_y, - std::vector axis_y, - bool merge_consecutive = true); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_ESTIMATOR_OFDM_H */ diff --git a/include/radar/estimator_rcs.h b/include/radar/estimator_rcs.h deleted file mode 100644 index 7b34a794..00000000 --- a/include/radar/estimator_rcs.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_ESTIMATOR_RCS_H -#define INCLUDED_RADAR_ESTIMATOR_RCS_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief Basic RCS block for estimating the RCS of a single target. Some hardware specs - need to be known for calculating RCS values, see parameters for details. The radar - equation is used to calculate the RCS: RCS = Pr*(4pi)^3*R^4/(Pt*Gt*Gr*lamda^2). The Rx - power (Pr) and the distance (R) are being estimated, while the other parameters are given - in the flowgraph. It is possible to average a number of samples by setting the num_mean - value > 1. The RCS will be 0 until enough samples are collected to calculate the mean - value (be patient). The Tx power (Pt) needs to be calibrated with external hardware. I - recommend to calibrate for the wanted power and not to change the parameters in the - flowgraph on the Tx side after that. The RCS block needs the Rx power, to estimate the - RCS. For that, the input power of the block needs to be determined analytically and - altered via the corr_factor and exponent values, to fit the following equation: Pr = - P_input ^ (exponent) * corr_factor / Pt. In addition, the FFTs need to be normalized for - correct power calculation. - * - * \param num_mean Number of samples taken into account for calculating mean value (1 for - no mean calculation) - * \param center_freq Center frequency of radar - * \param antenna_gain_tx Antenna Gain of the Tx antenna - * \param antenna_gain_rx Antenna Gain of the Rx antenna - * \param usrp_gain_rx Rx gain of USRP set in flowgraph - * \param power_tx Tx power of radar signal. Needs to be measured one time! - * \param corr_factor Correction factor for the RCS to calibrate system to a known target - or special signal paths - * \param exponent Exponent of the input power to calculate Rx power, depends on signal - path (calculate analytically) - * - * \ingroup radar - * - */ -class RADAR_API estimator_rcs : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::estimator_rcs. - * - * To avoid accidental use of raw pointers, radar::estimator_rcs's - * constructor is in a private implementation - * class. radar::estimator_rcs::make is the public interface for - * creating new instances. - */ - static sptr make(int num_mean, - float center_freq, - float antenna_gain_tx, - float antenna_gain_rx, - float usrp_gain_rx, - float power_tx, - float corr_factor, - float exponent = 1); - // callbacks - virtual void set_num_mean(int val) = 0; - virtual void set_center_freq(float val) = 0; - virtual void set_antenna_gain_tx(float val) = 0; - virtual void set_antenna_gain_rx(float val) = 0; - virtual void set_usrp_gain_rx(float val) = 0; - virtual void set_power_tx(float val) = 0; - virtual void set_corr_factor(float val) = 0; -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_ESTIMATOR_RCS_H */ diff --git a/include/radar/estimator_sync_pulse_c.h b/include/radar/estimator_sync_pulse_c.h deleted file mode 100644 index 91794db5..00000000 --- a/include/radar/estimator_sync_pulse_c.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_ESTIMATOR_SYNC_PULSE_C_H -#define INCLUDED_RADAR_ESTIMATOR_SYNC_PULSE_C_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block can be used to estimate the shift of a signal on input 1 in relation - * to another on input 2. For example the constant number of delay samples due to - * hardware effect from a signal source can be estimated. The calculation of the shift is - * done by a cross correlation of the input signals. The number of correlations in samples - * is given with num_xcorr. The output message is the number of delay samples with the - * identifier (symbol) 'sync_pulse'. This can be displayed with the 'Print Results' block. - * - * \param num_xcorr Number of cross correlations - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API estimator_sync_pulse_c : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::estimator_sync_pulse_c. - * - * To avoid accidental use of raw pointers, radar::estimator_sync_pulse_c's - * constructor is in a private implementation - * class. radar::estimator_sync_pulse_c::make is the public interface for - * creating new instances. - */ - static sptr make(int num_xcorr, const std::string len_key = "packet_len"); - - virtual void set_num_xcorr(int num) = 0; -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_ESTIMATOR_SYNC_PULSE_C_H */ diff --git a/include/radar/find_max_peak_c.h b/include/radar/find_max_peak_c.h deleted file mode 100644 index 0df3ecbe..00000000 --- a/include/radar/find_max_peak_c.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_FIND_MAX_PEAK_C_H -#define INCLUDED_RADAR_FIND_MAX_PEAK_C_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block estimates a single peak of a given FFT spectrum as tagged stream. - * Output is a message with the information of frequency, phase and power of the peak as a - * f32vector with a single item. All data is tagged with the identifiers (symbols) - * 'frequency', 'phase' and 'power'. The peak is estimated on the whole spectrum or on the - * range max_freq if cut_max_freq is true. Furthermore a threshold of the spectrum - * amplitude can be given with threshold. The DC peak can be cut out with the protected - * samples samp_protect. This value do not evaluate samp_protect samples around the DC - * peak. If no suitable peak is found the block returns empty vectors with the - * identifiers. - * - * \param samp_rate Sample rate - * \param threshold Threshold for detection of the spectrum amplitude - * \param samp_protect Protected samples for cutting DC peak - * \param max_freq Frequency range for cutting spectrum - * \param cut_max_freq Toggle cutting the spectrum for peak estimation - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API find_max_peak_c : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::find_max_peak_c. - * - * To avoid accidental use of raw pointers, radar::find_max_peak_c's - * constructor is in a private implementation - * class. radar::find_max_peak_c::make is the public interface for - * creating new instances. - */ - static sptr make(int samp_rate, - float threshold, - int samp_protect, - std::vector max_freq, - bool cut_max_freq, - const std::string& len_key = "packet_len"); - virtual void set_threshold(float threshold) = 0; - virtual void set_samp_protect(int samp) = 0; - virtual void set_max_freq(std::vector freq) = 0; -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_FIND_MAX_PEAK_C_H */ diff --git a/include/radar/msg_gate.h b/include/radar/msg_gate.h deleted file mode 100644 index c44df729..00000000 --- a/include/radar/msg_gate.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_MSG_GATE_H -#define INCLUDED_RADAR_MSG_GATE_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block blocks messages whose data is not in range of val_min to val_max. All - * parameters are given as vectors. Each index represents a dataset with given identifier - * (symbol) which should be tested on valid data in given range. All other data is pushed - * through. - * - * \param keys Identifiers (symbols) of the data as vector - * \param val_min Lower limit of the gate as vector - * \param val_max Higher limit of the gate as vector - * - * \ingroup radar - * - */ -class RADAR_API msg_gate : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::msg_gate. - * - * To avoid accidental use of raw pointers, radar::msg_gate's - * constructor is in a private implementation - * class. radar::msg_gate::make is the public interface for - * creating new instances. - */ - static sptr make(std::vector keys, - std::vector val_min, - std::vector val_max); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_MSG_GATE_H */ diff --git a/include/radar/msg_manipulator.h b/include/radar/msg_manipulator.h deleted file mode 100644 index e49f3b43..00000000 --- a/include/radar/msg_manipulator.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_MSG_MANIPULATOR_H -#define INCLUDED_RADAR_MSG_MANIPULATOR_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block manipulates data in a msg with given identifier (symbol). All data - * are given as vectors and each index represents a dataset with identifier which should - * be processed. All other data is pushed through. The addition is performed before the - * multiplication. - * - * \param symbols Identifier (symbols) of data as vector - * \param const_add Value to add on the data - * \param const_mult Value to multiply on the data - * - * \ingroup radar - * - */ -class RADAR_API msg_manipulator : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::msg_manipulator. - * - * To avoid accidental use of raw pointers, radar::msg_manipulator's - * constructor is in a private implementation - * class. radar::msg_manipulator::make is the public interface for - * creating new instances. - */ - static sptr make(std::vector symbols, - std::vector const_add, - std::vector const_mult); - virtual void set_const_add(std::vector val) = 0; - virtual void set_const_mult(std::vector val) = 0; -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_MSG_MANIPULATOR_H */ diff --git a/include/radar/ofdm_cyclic_prefix_remover_cvc.h b/include/radar/ofdm_cyclic_prefix_remover_cvc.h deleted file mode 100644 index c3047c1a..00000000 --- a/include/radar/ofdm_cyclic_prefix_remover_cvc.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_OFDM_CYCLIC_PREFIX_REMOVER_CVC_H -#define INCLUDED_RADAR_OFDM_CYCLIC_PREFIX_REMOVER_CVC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block removes the cyclic prefix of a OFDM signal by cut away the cyclic - * prefix data. cp_len gives the length of the cyclic prefix. fft_len represents the - * length of the data before the cyclic prefix. - * - * \param fft_len Length of FFT - * \param cp_len Length of cyclic prefix - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API ofdm_cyclic_prefix_remover_cvc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of - * radar::ofdm_cyclic_prefix_remover_cvc. - * - * To avoid accidental use of raw pointers, radar::ofdm_cyclic_prefix_remover_cvc's - * constructor is in a private implementation - * class. radar::ofdm_cyclic_prefix_remover_cvc::make is the public interface for - * creating new instances. - */ - static sptr make(int fft_len, int cp_len, std::string len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_OFDM_CYCLIC_PREFIX_REMOVER_CVC_H */ diff --git a/include/radar/ofdm_divide_vcvc.h b/include/radar/ofdm_divide_vcvc.h deleted file mode 100644 index dfcf6a4c..00000000 --- a/include/radar/ofdm_divide_vcvc.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_OFDM_DIVIDE_VCVC_H -#define INCLUDED_RADAR_OFDM_DIVIDE_VCVC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block performs a complex complex division with in0/in1. If vlen_out > - * vlen_in the additional space is filled with zeros. This can be used for zeropadding. - * discarded_carriers is a vector of the carriers which should be not used and set zero as - * division result. num_sync_words gives the number of sync words on which the - * discarded_carriers rule is not applied. - * - * \param vlen_in Input vector length - * \param vlen_out Output vector length - * \param discarded_carriers Discarded carriers - * \param num_sync_words Number of sync words - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API ofdm_divide_vcvc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::ofdm_divide_vcvc. - * - * To avoid accidental use of raw pointers, radar::ofdm_divide_vcvc's - * constructor is in a private implementation - * class. radar::ofdm_divide_vcvc::make is the public interface for - * creating new instances. - */ - static sptr make(int vlen_in, - int vlen_out, - std::vector discarded_carriers, - int num_sync_words, - std::string len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_OFDM_DIVIDE_VCVC_H */ diff --git a/include/radar/os_cfar_2d_vc.h b/include/radar/os_cfar_2d_vc.h deleted file mode 100644 index a9d72dee..00000000 --- a/include/radar/os_cfar_2d_vc.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_OS_CFAR_2D_VC_H -#define INCLUDED_RADAR_OS_CFAR_2D_VC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block estimates peaks of a given matrix. A matrix can be represented as a - * combination of vectors and tagged streams. Input has to be a matrix with linear scaled - * values (NOT logarithmic scaled!). Used algorithm is a 2D OS-CFAR algorithm. The - * algorithm uses around the cell under test (CUT) on each side samp_compare samples to - * estimate the noise floor. samp_protect is a protected are around the CUT which is not - * used for acquiring compare samples. Index 0 of a input vector refers to x axis - * properties and index 1 refers to y axis properties. The relative threshold is defined - * by the bin of the vector within the sorted samp_compare samples. A standard value is - * rel_threshold = 0.78. The value of this bin is multiplied by mult_threshold and - * compared with the CUT. If the magnitude square of the CUT is greater than the threshold - * the matrix item is accepted. Used identifiers (symbols) for data are 'axis_x', 'axis_y' - * and 'power'. - * - * \param vlen Input vector length - * \param samp_compare Compare samples (vector index refers to axis) - * \param samp_protect Protected samples (vector index refers to axis) - * \param rel_threshold Relative threshold - * \param mult_threshold Multiplier threshold - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API os_cfar_2d_vc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::os_cfar_2d_vc. - * - * To avoid accidental use of raw pointers, radar::os_cfar_2d_vc's - * constructor is in a private implementation - * class. radar::os_cfar_2d_vc::make is the public interface for - * creating new instances. - */ - static sptr make(int vlen, - std::vector samp_compare, - std::vector samp_protect, - float rel_threshold, - float mult_threshold, - const std::string& len_key = "packet_len"); - virtual void set_rel_threshold(float inp) = 0; - virtual void set_mult_threshold(float inp) = 0; - virtual void set_samp_compare(std::vector inp) = 0; - virtual void set_samp_protect(std::vector inp) = 0; -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_OS_CFAR_2D_VC_H */ diff --git a/include/radar/os_cfar_c.h b/include/radar/os_cfar_c.h deleted file mode 100644 index 297bae6e..00000000 --- a/include/radar/os_cfar_c.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_OS_CFAR_C_H -#define INCLUDED_RADAR_OS_CFAR_C_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block estimates peaks of a given FFT spectrum as tagged stream. Multi peak - * detection is implemented with the OS-CFAR algorithm. The algorithm uses around the cell - * under test (CUT) on each side samp_compare samples to estimate the noise floor. This - * relative threshold is defined by the bin of the vector within the sorted samp_compare - * samples. A standard value is rel_threshold = 0.78. The value of this bin is multiplied - * by mult_threshold and compared with the CUT. samp_protect samples are a protected are - * which is not used for acquiring compare samples. If consecutive bins are detected as - * valid peaks it is possible to merge these detections with merge_consecutive = true. - * Output data are f32vectors with the information of frequency, power and phase. The - * identifiers (symbols) are 'frequency', 'power' and 'phase'. - * - * \param samp_rate Sample rate - * \param samp_compare Sample to be compared with each other - * \param samp_protect Samples which are protected and not used for peak detection - * \param rel_threshold Relative threshold - * \param mult_threshold Multiplier threshold - * \param merge_consectuive Toggle merging consecutive detected peaks - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API os_cfar_c : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::os_cfar_c. - * - * To avoid accidental use of raw pointers, radar::os_cfar_c's - * constructor is in a private implementation - * class. radar::os_cfar_c::make is the public interface for - * creating new instances. - */ - static sptr make(int samp_rate, - int samp_compare, - int samp_protect, - float rel_threshold, - float mult_threshold, - bool merge_consecutive = true, - const std::string& len_key = "packet_len"); - virtual void set_rel_threshold(float inp) = 0; - virtual void set_mult_threshold(float inp) = 0; - virtual void set_samp_compare(int inp) = 0; - virtual void set_samp_protect(int inp) = 0; -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_OS_CFAR_C_H */ diff --git a/include/radar/print_results.h b/include/radar/print_results.h deleted file mode 100644 index 152e7454..00000000 --- a/include/radar/print_results.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_PRINT_RESULTS_H -#define INCLUDED_RADAR_PRINT_RESULTS_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block prints data of messages filled with data of the structure [ - * [[symbol_0],[data_0]], [[symbol_1],[data_1]], ...] on the command line. Only data of - * the datatypes f32vector and long, and rx_time tuples are displayed. The output can also - * be stored in a text file. - * - * \param store_msg Toggle save output to file - * \param filename Filename of the output file - * - * \ingroup radar - * - */ -class RADAR_API print_results : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::print_results. - * - * To avoid accidental use of raw pointers, radar::print_results's - * constructor is in a private implementation - * class. radar::print_results::make is the public interface for - * creating new instances. - */ - static sptr make(bool store_msg = false, const std::string filename = ""); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_PRINT_RESULTS_H */ diff --git a/include/radar/qtgui_scatter_plot.h b/include/radar/qtgui_scatter_plot.h deleted file mode 100644 index 20900938..00000000 --- a/include/radar/qtgui_scatter_plot.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_QTGUI_SCATTER_PLOT_H -#define INCLUDED_RADAR_QTGUI_SCATTER_PLOT_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block displays a scatter plot of two data sets. The identifiers (symbols) - * are given with label_x and label_y. The display range is given with axis_x and axis_y. - * Points that are not in range are simply not displayed (there are no errors or - * warnings). label gives an additional label to differ multiple scatter plots on the - * screen by the titles. The update interval is given in milliseconds. - * - * \param interval Update interval in milliseconds - * \param label_x Identifier (symbol) of first data set - * \param label_y Identifier (symbol) of second data set - * \param axis_x Display range on x axis - * \param axis_y Display range on y axis - * \param label Optional label for the title - * - * \ingroup radar - * - */ -class RADAR_API qtgui_scatter_plot : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::qtgui_scatter_plot. - * - * To avoid accidental use of raw pointers, radar::qtgui_scatter_plot's - * constructor is in a private implementation - * class. radar::qtgui_scatter_plot::make is the public interface for - * creating new instances. - */ - static sptr make(int interval, - std::string label_x, - std::string label_y, - std::vector axis_x, - std::vector axis_y, - std::string label = ""); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_QTGUI_SCATTER_PLOT_H */ diff --git a/include/radar/qtgui_spectrogram_plot.h b/include/radar/qtgui_spectrogram_plot.h deleted file mode 100644 index 9d04a1b8..00000000 --- a/include/radar/qtgui_spectrogram_plot.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_QTGUI_SPECTROGRAM_PLOT_H -#define INCLUDED_RADAR_QTGUI_SPECTROGRAM_PLOT_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block displays a spectrogram plot of a tagged stream with vectors. Tagged - * streams combined with vectors represent a matrix. The value of the matrix elements are - * displayed within a color plot. The colorbar can be scaled automatically or with a - * manual scale with axis_z. The axis of x and y are set with axis_x and axis_y. The - * update rate interval is given in milliseconds. - * - * \param vlen Vector length - * \param xlabel Label for x axis - * \param ylabel Label for y axis - * \param label Addition label for title - * \param axis_x Display range for x axis - * \param axis_y Display range for y axis - * \param axis_z Display range for z axis. This defines the colorbar if autoscale_z is - * disabled. \param autoscale_z Toggle automatic scale of the colorbar \param packet_len - * Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API qtgui_spectrogram_plot : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::qtgui_spectrogram_plot. - * - * To avoid accidental use of raw pointers, radar::qtgui_spectrogram_plot's - * constructor is in a private implementation - * class. radar::qtgui_spectrogram_plot::make is the public interface for - * creating new instances. - */ - static sptr make(int vlen, - int interval, - std::string xlabel, - std::string ylabel, - std::string label, - std::vector axis_x, - std::vector axis_y, - std::vector axis_z, - bool autoscale_z, - std::string len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_QTGUI_SPECTROGRAM_PLOT_H */ diff --git a/include/radar/qtgui_time_plot.h b/include/radar/qtgui_time_plot.h deleted file mode 100644 index d1fb8e96..00000000 --- a/include/radar/qtgui_time_plot.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_QTGUI_TIME_PLOT_H -#define INCLUDED_RADAR_QTGUI_TIME_PLOT_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block displays a plot of a value with a given interval in milliseconds. - * label_y represents the identifier (symbol) of the data. The y axis is scaled with - * axis_y. range_time gives the shown range of the x axis in seconds. label is an - * additional label for the title. - * - * \param interval Update interval in milliseconds - * \param label_y Lable for y axis and identifier (symbol) for data - * \param axis_y Display range y axis - * \param range_time Display range for x axis in seconds - * \param label Additional label for the title - * - * \ingroup radar - * - */ -class RADAR_API qtgui_time_plot : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::qtgui_time_plot. - * - * To avoid accidental use of raw pointers, radar::qtgui_time_plot's - * constructor is in a private implementation - * class. radar::qtgui_time_plot::make is the public interface for - * creating new instances. - */ - static sptr make(int interval, - std::string label_y, - std::vector axis_y, - float range_time, - std::string label = ""); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_QTGUI_TIME_PLOT_H */ diff --git a/include/radar/signal_generator_cw_c.h b/include/radar/signal_generator_cw_c.h deleted file mode 100644 index 460ac9c0..00000000 --- a/include/radar/signal_generator_cw_c.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_SIGNAL_GENERATOR_CW_C_H -#define INCLUDED_RADAR_SIGNAL_GENERATOR_CW_C_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block generates a signal for CW radar in baseband. The waveform consists of - * one (or sometimes multiple) constant frequency. - * - * \param packet_len packet_len is the length of a single tagged stream package which will - * be processed in subsequent tagged stream blocks. \param samp_rate Signal sample rate - * \param frequency This parameter holds a vector of all constant frequencies in baseband. - * \param amplitude Signal amplitude - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API signal_generator_cw_c : virtual public gr::sync_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::signal_generator_cw_c. - * - * To avoid accidental use of raw pointers, radar::signal_generator_cw_c's - * constructor is in a private implementation - * class. radar::signal_generator_cw_c::make is the public interface for - * creating new instances. - */ - static sptr make(int packet_len, - int samp_rate, - std::vector frequency, - float amplitude, - const std::string& len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_SIGNAL_GENERATOR_CW_C_H */ diff --git a/include/radar/signal_generator_fmcw_c.h b/include/radar/signal_generator_fmcw_c.h deleted file mode 100644 index 4618d226..00000000 --- a/include/radar/signal_generator_fmcw_c.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_SIGNAL_GENERATOR_FMCW_C_H -#define INCLUDED_RADAR_SIGNAL_GENERATOR_FMCW_C_H - -#include -#include - -namespace gr { -namespace radar { - -/*! Generates a signal for FMCW radar in baseband. - * - * The generated signal consists of three parts, in this order: - * - * 1. CW part with constant frequency - * 2. Up-chirp - * 3. Down-chirp - * - * The up-chirp goes from CW frequency to CW frequency plus sweep frequency - * and the down-chirp goes in the opposite direction. All of these parts - * can be disabled by setting the corresponding length to zero. - * - * The packet length for subsequent tagged streams is calculated by the sum - * of the number of samples of the single modulations parts. - * - * \ingroup radar - */ -class RADAR_API signal_generator_fmcw_c : virtual public gr::sync_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \param samp_rate Signal sample rate (samples per second) - * \param samp_up Number samples of up-chirp part - * \param samp_down Number samples of down-chirp part - * \param samp_cw Number samples of CW part - * \param freq_cw CW signal frequency in baseband - * \param freq_sweep Sweep frequency of up- and down-chirp - * \param amplitude Signal amplitude - * \param len_key Packet length key for tagged stream - */ - static sptr make(const int samp_rate, - const int samp_up, - const int samp_down, - const int samp_cw, - const float freq_cw, - const float freq_sweep, - const float amplitude, - const std::string& len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_SIGNAL_GENERATOR_FMCW_C_H */ diff --git a/include/radar/signal_generator_fsk_c.h b/include/radar/signal_generator_fsk_c.h deleted file mode 100644 index 1dd03b2c..00000000 --- a/include/radar/signal_generator_fsk_c.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_SIGNAL_GENERATOR_FSK_C_H -#define INCLUDED_RADAR_SIGNAL_GENERATOR_FSK_C_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block generates a signal for FSK radar in baseband. The waveform consists - * of a signal with an alternating frequency. The packet length for subsequent tagged - * streams is calculated with two times the samples per single frequency multiplied by the - * blocks per tag. - * - * \param samp_rate Signal sample rate - * \param samp_per_freq Number of samples per frequency until the frequency shifts - * \param blocks_per_tag A block contains samp_per_freq samples of the low frequency and - * samp_per_freq samples of the high frequency. The packet length for subsequent tagged - * stream blocks is calculated with 2*samp_per_freq*blocks_per_tag. \param freq_low Lower - * frequency in baseband \param freq_high Higher frequency in baseband \param amplitude - * Signal amplitude \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API signal_generator_fsk_c : virtual public gr::sync_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::signal_generator_fsk_c. - * - * To avoid accidental use of raw pointers, radar::signal_generator_fsk_c's - * constructor is in a private implementation - * class. radar::signal_generator_fsk_c::make is the public interface for - * creating new instances. - */ - static sptr make(int samp_rate, - int samp_per_freq, - int blocks_per_tag, - float freq_low, - float freq_high, - float amplitude, - const std::string& len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_SIGNAL_GENERATOR_FSK_C_H */ diff --git a/include/radar/signal_generator_sync_pulse_c.h b/include/radar/signal_generator_sync_pulse_c.h deleted file mode 100644 index 54b49a26..00000000 --- a/include/radar/signal_generator_sync_pulse_c.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_SIGNAL_GENERATOR_SYNC_PULSE_C_H -#define INCLUDED_RADAR_SIGNAL_GENERATOR_SYNC_PULSE_C_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block generates a signal for the synchronization of the USRP Echotimer in - * baseband. The signal is pulsed with a constant amplitude with various pulse length and - * wait samples in between. It is structured by alternating wait parts and burst parts and - * starting with the first wait part. The pulses are full real signals. - * - * \param packet_len The packet length has to be longer or equal than the sum of pulse_len - * and pulse_pause. \param pulse_len The length of the pulses are defined in a vector and - * given in number of samples. The pulses are generated alternating with the wait samples - * defined in pulse_pause. \param pulse_pause The wait samples between pulses are defined - * in a vector. The first segment of the whole signal is the first element in the - * pulse_pause vector. This element can be zero. \param pulse_amplitude Pulse amplitude of - * real signal \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API signal_generator_sync_pulse_c : virtual public gr::sync_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of - * radar::signal_generator_sync_pulse_c. - * - * To avoid accidental use of raw pointers, radar::signal_generator_sync_pulse_c's - * constructor is in a private implementation - * class. radar::signal_generator_sync_pulse_c::make is the public interface for - * creating new instances. - */ - static sptr make(int packet_len, - std::vector pulse_len, - std::vector pulse_pause, - float pulse_amplitude, - const std::string len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_SIGNAL_GENERATOR_SYNC_PULSE_C_H */ diff --git a/include/radar/split_cc.h b/include/radar/split_cc.h deleted file mode 100644 index bbede847..00000000 --- a/include/radar/split_cc.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_SPLIT_CC_H -#define INCLUDED_RADAR_SPLIT_CC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block splits a tagged stream into segments. As packet_parts you give the - * structure of the packet, e.g. (10, 20, 5). With the packet number you can choose which - * packet shall be pushed to output. Counting begins on zero. E.g. packet_num=1 returns 20 - * items. - * - * \param packet_num Number of packet to push to output - * \param packet_parts Packet structure as vector of packet length - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API split_cc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::split_cc. - * - * To avoid accidental use of raw pointers, radar::split_cc's - * constructor is in a private implementation - * class. radar::split_cc::make is the public interface for - * creating new instances. - */ - static sptr make(int packet_num, - const std::vector packet_parts, - const std::string& len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_SPLIT_CC_H */ diff --git a/include/radar/split_fsk_cc.h b/include/radar/split_fsk_cc.h deleted file mode 100644 index c785140b..00000000 --- a/include/radar/split_fsk_cc.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_SPLIT_FSK_CC_H -#define INCLUDED_RADAR_SPLIT_FSK_CC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block splits a FSK signal consisting of two separate signals. samp_per_freq - * items are taken and pushed alternating to the outputs. Discarded samples are thrown - * away at the beginning of samp_per_freq samples and only samp_per_freq-samp_discard are - * pushed to output. - * - * \param samp_per_freq Samples per frequency - * \param samp_discard Discarded samples - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API split_fsk_cc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::split_fsk_cc. - * - * To avoid accidental use of raw pointers, radar::split_fsk_cc's - * constructor is in a private implementation - * class. radar::split_fsk_cc::make is the public interface for - * creating new instances. - */ - static sptr - make(int samp_per_freq, int samp_discard, const std::string& len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_SPLIT_FSK_CC_H */ diff --git a/include/radar/static_target_simulator_cc.h b/include/radar/static_target_simulator_cc.h deleted file mode 100644 index ba08d500..00000000 --- a/include/radar/static_target_simulator_cc.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_STATIC_TARGET_SIMULATOR_CC_H -#define INCLUDED_RADAR_STATIC_TARGET_SIMULATOR_CC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! Simulates the backscattering of a given signal on point targets. - * - * Implements the point scatter model. The input signal is the transmitted - * signal. The output signal is the received, backscattered signal, and - * contains one output signal per receive antenna. - * - * \section radar_target_modeling Target modeling - * - * The targets are modeled by the vectors \p range, \p velocity, \p rcs, - * and \p azimuth. All these vectors need to be of length H, where H - * describes the number of reflecting targets. The backscattered signal - * can either have a zero phase, or a random phase (controlled by - * \p rndm_phaseshift). The received signal will be the linear - * superposition of H signals, each of which are derived from the input - * signal by the following equation: - * - * \f[ - * r_h(t) = b_h s(t - \tau_h) e^{j2\pi f_{D,h}} - * \f] - * - * The attenuation depends on the center frequency \f$f_C\f$, the radar - * cross section \f$\sigma_{\text{RCS},h}\f$, the distance of the target - * \f$d_h\f$ and the speed of light \f$c_0\f$: - * \f[ - * b_h = \sqrt{\frac{c_0^2 \sigma_{\text{RCS},h}}{(4\pi)^3 d_h^4 f_C^2}} - * \f] - * - * The delay \f$\tau_h\f$ depends on the distance of the target: - * \f[ - * \tau_h = 2\frac{d_h}{c_0} - * \f] - * - * The Doppler shift \f$f_{D,h}\f$ depends on the relative velocity and - * the center frequency: - * \f[ - * f_{D,h} = 2\frac{v_{\text{rel},h}{c_0} f_C - * \f] - * - * The signals are added up to produce the total sum signal: - * \f[ - * r(t) = \sum_{h=0}^{H-1} r_h(t) - * \f] - * - * \section radar_mimo_processing MIMO processing simulation - * - * This block has a limited capability of simulating multi-antenna - * reception. The \p position_rx vector determines the distance of every - * RX antenna from the origin (Note: The TX antenna is always in the - * origin). The length of the \p position_rx vector is thus also the number - * of output signals this block produces. For a simple, mono-static SISO - * radar, simply set position_rx to [0]. - * The RX antennas are always laid out in a straight line. When multiple - * antennas are given, the target azimuth plays a role; an azimuth of zero - * is perpendicular to the line in which the RX antennas are placed. - * - * \section radar_hw_impairments Self-coupling - * - * Self-coupling describes the amount of the TX signal that is directly - * coupled into the RX path. When \p self_coupling is set to true, - * effectively, a target with zero velocity and range is added. The - * parameter \p self_coupling_db describes the attenuation of the - * self-coupling, a value of -10 means that the transmit signal is - * attenuated by 10 dB on the receive signal. - * - * \ingroup radar - */ -class RADAR_API static_target_simulator_cc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \param range Target ranges as vector (length H) - * \param velocity Target velocities as vector (length H) - * \param rcs Target RCS as vector (length H) - * \param azimuth Target azimuth as vector (length H) - * \param position_rx Position RX antennas. A value of [0] means - * there is one antenna, located in the origin - * (simple monostatic case). - * \param samp_rate Sample rate (samples per second) - * \param center_freq Center frequency (Hz) - * \param self_coupling_db Self coupling attenuation (dB) - * \param rndm_phaseshift Toggle random phaseshift on targets - * \param self_coupling Toggle self coupling - * \param packet_len Packet length key for tagged stream - */ - static sptr make(std::vector range, - std::vector velocity, - std::vector rcs, - std::vector azimuth, - std::vector position_rx, - int samp_rate, - float center_freq, - float self_coupling_db, - bool rndm_phaseshift = true, - bool self_coupling = true, - const std::string& len_key = "packet_len"); - - virtual void setup_targets(std::vector range, - std::vector velocity, - std::vector rcs, - std::vector azimuth, - std::vector position_rx, - int samp_rate, - float center_freq, - float self_coupling_db, - bool rndm_phaseshift, - bool self_coupling) = 0; -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_STATIC_TARGET_SIMULATOR_CC_H */ diff --git a/include/radar/tracking_singletarget.h b/include/radar/tracking_singletarget.h deleted file mode 100644 index 4c8237f4..00000000 --- a/include/radar/tracking_singletarget.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_TRACKING_SINGLETARGET_H -#define INCLUDED_RADAR_TRACKING_SINGLETARGET_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block tracks a singletarget detection with a particle or kalman filter. As - * input values with identifiers 'range' and 'velocity' are needed and should hold a - * f32vector with only one element. All input variables tagged with std gives the standard - * deviation of the parameter. The threshold_track is a value which decides with the - * likelihood of the data if the new data is accepted as a track. A good starting value is - * threshold_track = 0.001. threshold_lost is the number of false tracks unitel the track - * is lost and the tracker begins with a new one. The string filter decides which tracking - * kernel should be used. 'kalman' or 'particle' are valid. If 'particle' is chosen - * num_particle gives the number of particles for the particle filter. If 'kalman' is - * chosen there is no effect on the tracker. - * - * \param num_particle Number of particles for particle filter. There is no effect if - * kalman filter is chosen. \param std_range_meas Standard deviation of the range - * measurement \param std_velocity_meas Standard deviation of the velocity measurement - * \param std_accel_sys Standard deviation of the system acceleration - * \param threshold_track Value to decide if data is valid for the track - * \param theshold_lost Number of false tracks until the current track is lost - * \param filter Filter kernel to be used. 'kalman' or 'particle' are valid. - * - * \ingroup radar - * - */ -class RADAR_API tracking_singletarget : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::tracking_singletarget. - * - * To avoid accidental use of raw pointers, radar::tracking_singletarget's - * constructor is in a private implementation - * class. radar::tracking_singletarget::make is the public interface for - * creating new instances. - */ - static sptr make(int num_particle, - float std_range_meas, - float std_velocity_meas, - float std_accel_sys, - float threshold_track, - int threshold_lost, - std::string filter); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_TRACKING_SINGLETARGET_H */ diff --git a/include/radar/transpose_matrix_vcvc.h b/include/radar/transpose_matrix_vcvc.h deleted file mode 100644 index 643ef0c5..00000000 --- a/include/radar/transpose_matrix_vcvc.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_TRANSPOSE_MATRIX_VCVC_H -#define INCLUDED_RADAR_TRANSPOSE_MATRIX_VCVC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block transposes a matrix. A tagged stream combined with vectors as items - * represent a matrix. vlen_in is the vector length of the input data and vlen_out the - * vector length of the output data. vlen_out is equal to the items (vectors) per tagged - * stream on the input stream. - * - * \param vlen_in Vector length input - * \param vlen_out Vector length output - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API transpose_matrix_vcvc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::transpose_matrix_vcvc. - * - * To avoid accidental use of raw pointers, radar::transpose_matrix_vcvc's - * constructor is in a private implementation - * class. radar::transpose_matrix_vcvc::make is the public interface for - * creating new instances. - */ - static sptr make(int vlen_in, int vlen_out, std::string len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_TRANSPOSE_MATRIX_VCVC_H */ diff --git a/include/radar/trigger_command.h b/include/radar/trigger_command.h deleted file mode 100644 index f04fa35c..00000000 --- a/include/radar/trigger_command.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_RADAR_TRIGGER_COMMAND_H -#define INCLUDED_RADAR_TRIGGER_COMMAND_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This block executes a command with the std::system() command if a value from a - * f32vector with a given identifier (symbol) is in a given range. Each index of a vector - * refers to a identifier. The execution of a command can be blocked for block_time - * milliseconds after the last execution. - * - * \param command Command string - * \param identifiers Identifiers (symbols) as vector of strings - * \param vals_min Minimum values as f32vector - * \param vals_max Maximum values as f32vector - * \param block_time Block executing commands for block_time milliseconds - * - * \ingroup radar - * - */ -class RADAR_API trigger_command : virtual public gr::block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::trigger_command. - * - * To avoid accidental use of raw pointers, radar::trigger_command's - * constructor is in a private implementation - * class. radar::trigger_command::make is the public interface for - * creating new instances. - */ - static sptr make(std::string command, - std::vector identifiers, - std::vector vals_min, - std::vector vals_max, - int block_time); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_TRIGGER_COMMAND_H */ diff --git a/include/radar/ts_fft_cc.h b/include/radar/ts_fft_cc.h deleted file mode 100644 index 7508dacc..00000000 --- a/include/radar/ts_fft_cc.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_TS_FFT_CC_H -#define INCLUDED_RADAR_TS_FFT_CC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief This blocks takes a tagged stream and returns a FFT of the length of the input - * stream. The output is NOT normalized on the number of input items and no window is - * used. - * - * \param packet_len Packet length of tagged stream - * \param len_key Packet length key for tagged stream - * - * \ingroup radar - * - */ -class RADAR_API ts_fft_cc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::ts_fft_cc. - * - * To avoid accidental use of raw pointers, radar::ts_fft_cc's - * constructor is in a private implementation - * class. radar::ts_fft_cc::make is the public interface for - * creating new instances. - */ - static sptr make(int packet_len, const std::string& len_key = "packet_len"); -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_TS_FFT_CC_H */ diff --git a/include/radar/usrp_echotimer_cc.h b/include/radar/usrp_echotimer_cc.h deleted file mode 100644 index 03048bc2..00000000 --- a/include/radar/usrp_echotimer_cc.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Communications Engineering Lab, KIT. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_RADAR_USRP_ECHOTIMER_CC_H -#define INCLUDED_RADAR_USRP_ECHOTIMER_CC_H - -#include -#include - -namespace gr { -namespace radar { - -/*! - * \brief <+description of block+> - * \ingroup radar - * - */ -class RADAR_API usrp_echotimer_cc : virtual public gr::tagged_stream_block -{ -public: - typedef std::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of radar::usrp_echotimer_cc. - * - * To avoid accidental use of raw pointers, radar::usrp_echotimer_cc's - * constructor is in a private implementation - * class. radar::usrp_echotimer_cc::make is the public interface for - * creating new instances. - */ - static sptr make(int samp_rate, - float center_freq, - int num_delay_samps, - std::string args_tx, - std::string wire_tx, - std::string clock_source_tx, - std::string time_source_tx, - std::string antenna_tx, - float gain_tx, - float timeout_tx, - float wait_tx, - float lo_offset_tx, - std::string args_rx, - std::string wire_rx, - std::string clock_source_rx, - std::string time_source_rx, - std::string antenna_rx, - float gain_rx, - float timeout_rx, - float wait_rx, - float lo_offset_rx, - const std::string& len_key = "packet_len"); - - virtual void set_num_delay_samps(int num_samps) = 0; - virtual void set_rx_gain(float gain) = 0; - virtual void set_tx_gain(float gain) = 0; -}; - -} // namespace radar -} // namespace gr - -#endif /* INCLUDED_RADAR_USRP_ECHOTIMER_CC_H */