在此前基础上,优化增加俩种模式选择,分区域,队列
模式一:分区域
通过聚类算法k-means 将整个路径划分为三块,然后单独分配给无人机去搜寻,起始无人机将保持三角形阵形,开始搜索后将走向各自负责区域
聚类算法,及初始化三角形
# 使用 K-means 算法对路径进行聚类
kmeans = KMeans(n_clusters=3, n_init=10)
df['cluster'] = kmeans.fit_predict(df[['x', 'y']])
colors = ['blue', 'green', 'yellow']
cluster_data_points = [df[df['cluster'] == i] for i in range(3)]
# 初始化小红点在中心位置的三角形阵形
triangle_offsets = np.array([[0, 2], [-2, -1], [2, -1]])
dots = []
for offset in triangle_offsets:
dot, = ax.plot(center_x + offset[0], center_y + offset[1], 'ro')
dots.append(dot)
模式一 聚类算法
def animate_mode1(frame, total_frames, move_back_start):
frames_per_segment = 10 # 每个线段之间的帧数
for i, cluster_data in enumerate(cluster_data_points):
ax.plot(cluster_data['x'], cluster_data['y'], marker='o', color=colors[i])
for i, dot in enumerate(dots):
if frame < 100: # 平滑移动到起点
start_x, start_y = cluster_data_points[i].iloc[0][['x', 'y']]
dot.set_data(np.linspace(center_x, start_x, 100)[frame],
np.linspace(center_y, start_y, 100)[frame])
elif frame < move_back_start:
# 遍历路径
frame_adjusted = frame - 100
segment_index = frame_adjusted // frames_per_segment
segment_progress = frame_adjusted % frames_per_segment / frames_per_segment
if segment_index < len(cluster_data_points[i]) - 1:
start_point = cluster_data_points[i].iloc[segment_index][['x', 'y']]
end_point = cluster_data_points[i].iloc[segment_index + 1][['x', 'y']]
x, y = (1 - segment_progress) * start_point + segment_progress * end_point
dot.set_data(x, y)
elif frame < total_frames:
# 移回起始位置
start_x, start_y = cluster_data_points[i].iloc[0][['x', 'y']]
dot.set_data(np.linspace(start_x, center_x, total_frames - move_back_start)[frame - move_back_start],
np.linspace(start_y, center_y, total_frames - move_back_start)[frame - move_back_start])
else:
# 保持在中心位置
dot.set_data(center_x, center_y)
return dots
模式二 一字队列遍历所有路径
def animate_mode2(frame, total_frames, move_back_start):
frames_per_segment = 10 # 每个线段之间的帧数
ax.plot(df['x'], df['y'], marker='o')
if frame < 100: # 平滑移动到第一个点
start_x, start_y = df.iloc[0][['x', 'y']]
# 计算移动过程中的中间点
for i, dot in enumerate(dots):
# 水平一字排列的初始 x 和 y 坐标
initial_x = center_x + i * 2 # 可以调整 2 以改变小红点之间的间距
initial_y = center_y
# 计算每个小红点在移动到起始点过程中的位置
dot_x = np.linspace(initial_x, start_x, 100)[frame]
dot_y = np.linspace(initial_y, start_y, 100)[frame]
dot.set_data(dot_x, dot_y)
elif frame < move_back_start:
# 遍历路径
frame_adjusted = frame - 100
segment_index = frame_adjusted // frames_per_segment
segment_progress = frame_adjusted % frames_per_segment / frames_per_segment
# 更新每个小红点的位置
for i, dot in enumerate(dots):
dot_index = segment_index - i
if dot_index >= 0 and dot_index < len(df):
start_point = df.iloc[dot_index][['x', 'y']]
end_point = df.iloc[min(dot_index + 1, len(df) - 1)][['x', 'y']]
x, y = (1 - segment_progress) * start_point + segment_progress * end_point
dot.set_data(x, y)
elif frame < total_frames:
# 移回起始位置
start_x, start_y = df.iloc[0][['x', 'y']]
for dot in dots:
dot.set_data(np.linspace(start_x, center_x, total_frames - move_back_start)[frame - move_back_start],
np.linspace(start_y, center_y, total_frames - move_back_start)[frame - move_back_start])
else:
# 保持在中心位置
for dot in dots:
dot.set_data(center_x, center_y)
return dots
切换模式按钮及模式展现
# 创建单选按钮
ax_mode_selector = plt.axes([0.1, 0.05, 0.15, 0.15], facecolor='lightgoldenrodyellow')
radio_mode = widgets.RadioButtons(ax_mode_selector, ('Mode 1(Cluster)', 'Mode 2(Entirety)'))
def on_click(event):
global animation, dots
if animation is not None:
animation.event_source.stop()
# 清除图形
ax.clear()
dots = []
for offset in triangle_offsets:
dot, = ax.plot(center_x + offset[0], center_y + offset[1], 'ro')
dots.append(dot)
plt.title('UAV Search Simulation')
# 获取当前选择的模式
current_mode = 1 if radio_mode.value_selected == 'Mode 1(Cluster)' else 2
if current_mode == 1:
move_back_start = 100 + (max(len(cluster) for cluster in cluster_data_points) - 1) * 10
total_frames = move_back_start + 100
animation = FuncAnimation(fig, animate_mode1, fargs=(total_frames, move_back_start), frames=total_frames + 1,
interval=10, blit=True)
elif current_mode == 2:
# 模式二的逻辑
move_back_start = 100 + (len(df) - 1) * 10
total_frames = move_back_start + 100
animation = FuncAnimation(fig, animate_mode2, fargs=(total_frames, move_back_start), frames=total_frames + 1,
interval=10, blit=True)
plt.show()
plt.show()
btn_run.on_clicked(on_click)
看看效果吧
优化飞行器模拟
结语:本质与之前变化不大,主要是关于聚类算法的应用,需要完整代码,后台私信
欢迎大家有什么疑问或者建议评论区提出