|
|
@@ -128,15 +128,15 @@ def data_analyse(path: List[str]):
|
|
|
|
|
|
# 读取数据,并检查是否有时间序列异常,分离2通道数据
|
|
|
data_nan, data_cen = process_data(locate_file)
|
|
|
- data_cen.iloc[:, 1] = data_cen.iloc[:, 1] * np.cos(np.deg2rad(angle_cen))
|
|
|
data_tip, data_root = process_data(measure_file)
|
|
|
|
|
|
# 全部数据进行降噪、去除异常点处理,叶根叶尖数据计算叶片扫掠起始、结束点,轮毂中心数据计算距离均值
|
|
|
start_tip, end_tip, filtered_data_tip = cycle_calculate(data_tip, noise_reduction, min_difference)
|
|
|
start_root, end_root, filtered_data_root = cycle_calculate(data_root, noise_reduction, min_difference)
|
|
|
- # start_nan, end_nan, filtered_data_nan = cycle_calculate(data_nan, noise_reduction, min_difference)
|
|
|
+ start_nan, end_nan, filtered_data_nan = cycle_calculate(data_nan, noise_reduction, min_difference)
|
|
|
filtered_data_cen = tower_filter(data_cen, noise_reduction)
|
|
|
dist_cen = np.mean(filtered_data_cen.iloc[:, 1].tolist())
|
|
|
+ filtered_data_cen.iloc[:, 1] = filtered_data_cen.iloc[:, 1] * np.cos(np.deg2rad(angle_cen))
|
|
|
|
|
|
# 检查起始结束点顺序,确保叶根叶尖测点同步开始、结束
|
|
|
if end_tip.iloc[0, 0] < start_root.iloc[0, 0]:
|
|
|
@@ -150,6 +150,7 @@ def data_analyse(path: List[str]):
|
|
|
# 计算叶根、叶尖处的塔筒距离,对轮毂中心做FFT分析
|
|
|
tower_dist_tip = ff.tower_cal(filtered_data_tip, start_tip, end_tip, sampling_fq_1)
|
|
|
tower_dist_root = ff.tower_cal(filtered_data_root, start_root, end_root, sampling_fq_1)
|
|
|
+ tower_dist_nan = ff.tower_cal(filtered_data_nan, start_nan, end_nan, sampling_fq)
|
|
|
lowpass_data, fft_x, fft_y, tower_freq, tower_max= ff.process_fft(filtered_data_cen, sampling_fq)
|
|
|
|
|
|
# 根据起始结束点,对叶根、对叶片数据进行归一化处理,计算每个叶片的散点表、线表、边界点表、标准循环周期长度、每个叶片平均最小值
|
|
|
@@ -157,6 +158,8 @@ def data_analyse(path: List[str]):
|
|
|
= data_normalize(filtered_data_tip, start_tip, end_tip)
|
|
|
result_line_root, result_scatter_root, border_rows_root, cycle_len_root, min_root \
|
|
|
= data_normalize(filtered_data_root, start_root, end_root)
|
|
|
+ result_line_nan, result_scatter_nan, border_rows_nan, cycle_len_nan, min_nan \
|
|
|
+ = data_normalize(filtered_data_nan, start_nan, end_nan)
|
|
|
|
|
|
# 计算3个叶片的平均轮廓,3个叶片的形状差
|
|
|
result_avg_tip, result_diff_tip = blade_shape(result_line_tip)
|
|
|
@@ -164,28 +167,40 @@ def data_analyse(path: List[str]):
|
|
|
|
|
|
# 对叶尖的边界点表和俯仰角做坐标归一化处理
|
|
|
border_rows_tip_new, angle_tip_new = coordinate_normalize(border_rows_tip, angle_tip)
|
|
|
+ border_rows_nan_new, angle_nan_new = coordinate_normalize(border_rows_nan, angle_nan)
|
|
|
|
|
|
# 对叶片的边界点表做半径计算
|
|
|
tip_r = radius_cal(border_rows_tip_new, angle_tip_new, dist_cen, angle_cen, axial_inclination, angle_cone)
|
|
|
root_r = radius_cal(border_rows_root, angle_root, dist_cen, angle_cen, axial_inclination, angle_cone)
|
|
|
+ nan_r = radius_cal(border_rows_nan_new, angle_nan_new, dist_cen, angle_cen, axial_inclination, angle_cone)
|
|
|
|
|
|
# 计算叶片测量位置处的绝对桨距角、相对桨距角、线速度、叶片内部中心点距离
|
|
|
pitch_angle_tip, aero_dist_tip, v_speed_tip, cen_blade_tip = (
|
|
|
blade_angle_aero_dist(border_rows_tip, tip_r, cycle_len_tip, tower_dist_tip, angle_tip_new))
|
|
|
pitch_angle_root, aero_dist_root, v_speed_root, cen_blade_root = (
|
|
|
blade_angle_aero_dist(border_rows_root, root_r, cycle_len_root, tower_dist_root, angle_root))
|
|
|
+ pitch_angle_nan, aero_dist_nan, v_speed_nan, cen_blade_nan = (
|
|
|
+ blade_angle_aero_dist(border_rows_nan_new, nan_r, cycle_len_nan, tower_dist_nan, angle_nan_new))
|
|
|
|
|
|
# 将列表转换为 numpy 数组
|
|
|
cen_blade_tip_array = np.array(cen_blade_tip)
|
|
|
+ cen_blade_nan_array = np.array(cen_blade_nan)
|
|
|
min_tip_array = np.array(min_tip)
|
|
|
+ min_nan_array = np.array(min_nan)
|
|
|
abs_diff = np.abs(cen_blade_tip_array - min_tip_array) # 计算差值的绝对值
|
|
|
+ abs_diff_nan = np.abs(cen_blade_nan_array - min_nan_array) # 计算差值的绝对值
|
|
|
blade_dist_tip = abs_diff * np.cos(np.deg2rad(angle_tip_new))
|
|
|
+ blade_dist_nan = abs_diff_nan * np.cos(np.deg2rad(angle_nan_new))
|
|
|
blade_dist_tip.tolist() # 如果需要将结果转换回列表
|
|
|
+ blade_dist_nan.tolist() # 如果需要将结果转换回列表
|
|
|
|
|
|
# 计算叶片转速-净空散点表
|
|
|
dist_distribute = blade_dist_distribute_cal(filtered_data_tip, start_tip, end_tip,
|
|
|
tower_dist_tip, angle_tip_new, blade_dist_tip)
|
|
|
- dist_distribute = [df.round(5) for df in dist_distribute]
|
|
|
+ dist_distribute_nan = blade_dist_distribute_cal(filtered_data_nan, start_nan, end_nan,
|
|
|
+ tower_dist_nan, angle_nan_new, blade_dist_nan)
|
|
|
+ # dist_distribute = [df.round(5) for df in dist_distribute]
|
|
|
+ dist_distribute = [df.round(5) for df in dist_distribute_nan]
|
|
|
|
|
|
# 获取净空距离的最小值和最大值,以及它们对应的转速值,并分别保存在列表中
|
|
|
min_values = []
|
|
|
@@ -219,6 +234,18 @@ def data_analyse(path: List[str]):
|
|
|
df.iloc[:, 0] = first_column * v_speed_root
|
|
|
df.iloc[:, 1] = sec_column * np.cos(np.deg2rad(angle_root))
|
|
|
|
|
|
+ for df in result_scatter_tip:
|
|
|
+ first_column = df.iloc[:, 0]
|
|
|
+ sec_column = df.iloc[:, 1]
|
|
|
+ df.iloc[:, 0] = first_column * v_speed_tip
|
|
|
+ df.iloc[:, 1] = sec_column * np.cos(np.deg2rad(angle_tip_new))
|
|
|
+
|
|
|
+ for df in result_scatter_root:
|
|
|
+ first_column = df.iloc[:, 0]
|
|
|
+ sec_column = df.iloc[:, 1]
|
|
|
+ df.iloc[:, 0] = first_column * v_speed_root
|
|
|
+ df.iloc[:, 1] = sec_column * np.cos(np.deg2rad(angle_root))
|
|
|
+
|
|
|
# 将叶片平均轮廓数据乘以线速度,得到实际叶片长度
|
|
|
avg_tip = result_avg_tip.iloc[:, 0]
|
|
|
result_avg_tip.iloc[:, 0] = avg_tip * v_speed_tip
|
|
|
@@ -418,7 +445,7 @@ def data_analyse(path: List[str]):
|
|
|
with open(json_file_path, 'w') as json_file:
|
|
|
json.dump(json_output, json_file, indent=4)
|
|
|
|
|
|
- print(csv_file_path)
|
|
|
+ print('csv文件路径' + str(csv_file_path))
|
|
|
print(result_line_tip[0].iloc[:, 0])
|
|
|
print(result_line_root[0].iloc[:, 0])
|
|
|
print('振动主频' + str(tower_freq))
|
|
|
@@ -427,17 +454,17 @@ def data_analyse(path: List[str]):
|
|
|
print('最小值对应的键', min_keys)
|
|
|
print('最大值', max_values)
|
|
|
print('最大值对应的键', max_keys)
|
|
|
- print(v_speed_tip, v_speed_root)
|
|
|
+ print('叶尖速度' + str(v_speed_tip), '叶根速度' + str(v_speed_root))
|
|
|
print('新俯仰角' + str(angle_tip_new))
|
|
|
print('轮毂中心距离' + str(dist_cen))
|
|
|
- print('time_length:' + str(data_root.iloc[-1, 0]))
|
|
|
+ print('叶根原始数据采样时间长度' + str(data_root.iloc[-1, 0]))
|
|
|
|
|
|
# plot_data(result_line_tip, 'line', 'data1')
|
|
|
# plot_data(result_diff_tip, 'line', 'data_diff_1')
|
|
|
# plot_data(result_scatter_tip, 'scatter', 'data1')
|
|
|
plot_data(result_line_root, 'line', 'data2')
|
|
|
# plot_data(result_diff_root, 'line', 'data_diff_2')
|
|
|
- # plot_data(result_scatter_root, 'scatter', 'data2')
|
|
|
+ plot_data(result_scatter_root, 'scatter', 'data2')
|
|
|
# plot_data(dist_distribute, 'scatter', 'dist_distribute')
|
|
|
|
|
|
return json_output
|
|
|
@@ -452,7 +479,7 @@ def process_data(file_path):
|
|
|
# 读取第2、4、9列的数据
|
|
|
data = pd.read_csv(file_path, usecols=[1, 3, 8], header=None, engine='c')
|
|
|
data = data.head(int(len(data) * 0.95))
|
|
|
- print(len(data))
|
|
|
+ print('原始数据长度' + str(len(data)))
|
|
|
|
|
|
'''
|
|
|
# 绘制原始数据图
|
|
|
@@ -534,7 +561,7 @@ def tower_filter(data_group: pd.DataFrame, noise_threshold: float):
|
|
|
|
|
|
nan_count = data_group['distance'].isna().sum()
|
|
|
all_count = data_group.shape[0]
|
|
|
- print(f"中值是:{mean_values},替换为NaN的distance值的数量是: {nan_count}, 总数量是: {all_count},"
|
|
|
+ print(f"中值是:{mean_values},替换为NaN的异常distance值的数量是: {nan_count}, 总数量是: {all_count},"
|
|
|
f"占比: {nan_count / all_count * 100:.2f}%")
|
|
|
|
|
|
# 前向填充
|
|
|
@@ -567,12 +594,12 @@ def cycle_calculate(data_group: pd.DataFrame, noise_threshold: float, min_distan
|
|
|
# 选择频率最大的5个值
|
|
|
top_5_distances = distance_counts.head(5).index
|
|
|
mean_values = data_group[data_group['distance'].isin(top_5_distances)]['distance'].mean()
|
|
|
- data_group.loc[(data_group['distance'] < mean_values-20) | (
|
|
|
+ data_group.loc[(data_group['distance'] < mean_values-30) | (
|
|
|
data_group['distance'] > mean_values*1.1), 'distance'] = np.nan
|
|
|
|
|
|
nan_count = data_group['distance'].isna().sum()
|
|
|
all_count = data_group.shape[0]
|
|
|
- print(f"中值是:{mean_values},替换为NaN的distance值的数量是: {nan_count}, 总数量是: {all_count},"
|
|
|
+ print(f"中值是:{mean_values},替换为NaN的distance异常值的数量是: {nan_count}, 总数量是: {all_count},"
|
|
|
f"占比: {nan_count / all_count * 100:.2f}%")
|
|
|
|
|
|
# 前向填充
|
|
|
@@ -593,7 +620,7 @@ def cycle_calculate(data_group: pd.DataFrame, noise_threshold: float, min_distan
|
|
|
# 获取当前行的 distance 值
|
|
|
current_distance = filtered_data.loc[idx, 'distance']
|
|
|
|
|
|
- next_rows_large = filtered_data.loc[idx - 300: idx - 1]
|
|
|
+ next_rows_large = filtered_data.loc[idx - 200: idx - 1]
|
|
|
|
|
|
# 检查是否任意 distance 的值小于 current_distance - 2
|
|
|
if next_rows_large['distance'].le(current_distance - min_distance).all():
|
|
|
@@ -604,7 +631,7 @@ def cycle_calculate(data_group: pd.DataFrame, noise_threshold: float, min_distan
|
|
|
# 获取当前行的 distance 值
|
|
|
current_distance = filtered_data.loc[idx - 1, 'distance']
|
|
|
|
|
|
- next_rows_small = filtered_data.iloc[idx: idx + 300]
|
|
|
+ next_rows_small = filtered_data.iloc[idx: idx + 200]
|
|
|
|
|
|
# 检查是否任意 distance 的值小于 current_distance - 2
|
|
|
if next_rows_small['distance'].le(current_distance - min_distance).all():
|
|
|
@@ -684,7 +711,7 @@ def data_normalize(data_group: pd.DataFrame, start_points: pd.DataFrame, end_poi
|
|
|
turbines_scattered = []
|
|
|
min_list = []
|
|
|
sd_time = [-1, -1]
|
|
|
- time_list = list(range(0, normalize_cycle, 10000))
|
|
|
+ time_list = list(range(0, normalize_cycle, 9000))
|
|
|
# time_list = [(i + 1) * normalize_cycle / fs * 100 for i in range(fs * 100)] # 生成时间序列
|
|
|
|
|
|
for turbine in turbines:
|
|
|
@@ -695,7 +722,7 @@ def data_normalize(data_group: pd.DataFrame, start_points: pd.DataFrame, end_poi
|
|
|
first_time = turbine_sorted['time'].iloc[0]
|
|
|
|
|
|
# 分组,时间列每1000为一组(每40个时间点一组)
|
|
|
- bins = list(range(int(first_time), int(turbine_sorted['time'].max()), 10000))
|
|
|
+ bins = list(range(int(first_time), int(turbine_sorted['time'].max()), 9000))
|
|
|
# 原始代码
|
|
|
# bins = list(range(int(first_time), int(turbine_sorted['time'].max()) + len(start_times), int(fs / 50)))
|
|
|
grouped = turbine_sorted.groupby(pd.cut(turbine_sorted['time'], bins=bins, right=False))
|
|
|
@@ -738,7 +765,7 @@ def data_normalize(data_group: pd.DataFrame, start_points: pd.DataFrame, end_poi
|
|
|
plt.subplots_adjust(hspace=2)
|
|
|
|
|
|
# 绘制 diff_points 的折线图
|
|
|
- axs.plot(diff_points, label='Diff Points', color='red', marker='x', markersize=2)
|
|
|
+ axs.plot(diff_points, label='Diff Points', color='red', marker='x', markersize=5)
|
|
|
axs.axhline(y=sdr_diff, color='red', linestyle='--')
|
|
|
axs.legend()
|
|
|
axs.set_title('Diff Points')
|
|
|
@@ -784,7 +811,7 @@ def data_normalize(data_group: pd.DataFrame, start_points: pd.DataFrame, end_poi
|
|
|
turbines_processed.append(processed_df)
|
|
|
turbines_scattered.append(scattered_df)
|
|
|
|
|
|
-
|
|
|
+ # 把三组叶片数据按sd_time进行筛选,并把每个的边界数据保存
|
|
|
border_rows = []
|
|
|
for i, turbine in enumerate(turbines_processed):
|
|
|
# 找到离 sd_time[0] 最近的行的索引
|
|
|
@@ -804,7 +831,6 @@ def data_normalize(data_group: pd.DataFrame, start_points: pd.DataFrame, end_poi
|
|
|
, ignore_index=True)
|
|
|
border_rows.append(sd_time_rows_turbine)
|
|
|
|
|
|
- time.sleep(1)
|
|
|
|
|
|
return turbines_processed, turbines_scattered, border_rows, full_cycle, min_list
|
|
|
|
|
|
@@ -840,7 +866,6 @@ def blade_shape(turbines_processed: List[pd.DataFrame]):
|
|
|
turbine_diff[j].loc[i, 'time'] = time_value
|
|
|
turbine_diff[j].loc[i, 'distance'] = distances[j]
|
|
|
|
|
|
- time.sleep(10)
|
|
|
|
|
|
return turbine_avg, turbine_diff
|
|
|
|
|
|
@@ -868,7 +893,7 @@ def coordinate_normalize(tip_border_rows: List[pd.DataFrame], tip_angle):
|
|
|
|
|
|
tip_angle_new = float(np.mean(tip_angle_list))
|
|
|
tip_angle_new1 = np.rad2deg(tip_angle_new)
|
|
|
- print('叶尖俯仰角: ' + str(tip_angle_new1))
|
|
|
+ print('坐标转换后的新叶尖俯仰角: ' + str(tip_angle_new1))
|
|
|
|
|
|
return tip_border_rows, tip_angle_new1
|
|
|
|
|
|
@@ -893,15 +918,16 @@ def radius_cal(border_rows, meas_angle, cen_dist, cen_angle, angle_main, angle_r
|
|
|
aero_x = np.cos(np.deg2rad(meas_angle)) * aero_dist
|
|
|
aero_y = np.sin(np.deg2rad(meas_angle)) * aero_dist
|
|
|
theta_4 = np.tan(np.pi - np.deg2rad(angle_main))
|
|
|
- theta_5 = np.tan(np.pi/2 - np.deg2rad(angle_main) + np.deg2rad(angle_rotate))
|
|
|
+ theta_5 = np.tan(np.pi/2 - np.deg2rad(angle_main) - np.deg2rad(angle_rotate))
|
|
|
|
|
|
- if np.abs(np.deg2rad(angle_main) - np.deg2rad(angle_rotate)) < 0.0001:
|
|
|
+ if theta_5 > 1000:
|
|
|
radius = np.abs((cen_y - aero_y) - theta_4 * (cen_x - aero_x))
|
|
|
+ print("轴向倾角与锥角相近,叶片垂直于地面")
|
|
|
|
|
|
else:
|
|
|
radius = (np.abs((theta_4 * (cen_x - aero_x) - (cen_y - aero_y))/(theta_4 - theta_5))
|
|
|
- * (1 + theta_5 ** 2) ** 0.5)
|
|
|
- print('半径:' + str(radius))
|
|
|
+ * ((1 + theta_5 ** 2) ** 0.5))
|
|
|
+ print('测量点旋转半径:' + str(radius))
|
|
|
|
|
|
return radius
|
|
|
|
|
|
@@ -1087,30 +1113,26 @@ def blade_dist_distribute_cal(data_group: pd.DataFrame, start_points: pd.DataFra
|
|
|
return tower_clearance
|
|
|
|
|
|
|
|
|
-# measure_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250513/pl_9_20250514083317_100_24.8_30.06.csv"
|
|
|
-# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250513/pl_9_20250514083134_100_33.53_33.53.csv"
|
|
|
-
|
|
|
-# measure_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250513/p'l_9p_20250514084957_100_27.48_29.47.csv"
|
|
|
-# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250513/p'l_9p_20250514084814_100_27.75_32.93.csv"
|
|
|
-
|
|
|
-# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250513/pl_63_20250513160502_100_41.38_41.38.csv"
|
|
|
-# measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250513/pl_63_20250513160655_100_28.10_35.43.csv"
|
|
|
+# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tf-20_20250630223600_20_13.03_23.32.csv"
|
|
|
+# measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tf-20_20250630223849_20_17.89_21.07.csv"
|
|
|
|
|
|
-# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250513/平陆_4_20250514073658_100_16.00_20.56.csv"
|
|
|
-# measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250513/平陆_4_20250514073248_100_12.72_17.3.csv"
|
|
|
+locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tf-50_20250630223358_50_13.03_23.32.csv"
|
|
|
+measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tf-50_20250630224408_50_17.89_21.07.csv"
|
|
|
|
|
|
-# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250416/__20250416134815_50_14.55_17.00.csv"
|
|
|
-# measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250416/__20250416135017_50_11.85_14.31.csv"
|
|
|
+# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tf-100_20250630222752_100_13.03_23.32.csv"
|
|
|
+# measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tf-100_20250630225119_100_17.89_21.07.csv"
|
|
|
|
|
|
-# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250616/qx_b14-1_20250616161311_50_38.06_37.81.csv"
|
|
|
-# measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250616/qx_b14-1_20250616160625_50_23.38_35.13.csv"
|
|
|
+# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tff-20_20250630231223_20_12.51_20.06.csv"
|
|
|
+# measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tff-20_20250630232052_20_15.36_18.17.csv"
|
|
|
|
|
|
-locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250616/qx_17_20250616140305_50_28.12_28.12.csv"
|
|
|
-measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250616/qx_17_20250616140452_50_21.09_26.22.csv"
|
|
|
+# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tff-50_20250630231417_50_12.51_20.06.csv"
|
|
|
+# measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tff-50_20250630233420_50_15.35_18.16.csv"
|
|
|
|
|
|
+# locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tff-100_20250630231610_100_12.51_20.06.csv"
|
|
|
+# measure_path= "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/gy_10-tff-100_20250630234012_100_15.35_18.16.csv"
|
|
|
|
|
|
start_t = time.time() # 记录开始时间
|
|
|
-data_path = [locate_path, measure_path, 5, 3.5]
|
|
|
+data_path = [locate_path, measure_path, 5, 6]
|
|
|
list_1 = data_analyse(data_path)
|
|
|
# print(list_1)
|
|
|
print(f"耗时: {time.time() - start_t:.2f} 秒")
|