最近由于 GR3.8 里的卷积编码模块有问题就换用了 GR3.9 ,发现 GR3.9 可以正常使用,关于 GR3.8 里的卷积编码模块为什么不能用就先不深究了,之前写过 GR3.8 编写 OOT 的流程, GR3.9 编写 OOT 跟 3.8 差别不大,但是有些修改需要注意下。
目录
1、依赖版本的问题
(GNURadio3.9.3有这个问题,但3.9.4已经解决了这个问题,如果图省事可以直接换新版本哈~)
GR3.9 与 GR3.8 一个很重要的区别就是 python 与 C++ 接口的方式变了, GR3.8 使用的是 swig ,而 GR3.9 使用的是 pybind11,如果没了解过这两个的也问题不大,相关接口会由 gr_modtool 自动完成,我们也不用关心具体如何实现的。 但是根据官网的教程, GR3.9 需要 pybind11 的版本 >= 2.5.0,
上面说的 ubuntu20.04 中的 pybind11 已经升级到了 2.5.0,但是我查了下的还是 2.4.3 版本的,至于为什么咱也不知道,所以索性直接源码安装个新的吧,也不是很麻烦~过程如下:
curl -Lo pybind11.tar.gz https://github.com/pybind/pybind11/archive/v2.5.0.tar.gz
mkdir pybind11 && tar xzf pybind11.tar.gz -C pybind11 --strip-components=1 && cd pybind11
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DPYBIND11_TEST=OFF
make
sudo make install
注意第一行命令是从指定的网址上下载下来压缩包文件并重命名为 pybind11.tar.gz。不过有可能因为网络原因下载失败,这时可以进行手动下载下载地址就是命令行中的那个:
https://github.com/pybind/pybind11/archive/v2.5.0.tar.gz
注意下载后要重命名为 pybind11.tar.gz 再执行后续的命令。
2、每次修改公共头文件后要重新 bind 绑定
不要问我什么是公共头文件,我也不清楚。。。按字面意思我的理解是可能就是你创建的 module 的 include/ 文件夹里的头文件就是公共头文件,因为这里的文件可以被你后面创建的所有 block 使用,我可真机智/狗头。就是说每次修改这里的头文件的内容都要执行以下命令进行重新绑定:
gr_modtool bind [blockname]
把 [blockname] 换成对应的 block 的名字就可以了。原因可以看官网解释。
这点比较坑,要是没有注意到会在 CMake 的时候遇到类似下面这个问题:
。。。。。。
CMake Error at /usr/local/lib/cmake/gnuradio/GrPybind.cmake:201 (message):
Python bindings for my_header_payload_demux.h are out of sync
Call Stack (most recent call first):
python/bindings/CMakeLists.txt:34 (GR_PYBIND_MAKE_OOT)
。。。。。。
你以为这就结束了?不,可能还有 bug 在等着你,我在执行 bind 时遇到了下面这个问题:
Error: Can't parse input signature.
Error: Can't parse output signature.
Writing binding code to ./python/bindings/my_header_payload_demux_python.cc
Writing binding code to ./python/bindings/docstrings/my_header_payload_demux_pydoc_template.h
就是这俩 error ,说没法解析我的输入输出?之前在我的这篇博客里也记录过类似的问题,但是当时的解决办法现在又用不了了,我也没管他,因为看后面的 log 信息还是成功了的,后面事实证明,这俩error 确实没没啥影响,让他俩搁那秀吧,咱就当没看到嘿嘿。
3、编译啥的都通过了,用的时候有问题了
我的问题报错是这样的:
AttributeError: 'myDemux.myDemux_python.my_header_payload_demux' object has no attribute 'to_basic_block'
就是形如:AttributeError: '×××' object has no attribute 'to_basic_block' 这样的错误,这个就又是 binding 文件出问题了(莫慌,bind也就这几个问题,目前还没发现其它问题),解决方法还是官网上的:
就是需要把 python/bindings/[blockname]_python.cc 文件中的相应位置加上这么几个参数:
gr::sync_block,
gr::block,
gr::basic_block,
给你们看看我该完后的效果:
是不是发现我注释掉了一个 gr::sync_block 参数,没错,如果我不注释掉这个参数,在我重新编译代码时就会出现以下 bug :
/home/wsx/USRPworkarea/mymodule/gr-myDemux/python/bindings/my_header_payload_demux_python.cc:37:23: error: ‘sync_block’ is not a member of ‘gr’
37 | gr::sync_block,
| ^~~~~~~~~~
/home/wsx/USRPworkarea/mymodule/gr-myDemux/python/bindings/my_header_payload_demux_python.cc:37:23: error: ‘sync_block’ is not a member of ‘gr’
然后我就把它注释掉了,然后再重新编译安装就可以用了,具体原因先不深究了。
参考:
GNU Radio 3.9 OOT Module Porting Guide - GNU Radio
Re: issues porting C++ OOT to 3.9 - fails at runtime import
https://github.com/gnuradio/gnuradio/issues/4773
(兄弟们如果遇到相关的问题欢迎交流哈~)