Procházet zdrojové kódy

激光测量v3.2,使用固定速度拟合圆,每个叶片与对应的圆心分别求桨距角,显示旋转修正后叶片轮廓,排查若干BUG

wei_lai před 1 měsícem
rodič
revize
6c0aebf932
3 změnil soubory, kde provedl 97 přidání a 44 odebrání
  1. 60 28
      data_analyse_origin.py
  2. 34 13
      data_clean.py
  3. 3 3
      orginal_plot.py

+ 60 - 28
data_analyse_origin.py

@@ -20,7 +20,6 @@ warnings.filterwarnings("ignore", category=FutureWarning) # 忽略特定警告
 plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
 plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
 
-# TODO: 将偏斜角度还原叶片数据的代码转移到最后的步骤
 
 def result_main():
 
@@ -109,6 +108,8 @@ def history_data(name):
 def data_analyse(path: List[str]):
 
     """
+    附带偏斜测量和抬升阈值的主进程,按顺序收到6个参数:偏斜定位测量数据路径,定位测量数据路径,测量数据路径,锥角,轴向倾角,偏斜角度
+    在正式版中去掉了偏斜测量功能,将按顺序收到5个数:定位测量数据路径,测量数据路径,锥角,轴向倾角,抬升阈值
     创建data目录,把分析数据保存到历史记录中,同时返回全量分析数据
     locate_file_0:非中心线数据,1通道下方,2通道上方
     locate_file:轮毂中心数据,1通道叶尖,2通道轮毂中心
@@ -116,9 +117,9 @@ def data_analyse(path: List[str]):
     """
 
     # 基础配置参数
-    locate_file_0 = path[0]
-    locate_file = path[1]
-    measure_file = path[2]
+    locate_file_0 = path[0]  # 偏斜定位数据
+    locate_file = path[1]  # 定位数据
+    measure_file = path[2]  # 测量数据
     angle_cone = float(path[3])  # 锥角
     axial_inclination = float(path[4])  # 轴向倾角
     rotate_angle = float(path[5])  # 偏航角
@@ -126,7 +127,7 @@ def data_analyse(path: List[str]):
     noise_reduction = 0.000001  # 如果一个距离值的所有样本量小于总样本量的noise_reduction,则被去掉
     min_difference = 1.5  # 如果相邻2个点的距离差大于min_difference,则被注意是否是周期节点
     group_length = [10000, 10000, 5000, 10000]  # 计算叶片轮廓时每个小切片的长度,4个数分别为叶中、叶根、叶尖、轴线计算切片长度
-    lift_up_limit = 0  #  如果法兰中的数据大于这个值,则提升5m
+    lift_up_limit = 0  #  抬升阈值,用于修复叶根瞄准位置得到的塔筒和叶片数据距离差过近的情况
     return_list = []
 
     # 读取文件信息,包括风场名、风机编号、时间、采样频率、2个通道俯仰角
@@ -180,7 +181,9 @@ def data_analyse(path: List[str]):
 
     print("\033[34m偏斜方程计算输入:\033[0m", equation_list)
     # skew_angle = ff.process_equations(equation_list)
+    # 至此偏斜计算部分结束
 
+    # 抬升阈值部分,将抬升阈值以上的数据
     if lift_up_limit >= 0.1:
         discrete_values = np.arange(0, 0.101, 0.001)
         condition = data_flange['distance'] > lift_up_limit
@@ -244,7 +247,9 @@ def data_analyse(path: List[str]):
                                    angle_flange + angle_cone + axial_inclination, group_length[3], flange_r)
 
     blade_axis_new, angle_flange_new = flange_coordinate_normalize(blade_axis, angle_flange)
-    blade_axis_tuple_new, angle_flange_new = flange_coordinate_normalize(blade_axis_tuple, angle_flange)
+    blade_axis_tuple_new0, angle_flange_new = flange_coordinate_normalize(blade_axis_tuple, angle_flange)
+    # 将纵坐标还原方便画图
+    blade_axis_tuple["中心y"] = blade_axis_tuple["中心y"] * np.cos(np.deg2rad(angle_flange + angle_cone + axial_inclination))
 
     if np.abs((root_r - flange_r) - d_radius) > 0.5:
         print(str(root_r - flange_r) + "对比" + str(d_radius))
