欢迎光临
我们一直在努力

C++ Qt6 雷达模拟器实战(五):TCP、雷达数据与 Qt 图形界面的完整整合

前面的四篇实战文章中,我们已经完成了:

  • 第一篇:Qt 项目架构设计
  • 第二篇:TCP 通信与自定义文本协议
  • 第三篇:雷达目标模型与坐标转换
  • 第四篇:QPainter 绘制 PPI 雷达界面

但是这些模块目前还是相对独立的。

一个完整的雷达模拟器,需要将:

控制命令、雷达数据、界面显示

真正连接起来。

这一篇将把 RadarSimulator 的核心数据流程进行完整整合。


1. RadarSimulator 整体数据流程

一个完整的数据链路如下:

在这里插入图片描述

图1 RadarSimulator 整体数据流架构

其中:

  • TCP Client 负责发送控制命令
  • RadarServer 负责 TCP 通信和协议解析
  • RadarSimulation 负责生成和更新雷达数据
  • RadarWidget 负责将数据转换为可视化界面

这种分层设计,可以让网络通信、数据处理和界面绘制相互独立。


2. TCP 命令如何影响雷达状态

在第二篇文章中,我们实现了基于 TCP 的自定义文本协议。

客户端发送的控制命令,会首先进入 RadarServer。 经过协议解析后,进一步改变雷达系统当前状态。

例如客户端发送:

START_SCAN

RadarServer 接收到命令后,会经过以下流程:

在这里插入图片描述

图2 TCP命令到雷达状态的处理流程

RadarServer 的职责并不是绘制界面,而是:

  • 接收客户端请求
  • 解析协议
  • 修改雷达状态
  • 返回处理结果

这样可以避免网络通信代码和 Qt 界面代码混在一起。


3. 雷达数据如何传递到 Qt 界面

第三篇文章中,我们介绍了雷达目标模型以及坐标转换过程。

雷达系统内部保存的并不是屏幕坐标,而是距离、方位角等雷达参数。

雷达目标通常包含:

  • 距离 Range
  • 方位角 Azimuth
  • 速度 Speed

例如:

struct Target
{
double range;
double azimuth;
double speed;
};

RadarSimulation 负责维护这些数据。

RadarWidget 不负责产生数据,而是读取当前状态。

整体关系:

在这里插入图片描述

图3 雷达数据与界面显示关系

这种设计符合 Qt 中常见的:

数据模型与界面显示分离

原则。


4. 雷达坐标到屏幕坐标的转换

RadarSimulation 保存的是雷达坐标。

例如:

  • 目标距离
  • 目标方位角

但是 Qt 界面使用的是屏幕像素坐标。

因此需要进行坐标转换。

首先计算目标在 PPI 中的显示半径:

r

s

=

r

a

n

g

e

m

a

x

R

a

n

g

e

×

R

r_s= \\frac{range}{maxRange}\\times R

rs​=maxRangerange​×R

其中:

  • r

    s

    r_s

    rs​ 为屏幕显示半径

  • r

    a

    n

    g

    e

    range

    range 为目标实际距离

  • m

    a

    x

    R

    a

    n

    g

    e

    maxRange

    maxRange 为最大显示距离

  • R

    R

    R 为 PPI 圆盘半径

然后计算目标屏幕坐标:

x

=

c

x

+

r

s

sin

⁡

(

θ

)

x=c_x+r_s\\sin(\\theta)

x=cx​+rs​sin(θ)

y

=

c

y

−

r

s

cos

⁡

(

θ

)

y=c_y-r_s\\cos(\\theta)

y=cy​−rs​cos(θ)

其中:

  • (

    c

    x

    ,

    c

    y

    )

    (c_x,c_y)

    (cx​,cy​) 为雷达中心坐标

  • θ

    \\theta

    θ 为目标方位角

经过转换以后,RadarWidget 就可以直接使用 QPainter 绘制目标。


5. Qt 动态刷新机制

雷达界面不是静态图片。

扫描角度、目标位置以及历史航迹都会不断变化。

因此需要周期刷新。

整体流程:

在这里插入图片描述

图4 Qt雷达界面动态刷新流程

其中:

update() 并不会立即执行绘制。

Qt 会将重绘请求加入事件队列,并在事件循环中触发

paintEvent()

完成界面刷新。


6. paintEvent 只负责绘制

第四篇文章中,我们介绍了使用 QPainter 绘制 PPI 雷达界面的过程。

其中一个重要原则: paintEvent() 只负责绘制,不负责业务逻辑。

如果将数据更新逻辑放入paintEvent(),会导致:

  • 数据更新依赖界面刷新
  • 绘制频率影响业务逻辑
  • 程序难以测试和维护

正确方式:

在这里插入图片描述

图5 数据更新与界面绘制分离

数据层负责产生和维护状态。

界面层只负责读取数据并显示。

这样即使界面暂时停止刷新,雷达数据仍然保持正确状态。


7. TCP、雷达数据与 PPI 的完整闭环

经过整合以后,RadarSimulator 的完整流程如下:

在这里插入图片描述

图6 RadarSimulator完整运行闭环

最终实现:

  • TCP 控制雷达状态
  • 雷达数据实时更新
  • PPI 界面动态显示
  • 目标和历史航迹同步变化

8. 最终运行效果

经过前面的整合以后,RadarSimulator 已经能够把网络命令、雷达数据和 Qt 图形界面连接起来,形成一个完整的运行系统。

下面展示 RadarSimulator 的实际运行效果。

在这里插入图片描述

图7 RadarSimulator实际运行效果

从最终效果来看,项目已经具备了以下几个核心能力:

  • 可以通过 TCP 命令控制雷达运行状态
  • 可以维护并更新目标数据
  • 可以将雷达坐标转换为屏幕坐标
  • 可以在 PPI 界面中动态绘制扫描波束、目标和历史航迹

这也意味着前面介绍的几个关键模块,已经真正形成了完整联动。


总结

到这里,RadarSimulator 已经完成了从 TCP 通信、雷达数据处理、坐标转换到 PPI 图形显示的完整链路整合。

前面的模块不再是独立功能,而是通过数据流连接起来,形成了一个完整运行的 Qt 雷达模拟系统。

后续如果继续扩展,可以围绕当前结构逐步完善:

  • 更复杂的目标运动轨迹模拟
  • 多目标管理与显示
  • 雷达参数配置功能
  • 数据记录与回放
  • 更完善的测试与工程化设计

项目源码

RadarSimulator 完整源码已经开源:

  • Gitee仓库
  • GitHub仓库

项目包含 Qt6 界面、TCP通信、自定义协议、雷达数据模拟以及 PPI 绘制等模块。

欢迎交流学习。

赞(0)
未经允许不得转载:171主机测评 » C++ Qt6 雷达模拟器实战(五):TCP、雷达数据与 Qt 图形界面的完整整合
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址