#include "DataProcess.h" GetDataValue MeasurementData_Nearbit; //近端测量值 GetDataValue MeasurementData_Farbit; //远端测量值 //获得权重范围 void get_weights_scores_range(GetFeatureValue* feature) { // 填充 weights_normal float weights_normal[ROWS][COLS_NORMAL] = { {0.02782361153708092f, 0.07425339118419849f, 0.12759042354281214f, 0.12291090933910485f, 0.057825758510349136f}, {0.027564071230094304f, 0.034914011597243846f, 0.03428079481697248f, 0.01543479395828397f, 0.07718536996417004f}, {0.019488141538371105f, 0.03279628785143933f, 0.07694254491891732f, 0.010422855733018327f, 0.022348371109245885f}, {0.30791780437151484f, 0.0433871871689603f, 0.03287291407974492f, 0.22075997995717458f, 0.11441410143843696f}, {0.041967380936312006f, 0.03073173344712312f, 0.10570414834976417f, 0.038395937926823887f, 0.4457716705304025f}, {0.08006381221588085f, 0.016748822025924905f, 0.02814835728381258f, 0.06657550807501712f, 8.589391929335013e-15f}, {0.08219625282668795f, 0.010732292674554226f, 0.030018966581668607f, 0.09360232815172899f, 0.081724331840547f}, {0.029540427522817107f, 0.04301860142552467f, 0.02658344150030427f, 0.12924826197604972f, 0.012136341727289321f}, {0.07933570776110352f, 0.014970424884683423f, 0.055678037816256847f, 0.04312882532615478f, 0.01724498153241749f}, {0.13425223325463498f, 0.20821822793072117f, 0.18170578370731505f, 0.07162196775825218f, 0.05237352825266105f}, {0.03346582696060625f, 0.031537897016211264f, 0.07854916838700497f, 0.038058057152586464f, 0.018421685430336208f}, {0.02450787860501228f, 0.020163834961829358f, 0.032592734764566145f, 0.027770217521932265f, 0.06720024464681389f}, {0.02270181024144438f, 0.151882044343984f, 0.05846495235235432f, 0.0692621315241782f, 0.03335361501730471f}, {0.02469783116319416f, 0.24075458769337896f, 0.09324354614973776f, 0.04024389436146122f, 8.589391929335013e-15f}, {0.0644772098352455f, 0.04589065579422297f, 0.03762418574876846f, 0.012564331238233306f, 8.589391929335013e-15f} }; // 填充 weights_abnormal // 填充标准分数 float std_scores_normal[COLS_NORMAL] = { 4.3300748832172875f,1.0124176131894556f,1.2331122890852892f,2.2906345596071116f,1.8271316432346785f }; // 填充范围值 float range_values[COLS_NORMAL] = { 0.14035106713875936f,0.07188706493959258f,0.34388788541653376f,0.6280178217431671f,0.30525313799525955f }; // 填充最小和最大值 float min_values[ROWS] = { 0.0f, // 压力差值最小值 0.0f, // 内压能量最小值 0.0f, // 外压能量最小值 0.0f, // 钻压均值最小值 0.0f, // 钻压幅度最小值 0.0f, // 钻压方差最小值 0.0f, // 扭矩均值最小值 0.0f, // 扭矩幅度最小值 0.0f, // 扭矩方差最小值 0.0f, // 转速均值最小值 0.0f, // 转速幅度最小值 0.0f, // 转速方差最小值 0.0f, // X振动严重性最小值 0.0f // Y振动严重性最小值 }; float max_values[ROWS] = { 10.0f, // 压力差值最大值 5.0f, // 内压能量最大值 5.0f, // 外压能量最大值 155.0f, // 钻压均值最大值 50.0f, // 钻压幅度最大值 100.0f, // 钻压方差最大值 10.0f, // 扭矩均值最大值 20.0f, // 扭矩幅度最大值 100.0f, // 扭矩方差最大值 120.0f, // 转速均值最大值 30.0f, // 转速幅度最大值 3150.0f, // 转速方差最大值 5.0f, // X振动严重性最大值 5.0f // Y振动严重性最大值 }; // 将数据赋值到结构体 for (int i = 0; i < ROWS; i++) { feature->min_values[i] = min_values[i]; feature->max_values[i] = max_values[i]; for (int j = 0; j < COLS_NORMAL; j++) { feature->weights_normal[i][j] = weights_normal[i][j]; } } for (int i = 0; i < COLS_NORMAL; i++) { feature->std_scores_normal[i] = std_scores_normal[i]; feature->range_values[i] = range_values[i]; } } // 归一化数据 void normalize_data(float* data, float* min_values, float* max_values, float* data_nor, int size) { for (int i = 0; i < size; i++) { data_nor[i] = 1 + 9 * (data[i] - min_values[i]) / (max_values[i] - min_values[i]); } } // 矩阵乘法:结果矩阵 = 数据向量 × 权重矩阵 void matrix_multiply(float* data, float weights[ROWS][COLS_NORMAL], float* result, int rows, int cols) { for (int i = 0; i < cols; i++) { result[i] = 0.0f; for (int j = 0; j < rows; j++) { result[i] += data[j] * weights[j][i]; } } } // 计算相对误差 float relative_error(float value, float standard) { return fabs((value - standard) / standard); } // 判断逻辑 int Zuanjin_weights_judge(float* data, GetFeatureValue* dataFeature) { float data_nor[ROWS]; normalize_data(data, dataFeature->min_values, dataFeature->max_values, data_nor, ROWS); // 计算 normal 的分数 float scores_normal[COLS_NORMAL]; matrix_multiply(data_nor, dataFeature->weights_normal, scores_normal, ROWS, COLS_NORMAL); float min_error = 1000000; int con_index = -1; // 计算最小相对误差 for (int i = 0; i < COLS_NORMAL; i++) { float error = relative_error(scores_normal[i], dataFeature->std_scores_normal[i]); if (error < min_error) { min_error = error; con_index = i; } } float con_value = scores_normal[con_index]; float range_normal = dataFeature->range_values[con_index]; float value_big = dataFeature->std_scores_normal[con_index] * (1 + range_normal); float value_small = dataFeature->std_scores_normal[con_index] * (1 - range_normal); // 检查是否在范围内 if (value_small < con_value && con_value < value_big) { return con_index; } else { return -1; } } unsigned char Get_MeasureData(GetDataValue DataValeNear) { unsigned char Temp; //工况信息临时变量 GetFeatureValue dataFeature; get_weights_scores_range(&dataFeature); float InPress = DataValeNear.Mean_InPress; //内压平均值 float OutPress = DataValeNear.Mean_OutPress; //外压平均值 float Mean_WOB = DataValeNear.Mean_WOB; //钻压平均值 float Mean_Torque = DataValeNear.Mean_Torque; //扭矩平均值 float Mean_RPM = DataValeNear.Mean_RPM; //转速平均值 float Mean_InTemprature = DataValeNear.Mean_InTemprature; //管内温度平均值 float Mean_OutTemprature = DataValeNear.Mean_OutTemprature; //环空温度平均值 float Mean_AxisX = DataValeNear.Mean_AxisX; //X轴振动平均值 float Mean_AxisY = DataValeNear.Mean_AxisY; //Y轴振动平均值 float Mean_AxisZ = DataValeNear.Mean_AxisZ; //Z轴振动平均值 float Mean_InDielectric = DataValeNear.Mean_InDielectric; //管内介电平均值 float Mean_OutDielectric = DataValeNear.Mean_OutDielectric; //环空介电平均值 float Different_Press = DataValeNear.Different_Press; //压力差值 float Energy_InPress = DataValeNear.Energy_InPress; //内压能量值 float Energy_OutPress = DataValeNear.Energy_OutPress; //外压能量值 float Amplitude_WOB = DataValeNear.Amplitude_WOB; //钻压幅度值 float Variance_WOB = DataValeNear.Variance_WOB; //钻压方差 float Amplitude_Torque = DataValeNear.Amplitude_Torque; //扭矩幅度值 float Variance_Torque = DataValeNear.Variance_Torque; //扭矩方差 float Amplitude_RPM = DataValeNear.Amplitude_RPM; //转速幅度值 float Variance_RPM = DataValeNear.Variance_RPM; //转速方差 float Vibration_AxisX = DataValeNear.Vibration_AxisX; //X轴振动严重性 float Vibration_AxisY = DataValeNear.Vibration_AxisY; //Y轴振动严重性 float Vibration_AxisZ = DataValeNear.Vibration_AxisZ; //Z轴振动严重性 float Variance_Vibration = DataValeNear.Variance_Vibration; //振动方差 float data[15]; data[0] = Different_Press; data[1] = Energy_InPress; data[2] = Energy_OutPress; data[3] = Mean_WOB; data[4] = Amplitude_WOB; data[5] = Variance_WOB; data[6] = Mean_Torque; data[7] = Amplitude_Torque; data[8] = Variance_Torque; data[9] = Mean_RPM; data[10] = Amplitude_RPM; data[11] = Variance_RPM; data[12] = Vibration_AxisX; data[13] = Vibration_AxisY; data[14] = Vibration_AxisZ; int con_result = Zuanjin_weights_judge(data, &dataFeature); if (con_result == 1) { Temp = 'A'; }; if (con_result == 2) { Temp = 'B'; } if (con_result == 3) { Temp = 'C'; } if (con_result == 4) { Temp = 'D'; } if (con_result == 5) { Temp = 'E'; } if (con_result == -1) { Temp = 'F'; } return Temp; // 返回处理结果 } void DataCompute(void) { uint8_t i; GetDataValue DataValeNear = { .Mean_InPress = 0.f, //内压平均值 .Mean_OutPress = 0.f, //外压平均值 .Mean_WOB = 0.f, //钻压平均值 .Mean_Torque = 2.399f, .Mean_RPM = 4.293f, .Mean_InTemprature = 22.74f, .Mean_OutTemprature = 0.93f, .Mean_AxisX = 1.08f, .Mean_AxisY = 0.32f, .Mean_AxisZ = 0.3f, .Mean_InDielectric = 4.2f, .Mean_OutDielectric = 3.8f, .Different_Press = 2.5f, .Energy_InPress = 10.0f, .Energy_OutPress = 8.5f, .Amplitude_WOB = 5.0f, .Variance_WOB = 0.8f, .Amplitude_Torque = 2.3f, .Variance_Torque = 1.0f, .Amplitude_RPM = 150.0f, .Variance_RPM = 2.5f, .Vibration_AxisX = 0.1f, .Vibration_AxisY = 0.15f, .Vibration_AxisZ = 0.2f, .Variance_Vibration = 0.05f }; //将接收到的数据赋值给运算参数 for(i = 0;i < DATALENG;i++) { DataValeNear.DataValue[i] = MeasurementData_Nearbit.DataValue[i]; } unsigned char con_index = Get_MeasureData(DataValeNear); // 打印结果 // printf("The integer is: %d\n", con_index); UART_SendByte(con_index); } void Get_Data_Process(void) { if(g_Data.Tim1Count1sFlag)//定时标志 { //接收完成标志为1,或者等待超时,发送第二组数据,两个串口分别判断 if(g_Data.GetUart1OverFlag) //串口1空闲 { switch(g_Data.Uart1SendCommendFlag) { case 0: Send_Slave(1); //读取近端工参数据 g_Data.Uart1SendCommendFlag = 1; g_Data.Uart1OverCount = 0; //超时计时标志 g_Data.GetUart1OverFlag = 0; //等待接收完成 break; case 1: Send_Slave(2); //读取近端工参数据 g_Data.Uart1SendCommendFlag = 2; g_Data.Uart1OverCount = 0; //超时计时标志 g_Data.GetUart1OverFlag = 0; //等待接收完成 break; default: break; } } if(g_Data.GetUart3OverFlag) //串口2空闲 { switch(g_Data.Uart3SendCommendFlag) { case 0: Send_Slave(3); //读取近端工参数据 g_Data.Uart3SendCommendFlag = 1; g_Data.Uart3OverCount = 0; //超时计时标志 g_Data.GetUart3OverFlag = 0; //等待接收完成 break; case 1: Send_Slave(4); //读取近端工参数据 g_Data.Uart3SendCommendFlag = 2; g_Data.Uart3OverCount = 0; //超时计时标志 g_Data.GetUart3OverFlag = 0; //等待接收完成 break; default: break; } } //1s内读取完成后清空1s标志 if((g_Data.Uart1SendCommendFlag==2)&&(g_Data.Uart3SendCommendFlag==2))//接收完成 { g_Data.Tim1Count1sFlag = _FALSE; g_Data.Uart1SendCommendFlag = 0; g_Data.Uart3SendCommendFlag = 0; //获取数据完成,用于数据计算 g_Data.GetComplate_Flag = 1; } } else { if(g_Data.GetComplate_Flag) { if((g_Data.GetUart1OverFlag)&&(g_Data.GetUart3OverFlag)) { DataCompute(); g_Data.GetComplate_Flag = 0; } } } }