You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Queue/weigh/WeightStabilityDetector.hpp

207 lines
6.8 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#ifndef WEIGHT_STABILITY_DETECTOR_HPP
#define WEIGHT_STABILITY_DETECTOR_HPP
#include <queue>
#include <vector>
#include <cmath>
#include <functional>
#include <memory>
#include <chrono>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
class WeightStabilityDetector {
public:
// 配置结构体
struct Config {
float jitter_threshold; // 抖动阈值(kg)
float min_weight_threshold; // 最小车辆重量阈值(kg)
float empty_car_threshold; // 空车阈值(kg)
float fast_drop_threshold; // 快速下降阈值(kg)
int required_stable_count; // 要求稳定次数
int min_jitter_count; // 最小抖动次数
int timeout_extra; // 超时额外次数
int window_size; // 滑动窗口大小
float max_std_dev; // 最大标准差(kg)
bool enable_debug_log; // 是否启用调试日志
bool reset_window_on_vehicle_on; // 车辆上磅时重置窗口
int leave_reset_delay_ms; // 离开状态重置延迟(ms)
};
// 车辆状态枚举
enum class VehicleState {
NO_VEHICLE, // 无车
VEHICLE_ON, // 车辆上磅
VEHICLE_STABLE, // 车辆稳定
VEHICLE_LEAVING // 车辆离开
};
// 回调函数类型定义
typedef std::function<void(VehicleState, float, void*)> StateCallback;
typedef std::function<void(float, bool, void*)> WeightCallback;
// 统计信息结构体
struct Statistics {
float mean; // 平均值
float std_dev; // 标准差
float min; // 最小值
float max; // 最大值
float variance; // 方差
int sample_count; // 样本数量
int stable_count; // 稳定次数
int increase_count; // 连续增长次数
Statistics() :
mean(0.0f),
std_dev(0.0f),
min(0.0f),
max(0.0f),
variance(0.0f),
sample_count(0),
stable_count(0),
increase_count(0) {}
};
// 重量数据类型定义
struct WeightData {
float value_kg; // 重量值(kg)
std::chrono::steady_clock::time_point timestamp; // 时间戳
bool is_valid; // 是否有效
bool is_stable; // 是否稳定
WeightData(float val = 0.0f) :
value_kg(val),
timestamp(std::chrono::steady_clock::now()),
is_valid(true),
is_stable(false) {}
};
// 构造函数和析构函数
explicit WeightStabilityDetector(const Config& config = Config());
~WeightStabilityDetector();
// 禁用拷贝构造和赋值
WeightStabilityDetector(const WeightStabilityDetector&) = delete;
WeightStabilityDetector& operator=(const WeightStabilityDetector&) = delete;
// 主要接口
bool processWeight(float weight_kg);
bool processWeightData(const WeightData& data);
// 状态获取
VehicleState getState() const { return current_state_; }
bool isStable() const { return current_state_ == VehicleState::VEHICLE_STABLE; }
bool hasVehicle() const {
return current_state_ == VehicleState::VEHICLE_ON ||
current_state_ == VehicleState::VEHICLE_STABLE;
}
// 重量获取
float getCurrentWeight() const { return current_weight_; }
float getStableWeight() const { return stable_weight_; }
float getLastWeight() const { return previous_weight_; }
// 统计信息获取
Statistics getStatistics() const { return stats_; }
const std::vector<float>& getWeightHistory() const { return weight_history_; }
// 配置管理
void setConfig(const Config& config);
const Config& getConfig() const { return config_; }
// 重置检测器
void reset(bool notify_callback = true);
// 强制设置状态(用于测试)
void forceState(VehicleState state) { current_state_ = state; }
// 回调设置
void setStateCallback(StateCallback callback, void* user_data = nullptr) {
state_callback_ = callback;
state_callback_data_ = user_data;
}
void setWeightCallback(WeightCallback callback, void* user_data = nullptr) {
weight_callback_ = callback;
weight_callback_data_ = user_data;
}
// 调试功能
void enableDebugLog(bool enable) { config_.enable_debug_log = enable; }
void setDebugOutput(std::function<void(const std::string&)> debug_func) {
debug_output_ = debug_func;
}
private:
// 内部辅助函数
void updateWindow(float weight_kg);
void updateVehicleWindow(float weight_kg);
void calculateVehicleStatistics();
void checkStateTransition(float weight_kg);
void transitionToState(VehicleState new_state);
// 状态判断函数 - 添加const修饰符
bool isJitterExceeded(float weight_diff) const;
bool isVehicleOn(float weight_kg) const;
bool isVehicleLeaving(float weight_kg) const;
bool checkFastDrop(float weight_kg) const;
bool checkStableCondition() const;
// 内部数据处理
void addWeightToHistory(float weight_kg);
// 调试输出 - 添加const修饰符
void debugLog(const std::string& message) const;
private:
Config config_;
VehicleState current_state_;
// 重量数据
float current_weight_;
float previous_weight_;
float stable_weight_;
float max_weight_; // 记录最大重量
// 滑动窗口
std::deque<float> weight_window_; // 全局重量窗口
std::deque<float> vehicle_weight_window_; // 车辆上磅后的重量窗口
size_t current_window_size_;
size_t vehicle_window_size_;
// 计数器
int stable_count_;
int continuous_increase_count_;
int total_samples_;
// 历史数据
std::vector<float> weight_history_;
static const size_t MAX_HISTORY_SIZE = 1000;
// 时间管理
std::chrono::steady_clock::time_point last_state_change_time_;
std::chrono::steady_clock::time_point last_weight_time_;
// 统计信息
mutable Statistics stats_; // 标记为mutable因为calculateVehicleStatistics需要修改它
// 回调函数
StateCallback state_callback_;
WeightCallback weight_callback_;
void* state_callback_data_;
void* weight_callback_data_;
// 调试输出
std::function<void(const std::string&)> debug_output_;
// 状态标志
bool is_initialized_;
bool has_vehicle_on_; // 是否有车在磅上
bool is_leaving_state_; // 是否处于离开状态
};
#endif // WEIGHT_STABILITY_DETECTOR_HPP