更新压力稳定判定算法
This commit is contained in:
+73
-20
@@ -2,57 +2,110 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
PressureMonitor::PressureMonitor()
|
PressureMonitor::PressureMonitor()
|
||||||
: m_stableTickCount(0)
|
: m_tickCounter(0)
|
||||||
|
, m_sampleCount(0)
|
||||||
|
, m_bufIdx(0)
|
||||||
, m_totalTickCount(0)
|
, m_totalTickCount(0)
|
||||||
, m_timeout(false)
|
, m_timeout(false)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < BUF_SIZE; i++) {
|
||||||
|
m_buf[i] = 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PressureMonitor::tick(float realtimePressure, float calibratedPressure)
|
bool PressureMonitor::tick(float realtimePressure, float calibratedPressure)
|
||||||
{
|
{
|
||||||
m_totalTickCount++;
|
m_totalTickCount++;
|
||||||
|
|
||||||
if (calibratedPressure <= 0.0f) {
|
|
||||||
m_stableTickCount = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float upperBound = calibratedPressure + 10.0f;
|
|
||||||
float lowerBound = calibratedPressure - 10.0f;
|
|
||||||
|
|
||||||
if (realtimePressure >= lowerBound && realtimePressure <= upperBound) {
|
|
||||||
m_stableTickCount++;
|
|
||||||
} else {
|
|
||||||
m_stableTickCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5分钟超时兜底:无论压力是否稳定,都触发结束
|
|
||||||
if (m_totalTickCount >= TIMEOUT_TICKS) {
|
if (m_totalTickCount >= TIMEOUT_TICKS) {
|
||||||
m_timeout = true;
|
m_timeout = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_stableTickCount >= REQUIRED_STABLE_TICKS;
|
if (m_tickCounter != 0) {
|
||||||
|
m_tickCounter = (m_tickCounter + 1) % SAMPLE_INTERVAL_TICKS;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_tickCounter = (m_tickCounter + 1) % SAMPLE_INTERVAL_TICKS;
|
||||||
|
|
||||||
|
if (calibratedPressure <= 0.0f) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buf[m_bufIdx] = realtimePressure;
|
||||||
|
m_bufIdx = (m_bufIdx + 1) % BUF_SIZE;
|
||||||
|
m_sampleCount++;
|
||||||
|
|
||||||
|
if (m_sampleCount < BUF_SIZE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rangeMin = calibratedPressure - 10.0f;
|
||||||
|
float rangeMax = calibratedPressure + 10.0f;
|
||||||
|
|
||||||
|
if (!checkFirst4InRange(rangeMin, rangeMax)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float avg = computeTrimmedMean();
|
||||||
|
return (avg >= rangeMin && avg <= rangeMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PressureMonitor::reset()
|
void PressureMonitor::reset()
|
||||||
{
|
{
|
||||||
m_stableTickCount = 0;
|
m_tickCounter = 0;
|
||||||
|
m_sampleCount = 0;
|
||||||
|
m_bufIdx = 0;
|
||||||
m_totalTickCount = 0;
|
m_totalTickCount = 0;
|
||||||
m_timeout = false;
|
m_timeout = false;
|
||||||
|
for (int i = 0; i < BUF_SIZE; i++) {
|
||||||
|
m_buf[i] = 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PressureMonitor::isCurrentlyInRange() const
|
bool PressureMonitor::isCurrentlyInRange() const
|
||||||
{
|
{
|
||||||
return m_stableTickCount > 0;
|
return (m_sampleCount >= BUF_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PressureMonitor::stableTickCount() const
|
int PressureMonitor::stableTickCount() const
|
||||||
{
|
{
|
||||||
return m_stableTickCount;
|
return m_sampleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PressureMonitor::wasTimeout() const
|
bool PressureMonitor::wasTimeout() const
|
||||||
{
|
{
|
||||||
return m_timeout;
|
return m_timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float* PressureMonitor::buffer() const
|
||||||
|
{
|
||||||
|
return m_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PressureMonitor::checkFirst4InRange(float rangeMin, float rangeMax) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
float val = m_buf[(m_bufIdx + i) % BUF_SIZE];
|
||||||
|
if (val < rangeMin || val > rangeMax) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float PressureMonitor::computeTrimmedMean() const
|
||||||
|
{
|
||||||
|
float minVal = m_buf[0];
|
||||||
|
float maxVal = m_buf[0];
|
||||||
|
float sum = 0.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < BUF_SIZE; i++) {
|
||||||
|
float val = m_buf[i];
|
||||||
|
sum += val;
|
||||||
|
if (val < minVal) minVal = val;
|
||||||
|
if (val > maxVal) maxVal = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sum - minVal - maxVal) / (float)(BUF_SIZE - 2);
|
||||||
|
}
|
||||||
+23
-14
@@ -6,33 +6,42 @@ class PressureMonitor
|
|||||||
public:
|
public:
|
||||||
PressureMonitor();
|
PressureMonitor();
|
||||||
|
|
||||||
// 每个100ms tick 调用一次
|
// 每个100ms tick 调用一次(外部调用频率不变)
|
||||||
// realtimePressure: 实时压力 (sysPara->status.PRESSURE)
|
// realtimePressure: 实时压力 (sysPara->status.PRESSURE)
|
||||||
// calibratedPressure: 标定压力 (sysPara->para.pressure)
|
// calibratedPressure: 标定压力 (sysPara->para.pressure)
|
||||||
|
//
|
||||||
|
// 内部逻辑:每500ms采样一次,维护最近12个采样的环形缓冲区。
|
||||||
|
// 缓冲区满12个后,先检查最旧的4个采样是否各自在标定值 ±10 范围内,
|
||||||
|
// 满足后去掉全部12个中的最大值和最小值取平均,判断均值是否在 ±10 内。
|
||||||
|
// 每次新采样入队、最旧采样出队后立即重新判定。
|
||||||
// 返回 true 表示:
|
// 返回 true 表示:
|
||||||
// 1) 压力已持续稳定 3 秒(±10 范围内),或
|
// 1) 前4入界且去极值均值在 ±10 范围内,或
|
||||||
// 2) 超过 2 分钟仍未稳定,兜底超时结束
|
// 2) 超过 2 分钟仍未稳定,兜底超时结束
|
||||||
bool tick(float realtimePressure, float calibratedPressure);
|
bool tick(float realtimePressure, float calibratedPressure);
|
||||||
|
|
||||||
// 重置监测器状态
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
// 当前压力是否在 ±10 范围内
|
|
||||||
bool isCurrentlyInRange() const;
|
bool isCurrentlyInRange() const;
|
||||||
|
|
||||||
// 当前连续稳定的 tick 计数
|
|
||||||
int stableTickCount() const;
|
int stableTickCount() const;
|
||||||
|
|
||||||
// 是否因超时而触发结束(兜底)
|
|
||||||
bool wasTimeout() const;
|
bool wasTimeout() const;
|
||||||
|
|
||||||
private:
|
// 返回环形缓冲区(12个压力值)
|
||||||
int m_stableTickCount;
|
const float* buffer() const;
|
||||||
int m_totalTickCount;
|
|
||||||
bool m_timeout;
|
|
||||||
|
|
||||||
static const int REQUIRED_STABLE_TICKS = 30; // 3秒 / 100ms = 30 ticks
|
private:
|
||||||
static const int TIMEOUT_TICKS = 1200; // 2分钟 / 100ms = 1200 ticks
|
float computeTrimmedMean() const;
|
||||||
|
bool checkFirst4InRange(float rangeMin, float rangeMax) const;
|
||||||
|
|
||||||
|
static const int SAMPLE_INTERVAL_TICKS = 5; // 500ms / 100ms
|
||||||
|
static const int BUF_SIZE = 12; // 缓冲区大小
|
||||||
|
static const int TIMEOUT_TICKS = 1200; // 2分钟 / 100ms
|
||||||
|
|
||||||
|
int m_tickCounter; // 100ms tick 计数,==0 时采样
|
||||||
|
int m_sampleCount; // 已采集样本总数
|
||||||
|
int m_bufIdx; // 环形缓冲区下一次写入位置
|
||||||
|
float m_buf[12]; // 环形缓冲区
|
||||||
|
int m_totalTickCount; // 超时用总 tick 计数
|
||||||
|
bool m_timeout; // 是否已超时
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PRESSUREMONITOR_H
|
#endif // PRESSUREMONITOR_H
|
||||||
+19
-2
@@ -1235,19 +1235,36 @@ void MainWidget::airPushingProcess()
|
|||||||
|
|
||||||
setRunStatus(tr("等待压力稳定..."));
|
setRunStatus(tr("等待压力稳定..."));
|
||||||
|
|
||||||
// 调用压力检测器,监测压力持续3秒波动范围不超过标定值的+-10%
|
|
||||||
if(m_pressureMonitor->tick((float)sysPara->status.PRESSURE, (float)sysPara->para.pressure)) {
|
if(m_pressureMonitor->tick((float)sysPara->status.PRESSURE, (float)sysPara->para.pressure)) {
|
||||||
reclaimTanOpen();
|
reclaimTanOpen();
|
||||||
sysPara->status.airPushingDone = 1;
|
sysPara->status.airPushingDone = 1;
|
||||||
sysPara->status.airPushing = 0;
|
sysPara->status.airPushing = 0;
|
||||||
sysPara->status.airPushingOnTime = 0;
|
sysPara->status.airPushingOnTime = 0;
|
||||||
airPushTimer->stop();
|
airPushTimer->stop();
|
||||||
|
bool isTimeout = m_pressureMonitor->wasTimeout();
|
||||||
|
float bufCopy[12];
|
||||||
|
memcpy(bufCopy, m_pressureMonitor->buffer(), sizeof(bufCopy));
|
||||||
m_pressureMonitor->reset();
|
m_pressureMonitor->reset();
|
||||||
setRunStatus(tr("喷嘴开启中"));
|
setRunStatus(tr("喷嘴开启中"));
|
||||||
|
|
||||||
LogInfo::setRunStatusText(m_pressureMonitor->wasTimeout()
|
LogInfo::setRunStatusText(isTimeout
|
||||||
? "Pressure unstable timeout, fallback open the reclaim tank."
|
? "Pressure unstable timeout, fallback open the reclaim tank."
|
||||||
: "Pressure has stabled, will open the reclaim tank.");
|
: "Pressure has stabled, will open the reclaim tank.");
|
||||||
|
|
||||||
|
QString pressureSet = QString("Pressure buffer: [%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12]")
|
||||||
|
.arg(bufCopy[0], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[1], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[2], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[3], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[4], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[5], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[6], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[7], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[8], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[9], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[10], 0, 'f', 1)
|
||||||
|
.arg(bufCopy[11], 0, 'f', 1);
|
||||||
|
LogInfo::setRunStatusText(pressureSet);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user