From 84ca40e3a5155901c9727aa7f0a418972775efb6 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Thu, 29 Feb 2024 15:43:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=A1=E5=87=86=E5=82=A8=E6=B6=B2=E6=A1=B6?= =?UTF-8?q?=E7=9A=84=E9=87=8D=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 60 --------------- iflytoplinuxsdk | 2 +- src/service/device_io_control_service.cpp | 121 +++++++++++++++++------------- src/service/device_io_control_service.hpp | 26 +++++-- src/utils/moving_average_filter.hpp | 43 +++++++++++ src/utils/volume_convertor.cpp | 81 ++++++++++++++++++++ src/utils/volume_convertor.hpp | 69 +++++++++++++++++ 7 files changed, 284 insertions(+), 118 deletions(-) create mode 100644 src/utils/moving_average_filter.hpp create mode 100644 src/utils/volume_convertor.cpp create mode 100644 src/utils/volume_convertor.hpp diff --git a/README.md b/README.md index f32e34c..5dd2025 100644 --- a/README.md +++ b/README.md @@ -7,33 +7,7 @@ ``` ``` -修改点: (OK) - 1. 用户等级分为3级别(后台不限制用户等级,前台限制用户操作)OK - 2. iflytop9973属于admin的超级密码 - 3. 修改用户密码 OK - 4. 登陆时给出提示,用户不存在,或者密码错误 - -消毒前,如果湿度太大,不允许消毒。 -添加预设参数 OK -添加预设参数配置 OK - -添加审计数据库接口 OK -添加审计 OK - -通过getState可以获得到log,小数 OK -数据库操作加锁 OK - - - --------------------------------- -记录用户操作 (TODO) -添加U盘数据导出 -添加审计数据导出 - -排液自动停止 -水禁传感器测试 -磁盘管理(磁盘容量不足时,弹出提示,且停止记录数据) ``` @@ -49,37 +23,3 @@ sudo apt-get install sqlitebrowser https://www.sqlite.org/docs.html ``` - - -``` -测试指令 - - -``` - - -``` -1. 开始消毒后 - - -``` - - -``` -液位测量压力传感器: -设备地址:01 -量程:-1~4kPa -4 kPa=407.888 毫米水柱 -传感器测量精度:0.407888 毫米水柱 -``` - -``` -1. 支持调速 -2. 液体容量进行滤波 -3. 打印日志去掉小数点 - -1. 加泵写死,速度不可修改,550g/min -2. 注射泵速率限制在30g/min - - -``` \ No newline at end of file diff --git a/iflytoplinuxsdk b/iflytoplinuxsdk index 45bd079..279b705 160000 --- a/iflytoplinuxsdk +++ b/iflytoplinuxsdk @@ -1 +1 @@ -Subproject commit 45bd079bb5f10f36ecfd610a0de0148cafc97bb5 +Subproject commit 279b7054fe46618b4084fba61bcef40763f7b269 diff --git a/src/service/device_io_control_service.cpp b/src/service/device_io_control_service.cpp index 7a3dfc4..28cfdc9 100644 --- a/src/service/device_io_control_service.cpp +++ b/src/service/device_io_control_service.cpp @@ -19,12 +19,71 @@ using namespace std; DeviceIoControlService::DeviceIoControlService() {} void DeviceIoControlService::initialize() { GET_TO_SERVICE(m_zcanHost); } +void DeviceIoControlService::updateDisinfectantVolumeSample(float _pa) { + float pa = _pa - 100; // 100当容器中没有液体时的压强 + if (pa < 0) pa = 0; + + float g = m_volumeConvertor.pressurePa2VolumeG(_pa); + + m_disinfectantVolumeSample_g = m_DisinfectantWeightFilter.filter(g); + + logger->info("{} pa {} g", _pa, m_disinfectantVolumeSample_g); +} + void DeviceIoControlService::startScan() { - m_workThread.reset(new Thread("DeviceIoControlService", [this]() { + m_PressureSensorDataSampleThread.reset(new Thread("PressureSensorDataSampleThread", [this]() { ThisThread thisThread; - uint32_t i = 0; - int readpressuresensor_id = 1; + while (!thisThread.getExitFlag()) { + /* code */ + ZCanHost::huacheng_pressure_sensor_read_c1005_t sdata; + if (m_zcanHost->huacheng_pressure_sensor_read_c1005(1, sdata) == 0) { + lock_guard lock(lock_); + m_pressure_sensor_data[1] = sdata; + } + + thisThread.sleepForMs(100); + + if (m_zcanHost->huacheng_pressure_sensor_read_c1005(2, sdata) == 0) { + lock_guard lock(lock_); + m_pressure_sensor_data[2] = sdata; + } + + thisThread.sleepForMs(100); + + if (m_zcanHost->huacheng_pressure_sensor_read_c1005(3, sdata) == 0) { + lock_guard lock(lock_); + m_pressure_sensor_data[3] = sdata; + } + + thisThread.sleepForMs(100); + + if (m_zcanHost->huacheng_pressure_sensor_read_c1005(4, sdata) == 0) { + lock_guard lock(lock_); + m_pressure_sensor_data[4] = sdata; + } + + thisThread.sleepForMs(100); + + // if (m_zcanHost->huacheng_pressure_sensor_read_c1005(5, sdata) == 0) { + // lock_guard lock(lock_); + // m_pressure_sensor_data[5] = sdata; + // } + // thisThread.sleepForMs(10); + + /** + * @brief 计算并更新过氧化清重量 + */ + { // + updateDisinfectantVolumeSample(m_pressure_sensor_data[1].value / 1.0 /*pa*/); + } + } + })); + + m_workThread.reset(new Thread("DeviceIoControlService", [this]() { + ThisThread thisThread; + uint32_t i = 0; + int error = 0; while (!thisThread.getExitFlag()) { /* code */ @@ -46,51 +105,21 @@ void DeviceIoControlService::startScan() { lock_guard lock(lock_); m_adc_2 = adcv; } - // m_zcanHost->readadc(1, m_adc_1); - // m_zcanHost->readadc(2, m_adc_2); - // m_zcanHost->readadc(3, m_adc_3); - // m_zcanHost->readadc(4, m_adc_4); - // m_zcanHost->readadc(5, m_adc_5); } - - if (i % 3000 == 0) { + if (i % 3000 == 0 && error < 10) { // m_hpp272_data_1 ZCanHost::hpp272_data_t m_hpp272_data_1_cache; int suc = m_zcanHost->hpp272_read_c1000(1, m_hpp272_data_1_cache); if (suc == 0) { lock_guard lock(lock_); m_hpp272_data_1 = m_hpp272_data_1_cache; + error = 0; + } else { + error++; + if (error == 10) { + logger->error("hpp272_read_c1000 error:{}", suc); + } } - // hydrogen_peroxide_volume - // water_vapor_saturation_pressure_h2o_h2o2 - // logger->info("---------hpp272_read_c1000---------"); - // logger->info("hydrogen_peroxide_volume :{}", m_hpp272_data_1.hydrogen_peroxide_volume); - // logger->info("h2o_h2o2_rs :{}", m_hpp272_data_1.h2o_h2o2_rs); - // logger->info("temperature1 :{}", m_hpp272_data_1.temperature1); - // logger->info("relative_humidity :{}", m_hpp272_data_1.relative_humidity); - // logger->info("absolute_hydrogen_peroxide :{}", m_hpp272_data_1.absolute_hydrogen_peroxide); - // logger->info("h2o_h2o2dew_point_temperature :{}", m_hpp272_data_1.h2o_h2o2dew_point_temperature); - // logger->info("reserved1 :{}", m_hpp272_data_1.reserved1); - // logger->info("water_volume :{}", m_hpp272_data_1.water_volume); - // logger->info("water_vapor_pressure :{}", m_hpp272_data_1.water_vapor_pressure); - // logger->info("absolute_humidity :{}", m_hpp272_data_1.absolute_humidity); - // logger->info("water_vapor_saturation_pressure_h2o:{}", m_hpp272_data_1.water_vapor_saturation_pressure_h2o); - // logger->info("temperature2 :{}", m_hpp272_data_1.temperature2); - // logger->info("h2o2_vapor_pressure :{}", m_hpp272_data_1.h2o2_vapor_pressure); - // logger->info("water_vapor_saturation_pressure_h2o_h2o2:{}", m_hpp272_data_1.water_vapor_saturation_pressure_h2o_h2o2); - // logger->info(""); - } - - if (i % 300 == 0) { - if (readpressuresensor_id == 5) { - readpressuresensor_id = 1; - } - ZCanHost::huacheng_pressure_sensor_read_c1005_t sdata; - if (m_zcanHost->huacheng_pressure_sensor_read_c1005(readpressuresensor_id, sdata) == 0) { - lock_guard lock(lock_); - m_pressure_sensor_data[readpressuresensor_id] = sdata; - } - readpressuresensor_id++; } if (i % 100 == 0) { @@ -264,17 +293,7 @@ static int filter(int data) { int DeviceIoControlService::getDisinfectantVolume_g() { // kpa; lock_guard lock(lock_); - - float kpa = m_pressure_sensor_data[1].value / 1000.0; - int g = 2.11 * kpa * 1000 * 1.3; - if (g < 450) { /*零点*/ - return 0; - } else { - g -= 450; - } - g = filter(g); - // logger->info("g {}", g); - return g; + return m_disinfectantVolumeSample_g; } int DeviceIoControlService::getPressureSensorData(int index) { lock_guard lock(lock_); diff --git a/src/service/device_io_control_service.hpp b/src/service/device_io_control_service.hpp index b75886a..4a83ebc 100644 --- a/src/service/device_io_control_service.hpp +++ b/src/service/device_io_control_service.hpp @@ -17,6 +17,10 @@ #include "iflytop/components/zcanreceiver/zcanhost.hpp" #include "iflytop/core/core.hpp" #include "zservice_container/zservice_container.hpp" +// +#include "utils/moving_average_filter.hpp" +#include "utils/volume_convertor.hpp" + // lock_guard lock(lock_); #include @@ -44,12 +48,19 @@ class DeviceIoControlService : public enable_shared_from_this m_workThread; shared_ptr m_zcanHost; + unique_ptr m_PressureSensorDataSampleThread; + // // std::mutex lock_; std::recursive_mutex lock_; ZCanHost::hpp272_data_t m_hpp272_data_1 = {0}; ZCanHost::huacheng_pressure_sensor_read_c1005_t m_pressure_sensor_data[5] = {0}; + int32_t m_disinfectantVolumeSample_g; // 消毒液量采样 + + // 液体重量计算 + VolumeConvertor m_volumeConvertor; + MovingAverageFilter m_DisinfectantWeightFilter = MovingAverageFilter(20); // bool m_waterImmersionSensor1 = false; // 漏液检测 @@ -68,11 +79,11 @@ class DeviceIoControlService : public enable_shared_from_this +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace iflytop { +using namespace std; + +class MovingAverageFilter { + size_t size_; + float sum_ = 0; + std::list values_; + + public: + MovingAverageFilter(size_t size) : size_(size) { + if (size_ <= 0) { + throw std::invalid_argument("size must be greater than 0"); + } + } + + float filter(float value) { + if (values_.size() < size_) { + values_.push_back(value); + sum_ += value; + return sum_ / values_.size(); + } + + sum_ -= values_.front(); + values_.pop_front(); + values_.push_back(value); + sum_ += value; + return sum_ / size_; + } + + private: +}; +} // namespace iflytop diff --git a/src/utils/volume_convertor.cpp b/src/utils/volume_convertor.cpp new file mode 100644 index 0000000..8b0fb5c --- /dev/null +++ b/src/utils/volume_convertor.cpp @@ -0,0 +1,81 @@ +#include "volume_convertor.hpp" + +using namespace iflytop; + +float VolumeConvertor::pa2high(float pa) { + /** + * @brief kpa 转换成液面高度 + * + * p = h*density*g + * + * h = p/(density*g) + * + * p :压强, 单位 pa + * density:液体密度, 单位 kg/m^3 + * g :重力加速度, 单位 + * h :液面高度, 单位 m + * + * 过氧化氢 浓度30.5%时密度=1.11331981022045g/cm^3 = 1113.31981022045kg/m^3 + * + */ + // 计算液面高度 + float h_m = pa / (density * 9.78); // 液体密度最后会被约掉,大小不影响结果 + float h_dm = h_m * 10; + + return h_dm; +} +/** + * @brief 计算倒圆锥体积 + * + * @param rb 圆锥体底部半径 + * @param ru 圆锥体顶部半径 + * @param h 圆锥体高度 + * @param nowh 圆锥内液面高度 + * @return float + */ +float VolumeConvertor::computeConeVolume(float rb, float ru, float h, float nowh) { + if (nowh > h) nowh = h; + if (nowh < 0) nowh = 0; + + float rb_now = rb + (ru - rb) * nowh / h; + float v = PI * nowh * (rb_now * rb_now + rb_now * ru + ru * ru) / 3; + return v; +} + +float VolumeConvertor::pressurePa2VolumeG(float _pa) { + float pa = _pa - 90; + if (pa < 0) { + pa = 0; + } + + // 计算液面高度 + float h_dm = pa2high(pa); + + float h1_dm = h_dm; + float h2_dm = h_dm - container_h1; + float h3_dm = h_dm - container_h2 - container_h1; + float h4_dm = h_dm - container_h3 - container_h2 - container_h1; + + h1_dm = h1_dm < 0 ? 0 : h1_dm; + h2_dm = h2_dm < 0 ? 0 : h2_dm; + h3_dm = h3_dm < 0 ? 0 : h3_dm; + h4_dm = h4_dm < 0 ? 0 : h4_dm; + + h1_dm = h1_dm > container_h1 ? container_h1 : h1_dm; + h2_dm = h2_dm > container_h2 ? container_h2 : h2_dm; + h3_dm = h3_dm > container_h3 ? container_h3 : h3_dm; + h4_dm = h4_dm > container_h4 ? container_h4 : h4_dm; + +// printf("h_dm:%f h1_dm:%f, h2_dm:%f, h3_dm:%f, h4_dm:%f\n",h_dm, h1_dm, h2_dm, h3_dm, h4_dm); + + float v1 = computeConeVolume(container_rb1, container_ru1, container_h1, h1_dm); + float v2 = computeConeVolume(container_rb2, container_ru2, container_h2, h2_dm); + float v3 = computeConeVolume(container_rb3, container_ru3, container_h3, h3_dm); + float v4 = computeConeVolume(container_rb4, container_ru4, container_h4, h4_dm); +// printf("v1:%f, v2:%f, v3:%f, v4:%f\n", v1, v2, v3, v4); + + // h4_dm * (double)(2.1124069002737764) + float V_L = v1 + v2 + v3 + v4; // 0.001m^3 + float g = V_L * density; // 1m^3 = 1000L + return g; +} \ No newline at end of file diff --git a/src/utils/volume_convertor.hpp b/src/utils/volume_convertor.hpp new file mode 100644 index 0000000..413aa6e --- /dev/null +++ b/src/utils/volume_convertor.hpp @@ -0,0 +1,69 @@ + +#pragma once +#include + +namespace iflytop { + +#define PI 3.14159265358979323846 + +class VolumeConvertor { + /** + * @brief + * + * | <--r4_2 -->| + * _____________ + * | | + * | | + * | | h4 + * | | + * | r4_1 | + * \ / h3 + * | | h2 + * \ _____ / h1 + * + * + * | ru | + * ----------- + * \ / + * \ / h + * \_____/ + * |rb| + * + */ + + float container_h4 = 2.2069; + float container_ru4 = 0.82; + float container_rb4 = 0.82; + + float container_h3 = 0.15; + float container_ru3 = 0.82; + float container_rb3 = 0.67; + + float container_h2 = 0.0845; + float container_ru2 = 0.67; + float container_rb2 = 0.67; + + float container_h1 = 0.0845; + float container_ru1 = 0.67; + float container_rb1 = 0.05; + + float density = 1000; // kg/m^3 + + public: + float pressurePa2VolumeG(float _pa); + + private: + float pa2high(float pa); + /** + * @brief 计算倒圆锥体积 + * + * @param rb 圆锥体底部半径 + * @param ru 圆锥体顶部半径 + * @param h 圆锥体高度 + * @param nowh 圆锥内液面高度 + * @return float + */ + float computeConeVolume(float rb, float ru, float h, float nowh); +}; + +} // namespace iflytop