新增 pELoad 电子负载(IT6000C)控制程序:以太网 Raw Socket SCPI 直连设备,100ms 周期功率控制(订阅 MOOS 功率消息按 P/U 折算电流,CC/CV 双环路优先 + FUNC:MODE FIX 防护),网页人机交互(步骤引导/防误触确认),sqlite3 存储(100ms 高采样 V/I/P 测量表 meas_log + CSV 导出分析),并接入 scripts/build-board.sh 板卡部署与 systemd 服务、missions/h100.moos 配置

This commit is contained in:
zjk
2026-09-03 12:26:02 +08:00
parent 38c489caec
commit 2a34b79461
21 changed files with 3601 additions and 5 deletions
+115
View File
@@ -0,0 +1,115 @@
#ifndef PELOAD_DB_STORE_H
#define PELOAD_DB_STORE_H
#include <string>
#include <mutex>
#include <vector>
struct sqlite3;
struct sqlite3_stmt;
namespace eload {
//============================================================================
// DbStore:pELoad SQLite 存储(复用仓库内 sqlite3.c)。
//
// eload_log:运行状态低频快照(1Hz),含连接/输出/模式/限值等状态;
// meas_log :高采样测量记录(默认每控制周期 100ms 一条),
// 实测电压/电流/功率 + 指令电流/目标功率 —— 供功率波形分析;
// scpi_log :非常规 SCPI 收发记录(设定/控制/识别/错误查询等,
// 例行的 MEAS 测量轮询不落库,防止表无限膨胀)。
// log_keep_hours 对三张表统一做历史清理。
//============================================================================
struct ELoadLogRow {
long long id;
long long time;
int connected;
int outp;
std::string mode; // follow / manual / current / volt
double targetPower; // 目标功率 W
double cmdCurrent; // 指令电流 A
double measVoltage; // 实测电压 V
double measCurrent; // 实测电流 A
double measPower; // 实测功率 W
std::string funcMode; // CURR / VOLT
long long txCount;
long long rxCount;
long long txErr;
};
// 高采样测量记录(meas_log)
struct MeasRow {
long long id;
double time; // unix 时间(秒,带小数)
double measVoltage;
double measCurrent;
double measPower;
double cmdCurrent;
double targetPower;
int outp;
};
class DbStore {
public:
explicit DbStore(const std::string& dbPath);
~DbStore();
bool open();
void close();
bool isOpen() const { return m_db != nullptr; }
std::string lastError() const { return m_lastError; }
// 运行状态快照落库(控制线程周期调用)
void insertStatus(bool connected, bool outp, const std::string& mode,
double targetPower, double cmdCurrent,
double measV, double measI, double measP,
const std::string& funcMode,
unsigned long tx, unsigned long rx, unsigned long txErr);
// 高采样测量落库(每个控制周期调用,meas_log)
void insertMeas(double measV, double measI, double measP,
double cmdCurrent, double targetPower, bool outp);
// SCPI 非常规收发落库:text 为 "CMD" 或 "CMD => RESP"(已配对)
// direction: 1=命令 0=查询应答
void insertScpi(int direction, const std::string& text);
// 历史查询(网页展示)
std::vector<ELoadLogRow> queryRecentStatus(int limit);
// 测量查询:limit 条最近记录(倒序);或指定时间范围(unix 秒)
std::vector<MeasRow> queryMeas(int limit);
std::vector<MeasRow> queryMeasRange(double startSec, double endSec, int maxRows);
struct ScpiRow {
long long id;
long long time;
int direction;
std::string text;
};
std::vector<ScpiRow> queryRecentScpi(int limit);
long long countStatus() const;
long long countScpi() const;
long long countMeas() const;
// 历史清理:删除 time < cutoff 的记录,返回删除行数(<0 表示出错)
long long pruneOlderThan(long long cutoff);
private:
bool exec(const char* sql);
bool prepareInsert();
bool prepareMeasInsert();
bool prepareScpiInsert();
std::string m_dbPath;
sqlite3* m_db = nullptr;
sqlite3_stmt* m_stmtInsert = nullptr;
sqlite3_stmt* m_stmtMeasInsert = nullptr;
sqlite3_stmt* m_stmtScpiInsert = nullptr;
mutable std::mutex m_mutex;
std::string m_lastError;
};
} // namespace eload
#endif // PELOAD_DB_STORE_H