diff --git a/uart/uart.cpp b/uart/uart.cpp index ee9d9de..4a6fa3c 100644 --- a/uart/uart.cpp +++ b/uart/uart.cpp @@ -503,7 +503,7 @@ int Uart::WaveSendCondition(char* shortAddr){ sprintf(whereCon,"shortAddr = '%s' ",shortAddr); vec_t vecResult = sqlite_db_ctrl::instance().GetDataSingleLine("t_shutdown_info","*",whereCon); effect = vecResult[5]; - if((lowSignal == 1 && atof(rssi.c_str()) < signalThreshold) || (lowBatteryLevel == 1 && fBatteryPower < batteryLevelThreshold) || effect == "1"){ + if((lowSignal == 1 && (atof(rssi.c_str())*100) < signalThreshold) || (lowBatteryLevel == 1 && fBatteryPower < batteryLevelThreshold) || effect == "1"){ zlog_warn(zct, "WaveSendCondition not meet condition shortAddr = %s,rssi = %s,batteryPower = %s,effect = %s",shortAddr,rssi.c_str(),batteryPower.c_str(),effect.c_str()); return 1; } diff --git a/uart/uart_feature_parse.cpp b/uart/uart_feature_parse.cpp index 899daa7..29b147b 100644 --- a/uart/uart_feature_parse.cpp +++ b/uart/uart_feature_parse.cpp @@ -30,6 +30,7 @@ unsigned char data[96000] = {0x00}; unsigned char outdata[96000] = {0x00}; unsigned char dealdata[96000] = {0x00}; char mqttData[1024000] = {0}; +char mqttData_vel[10240] = {0}; void Uart::RecordBattery(std::string &strLongAddr, DataRecvStatic &dataStatic, std::string &nowTimetamp) { char insertSql[1024] = {0}; @@ -106,23 +107,39 @@ void Uart::DealTriger(uint16_t ushortAdd,std::string & measurementID){ sprintf(whereCon, "MeasurementID='%s' and status ='1' ", measurementID.c_str()); sprintf(tablename,"t_data_%s",measurementID.c_str()); vecTrigger = sqlite_db_ctrl::instance().GetDataSingleLine(" t_wave_triger_info ", " * ", whereCon); + int triger_x = 0,triger_y = 0,triger_z = 0; if (vecTrigger.size() > 0){// 加速度有效值 memset(whereCon, 0x00, sizeof(whereCon)); sprintf(whereCon,"dataNodeNo = '%s' order by timeStamp desc limit 0,3;",measurementID.c_str()); if(vecTrigger[3] == "0"){ array_t arrValue = sqlite_db_ctrl::instance().GetDataMultiLine(tablename, " channelID,rmsValues ", whereCon); if(arrValue.size()){ + triger_x = 0,triger_y = 0,triger_z = 0; for (size_t i = 0; i < arrValue.size(); i++) { float rmsValue_f = atof(arrValue[i][1].c_str()); - if (rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("X") != std::string::npos || arrValue[i][0].find("Y") != std::string::npos)) { - zlog_warn(zct, "measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd); - scheduler::instance().TriggerWave(ushortAdd, 0, 1); - }else if (rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Z") != std::string::npos)) + if(rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("X") != std::string::npos)){ + triger_x = 1; + zlog_warn(zct, "X measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd); + + } + if(rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Y") != std::string::npos)) { + zlog_warn(zct, "Y measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd); + triger_y = 1; + } + if (rmsValue_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Z") != std::string::npos)) { - zlog_warn(zct, "measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd); - scheduler::instance().TriggerWave(ushortAdd, 1, 0); - } + zlog_warn(zct, "Z measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), rmsValue_f,ushortAdd); + triger_z = 1; + } + } + zlog_info(zct, "triger_x=%d,triger_y=%d,triger_z=%d", triger_x, triger_y, triger_z); + if((triger_x == 1 || triger_y == 1) && triger_z == 1){ + scheduler::instance().TriggerWave(ushortAdd, 1, 1); + }else if((triger_x == 1 || triger_y == 1) && triger_z != 1){ + scheduler::instance().TriggerWave(ushortAdd, 0, 1); + }else if(triger_x != 1 && triger_y != 1 && triger_z == 1){ + scheduler::instance().TriggerWave(ushortAdd, 1, 0); } if (vecTrigger[4] == "0") { @@ -134,18 +151,33 @@ void Uart::DealTriger(uint16_t ushortAdd,std::string & measurementID){ }else if (vecTrigger[3] == "1"){// 速度有效值 array_t arrValue = sqlite_db_ctrl::instance().GetDataMultiLine(tablename, " channelID,integratRMS ", whereCon); if(arrValue.size()){ + triger_x = 0,triger_y = 0,triger_z = 0; for (size_t i = 0; i < arrValue.size(); i++) { float integratRMS_f = atof(arrValue[i][1].c_str()); - if (integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("X") != std::string::npos || arrValue[i][0].find("Y") != std::string::npos)) { - zlog_warn(zct, "measurementID='%s' trigger activated, integratRMS=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd); - scheduler::instance().TriggerWave(ushortAdd, 0, 1); - }else if (integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Z") != std::string::npos)) + if (integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("X") != std::string::npos)){ + zlog_warn(zct, "X measurementID='%s' trigger activated, rmsValue=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd); + triger_x = 1; + } + if(integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Y") != std::string::npos)) { + zlog_warn(zct, "Y measurementID='%s' trigger activated, integratRMS=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd); + triger_y = 1; + } + if (integratRMS_f >= atof(vecTrigger[4].c_str()) && (arrValue[i][0].find("Z") != std::string::npos)) { - zlog_warn(zct, "measurementID='%s' trigger activated, integratRMS=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd); - scheduler::instance().TriggerWave(ushortAdd, 1, 0); - } + zlog_warn(zct, "Z measurementID='%s' trigger activated, integratRMS=%f,ushortAdd %04x", measurementID.c_str(), integratRMS_f,ushortAdd); + triger_z = 1; + } + } + zlog_info(zct, "triger_x=%d,triger_y=%d,triger_z=%d", triger_x, triger_y, triger_z); + if((triger_x == 1 || triger_y == 1) && triger_z == 1){ + scheduler::instance().TriggerWave(ushortAdd, 1, 1); + }else if((triger_x == 1 || triger_y == 1) && triger_z != 1){ + scheduler::instance().TriggerWave(ushortAdd, 0, 1); + }else if(triger_x != 1 && triger_y != 1 && triger_z == 1){ + scheduler::instance().TriggerWave(ushortAdd, 1, 0); + } if (vecTrigger[4] == "0") { memset(whereCon, 0x00, sizeof(whereCon)); @@ -1387,11 +1419,12 @@ void Uart::WriteDatFile(int sampleRate, std::string &strMeasurementID, int iChan zlog_info(zct, " product = %s,version = %d ,iChannel = %d", product.c_str(),version,iChannel); if ((product == "02" && sampleRate == 24000 && iChannel == WAVE_Z && version == 1) || (iChannel == WAVE_Z && version == 0) || - ((iChannel == WAVE_LF_X || iChannel == WAVE_LF_Y|| iChannel == WAVE_LF_Z) && version == 0)){ + ((iChannel == WAVE_LF_X || iChannel == WAVE_LF_Y|| iChannel == WAVE_LF_Z) && version == 0) || + ((iChannel == WAVE_X || iChannel == WAVE_Y) && version == 0)){ sampleRate = 25600; zlog_info(zct, " sampleRate = %d,product = %s,ACCSampleTime = %f ", sampleRate,product.c_str(),ACCSampleTime); size_t outSize = 25600; - std::vector outputData,outputData2; + std::vector outputData,outputData2,IntegrationWave; float epsilon = 1e-6f; if (std::fabs(ACCSampleTime - 1) < epsilon){ outputData = Calculation::fftInterpolate(vecData, outSize); @@ -1408,21 +1441,23 @@ void Uart::WriteDatFile(int sampleRate, std::string &strMeasurementID, int iChan outSize = 32768; sampleRate = 25600; outputData = Calculation::fftInterpolate(vecData, outSize); - zlog_info(zct, " outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime); + zlog_info(zct, "1.28 outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime); }else if(std::fabs(ACCSampleTime - 3.2) < epsilon){ outSize = 8192; sampleRate = 2560; outputData = Calculation::fftInterpolate(vecData, outSize); - zlog_info(zct, " outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime); + + zlog_info(zct, "3.2 outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime); }else if(std::fabs(ACCSampleTime - 1.6) < epsilon){ - outSize = 5120; + outSize = 8192; sampleRate = 5120; outputData = Calculation::fftInterpolate(vecData, outSize); - zlog_info(zct, " outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime); + zlog_info(zct, "1.6 outputData_size %zu ,ACCSampleTime %f", outputData.size(),ACCSampleTime); } zlog_info(zct, " outputData_size %zu ", outputData.size()); float mean = Calculation::mean(outputData); memset(mqttData,0,sizeof(mqttData)); + memset(mqttData_vel,0,sizeof(mqttData_vel)); id = 0; for (size_t i = 0; i < outputData.size(); i++) { frTemp = outputData[i] - mean; @@ -1437,6 +1472,29 @@ void Uart::WriteDatFile(int sampleRate, std::string &strMeasurementID, int iChan strncpy(mqttData + id ,buf,strlen(buf)); } } + if(iChannel == WAVE_LF_X || iChannel == WAVE_LF_Y|| iChannel == WAVE_LF_Z){ + double resolution = 1 / 3.2 ; + //积分 + id = 0; + std::vector outputDataAC(outputData.size()); + for (size_t i = 0; i < outputData.size(); i++) + { + outputDataAC[i] = outputData[i] - mean; + } + Calculation::Integration(outputDataAC, IntegrationWave, resolution); + for (size_t i = 0; i < IntegrationWave.size(); i++) { + memset(buf, 0x00, sizeof(buf)); + sprintf(buf, "%.2f", IntegrationWave[i]); + if (i != IntegrationWave.size() -1){ + strncpy(mqttData_vel + id ,buf,strlen(buf)); + id = id + strlen(buf); + strncpy(mqttData_vel + id,",",1); + id = id + 1; + }else{ + strncpy(mqttData_vel + id ,buf,strlen(buf)); + } + } + } } zlog_info(zct, "fopen file vecData.size : %zu end ", vecData.size()); @@ -1452,6 +1510,10 @@ void Uart::WriteDatFile(int sampleRate, std::string &strMeasurementID, int iChan valWaveData["waveData"] = mqttData; valWaveData["mean"] = mean; valWaveData["waveType"] = wave_type; + if(iChannel == WAVE_LF_X || iChannel == WAVE_LF_Y|| iChannel == WAVE_LF_Z){ + valWaveData["waveDataVel"] = mqttData_vel; + } + valWaveData["seconds"] = ACCSampleTime; Json::FastWriter WaveValue; std::string WaveData = WaveValue.write(valWaveData); diff --git a/utility/calculation.cpp b/utility/calculation.cpp index 6b13fbc..c68abe9 100644 --- a/utility/calculation.cpp +++ b/utility/calculation.cpp @@ -298,54 +298,89 @@ void Calculation::Integration(std::vector &vecData, std::vector &r std::vector Calculation::fftInterpolate(const std::vector& input, size_t outputSize) { - size_t inputSize = input.size(); - double in[inputSize]; - for (int i = 0; i < inputSize; i++) { - in[i] = input[i]; + const size_t inputSize = input.size(); + if (inputSize == 0 || outputSize == 0) { + return {}; } - // 1. FFTW 初始化 - fftw_complex *freqDomain = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * inputSize); - fftw_complex *paddedFreqDomain = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * outputSize); - fftw_plan forwardPlan = fftw_plan_dft_r2c_1d(inputSize, in, freqDomain, FFTW_ESTIMATE); - - // 2. 执行 FFT + + // FFTW 的实数输入建议用 double + std::vector in(inputSize); + for (size_t i = 0; i < inputSize; ++i) { + in[i] = static_cast(input[i]); + } + + const size_t inFreqSize = inputSize / 2 + 1; + const size_t outFreqSize = outputSize / 2 + 1; + + fftw_complex* freqIn = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * inFreqSize); + fftw_complex* freqOut = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * outFreqSize); + + if (!freqIn || !freqOut) { + if (freqIn) fftw_free(freqIn); + if (freqOut) fftw_free(freqOut); + throw std::runtime_error("FFTW malloc failed"); + } + + // 清零输出频谱 + for (size_t i = 0; i < outFreqSize; ++i) { + freqOut[i][0] = 0.0; + freqOut[i][1] = 0.0; + } + + fftw_plan forwardPlan = fftw_plan_dft_r2c_1d( + static_cast(inputSize), + in.data(), + freqIn, + FFTW_ESTIMATE + ); + fftw_execute(forwardPlan); - // 3. 频域插值:扩展频谱 - size_t halfSize = inputSize / 2 + 1; // 实数FFT的对称部分 - for (size_t i = 0; i < halfSize; ++i) { - paddedFreqDomain[i][0] = freqDomain[i][0]; // 实部 - paddedFreqDomain[i][1] = freqDomain[i][1]; // 虚部 - } - for (size_t i = halfSize; i < outputSize - halfSize; ++i) { - paddedFreqDomain[i][0] = 0.0; // 实部填零 - paddedFreqDomain[i][1] = 0.0; // 虚部填零 - } - for (size_t i = outputSize - halfSize; i < outputSize; ++i) { - paddedFreqDomain[i][0] = freqDomain[inputSize - (outputSize - i)][0]; - paddedFreqDomain[i][1] = freqDomain[inputSize - (outputSize - i)][1]; + // 只复制半谱里能容纳的低频部分 + // 对于重采样,保留共同可表示的频率范围 + size_t copyBins = std::min(inFreqSize, outFreqSize); + + // Nyquist 点要小心,但先按通用方式复制可用部分 + for (size_t k = 0; k < copyBins; ++k) { + freqOut[k][0] = freqIn[k][0]; + freqOut[k][1] = freqIn[k][1]; } - // 4. IFFT 变换回时域 - std::vector output(outputSize); - fftw_plan inversePlan = fftw_plan_dft_c2r_1d(outputSize, paddedFreqDomain, output.data(), FFTW_ESTIMATE); + // 如果是偶数长度,Nyquist 点必须是纯实数 + if (outputSize % 2 == 0) { + freqOut[outFreqSize - 1][1] = 0.0; + } + + std::vector out(outputSize, 0.0); + + fftw_plan inversePlan = fftw_plan_dft_c2r_1d( + static_cast(outputSize), + freqOut, + out.data(), + FFTW_ESTIMATE + ); + fftw_execute(inversePlan); - - // 5. 缩放输出结果 - for (double& val : output) { - val /= outputSize; + + // FFTW 的 c2r 没有自动归一化 + // 这里除以 outputSize 是 IFFT 归一化 + // 再乘 outputSize/inputSize 用于尽量保持幅值一致 + const double scale = 1.0 / static_cast(inputSize); + for (size_t i = 0; i < outputSize; ++i) { + out[i] *= scale; } - std::vector output2(outputSize); - for (int i = 0; i < outputSize; i++) { - output2[i] = output[i]; + + std::vector result(outputSize); + for (size_t i = 0; i < outputSize; ++i) { + result[i] = static_cast(out[i]); } - // 清理 FFTW + fftw_destroy_plan(forwardPlan); fftw_destroy_plan(inversePlan); - fftw_free(freqDomain); - fftw_free(paddedFreqDomain); + fftw_free(freqIn); + fftw_free(freqOut); - return output2; + return result; } bool Calculation::freqDomainDecimateFFTW(const std::vector& input,