优化碰撞检测逻辑,添加冲突释放策略和时间戳记录
This commit is contained in:
parent
3463926e98
commit
c8727fb665
@ -3,9 +3,18 @@
|
||||
#include "config/SystemConfig.h"
|
||||
#include "utils/Logger.h"
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace {
|
||||
// 冲突释放参数:
|
||||
// 1) 当前距离达到预警阈值的倍数且不再预测碰撞 -> 立即释放
|
||||
// 2) 连续一段时间无风险 -> 强制释放(防止历史记录粘连)
|
||||
constexpr double kResolveDistanceMultiplier = 1.5;
|
||||
constexpr int64_t kResolveNoRiskTimeoutMs = 5000;
|
||||
}
|
||||
|
||||
CollisionDetector::CollisionDetector(const AirportBounds& bounds, const ControllableVehicles& controllableVehicles)
|
||||
: airportBounds_(bounds),
|
||||
vehicleTree_(bounds.getAirportBounds(), 8), // 使用机场总边界初始化四叉树
|
||||
@ -61,6 +70,8 @@ void CollisionDetector::updateTraffic(const std::vector<Aircraft>& aircraft,
|
||||
|
||||
std::vector<CollisionRisk> CollisionDetector::detectCollisions() {
|
||||
std::vector<CollisionRisk> risks;
|
||||
const auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
|
||||
// 获取配置参数
|
||||
const auto& predictionConfig =
|
||||
@ -136,6 +147,7 @@ std::vector<CollisionRisk> CollisionDetector::detectCollisions() {
|
||||
record.maxLevel = std::max(record.maxLevel, level);
|
||||
record.collisionPoint =
|
||||
collisionResult.collisionPoint; // 更新冲突点
|
||||
record.detectedTime = now_ms;
|
||||
Logger::debug("更新冲突记录: obj1=", aircraft.id,
|
||||
", obj2=", vehicle.id, ", maxLevel=",
|
||||
static_cast<int>(record.maxLevel),
|
||||
@ -145,9 +157,7 @@ std::vector<CollisionRisk> CollisionDetector::detectCollisions() {
|
||||
// 创建新的冲突记录
|
||||
record = { collisionResult
|
||||
.collisionPoint, // 使用当前检测到的冲突点
|
||||
std::chrono::system_clock::now()
|
||||
.time_since_epoch()
|
||||
.count(),
|
||||
now_ms,
|
||||
level, false };
|
||||
Logger::debug("创建新的冲突记录: obj1=", aircraft.id,
|
||||
", obj2=", vehicle.id,
|
||||
@ -178,12 +188,26 @@ std::vector<CollisionRisk> CollisionDetector::detectCollisions() {
|
||||
", timeToCollision=", collisionResult.timeToCollision, "s",
|
||||
", level=", static_cast<int>(level));
|
||||
} else if (hasUnresolvedConflict) {
|
||||
// 检查是否满足解除条件
|
||||
if (checkCollisionResolved(aircraft, vehicle, it->second,
|
||||
safeDistance)) {
|
||||
// 专业化释放策略:
|
||||
// A. 距离已明显拉开且当前不再预测碰撞 -> 立即释放
|
||||
// B. 连续无风险超过阈值 -> 强制释放,防止历史 maxLevel 粘连
|
||||
// C. 其余场景沿用原有几何释放条件
|
||||
const bool farEnoughAndNoRisk =
|
||||
!collisionResult.willCollide &&
|
||||
collisionResult.distance >= safeDistance * kResolveDistanceMultiplier;
|
||||
const bool noRiskTimeout =
|
||||
!collisionResult.willCollide &&
|
||||
(now_ms - it->second.detectedTime) >= kResolveNoRiskTimeoutMs;
|
||||
const bool geometricResolved =
|
||||
checkCollisionResolved(aircraft, vehicle, it->second, safeDistance);
|
||||
|
||||
if (farEnoughAndNoRisk || noRiskTimeout || geometricResolved) {
|
||||
it->second.resolved = true;
|
||||
Logger::debug("冲突已解除: obj1=", aircraft.id,
|
||||
", obj2=", vehicle.id);
|
||||
", obj2=", vehicle.id,
|
||||
", reason=",
|
||||
farEnoughAndNoRisk ? "far_enough_no_risk" :
|
||||
(noRiskTimeout ? "no_risk_timeout" : "geometric_condition"));
|
||||
} else {
|
||||
// 虽然当前没有检测到风险,但由于未满足解除条件,继续保持原有风险等级
|
||||
currentCollisions.insert(collisionKey);
|
||||
@ -509,4 +533,4 @@ CollisionResult CollisionDetector::predictCircleBasedCollision(
|
||||
result.object2State = CollisionObjectState(p2_hit, speed2, heading2);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user