文章目录
SituationProcess 教学文档
概述
SituationProcess 是一个基于Qt的进程管理类,专门用于启动、监控和控制AFSIM仿真任务进程。它是整个态势感知系统中的关键组件,负责与外部仿真引擎进行交互。
功能点
- 集成AFSim仿真推演系统
- 支持mission文件打开推演
- 支持推演过程状态操作,开始、暂停、终止
- 支持推演倍速设置
核心功能
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仿真任务,传入任务文件路径作为参数。
工作流程
- 状态检查:检查是否已有进程在运行
- 路径解析:自动查找AFSIM可执行文件
- 环境准备:确保输出目录存在
- 进程创建:创建QProcess对象并设置信号连接
- 参数设置:设置命令行参数为
-rt <任务文件路径> - 启动进程:异步启动外部进程
代码示例
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)
功能描述
优雅地停止正在运行的仿真进程。
停止策略
- 优雅终止:首先发送SIGTERM信号
- 等待超时:等待指定时间(默认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仿真任务提供了完整的生命周期管理。通过合理使用其提供的接口和信号,可以构建稳定可靠的仿真控制系统。
关键要点
- 异步操作:所有操作都是异步的,通过信号通知结果
- 资源管理:自动管理进程资源,析构时自动清理
- 错误处理:提供完整的错误处理机制
- 状态监控:实时监控进程状态和输出
- 优雅关闭:支持优雅停止和强制终止
Group
1062801117
浙公网安备 33010602011771号