@@ -261,7 +266,7 @@ def data_analyse(path: List[str]):
     #     * np.cos(np.deg2rad(90 - angle_cone - axial_inclination - angle_flange_new)))
 
     blade_axis_new["中心y"] = blade_axis_new["中心y"] - (flange_ava - root_ava)
-    blade_axis_tuple_new["中心y"] = blade_axis_tuple_new["中心y"] - (flange_ava - root_ava)
+    blade_axis_tuple_new0["中心y"] = blade_axis_tuple_new0["中心y"] - (flange_ava - root_ava)
 
     # 计算叶片测量位置处的绝对桨距角、相对桨距角、线速度、叶片内部中心点距离
     aero_dist_flange, v_speed_flange, cen_blade_flange = (
@@ -269,7 +274,7 @@ def data_analyse(path: List[str]):
     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))
     pitch_angle_root, v_speed_root, blade_axis_tuple_new = (
-        blade_angle(border_rows_root, blade_axis_tuple_new, root_r, cycle_len_root, angle_root + angle_cone + axial_inclination))
+        blade_angle(border_rows_root, blade_axis_tuple_new0, root_r, cycle_len_root, angle_root + angle_cone + axial_inclination))
 
     blade_axis_tuple_new["中心y"] = blade_axis_tuple_new["中心y"]*np.cos(np.deg2rad(angle_root + angle_cone + axial_inclination))
 
@@ -401,6 +406,20 @@ def data_analyse(path: List[str]):
 
         rotated_root[i % 3] = pd.concat([rotated_root[i % 3], rotated_points])
 
+    circle_fit = [pd.DataFrame() for _ in range(3)]
+    for i in range(3):
+        # 最优参数
+        v, xc, yc, circle_r = blade_axis_tuple[['旋转半径', '中心x', '中心y', '圆半径']].values[i]
+
+        # 拟合圆
+        theta = np.linspace(0, 2 * np.pi, 500)
+        x_circle = xc + circle_r * np.cos(theta)
+        y_circle = yc + circle_r * np.sin(theta)
+        circle_fit[i] = pd.DataFrame({
+            'x_circle': x_circle,
+            'y_circle': y_circle
+        })
+
     # 将需要保存到CSV的数据添加到return_list中
     return_list.append(str(time_code))
     return_list.append(str(wind_name))
@@ -478,6 +497,18 @@ def data_analyse(path: List[str]):
             'blade_center': {
                 'xdata': blade_axis_tuple.iloc[:, 1].tolist(),
                 'ydata': blade_axis_tuple.iloc[:, 2].tolist()
+            },
+            'first_circle': {
+                'xdata': circle_fit[0].iloc[:, 0].tolist(),
+                'ydata': circle_fit[0].iloc[:, 1].tolist()
+            },
+            'second_circle': {
+                'xdata': circle_fit[1].iloc[:, 0].tolist(),
+                'ydata': circle_fit[1].iloc[:, 1].tolist()
+            },
+            'third_circle': {
+                'xdata': circle_fit[2].iloc[:, 0].tolist(),
+                'ydata': circle_fit[2].iloc[:, 1].tolist()
             }
         },
         'blade_root': {
@@ -616,13 +647,13 @@ def data_analyse(path: List[str]):
     print('叶根原始数据采样时间长度' + str(data_root.iloc[-1, 0]))
     print('-' * 50)
 
-    plot_data(result_line_flange, blade_axis_tuple, 'line', 'data1')
+    plot_data(result_line_flange, blade_axis_tuple, 'line', '叶根')
     # plot_data(result_diff_flange, 'line', 'data_diff_1')
-    # plot_data(result_scatter_flange, 'scatter', 'data1')
-    plot_data(result_line_root, blade_axis_tuple_new, 'line', 'data2')
-    plot_data(rotated_root, blade_axis_tuple_new, 'line', 'data3')
+    plot_data(result_scatter_flange, blade_axis_tuple, 'scatter', '叶根')
+    plot_data(result_line_root, blade_axis_tuple_new, 'line', '叶片最宽')
+    plot_data(rotated_root, blade_axis_tuple_new, 'line', '模拟还原')
     # plot_data(result_diff_root, 'line', 'data_diff_2')
-    # plot_data(result_scatter_root, blade_axis_tuple_new,  'scatter', 'data2')
+    plot_data(result_scatter_root, blade_axis_tuple_new,  'scatter', '叶片最宽')
     # plot_data(dist_distribute, 'scatter', 'dist_distribute')
 
     return json_output
@@ -830,7 +861,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 - 500: idx - 1]
+        next_rows_large = filtered_data.loc[idx - 100: idx - 1]
 
         # 检查是否任意 distance 的值小于 current_distance - 2
         if next_rows_large['distance'].le(current_distance - min_distance).all():
