You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C++ OOT模块实现类似滑块的参数输出以计算调谐频率?

实现GNU Radio C++ OOT模块的参数输出(替代QT GUI Range滑块)

如果你需要用C++编写的OOT模块计算调谐频率,并将结果传递给其他模块(替代QT GUI Range的滑块控制),核心是让模块具备消息输出能力或可外部访问的参数接口,以下是具体实现步骤:

核心思路

QT GUI Range本质是通过消息端口将滑块值发送给目标模块,我们的OOT模块只需实现相同的消息发送逻辑:在模块内部完成频率计算,将结果打包成PMT消息并通过输出端口发送,供其他模块接收解析。

步骤1:定义模块结构(头文件)

首先在模块头文件中声明消息输出端口、计算参数以及核心方法:

#ifndef MY_FREQ_CALC_BLOCK_H
#define MY_FREQ_CALC_BLOCK_H

#include <gnuradio/sync_block.h>
#include <pmt/pmt.h>

namespace gr {
    namespace my_oot_module {

        class my_freq_calc_block : virtual public gr::sync_block
        {
        public:
            typedef std::shared_ptr<my_freq_calc_block> sptr;
            static sptr make(double base_freq, double step_size);

            // 外部可调参数接口(可选)
            void set_base_freq(double freq);
            void set_step_size(double step);

        protected:
            my_freq_calc_block(double base_freq, double step_size);

            // 计算用参数
            double d_base_freq;
            double d_step_size;
            uint64_t d_counter;

            // 消息输出端口标识
            pmt::pmt_t d_out_port;

        public:
            int work(int noutput_items,
                    gr_vector_const_void_star &input_items,
                    gr_vector_void_star &output_items) override;
        };

    } // namespace my_oot_module
} // namespace gr

#endif // MY_FREQ_CALC_BLOCK_H

步骤2:实现模块逻辑(源文件)

在源文件中完成端口注册、计算逻辑和消息发送:

#include "my_freq_calc_block.h"

namespace gr {
    namespace my_oot_module {

        my_freq_calc_block::sptr my_freq_calc_block::make(double base_freq, double step_size)
        {
            return std::make_shared<my_freq_calc_block>(base_freq, step_size);
        }

        my_freq_calc_block::my_freq_calc_block(double base_freq, double step_size)
            : gr::sync_block("my_freq_calc_block",
                            gr::io_signature::make(0, 0, 0), // 无输入流
                            gr::io_signature::make(0, 0, 0)), // 无输出流
              d_base_freq(base_freq),
              d_step_size(step_size),
              d_counter(0)
        {
            // 注册名为"freq_out"的消息输出端口
            d_out_port = pmt::mp("freq_out");
            message_port_register_out(d_out_port);
        }

        void my_freq_calc_block::set_base_freq(double freq)
        {
            d_base_freq = freq;
        }

        void my_freq_calc_block::set_step_size(double step)
        {
            d_step_size = step;
        }

        int my_freq_calc_block::work(int noutput_items,
                                    gr_vector_const_void_star &input_items,
                                    gr_vector_void_star &output_items)
        {
            // 示例:步进式频率计算,替换为你的实际计算逻辑
            double current_freq = d_base_freq + d_counter * d_step_size;
            d_counter++;

            // 将频率值打包为PMT消息
            pmt::pmt_t freq_msg = pmt::from_double(current_freq);
            // 发送消息到输出端口
            message_port_pub(d_out_port, freq_msg);

            // 无流输出时返回0;如需定时发送,建议改用message_passing_block
            return 0;
        }

    } // namespace my_oot_module
} // namespace gr

步骤3:适配接收模块

大部分需要调谐频率的模块(如UHD USRP Source)支持通过消息端口接收配置命令,通常需要将频率消息封装为PMT字典:

如果你的接收模块需要命令字典(比如UHD的"cmd"端口),修改work函数中的消息打包逻辑:

// 构造命令字典:键为"freq",值为计算得到的频率
pmt::pmt_t cmd_dict = pmt::make_dict();
cmd_dict = pmt::dict_add(cmd_dict, pmt::mp("freq"), pmt::from_double(current_freq));
message_port_pub(d_out_port, cmd_dict);

步骤4:编译与测试

  1. 按GNU Radio OOT模块的标准流程编译安装(修改CMakeLists.txt,添加模块注册)
  2. 在GRC中添加你的OOT模块,将其"freq_out"端口连接到目标模块的消息输入端口
  3. 运行流图,验证目标模块的频率是否按你的计算逻辑更新

补充说明

  • 若需要定时触发频率计算(而非随work函数执行),建议继承gr::message_passing_block,在foreground_loop中实现定时逻辑
  • 若需模块参数在GRC中可直接引用(静态慢变场景),可在模块注册时添加parameter配置,结合setter方法实现参数同步

内容的提问来源于stack exchange,提问作者Doug

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:42:36