266 lines
9.4 KiB
C++
266 lines
9.4 KiB
C++
#include "app.hpp"
|
||
#include <iostream>
|
||
#include <string>
|
||
#include <thread>
|
||
#include <chrono>
|
||
#include <cstdlib>
|
||
#include <csignal>
|
||
#include <iomanip>
|
||
|
||
// 全局变量用于信号处理
|
||
static bool g_interrupted = false;
|
||
|
||
/**
|
||
* @brief 信号处理函数
|
||
*/
|
||
void signalHandler(int signal) {
|
||
if (signal == SIGINT || signal == SIGTERM) {
|
||
std::cout << "\n接收到终止信号,正在停止系统..." << std::endl;
|
||
g_interrupted = true;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 显示帮助信息
|
||
*/
|
||
void showHelp() {
|
||
std::cout << "高度测量系统 (Height Measurement System) - 命令行界面\n\n";
|
||
std::cout << "使用方法:\n";
|
||
std::cout << " hsm_main [选项]\n\n";
|
||
std::cout << "选项:\n";
|
||
std::cout << " --help 显示此帮助信息\n";
|
||
std::cout << " --simulate 运行模拟模式(持续测量)\n";
|
||
std::cout << " --threshold <上限> <下限> 设置预警阈值(单位:米)\n";
|
||
std::cout << " --calibrate <气压> 校准海平面气压值(单位:hPa)\n";
|
||
std::cout << " --export <文件名> 导出历史数据到指定文件\n";
|
||
std::cout << " --status 显示系统状态\n";
|
||
std::cout << " --reset-zero 执行零点归位\n";
|
||
std::cout << " --sim-height <变化量> 模拟高度变化(单位:米)\n";
|
||
std::cout << " --sensor-fault 模拟传感器故障\n";
|
||
std::cout << " --sensor-normal 恢复传感器正常状态\n";
|
||
std::cout << " --acknowledge 确认所有预警\n";
|
||
std::cout << "\n示例:\n";
|
||
std::cout << " hsm_main --simulate # 运行模拟模式\n";
|
||
std::cout << " hsm_main --threshold 100 -50 # 设置预警阈值\n";
|
||
std::cout << " hsm_main --calibrate 1013.25 # 校准海平面气压\n";
|
||
std::cout << " hsm_main --export data.csv # 导出数据到CSV\n";
|
||
std::cout << " hsm_main --status # 显示系统状态\n";
|
||
}
|
||
|
||
/**
|
||
* @brief 解析命令行参数
|
||
*/
|
||
bool parseArguments(int argc, char* argv[], HeightMeasurementApp& app) {
|
||
for (int i = 1; i < argc; ++i) {
|
||
std::string arg = argv[i];
|
||
|
||
if (arg == "--help") {
|
||
showHelp();
|
||
return false; // 不继续执行主程序
|
||
|
||
} else if (arg == "--simulate") {
|
||
// 模拟模式在main函数中处理
|
||
continue;
|
||
|
||
} else if (arg == "--threshold" && i + 2 < argc) {
|
||
try {
|
||
float upper = std::stof(argv[++i]);
|
||
float lower = std::stof(argv[++i]);
|
||
app.setAlertThresholds(upper, lower);
|
||
} catch (...) {
|
||
std::cerr << "错误:无效的阈值参数" << std::endl;
|
||
return false;
|
||
}
|
||
|
||
} else if (arg == "--calibrate" && i + 1 < argc) {
|
||
try {
|
||
float pressure = std::stof(argv[++i]);
|
||
app.calibrateSeaLevelPressure(pressure);
|
||
} catch (...) {
|
||
std::cerr << "错误:无效的气压值参数" << std::endl;
|
||
return false;
|
||
}
|
||
|
||
} else if (arg == "--export" && i + 1 < argc) {
|
||
std::string filename = argv[++i];
|
||
if (app.exportHistoryData(filename)) {
|
||
std::cout << "数据导出成功: " << filename << std::endl;
|
||
} else {
|
||
std::cerr << "数据导出失败" << std::endl;
|
||
}
|
||
|
||
} else if (arg == "--status") {
|
||
std::cout << app.getStatus() << std::endl;
|
||
return false; // 显示状态后退出
|
||
|
||
} else if (arg == "--reset-zero") {
|
||
if (app.performZeroReset()) {
|
||
std::cout << "零点归位成功" << std::endl;
|
||
} else {
|
||
std::cerr << "零点归位失败" << std::endl;
|
||
}
|
||
|
||
} else if (arg == "--sim-height" && i + 1 < argc) {
|
||
try {
|
||
float delta = std::stof(argv[++i]);
|
||
// 注意:这里需要访问传感器模拟器,但为了接口简洁,暂时不实现
|
||
std::cout << "模拟高度变化功能需要在app中实现" << std::endl;
|
||
} catch (...) {
|
||
std::cerr << "错误:无效的高度变化参数" << std::endl;
|
||
return false;
|
||
}
|
||
|
||
} else if (arg == "--sensor-fault") {
|
||
app.getAlertManager().triggerSensorFailure(
|
||
static_cast<uint32_t>(std::time(nullptr)));
|
||
std::cout << "已触发传感器故障预警" << std::endl;
|
||
|
||
} else if (arg == "--sensor-normal") {
|
||
// 这里需要访问传感器模拟器,暂时不实现
|
||
std::cout << "恢复传感器正常功能需要在app中实现" << std::endl;
|
||
|
||
} else if (arg == "--acknowledge") {
|
||
app.getAlertManager().acknowledgeAllAlerts(
|
||
static_cast<uint32_t>(std::time(nullptr)));
|
||
std::cout << "已确认所有预警" << std::endl;
|
||
|
||
} else {
|
||
std::cerr << "未知参数: " << arg << std::endl;
|
||
std::cerr << "使用 --help 查看帮助信息" << std::endl;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* @brief 运行模拟模式
|
||
*/
|
||
void runSimulationMode(HeightMeasurementApp& app) {
|
||
std::cout << "=== 高度测量系统模拟模式 ===\n";
|
||
std::cout << "系统正在运行,按 Ctrl+C 停止\n\n";
|
||
|
||
// 显示初始状态
|
||
std::cout << app.getStatus() << std::endl;
|
||
|
||
// 主循环
|
||
int cycle_count = 0;
|
||
const int STATUS_UPDATE_INTERVAL = 20; // 每20次测量更新一次状态显示
|
||
|
||
while (!g_interrupted) {
|
||
// 执行一次测量循环
|
||
if (!app.measureCycle()) {
|
||
std::cerr << "测量循环失败" << std::endl;
|
||
break;
|
||
}
|
||
|
||
// 定期更新状态显示
|
||
if (++cycle_count % STATUS_UPDATE_INTERVAL == 0) {
|
||
std::cout << "\n=== 系统状态更新 ===\n";
|
||
|
||
float altitude = app.getCurrentAltitude();
|
||
float relative = app.getRelativeHeight();
|
||
|
||
std::cout << std::fixed << std::setprecision(2);
|
||
std::cout << "测量次数: " << cycle_count << "\n";
|
||
std::cout << "当前高度: " << altitude << " 米\n";
|
||
std::cout << "相对高度: " << relative << " 米\n";
|
||
|
||
// 检查预警状态
|
||
if (app.getAlertManager().hasActiveAlerts()) {
|
||
std::cout << "预警状态: " << app.getAlertManager().getStatusDescription() << "\n";
|
||
}
|
||
|
||
// 数据记录状态
|
||
auto& logger = app.getDataLogger();
|
||
std::cout << "数据记录: " << logger.getRecordCount() << " 条\n";
|
||
|
||
std::cout << "========================\n";
|
||
}
|
||
|
||
// 等待1秒(模拟1秒采样间隔)
|
||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||
|
||
// 每100次测量模拟一次传感器故障(测试用)
|
||
if (cycle_count % 100 == 0 && cycle_count > 0) {
|
||
std::cout << "\n[测试] 模拟传感器故障..." << std::endl;
|
||
app.getAlertManager().triggerSensorFailure(
|
||
static_cast<uint32_t>(std::time(nullptr)));
|
||
}
|
||
|
||
// 每150次测量恢复传感器正常(测试用)
|
||
if (cycle_count % 150 == 0 && cycle_count > 0) {
|
||
std::cout << "\n[测试] 恢复传感器正常..." << std::endl;
|
||
// 这里需要实际恢复传感器状态,暂时只输出信息
|
||
}
|
||
}
|
||
|
||
// 显示最终状态
|
||
std::cout << "\n=== 模拟结束 ===\n";
|
||
std::cout << "总测量次数: " << cycle_count << "\n";
|
||
std::cout << "最终系统状态:\n";
|
||
std::cout << app.getStatus() << std::endl;
|
||
}
|
||
|
||
/**
|
||
* @brief 主函数
|
||
*/
|
||
int main(int argc, char* argv[]) {
|
||
// 设置信号处理
|
||
std::signal(SIGINT, signalHandler);
|
||
std::signal(SIGTERM, signalHandler);
|
||
|
||
std::cout << "高度测量系统 v1.0.0 启动..." << std::endl;
|
||
|
||
// 创建应用实例
|
||
HeightMeasurementApp app;
|
||
|
||
// 初始化系统
|
||
if (!app.initialize()) {
|
||
std::cerr << "系统初始化失败!" << std::endl;
|
||
return EXIT_FAILURE;
|
||
}
|
||
|
||
// 解析命令行参数
|
||
if (!parseArguments(argc, argv, app)) {
|
||
// 如果只是显示帮助或状态,正常退出
|
||
return EXIT_SUCCESS;
|
||
}
|
||
|
||
// 检查是否要运行模拟模式
|
||
bool run_simulation = false;
|
||
for (int i = 1; i < argc; ++i) {
|
||
if (std::string(argv[i]) == "--simulate") {
|
||
run_simulation = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (run_simulation) {
|
||
// 启动系统
|
||
app.start();
|
||
|
||
// 运行模拟模式
|
||
runSimulationMode(app);
|
||
|
||
// 停止系统
|
||
app.stop();
|
||
} else if (argc == 1) {
|
||
// 没有参数时,显示帮助信息
|
||
showHelp();
|
||
}
|
||
|
||
// 导出最终数据(如果运行了模拟模式)
|
||
if (run_simulation) {
|
||
std::string filename = "hsm_data_" +
|
||
std::to_string(std::time(nullptr)) + ".csv";
|
||
|
||
if (app.exportHistoryData(filename)) {
|
||
std::cout << "数据已自动导出到: " << filename << std::endl;
|
||
}
|
||
}
|
||
|
||
std::cout << "程序正常结束。" << std::endl;
|
||
return EXIT_SUCCESS;
|
||
} |