|
|
#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 isVehicleShaking(float weight_kg);
|
|
|
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
|