SituationProcess 教学文档

概述

SituationProcess 是一个基于Qt的进程管理类,专门用于启动、监控和控制AFSIM仿真任务进程。它是整个态势感知系统中的关键组件,负责与外部仿真引擎进行交互。
在这里插入图片描述

功能点

  1. 集成AFSim仿真推演系统
  2. 支持mission文件打开推演
  3. 支持推演过程状态操作,开始、暂停、终止
  4. 支持推演倍速设置

核心功能

1. 进程生命周期管理

  • 启动仿真任务:通过指定任务文件路径启动AFSIM仿真进程
  • 监控进程状态:实时监控仿真进程的运行状态
  • 优雅停止:支持正常终止和强制杀死进程
  • 输出捕获:捕获进程的标准输出和错误输出

2. 与AFSIM仿真引擎集成

  • 自动定位AFSIM可执行文件mission
  • 传递正确的命令行参数(-rt + 任务文件路径)
  • 设置合适的工作目录和环境

类结构分析

头文件:situation_process.h

class SITUATION_EXPORT SituationProcess : public QObject
{
Q_OBJECT
public:
explicit SituationProcess(QObject *parent = nullptr);
~SituationProcess();
// 核心方法
bool start(const QString &missionFilePath);
bool stop(int gracefulTerminationMs = 3000);
bool isRunning() const;
qint64 pid() const;
signals:
void started();
void finished(int exitCode, QProcess::ExitStatus status);
void errorOccurred(QProcess::ProcessError error);
void readyOutput(QString stdOut);
void readyError(QString stdErr);
};

关键成员变量

  • QPointer<QProcess> m_process:Qt进程对象,用于管理外部进程

详细功能说明

1. 启动仿真任务

方法签名
bool start(const QString &missionFilePath)
功能描述

启动AFSIM仿真任务,传入任务文件路径作为参数。

工作流程
  1. 状态检查:检查是否已有进程在运行
  2. 路径解析:自动查找AFSIM可执行文件
  3. 环境准备:确保输出目录存在
  4. 进程创建:创建QProcess对象并设置信号连接
  5. 参数设置:设置命令行参数为 -rt <任务文件路径>
  6. 启动进程:异步启动外部进程
代码示例
SituationProcess* process = new SituationProcess(this);
// 连接信号
connect(process, &SituationProcess::started, [](){
qDebug() << "仿真任务已启动";
});
connect(process, &SituationProcess::finished, [](int exitCode, QProcess::ExitStatus status){
qDebug() << "仿真任务结束,退出码:" << exitCode;
});
// 启动任务
bool success = process->start("/path/to/mission.txt");
if (success) {
qDebug() << "启动请求已发送";
} else {
qDebug() << "启动失败";
}

2. 停止仿真任务

方法签名
bool stop(int gracefulTerminationMs = 3000)
功能描述

优雅地停止正在运行的仿真进程。

停止策略
  1. 优雅终止:首先发送SIGTERM信号
  2. 等待超时:等待指定时间(默认3秒)
  3. 强制杀死:如果优雅终止失败,则强制杀死进程
代码示例
// 优雅停止(等待3秒)
process->stop();
// 自定义等待时间(等待5秒)
process->stop(5000);

3. 状态查询

运行状态检查
bool isRunning() const

返回进程是否正在运行。

进程ID获取
qint64 pid() const

返回进程ID,如果进程未运行则返回0。

代码示例
if (process->isRunning()) {
qDebug() << "进程正在运行,PID:" << process->pid();
  } else {
  qDebug() << "进程未运行";
  }

4. 信号处理

进程启动信号
void started()

当进程成功启动时发出。

进程结束信号
void finished(int exitCode, QProcess::ExitStatus status)

当进程结束时发出,包含退出码和退出状态。

错误信号
void errorOccurred(QProcess::ProcessError error)

当进程发生错误时发出。

