# ServiceFrame_Linux **Repository Path**: SpidermanW/service-frame_-linux ## Basic Information - **Project Name**: ServiceFrame_Linux - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-18 - **Last Updated**: 2026-09-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 炮塔任务自定义服务化开发平台 — 工程骨架 按《炮塔任务自定义服务化开发平台设计方案》搭建的 **Qt C++(Qt Widgets + Graphics View)** 工程骨架,当前阶段包含: - 可编译运行的 QT 三栏界面框架(组件库 / 编排画布 / 属性面板 + 日志面板 + 顶部工具栏) - 完整 **组件库数据模型**:57 个参数原子组件 + 41 个功能原子组件(炮塔、武器、光电、自动机四大控制体系 + 延迟时序 + 工作模式 + DDS 发布/订阅通讯模块 + IF/ELSE、SWITCH/CASE、FOR、WHILE 编程语法模块)+ 1 个“自定义服务框”容器模板,全部以规格化数据注册 - 跨类“组件组”架构:炮塔/武器/光电为「参数配置类子组 + 功能类子组」结构,工作模式组件组亦扩展出“工作模式参数小组”;自动机、延迟模块保持纯功能类组件组;功能组件支持内嵌可配置参数(如延时数值);图像处理:视频流组件作为光电控制组件组直属顶层组件(拖入画布即视频容器);组件库最底部为“自定义服务组件组”,内置“自定义服务框”容器模板;DDS 通讯组件组提供发布/订阅模块,主题名等字符串参数使用 Text 型(QLineEdit)编辑 - 左侧新增「数据面板模块」窗口(位于“编程语法”窗口下方):通用数据显示面板(CMD 综合管理状态 / ExecuteCtrl 射控执行状态),拖入画布即成为实时数据显示面板;每个面板实例拥有独立的 DDS 订阅线程,支持在面板内点击「连接/断开」实时订阅显示;随在线仿真/在线运行自动连接,点「仿真停止」统一断开。字段以“原始值 + 语义解析”双栏展示,枚举/位定义(故障位、传感器到位位定义等)自动解读;面板的字段/语义与 `DDS/SubPub` 演示共用 `DDS/common/display_semantics.json`(转写自 IDL 注释)——pub 发什么演示值、sub 打印什么含义、面板显示什么含义三者始终一致。CMD 与 ExecuteCtrl 面板拖入后行为完全一致:未连接时均先显示“字段名 | — | —”骨架,点击「连接」后才填充实时值。为便于无真实设备时联调,面板连接后若约 1.5s 总线上仍无任何外部数据,会自动启动「内置演示数据源」(进程内按主题共享一个发布线程,200ms/帧按 IDL 注释语义持续发帧,面板状态与收帧数标注“演示源”),断开/仿真停止即停止;存在真实发布(连接初期即收到帧)时不会启动演示源,可用环境变量 `SFX_NO_DEMO_SOURCE=1` 彻底关闭 - 画布拖拽实例化、组件选中与属性表单联动;端口拖线连线(参数流/控制流),连线随组件移动自动刷新 - 任务编排图 → main 程序实时翻译:画布顶层控制流拓扑(容器/延时/DDS 发布/服务调用)驱动“代码预览”,支持代码预览手动修改 + g++ 在线运行(编译当前编辑器代码) + 导出源码(.cpp) ## 技术栈 | 项 | 选择 | | :--- | :--- | | 语言 | C++17 | | UI 框架 | Qt Widgets + QGraphicsView(优先 Qt 6,兼容 Qt 5) | | 构建 | CMake ≥ 3.16(Unix Makefiles / Ninja) | | 运行环境 | Ubuntu 22.04(WSL)+ Qt 6.2.4(qt6-base-dev)+ GCC 11 | | DDS | CycloneDDS ≥ 0.10(可选):用于数据显示面板实时订阅 / DDS/SubPub 回归测试 | ```text Codex_ServiceFrame_Linux/ # Ubuntu/WSL 独立开发工程(Linux 适配版源码) ├─ CMakeLists.txt # 工程构建(自动 moc,Qt6 优先 / Qt5 回退) ├─ README.md # 使用与构建说明(Ubuntu/WSL) ├─ IDL/ # 任务 IDL(As/AutoGun/CMD/ExecuteCtrl/FireCtrl/ │ # GenericCom/Image/ServiceCtrl/Servo) ├─ DDS/SubPub/ # CycloneDDS 验证:每 IDL 一对 pub/sub + run_all_demo.sh ├─ DDS/common/display_semantics.json # 语义表(由 IDL 注释转写,SubPub 演示与数据显示面板共用) ├─ docs/ │ ├─ architecture.md # 架构说明与设计映射 │ └─ preview-code-mapping.md # 画布→预览代码映射机制说明 ├─ outputs/ # 运行时产物 │ ├─ projects/ # 任务编排工程 JSON(保存/打开默认目录) │ ├─ preview_code/ # 预览代码 + custom_code(手工代码块在线保存) │ └─ sim_run/ # 在线运行:源文件 / 可执行程序 / 运行日志 ├─ src/ │ ├─ main.cpp # 入口(含 --smoke 等自检参数) │ ├─ core/model/ # 领域模型(仅 QtCore,可服务端复用) │ │ ├─ componentmodel.h/cpp # 组件/分组/参数/端口/服务端点 规格 + 校验 │ │ └─ componentcatalog.h/cpp # 预置组件库装配(新增组件只改这里) │ ├─ core/util/textmerge.h/cpp # 手工代码三向合并 / 锚定区掩码工具 │ ├─ core/task/taskmodel.h/cpp # 任务编排模型:步骤链 → main 代码生成 │ └─ ui/ # 界面层 │ ├─ MainWindow # 主窗口:菜单/工具栏 + Dock 布局 + 编译运行 │ ├─ ComponentLibraryPanel # 左:搜索 + 分组折叠树 + 拖拽 │ ├─ GrammarPalette # 左:编程语法(IF/SWITCH/FOR/WHILE)面板 │ ├─ EditorCanvas # 中:GraphicsView 画布 │ ├─ ComponentItem # 画布组件图形项(规格 + UUID + 运行时参数) │ ├─ ConnectionItem # 画布连线边(随端点移动刷新) │ ├─ FlowTranslator # 画布图 → 任务 main 步骤链翻译 │ ├─ PropertyPanel # 右:类型化参数表单 │ ├─ CodePreviewPanel # 右:Tab 代码预览(实时刷新 / 手工编辑) │ ├─ VideoStreamPanel # 图像处理:ffmpeg 拉流 + 实时画面 │ ├─ LogPanel # 底:彩色分级日志 │ └─ componentvisuals # 分类颜色 / 图标 ├─ build/ # Release 构建产物(不入库) └─ build-dbg/ # Debug 构建产物(不入库) ``` ## 构建与运行(Ubuntu 22.04 / WSL) ```bash # 依赖示例 sudo apt update && sudo apt install -y build-essential cmake qt6-base-dev libgl1-mesa-dev # 编译(默认 Release) cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build -j "$(nproc)" # 运行 GUI(需 WSLg;系统默认只带 xcb 平台插件,显式指定最稳) QT_QPA_PLATFORM=xcb ./build/CodexServiceFrame # 无头自检(无需显示服务器,适合回归) QT_QPA_PLATFORM=offscreen ./build/CodexServiceFrame --smoke QT_QPA_PLATFORM=offscreen ./build/CodexServiceFrame --selftest-project QT_QPA_PLATFORM=offscreen ./build/CodexServiceFrame --selftest-connzoom QT_QPA_PLATFORM=offscreen ./build/CodexServiceFrame --selftest-runstop QT_QPA_PLATFORM=offscreen ./build/CodexServiceFrame --selftest-panels # 数据面板几何回归(ExecuteCtrl 右突项) QT_QPA_PLATFORM=offscreen ./build/CodexServiceFrame --selftest-demosrc # 内置演示数据源自检(无外部发布时自动持续发帧/断开即停) # 调试构建 cmake -S . -B build-dbg -DCMAKE_BUILD_TYPE=Debug cmake --build build-dbg -j "$(nproc)" ``` > 本目录为 Ubuntu/WSL 独立开发工程;Windows 旧版保留在 Windows 源工程中。 ## 图像处理视频流模块(实时拉流显示) - 左侧组件库 光电控制组件组 顶层直属组件:“图像处理视频流(实时显示)”模块(位于光电组件组根节点下,无需深入子组,便于查找/拖拽); - 参数支持手动设置:**服务器 IP**、**端口**、**流路径**、自动拉流显示开关(完整地址 = rtsp://IP:端口/路径); - 拖入画布后模块内嵌“连接/断开 + 实时画面 + 状态行”面板;实时画面由本机 ffmpeg 拉取 RTSP流并以 MJPEG 帧流输出解码显示(需 ffmpeg 可用); - 本地模拟推流示例(先启动本地 RTSP 服务器,再执行): ```text ffmpeg -re -stream_loop -1 -i out.mp4 -c copy -f rtsp rtsp://127.0.0.1:8554/video ``` ## 与设计方案的映射 | 方案章节 | 工程落点 | | :--- | :--- | | 二、左侧组件库(分组/原子组件) | `componentcatalog.cpp` 注册表;`ComponentLibraryPanel` 展示 | | 二~四、炮塔/武器/光电控制组件组 | `hybridGroups()` 跨类组件组;统一「参数配置类子组 + 功能类子组」二级结构 | | 自定义服务容器(子流程骨架) | `ComponentCategory::Container` + `custom_service` 组件组;画布容器收容原子组件为子组件 | | 三、原子组件标准化服务模型 | `ComponentSpec / ParameterSpec / PortSpec / ServiceEndpoint` | | 四、平台界面架构 | `MainWindow` + `QDockWidget` 四面板 + 工具栏 | | 五、拖拽编排流程 | 库面板拖拽/双击 → 画布 `ComponentItem` 实例化 | | 任务编排 → main 代码/仿真 | `src/core/task` 任务模型 + `FlowTranslator` 画布拓扑翻译;`CodePreviewPanel` 实时预览;`compileRun` g++ 实机运行 | | 五、服务化执行逻辑 | `ServiceEndpoint` 占位定义;执行引擎为下一迭代 | ## 骨架当前已实现 / 未实现 **已实现** - 全部预置组件规格化注册与合法参数默认值/边界/单位/枚举 - 参数按类型生成表单控件(布尔/整型/浮点/字符串/枚举/区间/三维坐标)并做范围校验;字符串型参数使用 QLineEdit 编辑 - 任务编排框架:把画布控制流图实时转译为任务 main 程序(参数容器/延时/DDS 发布/图像处理/服务调用);容器角色自动识别为越障/禁射/工作模式/光电参数/炮塔扇扫/图像处理/控制伺服逻辑容器(IF/ELSE 模块化编程),容器内增删组件即时同步为参数行或功能代码段;右侧“属性配置 / 代码预览”以 Tab 页切换、代码随编排实时刷新;刷新让“画布编排与手工修改共存”:自动生成区整段重建并与画布组件/连线/参数/顺序对应,同时以“三向合并”把编辑器里的手工修改重新锚定保留 —— 锚定区(功能代码块 SFX_FUNC_BEGIN/END 正文、USER_GLOBAL_BEGIN/END 全局附加区)在线保存并在刷新时自动回填;其它位置的手工修改就地保留,其上下文被画布删除时才移入文件尾 `// [保留]` 区(带标记、不丢失不重复,删除该区即彻底移除);编辑器每次修改实时落盘、启动时自动恢复上次保存的文本;“在线仿真”按真实延时逐行回显,并同步启动画布图像视频流面板;“在线运行(编译当前代码)”以 g++ 编译执行代码预览当前编辑器文本(含手动修改);“导出源码(.cpp)”可保存编排结果 - 任意位置手工修改的跨重启持久化:预览代码不仅“功能代码块”内可编辑,文件任意位置(自动生成区中间/尾部)手工新增、修改、删除都会在线保存;工程保存时同时写入 `code.mainPreview`(编辑器全文)与 `code.baseline`(该文本所基于的画布权威生成代码),重开/重启时做“基线锚定三向合并”,任意位置的手工代码与画布编排框架共存保留,不再依赖“同源覆盖率”近似判定 - 左侧组件库下方新增“编程语法”窗口:IF/ELSE、SWITCH/CASE、FOR、WHILE 语法模块;拖入画布成为逻辑实例后,可在右侧属性面板“在线添加/修改/删除”条件行(IF 自动组成 else if 链、SWITCH/CASE 的 case 1/2/3… 自动编号且数量可增减),画布上实时预览条件行摘要 - 画布:网格背景、Ctrl+滚轮缩放、Shift+滚轮左右平移、拖入实例化、选中/移动/Delete 删除 - 组件间连线:从输出端口拖到输入端口建立“参数线/控制线”(流类型校验、重复检测),连线随组件移动自动刷新;选中连线按 Delete 删除 - 实时代码生成:画布图(顶层控制流)实时翻译为任务 main 程序;在右侧“代码预览”Tab 查看,属性参数/延时/连线改动即时刷新 - 示例作战任务:启动即生成八段可连线任务链 —— ①越障参数框架(上越/-120~120/区号2/高低20~50)→延时1000ms→DDS发布(Servo_Ctrl_Topic);②禁射参数框架(区号3/-100~100/高低20~60)→延时1000ms→DDS发布(AutoGun_Ctrl_Topic);③工作模式框架(作战)→DDS发布(CMD_Ctrl_Topic);④光电参数框架(变倍+1/单步+1/极性白热/显示可见光)→DDS发布(Image_Ctrl_Topic)→延时1000ms;⑤炮塔扇扫参数框架(扇扫模式/低速/方位-60~60/高低20~40)→DDS发布(Servo_Ctrl_Topic)→延时1000ms;⑥图像处理框架(实时拉取视频流并实时显示视频内容)→⑦DDS 订阅(Servo_State_Topic,依据 IDL/Servo.idl::ServoData::ServoState 解码 servoState)→⑧“控制伺服”自定义服务框:容器内使用 IF/ELSE 编程语法模块做模块化控制 —— 条件 `servoState.TrackMode_Feedback == 0x01`(已在跟踪)成立即跳出容器;否则(else)按容器内排版依次执行 炮塔稳定:启动→延时100ms→炮塔:启动→延时100ms→炮塔跟踪:启动。各段载荷与 IDL 字段一一对应,容器内部增删组件时生成代码随之同步 - 在线仿真:按编排步骤真实延时逐行回显,并同步启动画布图像视频流面板(无真实 RTSP 时显示本地仿真画面);在线运行(编译当前代码):以 g++ 编译执行代码预览当前编辑器文本(含手动修改)——日志面板先逐行回显编译过程(数据源/工作目录/编译命令/编译器诊断/用时),再实时回显程序运行输出;“编译过程 + 运行输出”整段会话同时存档到 `outputs/sim_run/last_run.log` 与 `run_<时间戳>.log` - 仿真停止:随时终止正在执行的预览代码(在线运行进程 / 在线仿真未执行步骤序列),并同步停止画布图像视频流显示;按钮在无运行状态自动置灰 - 任务工程 JSON 序列化(保存/打开/新建/另存为):编排内容可随时保存为自包含 JSON 工程文件,并切换到不同编排文件修改升级 —— “保存工程”写入当前路径、“工程另存为/打开工程”可自由选择;文件含 `format/version` 头标识、完整画布图(实例 UUID/坐标/容器尺寸/参数值/逻辑行/连线)、代码预览快照(含 SFX/USER_GLOBAL 手工代码)与功能代码块正文(仅内嵌属于当前画布容器的键);“新建任务工程”则清空画布从零编排;同一文件可重复“保存 → 新建 → 打开”往返不丢内容(`--selftest-project` 自动化回归校验) - 工程内独立输出目录:所有源码与产物统一保存于工程根;`outputs/projects` 存放任务编排工程 JSON 文件(保存/打开的默认目录);`outputs/preview_code` 存放实时生成的预览代码(画布变更/手动编辑即时落盘,导出默认位置);`outputs/sim_run` 存放在线运行的源文件、可执行程序(Linux 为 mission_main)与运行日志(`last_run.log` + 按时间戳归档 `run_<时间戳>.log`) - 自定义服务框容器:紫色虚线框渲染,内部虚线工作区提示;拖入的原子组件成为其子组件,随容器移动/删除;右下角握把可手动调整容器长宽(最小 200×120) - 容器“代码框”映射:在编排区放入自定义服务框(容器)即自动映射一段代码框;容器内每加入一个参数组件,代码预览按“拖入先后顺序”自动生成对应变量的初始化代码行(数值/布尔/枚举/区间/坐标按类型转 C++ 初始化);加入功能组件时自动展开一段标准模板代码块,模板包裹于 `SFX_FUNC_BEGIN/END` 标记中,可直接在“代码预览”页手工编码;生成文件头部另有 `USER_GLOBAL_BEGIN/END` 全局附加区(在自动 include 之后),用于手写全局声明/辅助函数 - 功能代码块在线保存:容器内功能代码块的手工修改自动在线保存到 `outputs/preview_code/custom_code/.txt`(key 形如 obstacle.automat_power_on.1);应用重启(或画布重建)后自动载入并重新注入对应功能代码块,实现“下次打开仍然可见” - 实例改名:选中画布上任意组件(含自定义服务框容器),在右侧“属性配置 → 实例名称”中手动修改名称并点“应用配置”;画布标题即时更新,容器/代码框内组件的代码注释同步采用新名称(留空则恢复组件默认名) - 选中组件 → 右侧属性表单联动,应用/重置写回实例运行时参数 - 界面日志、分类图标、Dock 拖拽浮动 **待迭代(TODO)** - SWITCH/CASE、FOR、WHILE 语法组件在容器代码生成中的分支体/循环体展开(IF/ELSE 已支持:条件成立→跳出容器,否则按容器内排版顺序生成 else 动作链) - 后端服务调用封装(QNetwork 或内部调用)与状态回传 - 实装部署与后端服务封装(在线仿真/在线运行已落地,服务下发仍为骨架) - 子流程/复合组件封装与模板批量生成 ## 扩展新组件(无需改框架) 1. 在 `componentcatalog.cpp` 的对应 `buildXxxGroup()` 中追加 `makeParameterComponent / makeFunctionComponent` 条目; 2. 参数项用 `ParameterSpec::makeNumber/makeInteger/makeBoolean/makeEnum/makeRange/makeVector3` 描述; 3. 分组如需二级分组,追加到 `GroupSpec::subgroups`;重新构建即可在组件库面板中看到。