#include "graph_map.h" #include #include #include // A*路径规划实现(简化版,不考虑其他AGV) std::vector GraphMap::findPath(Point* start, Point* end, const std::vector& avoid_agvs) { if (start == end) { return {}; } // 注意:avoid_agvs参数保留以保持接口兼容性,但不再使用 // 路径规划专注于找到理论最优路径,避让由资源管理器处理 // A*算法 struct Node { Point* point; Path* path_from_parent; // 到达这个点的路径 double g_score; // 从起点到当前点的实际代价 double f_score; // g_score + 启发式代价 Node(Point* p, Path* path, double g, double f) : point(p), path_from_parent(path), g_score(g), f_score(f) {} bool operator<(const Node& other) const { return f_score > other.f_score; // 最小堆 } }; std::priority_queue open_set; std::unordered_map came_from; std::unordered_map g_score; // 初始化起点 open_set.emplace(start, nullptr, 0, start->distanceTo(*end)); g_score[start] = 0; while (!open_set.empty()) { Node current = open_set.top(); open_set.pop(); // 到达终点 if (current.point == end) { std::vector path_list; Point* curr = end; // 回溯构建路径 while (curr != start && came_from.find(curr) != came_from.end()) { Path* path = came_from[curr]; path_list.insert(path_list.begin(), path); curr = path->start == curr ? path->end : path->start; } return path_list; } // 探索相邻路径 const std::vector& adj_paths = getAdjacentPaths(current.point); for (Path* path : adj_paths) { // 简化版:不再检查路径占用,由资源管理器处理 // 获取相邻节点 Point* neighbor = path->getOtherEnd(current.point); if (!neighbor) { continue; } // 计算代价 double tentative_g = current.g_score + path->length; // 如果这是更好的路径或者首次访问 if (g_score.find(neighbor) == g_score.end() || tentative_g < g_score[neighbor]) { came_from[neighbor] = path; g_score[neighbor] = tentative_g; // 计算启发式代价(到终点的直线距离) double f_score = tentative_g + neighbor->distanceTo(*end); open_set.emplace(neighbor, path, tentative_g, f_score); } } } // 无法找到路径 return {}; } bool GraphMap::isPathAvailable(Path* path, const AGV* requester) { std::lock_guard lock(map_mutex_); // 如果路径未被占用,则可用 if (!path->isOccupied()) { return true; } // 如果被请求者自己占用,也认为可用(已在路上) return path->occupied_by == requester; } void GraphMap::reservePath(Path* path, AGV* agv) { std::lock_guard lock(map_mutex_); path->occupied_by = agv; } void GraphMap::releasePath(Path* path, AGV* agv) { std::lock_guard lock(map_mutex_); if (path->occupied_by == agv) { path->occupied_by = nullptr; } } // K最短路径实现 (简化版Yen's算法变体) std::vector> GraphMap::findKShortestPaths( Point* start, Point* end, int K, const std::vector& avoid_agvs ) { std::vector> results; if (K <= 0 || start == nullptr || end == nullptr || start == end) { return results; } // 1. 找到最短路径 (使用标准A*) std::vector first_path = findPath(start, end, avoid_agvs); if (first_path.empty()) { return results; // 无法找到任何路径 } results.push_back(first_path); if (K == 1) { return results; } // 2. 寻找K-1条备选路径 (通过边惩罚方法) std::unordered_map edge_penalties; for (int k = 1; k < K; ++k) { std::vector best_alternative; double best_cost = 1e9; // 尝试惩罚前一条路径中的每条边,寻找替代方案 const std::vector& prev_path = results[k-1]; // 随机选择一些偏离点来探索不同路径 (简化版) // 完整Yen's算法会比较慢,这里使用贪心偏离策略 for (size_t deviate_idx = 0; deviate_idx < prev_path.size() && deviate_idx < 3; ++deviate_idx) { Path* banned_path = prev_path[deviate_idx]; // 临时增加这条边的代价 double original_penalty = edge_penalties[banned_path]; edge_penalties[banned_path] += 1000.0; // 大惩罚值 // 使用修改后的代价重新运行A* std::vector alternative = _findPathWithPenalties(start, end, edge_penalties, avoid_agvs); // 恢复代价 edge_penalties[banned_path] = original_penalty; if (!alternative.empty()) { // 计算路径总长度 double total_length = 0.0; for (Path* p : alternative) { total_length += p->length; } // 检查是否与已有路径重复 bool is_duplicate = false; for (const auto& existing : results) { if (_arePathsSame(alternative, existing)) { is_duplicate = true; break; } } if (!is_duplicate && total_length < best_cost) { best_cost = total_length; best_alternative = alternative; } } } if (best_alternative.empty()) { break; // 无法找到更多路径 } results.push_back(best_alternative); } return results; } // 带边惩罚的A*算法 (内部辅助函数) std::vector GraphMap::_findPathWithPenalties( Point* start, Point* end, const std::unordered_map& penalties, const std::vector& avoid_agvs ) { if (start == end) { return {}; } struct Node { Point* point; Path* path_from_parent; double g_score; double f_score; Node(Point* p, Path* path, double g, double f) : point(p), path_from_parent(path), g_score(g), f_score(f) {} bool operator<(const Node& other) const { return f_score > other.f_score; } }; std::priority_queue open_set; std::unordered_map came_from; std::unordered_map g_score; open_set.emplace(start, nullptr, 0, start->distanceTo(*end)); g_score[start] = 0; while (!open_set.empty()) { Node current = open_set.top(); open_set.pop(); if (current.point == end) { std::vector path_list; Point* curr = end; while (curr != start && came_from.find(curr) != came_from.end()) { Path* path = came_from[curr]; path_list.insert(path_list.begin(), path); curr = path->start == curr ? path->end : path->start; } return path_list; } const std::vector& adj_paths = getAdjacentPaths(current.point); for (Path* path : adj_paths) { Point* neighbor = path->getOtherEnd(current.point); if (!neighbor) { continue; } // 计算带惩罚的代价 double penalty = 0.0; auto it = penalties.find(path); if (it != penalties.end()) { penalty = it->second; } double tentative_g = current.g_score + path->length + penalty; if (g_score.find(neighbor) == g_score.end() || tentative_g < g_score[neighbor]) { came_from[neighbor] = path; g_score[neighbor] = tentative_g; double f_score = tentative_g + neighbor->distanceTo(*end); open_set.emplace(neighbor, path, tentative_g, f_score); } } } return {}; } // 检查两条路径是否相同 (内部辅助函数) bool GraphMap::_arePathsSame(const std::vector& path1, const std::vector& path2) { if (path1.size() != path2.size()) { return false; } for (size_t i = 0; i < path1.size(); ++i) { if (path1[i] != path2[i]) { return false; } } return true; } // 计算路径特征 GraphMap::PathFeatures GraphMap::calculatePathFeatures(const std::vector& path) { PathFeatures features; if (path.empty()) { features.length = 0.0; features.conflicts = 0; features.avg_speed = 0.0; features.smoothness = 0.0; return features; } // 计算总长度和平均速度 double total_length = 0.0; double total_speed = 0.0; int conflicts = 0; for (Path* p : path) { total_length += p->length; total_speed += p->max_speed; if (p->isOccupied()) { conflicts++; } } features.length = total_length; features.avg_speed = path.empty() ? 0.0 : total_speed / path.size(); features.conflicts = conflicts; // 计算平滑度 (基于角度变化) double curvature_changes = 0.0; for (size_t i = 1; i < path.size() - 1; ++i) { // 计算三个连续点形成的角度 Point* p1 = path[i-1]->start == path[i]->start ? path[i-1]->end : path[i-1]->start; Point* p2 = path[i]->start; Point* p3 = path[i+1]->end == path[i]->end ? path[i+1]->start : path[i+1]->end; if (p1 && p2 && p3) { // 计算向量 double v1x = p2->x - p1->x; double v1y = p2->y - p1->y; double v2x = p3->x - p2->x; double v2y = p3->y - p2->y; // 归一化 double norm1 = std::sqrt(v1x * v1x + v1y * v1y); double norm2 = std::sqrt(v2x * v2x + v2y * v2y); if (norm1 > 1e-6 && norm2 > 1e-6) { v1x /= norm1; v1y /= norm1; v2x /= norm2; v2y /= norm2; // 点积 double dot = v1x * v2x + v1y * v2y; dot = std::max(-1.0, std::min(1.0, dot)); // 裁剪到[-1, 1] // 角度 double angle = std::acos(dot); curvature_changes += angle; } } } features.smoothness = 1.0 / (1.0 + curvature_changes); return features; }