输出信号
void readyOutput(QString stdOut)  // 标准输出
void readyError(QString stdErr)   // 标准错误输出
完整信号处理示例
SituationProcess* process = new SituationProcess(this);
// 连接所有信号
connect(process, &SituationProcess::started, [](){
qDebug() << "✅ 仿真任务启动成功";
});
connect(process, &SituationProcess::finished, [](int exitCode, QProcess::ExitStatus status){
if (status == QProcess::NormalExit) {
qDebug() << "✅ 仿真任务正常结束,退出码:" << exitCode;
} else {
qDebug() << "❌ 仿真任务异常结束,退出码:" << exitCode;
}
});
connect(process, &SituationProcess::errorOccurred, [](QProcess::ProcessError error){
qDebug() << "❌ 进程错误:" << error;
});
connect(process, &SituationProcess::readyOutput, [](const QString& output){
qDebug() << " 标准输出:" << output;
});
connect(process, &SituationProcess::readyError, [](const QString& error){
qDebug() << " 错误输出:" << error;
});
## 环境准备
### 输出目录创建
启动进程前,会自动检查并创建输出目录:
- 在可执行文件所在目录创建 `output` 文件夹
- 用于存储仿真结果和日志文件
## 最佳实践
### 1. 资源管理
```cpp
// 推荐:使用智能指针或父对象管理
SituationProcess* process = new SituationProcess(this);
// 析构函数会自动清理资源
// 如果进程仍在运行,会自动停止

2. 错误处理

SituationProcess* process = new SituationProcess(this);
// 启动前检查
if (!process->start(missionFile)) {
qWarning() << "启动仿真任务失败";
return;
}
// 监听错误信号
connect(process, &SituationProcess::errorOccurred, [](QProcess::ProcessError error){
switch (error) {
case QProcess::FailedToStart:
qWarning() << "进程启动失败";
break;
case QProcess::Crashed:
qWarning() << "进程崩溃";
break;
case QProcess::Timedout:
qWarning() << "进程超时";
break;
default:
qWarning() << "未知进程错误";
break;
}
});

3. 状态监控

// 定期检查进程状态
QTimer* statusTimer = new QTimer(this);
connect(statusTimer, &QTimer::timeout, [process](){
if (process->isRunning()) {
qDebug() << "进程运行中,PID:" << process->pid();
  }
  });
  statusTimer->start(5000); // 每5秒检查一次

4. 优雅关闭

// 应用退出时优雅关闭
void MainWindow::closeEvent(QCloseEvent *event) {
if (m_situationProcess && m_situationProcess->isRunning()) {
qDebug() << "正在停止仿真任务...";
m_situationProcess->stop(5000); // 等待5秒
}
event->accept();
}

常见问题与解决方案

1. 可执行文件未找到

问题:启动时提示找不到 mission.exe

解决方案

  • 检查 resources/afsim/ 目录是否存在
  • 确认可执行文件路径正确
  • 检查文件权限

2. 进程启动失败

问题start() 返回 false

可能原因

  • 任务文件路径无效
  • 已有进程在运行
  • 权限不足

解决方案

// 检查任务文件
QFileInfo missionFile(missionFilePath);
if (!missionFile.exists()) {
qWarning() << "任务文件不存在:" << missionFilePath;
return false;
}
// 检查进程状态
if (process->isRunning()) {
qWarning() << "已有进程在运行";
return false;
}

3. 进程无法停止

问题:调用 stop() 后进程仍在运行

解决方案

// 增加等待时间
process->stop(10000); // 等待10秒
// 或者强制杀死
if (process->isRunning()) {
process->stop(0); // 立即强制杀死
}

集成示例

与SituationManager集成

class SimulationController : public QObject {
Q_OBJECT
public:
SimulationController(QObject* parent = nullptr)
: QObject(parent)
, m_process(new SituationProcess(this))
{
setupConnections();
}
void startSimulation(const QString& missionFile) {
if (m_process->start(missionFile)) {
qDebug() << "仿真启动成功";
} else {
qDebug() << "仿真启动失败";
}
}
void stopSimulation() {
m_process->stop();
}
private slots:
void onProcessStarted() {
// 通知UI更新
emit simulationStarted();
}
void onProcessFinished(int exitCode, QProcess::ExitStatus status) {
// 清理资源
emit simulationFinished(exitCode, status);
}
private:
void setupConnections() {
connect(m_process, &SituationProcess::started,
this, &SimulationController::onProcessStarted);
connect(m_process, &SituationProcess::finished,
this, &SimulationController::onProcessFinished);
}
private:
SituationProcess* m_process;
};

总结

SituationProcess 是一个功能完善的进程管理类,为AFSIM仿真任务提供了完整的生命周期管理。通过合理使用其提供的接口和信号,可以构建稳定可靠的仿真控制系统。

关键要点

  1. 异步操作:所有操作都是异步的,通过信号通知结果
  2. 资源管理:自动管理进程资源,析构时自动清理
  3. 错误处理:提供完整的错误处理机制
  4. 状态监控:实时监控进程状态和输出
  5. 优雅关闭:支持优雅停止和强制终止

Group

1062801117

posted on 2025-10-02 13:45  ycfenxi  阅读(1)  评论(0)    收藏  举报