@@ -841,7 +872,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 + 500]
+        next_rows_small = filtered_data.iloc[idx: idx + 100]
 
         # 检查是否任意 distance 的值小于 current_distance - 2
         if next_rows_small['distance'].le(current_distance - min_distance).all():
@@ -1152,22 +1183,22 @@ def flange_coordinate_normalize(flange_cen_row: pd.DataFrame, flange_angle):
     """
     flange_angle1 = np.deg2rad(flange_angle)
     center_y_mean = flange_cen_row['中心y'].mean()
-
+    flange_cen_row_new = flange_cen_row.copy()
     # 计算新的俯仰角
     flange_angle_cal0 = ((np.sin(flange_angle1) * center_y_mean - 0.07608) /
                          (np.cos(flange_angle1) * center_y_mean))
     flange_angle_cal = np.arctan(flange_angle_cal0)
 
     # 更新中心y列
-    flange_cen_row['中心y'] = (flange_cen_row['中心y'] ** 2 + 0.0057881664 -
-                                     0.15216 * flange_cen_row['中心y'] * np.sin(flange_angle1)) ** 0.5
+    flange_cen_row_new['中心y'] = (flange_cen_row_new['中心y'] ** 2 + 0.0057881664 -
+                                     0.15216 * flange_cen_row_new['中心y'] * np.sin(flange_angle1)) ** 0.5
 
     # 计算新的俯仰角(由于现在只有一个值,直接使用计算出的值)
     flange_angle_new = float(flange_angle_cal)
     flange_angle_new1 = np.rad2deg(flange_angle_new)
     print('坐标转换后的新法兰俯仰角: ' + str(flange_angle_new1))
 
-    return flange_cen_row, flange_angle_new1
+    return flange_cen_row_new, flange_angle_new1
 
 
 def blade_axis_cal(data_group: pd.DataFrame, start_points: pd.DataFrame, end_points: pd.DataFrame, horizon_angle: float,
@@ -1367,7 +1398,7 @@ def blade_axis_cal(data_group: pd.DataFrame, start_points: pd.DataFrame, end_poi
 
         process_df['time'] = process_df['time'] / 5000000
         lower_bound = process_df['time'].quantile(0.2)
-        upper_bound = process_df['time'].quantile(0.8)
+        upper_bound = process_df['time'].quantile(0.6)
         processed_df = process_df[(process_df['time'] >= lower_bound) & (process_df['time'] <= upper_bound)]
         blade_cen_est = fit_circle(processed_df, v_blade)
 
@@ -1673,20 +1704,21 @@ if __name__ == "__main__":
     # locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-zz_20251011123102_50_25.23_32.98.csv"
     # measure_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-zz_20251011122457_50_32.24_31.02.csv"
     # 第七组右侧
-    locate_path0 = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-r-z_20251011124902_50_31.19_34.81.csv"
-    locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-r-z_20251011124620_50_24.85_32.90.csv"
-    measure_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-r-z_20251011124036_50_32.24_31.14.csv"
+    # locate_path0 = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-r-z_20251011124902_50_31.19_34.81.csv"
+    # locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-r-z_20251011124620_50_24.85_32.90.csv"
+    # measure_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-r-z_20251011124036_50_32.24_31.14.csv"
     # dq-8
     # locate_path0 = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-r-z_20251011124902_50_31.19_34.81.csv"
     # locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251023大庆/第三天/dh_8_20251109102949_50_17.22_27.45.csv"
     # measure_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251023大庆/第三天/dh_8_20251109102255_50_26.18_24.06.csv"
-    # zb-9
-    # locate_path0 = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-r-z_20251011124902_50_31.19_34.81.csv"
-    # locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251121淄博/数据/zb_9_20251122110132_50_14.19_19.83.csv"
-    # measure_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251121淄博/数据/zb_9_20251122105534_50_19.37_17.73.csv"
+    # fk-20
+    locate_path0 = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20251011沽源/验证/gy_20-r-z_20251011124902_50_31.19_34.81.csv"
+    locate_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20260603张北/zbbw_49-01_20260607104842_50_6.12_33.22.csv"
+    measure_path = "C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20260603张北/zbbw_49-01_20260607104157_50_32.49_29.10.csv"
 
+    # 调用data_analyse主进程开始分析,在正式版中使用接口调用。此处只测试主进程,如history_data/delete_data/result_main等附加进程未纳入测试。
     start_t = time.time()  # 记录开始时间
-    data_path = [locate_path0, locate_path, measure_path, 3.5, 5, 1.54]  # 偏斜测量数据、轮毂数据、叶根数据、锥角、轴向倾角、偏航角
+    data_path = [locate_path0, locate_path, measure_path, 3, 8.5, 1.54]  # 偏斜测量数据、轮毂数据、叶根数据、锥角、轴向倾角、偏航角
     list_1 = data_analyse(data_path)
     print(f"耗时: {time.time() - start_t:.2f} 秒")
 

+ 34 - 13
data_clean.py

@@ -159,7 +159,8 @@ def data_analyse(path: List[str]):
                                    angle_flange + angle_cone + axial_inclination, group_length[3], flange_r)
 
     blade_axis_new, angle_flange_new = flange_coordinate_normalize(blade_axis, angle_flange)
-    blade_axis_tuple_new, angle_flange_new = flange_coordinate_normalize(blade_axis_tuple, angle_flange)
+    blade_axis_tuple_new0, angle_flange_new = flange_coordinate_normalize(blade_axis_tuple, angle_flange)
+    blade_axis_tuple["中心y"] = blade_axis_tuple["中心y"] * np.cos(np.deg2rad(angle_flange + angle_cone + axial_inclination))
 
     if np.abs((root_r - flange_r) - d_radius) > 0.5:
         root_r = flange_r + d_radius
@@ -168,14 +169,14 @@ def data_analyse(path: List[str]):
         root_r = flange_r + flange_root_dist
 
     blade_axis_new["中心y"] = blade_axis_new["中心y"] - (flange_ava - root_ava)
-    blade_axis_tuple_new["中心y"] = blade_axis_tuple_new["中心y"] - (flange_ava - root_ava)
+    blade_axis_tuple_new0["中心y"] = blade_axis_tuple_new0["中心y"] - (flange_ava - root_ava)
 
     aero_dist_flange, v_speed_flange, cen_blade_flange = (
         blade_angle_aero_dist(border_rows_flange, flange_r, cycle_len_flange, tower_dist_flange, angle_flange_new))
     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))
     pitch_angle_root, v_speed_root, blade_axis_tuple_new = (
-        blade_angle(border_rows_root, blade_axis_tuple_new, root_r, cycle_len_root, angle_root + angle_cone + axial_inclination))
+        blade_angle(border_rows_root, blade_axis_tuple_new0, root_r, cycle_len_root, angle_root + angle_cone + axial_inclination))
 
     blade_axis_tuple_new["中心y"] = blade_axis_tuple_new["中心y"]*np.cos(np.deg2rad(angle_root + angle_cone + axial_inclination))
 
@@ -266,6 +267,19 @@ def data_analyse(path: List[str]):
 
         rotated_root[i % 3] = pd.concat([rotated_root[i % 3], rotated_points])
 
+    circle_fit = [pd.DataFrame() for _ in range(3)]
+    for i in range(3):
+
+        v, xc, yc, circle_r = blade_axis_tuple[['旋转半径', '中心x', '中心y', '圆半径']].values[i]
+
+        theta = np.linspace(0, 2 * np.pi, 500)
+        x_circle = xc + circle_r * np.cos(theta)
+        y_circle = yc + circle_r * np.sin(theta)
+        circle_fit[i] = pd.DataFrame({
+            'x_circle': x_circle,
+            'y_circle': y_circle
+        })
+
 
     return_list.append(str(time_code))
     return_list.append(str(wind_name))
@@ -343,6 +357,18 @@ def data_analyse(path: List[str]):
             'blade_center': {
                 'xdata': blade_axis_tuple.iloc[:, 1].tolist(),
                 'ydata': blade_axis_tuple.iloc[:, 2].tolist()
+            },
+            'first_circle': {
+                'xdata': circle_fit[0].iloc[:, 0].tolist(),
+                'ydata': circle_fit[0].iloc[:, 1].tolist()
+            },
+            'second_circle': {
+                'xdata': circle_fit[1].iloc[:, 0].tolist(),
+                'ydata': circle_fit[1].iloc[:, 1].tolist()
+            },
+            'third_circle': {
+                'xdata': circle_fit[2].iloc[:, 0].tolist(),
+                'ydata': circle_fit[2].iloc[:, 1].tolist()
             }
         },
         'blade_root': {
@@ -798,18 +824,18 @@ def flange_coordinate_normalize(flange_cen_row: pd.DataFrame, flange_angle):
     flange_angle1 = np.deg2rad(flange_angle)
 
     center_y_mean = flange_cen_row['中心y'].mean()
-
+    flange_cen_row_new = flange_cen_row.copy()
     flange_angle_cal0 = ((np.sin(flange_angle1) * center_y_mean - 0.07608) /
                          (np.cos(flange_angle1) * center_y_mean))
     flange_angle_cal = np.arctan(flange_angle_cal0)
 
-    flange_cen_row['中心y'] = (flange_cen_row['中心y'] ** 2 + 0.0057881664 -
-                                     0.15216 * flange_cen_row['中心y'] * np.sin(flange_angle1)) ** 0.5
+    flange_cen_row_new['中心y'] = (flange_cen_row_new['中心y'] ** 2 + 0.0057881664 -
+                                     0.15216 * flange_cen_row_new['中心y'] * np.sin(flange_angle1)) ** 0.5
 
     flange_angle_new = float(flange_angle_cal)
     flange_angle_new1 = np.rad2deg(flange_angle_new)
 
-    return flange_cen_row, flange_angle_new1
+    return flange_cen_row_new, flange_angle_new1
 
 
 def blade_axis_cal(data_group: pd.DataFrame, start_points: pd.DataFrame, end_points: pd.DataFrame, horizon_angle: float,
@@ -945,7 +971,7 @@ def blade_axis_cal(data_group: pd.DataFrame, start_points: pd.DataFrame, end_poi
 
         process_df['time'] = process_df['time'] / 5000000
         lower_bound = process_df['time'].quantile(0.2)
-        upper_bound = process_df['time'].quantile(0.8)
+        upper_bound = process_df['time'].quantile(0.6)
         processed_df = process_df[(process_df['time'] >= lower_bound) & (process_df['time'] <= upper_bound)]
         blade_cen_est = fit_circle(processed_df, v_blade)
         processed_df['time'] = processed_df['time'] * v_blade
@@ -1005,16 +1031,11 @@ def blade_angle(border_rows: List[pd.DataFrame], cen_data: pd.DataFrame, radius:
 
     for i in [0, 1, 2]:
         if np.abs(cen_data['中心y'].iloc[i] - mean_value) > 0.5:
-            print('原本:' + str(cen_data['中心y'].iloc[i]) + '标准:' + str(mean_value))
             cen_data['中心y'].iloc[i] = mean_value
-            print('y_change')
         if cen_data['中心x'].iloc[i] > 1.5:
             cen_data['中心x'].iloc[i] = 1.5
-            print('x_change')
         if cen_data['中心x'].iloc[i] < 0.75:
             cen_data['中心x'].iloc[i] = 0.75
-            print('x_change')
-        print(cen_data['中心x'].iloc[i])
 
     pitch_angle_list = []
     for idx, turbine in enumerate(border_rows, start=1):

+ 3 - 3
orginal_plot.py

@@ -10,7 +10,7 @@ plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
 plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
 
 # 指定文件夹路径
-folder_path = r'C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250728/'
+folder_path = r'C:/Users/laiwe/Desktop/风电/激光测量/测试数据/'
 
 # 遍历文件夹中的所有CSV文件
 for filename in os.listdir(folder_path):
@@ -31,7 +31,7 @@ for filename in os.listdir(folder_path):
             # 将最小值及其之后的所有值都加上最大值
             data.iloc[min_index:, 0] += max_value
 
-        data = data.head(int(len(data) * 0.01))
+        data = data.head(int(len(data) * 1))
 
         # 绘制原始数据图
         data.columns = ['time', 'distance1', 'distance2']
@@ -47,7 +47,7 @@ for filename in os.listdir(folder_path):
         abxy.tick_params(axis='y', labelsize=14, labelcolor='black', width=2)  # 设置y轴刻度标签
 
         # 生成图像文件名
-        image_filename = os.path.splitext(filename)[0] + 'small.png'
+        image_filename = os.path.splitext(filename)[0] + '.png'
         image_path = os.path.join(folder_path, image_filename)
 
         # 保存图像