修改碰撞检测逻辑

This commit is contained in:
Tian jianyong 2024-12-12 21:10:02 +08:00
parent 573964b16f
commit dce6f88c77
17 changed files with 675 additions and 223 deletions

View File

@ -49,14 +49,15 @@ set(LIB_SOURCES
src/collector/DataCollector.cpp
src/core/System.cpp
src/detector/CollisionDetector.cpp
src/detector/SimpleCollisionDetector.cpp
src/network/HTTPDataSource.cpp
src/network/WebSocketServer.cpp
src/network/HTTPClient.cpp
src/spatial/AirportBounds.cpp
src/spatial/CoordinateConverter.cpp
src/types/BasicTypes.cpp
src/types/VehicleData.cpp
src/vehicle/ControllableVehicles.cpp
src/config/AirportBounds.cpp
src/config/SystemConfig.cpp
src/config/IntersectionConfig.cpp
src/detector/TrafficLightDetector.cpp

View File

@ -17,7 +17,7 @@
},
"config": {
"vehicle_collision_radius": 50.0,
"aircraft_ground_radius": 100.0,
"aircraft_collision_radius": 100.0,
"height_threshold": 15.0,
"warning_zone_radius": 100.0,
"alert_zone_radius": 50.0
@ -32,7 +32,7 @@
},
"config": {
"vehicle_collision_radius": 30.0,
"aircraft_ground_radius": 50.0,
"aircraft_collision_radius": 50.0,
"height_threshold": 10.0,
"warning_zone_radius": 50.0,
"alert_zone_radius": 25.0
@ -47,7 +47,7 @@
},
"config": {
"vehicle_collision_radius": 20.0,
"aircraft_ground_radius": 40.0,
"aircraft_collision_radius": 40.0,
"height_threshold": 5.0,
"warning_zone_radius": 40.0,
"alert_zone_radius": 20.0
@ -62,7 +62,7 @@
},
"config": {
"vehicle_collision_radius": 15.0,
"aircraft_ground_radius": 30.0,
"aircraft_collision_radius": 30.0,
"height_threshold": 5.0,
"warning_zone_radius": 30.0,
"alert_zone_radius": 15.0
@ -77,7 +77,7 @@
},
"config": {
"vehicle_collision_radius": 25.0,
"aircraft_ground_radius": 50.0,
"aircraft_collision_radius": 50.0,
"height_threshold": 10.0,
"warning_zone_radius": 100.0,
"alert_zone_radius": 50.0

View File

@ -35,27 +35,9 @@
"collision_detection": {
"update_interval_ms": 200,
"prediction": {
"time_window": 30.0,
"vehicle_size": 10.0,
"aircraft_size": 50.0
},
"thresholds": {
"runway": {
"aircraft_ground": 100.0,
"vehicle": 50.0
},
"taxiway": {
"aircraft_ground": 50.0,
"vehicle": 30.0
},
"apron": {
"aircraft_ground": 40.0,
"vehicle": 20.0
},
"service": {
"aircraft_ground": 30.0,
"vehicle": 15.0
}
"time_window": 20.0,
"vehicle_size": 5.0,
"aircraft_size": 25.0
}
},
"logging": {

View File

@ -1,4 +1,4 @@
#include "spatial/AirportBounds.h"
#include "AirportBounds.h"
#include <nlohmann/json.hpp>
#include <fstream>
#include <filesystem>
@ -77,7 +77,7 @@ void AirportBounds::loadConfig(const std::string& configFile) {
auto& config = value["config"];
areaConfigs_[type] = {
config["vehicle_collision_radius"].get<double>(),
config["aircraft_ground_radius"].get<double>(),
config["aircraft_collision_radius"].get<double>(),
config["height_threshold"].get<double>(),
config["warning_zone_radius"].get<double>(),
config["alert_zone_radius"].get<double>()

View File

@ -17,7 +17,7 @@ enum class AreaType {
// 区域配置
struct AreaConfig {
double vehicleCollisionRadius = 0.0; // 车辆间冲突检测半径
double aircraftGroundRadius = 0.0; // 航空器与车辆冲突检测半径
double aircraftCollisionRadius = 0.0; // 航空器与车辆冲突检测半径
double heightThreshold = 0.0; // 高度阈值
double warning_zone_radius = 0.0; // 预警区域半径
double alert_zone_radius = 0.0; // 警报区域半径
@ -32,9 +32,9 @@ struct AreaConfig {
CollisionThresholds getThresholds(bool isAircraft1, bool isAircraft2) const {
// 如果没有配置预警和警报距离,使用碰撞半径作为默认值
double warningRadius = warning_zone_radius > 0 ? warning_zone_radius :
(isAircraft1 || isAircraft2 ? aircraftGroundRadius : vehicleCollisionRadius);
(isAircraft1 || isAircraft2 ? aircraftCollisionRadius : vehicleCollisionRadius);
double alertRadius = alert_zone_radius > 0 ? alert_zone_radius :
(isAircraft1 || isAircraft2 ? aircraftGroundRadius * 0.5 : vehicleCollisionRadius * 0.5);
(isAircraft1 || isAircraft2 ? aircraftCollisionRadius * 0.5 : vehicleCollisionRadius * 0.5);
return {
warningRadius, // 预警距离

View File

@ -39,16 +39,10 @@ void SystemConfig::load(const std::string& filename) {
// 加载碰撞检测配置
collision_detection.update_interval_ms = j["collision_detection"]["update_interval_ms"];
// 加载阈值配置
auto& thresholds = j["collision_detection"]["thresholds"];
collision_detection.thresholds.runway.aircraft_ground = thresholds["runway"]["aircraft_ground"];
collision_detection.thresholds.runway.vehicle = thresholds["runway"]["vehicle"];
collision_detection.thresholds.taxiway.aircraft_ground = thresholds["taxiway"]["aircraft_ground"];
collision_detection.thresholds.taxiway.vehicle = thresholds["taxiway"]["vehicle"];
collision_detection.thresholds.apron.aircraft_ground = thresholds["apron"]["aircraft_ground"];
collision_detection.thresholds.apron.vehicle = thresholds["apron"]["vehicle"];
collision_detection.thresholds.service.aircraft_ground = thresholds["service"]["aircraft_ground"];
collision_detection.thresholds.service.vehicle = thresholds["service"]["vehicle"];
// 加载碰撞预测配置
collision_detection.prediction.time_window = j["collision_detection"]["prediction"]["time_window"];
collision_detection.prediction.vehicle_size = j["collision_detection"]["prediction"]["vehicle_size"];
collision_detection.prediction.aircraft_size = j["collision_detection"]["prediction"]["aircraft_size"];
// 加载日志配置
logging.level = j["logging"]["level"];

View File

@ -59,16 +59,6 @@ public:
double vehicle_size;
double aircraft_size;
} prediction;
struct Thresholds {
struct Area {
double aircraft_ground;
double vehicle;
};
Area runway;
Area taxiway;
Area apron;
Area service;
} thresholds;
} collision_detection;
struct Logging {

View File

@ -74,6 +74,11 @@ bool System::initialize() {
system_config.warning.log_interval_ms
};
// 初始化简单冲突检测器
// simpleCollisionDetector_ = std::make_unique<SimpleCollisionDetector>(
// intersection_config_, *controllableVehicles_);
// Logger::info("简单冲突检测器初始化完成");
return dataCollector_->initialize(dataSourceConfig, warnConfig);
}
catch (const std::exception& e) {
@ -207,11 +212,11 @@ void System::processLoop() {
} else {
// 正常的更新检查
for (const auto& veh : vehicles) {
Logger::debug("处理车辆: ", veh.vehicleNo);
Logger::debug(" - 位置: (", veh.geo.longitude, ", ", veh.geo.latitude, ")");
Logger::debug(" - 速度: ", veh.speed, "m/s");
Logger::debug(" - 时间戳: ", veh.timestamp);
Logger::debug(" - 时间差: ", veh.timestamp - last_vehicle_timestamp);
// Logger::debug("处理车辆: ", veh.vehicleNo);
// Logger::debug(" - 位置: (", veh.geo.longitude, ", ", veh.geo.latitude, ")");
// Logger::debug(" - 速度: ", veh.speed, "m/s");
// Logger::debug(" - 时间戳: ", veh.timestamp);
// Logger::debug(" - 时间差: ", veh.timestamp - last_vehicle_timestamp);
if (veh.timestamp > last_vehicle_timestamp) {
has_new_vehicles = true;
@ -248,6 +253,7 @@ void System::processLoop() {
// 只有当有新的数据时才更新冲突检测
if (last_aircraft_timestamp > last_collision_timestamp ||
last_vehicle_timestamp > last_collision_timestamp) {
// 更新冲突检测器
collisionDetector_->updateTraffic(aircraft, vehicles);
auto collisions = collisionDetector_->detectCollisions();
@ -261,8 +267,47 @@ void System::processLoop() {
", 区域类型=", static_cast<int>(risk.zoneType));
}
processCollisions(collisions);
// 简单冲突检测
// simpleCollisionDetector_->updateTraffic(aircraft, vehicles);
// auto simpleCollisions = simpleCollisionDetector_->detectCollisions();
// if(!simpleCollisions.empty()){
// Logger::debug("检测到 ", simpleCollisions.size(), "个碰撞风险");
// for (const auto& risk : simpleCollisions) {
// Logger::debug("碰撞风险详情: id1=", risk.id1,
// ", id2=", risk.id2,
// ", 距离=", risk.distance, "m, 风险等级=", static_cast<int>(risk.level),
// ", 区域类型=", static_cast<int>(risk.isIntersection));
// }
// processCollisions(simpleCollisions);
} else if (!lastVehiclesWithRisk_.empty()) {
// 当前没有任何风险,但上次有风险车辆,需要处理恢复指令
Logger::debug("当前无碰撞风险,检查是否需要发送恢复指令");
for (const auto& vehicleId : lastVehiclesWithRisk_) {
Logger::debug("车辆 ", vehicleId, " 当前没有风险,准备发送恢复指令");
VehicleCommand cmd;
cmd.vehicleId = vehicleId;
cmd.type = CommandType::RESUME;
cmd.reason = CommandReason::RESUME_TRAFFIC;
cmd.timestamp = std::chrono::system_clock::now().time_since_epoch().count();
broadcastVehicleCommand(cmd);
controllableVehicles_->sendCommand(vehicleId, cmd);
Logger::info("发送恢复指令到车辆: ", vehicleId);
}
// 清空风险车辆列表
Logger::debug("清空风险车辆列表: 原数量=", lastVehiclesWithRisk_.size(),
", 原列表={", [&]() {
std::string s;
for (const auto& id : lastVehiclesWithRisk_) {
s += id + ",";
}
return s;
}(), "}");
lastVehiclesWithRisk_.clear();
}
last_collision_timestamp = std::max(last_aircraft_timestamp, last_vehicle_timestamp);
}
last_collision_update = now;
@ -316,6 +361,141 @@ void System::processLoop() {
}
}
void System::processCollisions(const std::vector<SimpleCollisionRisk>& risks) {
// 记录当前有风险的可控车辆
std::unordered_set<std::string> currentVehiclesWithRisk;
const auto& config = SystemConfig::instance().collision_detection;
Logger::debug("开始处理碰撞风险,当前风险数量: ", risks.size());
// 处理当前的碰撞风险
for (const auto& risk : risks) {
// 处理 id1 和 id2 中的可控车辆
bool id1_controllable = controllableVehicles_->isControllable(risk.id1);
bool id2_controllable = controllableVehicles_->isControllable(risk.id2);
// 如果两个都不是可控车辆,跳过
if (!id1_controllable && !id2_controllable) {
continue;
}
// 根据风险等级处理
auto processVehicle = [&](const std::string& vehicleId, const std::string& otherId) {
switch (risk.level) {
case SimpleRiskLevel::CRITICAL: {
// 危险区域:立即发送告警指令
VehicleCommand cmd;
cmd.vehicleId = vehicleId;
cmd.type = CommandType::ALERT;
cmd.reason = otherId.substr(0, 2) == "AC" ?
CommandReason::AIRCRAFT_CROSSING :
CommandReason::SPECIAL_VEHICLE;
cmd.timestamp = std::chrono::system_clock::now().time_since_epoch().count();
// 设置目标位置(冲突对象的位置)
const MovingObject* target = findVehicle(otherId);
if (target) {
cmd.latitude = target->geo.latitude;
cmd.longitude = target->geo.longitude;
cmd.relativeSpeed = risk.relativeSpeed;
}
broadcastVehicleCommand(cmd);
controllableVehicles_->sendCommand(vehicleId, cmd);
Logger::warning("发送告警指令到车辆: ", vehicleId,
" 当前距离: ", risk.distance, "m",
" 相对速度: ", risk.relativeSpeed, "m/s");
break;
}
case SimpleRiskLevel::WARNING: {
// 预警区域:发送预警指令
VehicleCommand cmd;
cmd.vehicleId = vehicleId;
cmd.type = CommandType::WARNING;
cmd.reason = otherId.substr(0, 2) == "AC" ?
CommandReason::AIRCRAFT_CROSSING :
CommandReason::SPECIAL_VEHICLE;
cmd.timestamp = std::chrono::system_clock::now().time_since_epoch().count();
// 设置目标位置
const MovingObject* target = findVehicle(otherId);
if (target) {
cmd.latitude = target->geo.latitude;
cmd.longitude = target->geo.longitude;
cmd.relativeSpeed = risk.relativeSpeed;
}
broadcastVehicleCommand(cmd);
controllableVehicles_->sendCommand(vehicleId, cmd);
Logger::info("发送预警指令到车辆: ", vehicleId,
" 当前距离: ", risk.distance, "m",
" 相对速度: ", risk.relativeSpeed, "m/s");
break;
}
default:
break;
}
};
// 为每个可控车辆处理风险
if (id1_controllable) {
currentVehiclesWithRisk.insert(risk.id1);
Logger::debug("添加当前有风险的可控车辆: ", risk.id1,
", 当前风险车辆数量: ", currentVehiclesWithRisk.size());
processVehicle(risk.id1, risk.id2);
}
if (id2_controllable) {
currentVehiclesWithRisk.insert(risk.id2);
Logger::debug("添加当前有风险的可控车辆: ", risk.id2,
", 当前风险车辆数量: ", currentVehiclesWithRisk.size());
processVehicle(risk.id2, risk.id1);
}
// 广播碰撞预警消息
broadcastCollisionWarning(risk);
}
Logger::debug("当前有风险的可控车辆数量: ", currentVehiclesWithRisk.size());
Logger::debug("上一次有风险的可控车辆数量: ", lastVehiclesWithRisk_.size());
// 对之前有风险但现在没有风险的车辆发送恢复指令
for (const auto& vehicleId : lastVehiclesWithRisk_) {
Logger::debug("检查车辆是否需要恢复: ", vehicleId);
if (currentVehiclesWithRisk.find(vehicleId) == currentVehiclesWithRisk.end()) {
Logger::debug("车辆 ", vehicleId, " 当前没有风险,准备发送恢复指令");
VehicleCommand cmd;
cmd.vehicleId = vehicleId;
cmd.type = CommandType::RESUME;
cmd.reason = CommandReason::RESUME_TRAFFIC;
cmd.timestamp = std::chrono::system_clock::now().time_since_epoch().count();
broadcastVehicleCommand(cmd);
controllableVehicles_->sendCommand(vehicleId, cmd);
Logger::info("发送恢复指令到车辆: ", vehicleId);
} else {
Logger::debug("车辆 ", vehicleId, " 仍然有风险,不发送恢复指令");
}
}
// 更新上一次有风险的车辆列表
Logger::debug("更新风险车辆列表: 原数量=", lastVehiclesWithRisk_.size(),
", 新数量=", currentVehiclesWithRisk.size(),
", 原列表={", [&]() {
std::string s;
for (const auto& id : lastVehiclesWithRisk_) {
s += id + ",";
}
return s;
}(), "}, 新列表={", [&]() {
std::string s;
for (const auto& id : currentVehiclesWithRisk) {
s += id + ",";
}
return s;
}(), "}");
lastVehiclesWithRisk_ = std::move(currentVehiclesWithRisk);
}
void System::processCollisions(const std::vector<CollisionRisk>& risks) {
// 记录当前有风险的可控车辆
std::unordered_set<std::string> currentVehiclesWithRisk;
@ -403,12 +583,14 @@ void System::processCollisions(const std::vector<CollisionRisk>& risks) {
// 为每个可控车辆处理风险
if (id1_controllable) {
currentVehiclesWithRisk.insert(risk.id1);
Logger::debug("添加当前有风险的可控车辆: ", risk.id1);
Logger::debug("添加当前有风险的可控车辆: ", risk.id1,
", 当前风险车辆数量: ", currentVehiclesWithRisk.size());
processVehicle(risk.id1, risk.id2);
}
if (id2_controllable) {
currentVehiclesWithRisk.insert(risk.id2);
Logger::debug("添加当前有风险的可控车辆: ", risk.id2);
Logger::debug("添加当前有风险的可控车辆: ", risk.id2,
", 当前风险车辆数量: ", currentVehiclesWithRisk.size());
processVehicle(risk.id2, risk.id1);
}
@ -438,8 +620,22 @@ void System::processCollisions(const std::vector<CollisionRisk>& risks) {
}
}
// 更新上一次有风险的可控车辆列表
Logger::debug("更新风险车辆列表: ", lastVehiclesWithRisk_.size(), " -> ", currentVehiclesWithRisk.size());
// 更新上一次有风险的车辆列表
Logger::debug("更新风险车辆列表: 原数量=", lastVehiclesWithRisk_.size(),
", 新数量=", currentVehiclesWithRisk.size(),
", 原列表={", [&]() {
std::string s;
for (const auto& id : lastVehiclesWithRisk_) {
s += id + ",";
}
return s;
}(), "}, 新列表={", [&]() {
std::string s;
for (const auto& id : currentVehiclesWithRisk) {
s += id + ",";
}
return s;
}(), "}");
lastVehiclesWithRisk_ = std::move(currentVehiclesWithRisk);
}
@ -520,6 +716,17 @@ std::string getRiskLevelString(RiskLevel level) {
}
}
std::string getRiskLevelString(SimpleRiskLevel level) {
switch (level) {
case SimpleRiskLevel::CRITICAL:
return "CRITICAL";
case SimpleRiskLevel::WARNING:
return "WARNING";
default:
return "NONE";
}
}
void System::broadcastCollisionWarning(const CollisionRisk& risk) {
if (!ws_server_) {
return;
@ -544,6 +751,30 @@ void System::broadcastCollisionWarning(const CollisionRisk& risk) {
" level=", getRiskLevelString(risk.level));
}
void System::broadcastCollisionWarning(const SimpleCollisionRisk& risk) {
if (!ws_server_) {
return;
}
// 构造冲突预警消息
nlohmann::json j = {
{"type", "collision_warning"},
{"id1", risk.id1},
{"id2", risk.id2},
{"distance", risk.distance},
{"relativeSpeed", risk.relativeSpeed},
{"warningLevel", getRiskLevelString(risk.level)},
{"timestamp", std::chrono::system_clock::now().time_since_epoch().count()}
};
// 广播冲突预警消息
ws_server_->broadcast(j.dump());
Logger::debug("广播冲突预警: id1=", risk.id1, " id2=", risk.id2,
" distance=", risk.distance, "m",
" relativeSpeed=", risk.relativeSpeed, "m/s",
" level=", getRiskLevelString(risk.level));
}
void System::broadcastTimeoutWarning(const network::TimeoutWarningMessage& warning) {
if (ws_server_) {
ws_server_->broadcast(warning.toJson().dump());

View File

@ -8,12 +8,13 @@
#include "types/BasicTypes.h"
#include "detector/CollisionDetector.h"
#include "detector/TrafficLightDetector.h"
#include "spatial/AirportBounds.h"
#include "config/AirportBounds.h"
#include "vehicle/ControllableVehicles.h"
#include "network/WebSocketServer.h"
#include "network/MessageTypes.h"
#include "config/SystemConfig.h"
#include "config/IntersectionConfig.h"
#include "detector/SimpleCollisionDetector.h"
// 前向声明
class DataCollector;
@ -34,6 +35,7 @@ public:
virtual void broadcastTimeoutWarning(const network::TimeoutWarningMessage& warning);
void broadcastPositionUpdate(const MovingObject& obj);
void broadcastCollisionWarning(const CollisionRisk& risk);
void broadcastCollisionWarning(const SimpleCollisionRisk& risk);
void broadcastVehicleCommand(const VehicleCommand& cmd);
void broadcastTrafficLightStatus(const TrafficLightSignal& signal);
@ -43,6 +45,7 @@ public:
private:
void processLoop();
void processCollisions(const std::vector<CollisionRisk>& collisions);
void processCollisions(const std::vector<SimpleCollisionRisk>& risks);
std::atomic<bool> running_{false};
std::thread processThread_;
@ -70,4 +73,6 @@ private:
// 辅助函数
const MovingObject* findVehicle(const std::string& vehicleId) const;
std::unique_ptr<SimpleCollisionDetector> simpleCollisionDetector_;
};

View File

@ -11,11 +11,6 @@ CollisionDetector::CollisionDetector(const AirportBounds& bounds, const Controll
// 记录初始化信息
const auto& airportBounds = bounds.getAirportBounds();
Logger::debug(
"碰撞检测器初始化: 机场边界=(",
airportBounds.x, ",", airportBounds.y, ") - (",
airportBounds.x + airportBounds.width, ",", airportBounds.y + airportBounds.height, ")"
);
}
void CollisionDetector::updateTraffic(const std::vector<Aircraft>& aircraft,
@ -85,6 +80,8 @@ std::vector<CollisionRisk> CollisionDetector::detectCollisions() {
// 检测可控车辆与航空器的碰撞
for (const auto& aircraft : aircraftData_) {
for (const auto& vehicle : controlVehicles) {
Logger::debug("检查车辆与航空器碰撞: ", vehicle.vehicleNo, "", aircraft.flightNo);
// 计算当前距离
double dx = aircraft.position.x - vehicle.position.x;
double dy = aircraft.position.y - vehicle.position.y;
@ -93,8 +90,8 @@ std::vector<CollisionRisk> CollisionDetector::detectCollisions() {
// 计算预测阈值
double maxSpeed = std::max(aircraft.speed, vehicle.speed);
double predictionDistance = maxSpeed * predictionConfig.time_window;
double baseThreshold = getCollisionParams(aircraft.position).aircraftGroundRadius;
double predictionThreshold = std::max(predictionDistance, baseThreshold * 2.0);
double baseThreshold = getCollisionParams(aircraft.position).alert_zone_radius;
double predictionThreshold = std::max(predictionDistance, baseThreshold * 4.0);
// 如果在预测距离内,进行轨迹预测
if (currentDistance <= predictionThreshold) {
@ -152,7 +149,7 @@ std::vector<CollisionRisk> CollisionDetector::detectCollisions() {
}
}
// 检测可控车辆之间的碰撞
// 检测可控车辆与所有车辆的碰撞
for (size_t i = 0; i < controlVehicles.size(); ++i) {
const auto& vehicle1 = controlVehicles[i];
@ -174,8 +171,8 @@ std::vector<CollisionRisk> CollisionDetector::detectCollisions() {
// 计算预测阈值
double maxSpeed = std::max(vehicle1.speed, vehicle2.speed);
double predictionDistance = maxSpeed * predictionConfig.time_window;
double baseThreshold = getCollisionParams(vehicle1.position).vehicleCollisionRadius;
double predictionThreshold = std::max(predictionDistance, baseThreshold * 2.0);
double baseThreshold = getCollisionParams(vehicle1.position).alert_zone_radius;
double predictionThreshold = std::max(predictionDistance, baseThreshold * 4.0);
// 如果在预测距离内,进行轨迹预测
if (currentDistance <= predictionThreshold) {
@ -246,54 +243,6 @@ std::vector<CollisionRisk> CollisionDetector::detectCollisions() {
return risks;
}
RiskLevel CollisionDetector::calculateRiskLevel(double distance, const Vector2D& position,
bool isAircraft1, bool isAircraft2) const {
const auto& areaConfig = getCollisionParams(position);
// 获取合适的阈值配置
auto thresholds = areaConfig.getThresholds(isAircraft1, isAircraft2);
double warningDistance = thresholds.warning;
double alertDistance = thresholds.critical;
// 记录调试信息
Logger::debug(
"风险等级计算: 距离=", distance,
"m, 预警阈值=", warningDistance,
"m, 警报阈值=", alertDistance,
"m, 物体类型=",
isAircraft1 ? (isAircraft2 ? "航空器-航空器" : "航空器-车辆") : "车辆-车辆"
);
// 根据距离判断风险等级
if (distance <= alertDistance) {
return RiskLevel::CRITICAL;
} else if (distance <= warningDistance) {
return RiskLevel::WARNING;
}
return RiskLevel::NONE;
}
WarningZoneType CollisionDetector::determineWarningZone(double distance, double threshold) const {
// 获取警报和预警距离
double alertDistance = threshold * 0.5; // 警报距离为阈值的50%
double warningDistance = threshold; // 预警距离为阈值的100%
// 记录调试信息
Logger::debug(
"预警区域判断: 当前距离=", distance,
"m, 警报距离=", alertDistance,
"m, 预警距离=", warningDistance, "m"
);
// 根据距离判断区域类型
if (distance <= alertDistance) {
return WarningZoneType::DANGER;
} else if (distance <= warningDistance) {
return WarningZoneType::WARNING;
}
return WarningZoneType::NONE;
}
// 添加一个新的辅助函数来统一处理风险等级和预警区域的判断
std::pair<RiskLevel, WarningZoneType> CollisionDetector::evaluateRisk(
double currentDistance,
@ -309,13 +258,13 @@ std::pair<RiskLevel, WarningZoneType> CollisionDetector::evaluateRisk(
RiskLevel level = RiskLevel::NONE;
WarningZoneType zoneType = WarningZoneType::NONE;
// 如果预测到碰撞距离小于警报距离,设置为危险等级
if (willCollide || currentDistance <= thresholds.critical) {
// 如果预测到碰撞并且当前距离小于警报距离,设置为危险等级
if (willCollide && currentDistance <= thresholds.critical) {
level = RiskLevel::CRITICAL;
zoneType = WarningZoneType::DANGER;
}
// 如果距离在预警范围内,设置为预警等级
else if (currentDistance <= thresholds.warning) {
// 如果预测到碰撞并且当前距离在预警范围内,设置为预警等级
else if (willCollide && currentDistance <= thresholds.warning) {
level = RiskLevel::WARNING;
zoneType = WarningZoneType::WARNING;
}
@ -352,7 +301,7 @@ bool CollisionDetector::checkCollisionRisk(
double predictionDistance = maxSpeed * predictionConfig.time_window;
// 根据物体类型选择基准阈值
double baseThreshold = (isAircraft1 || isAircraft2) ?
areaConfig.aircraftGroundRadius :
areaConfig.aircraftCollisionRadius :
areaConfig.vehicleCollisionRadius;
double predictionThreshold = std::max(predictionDistance, baseThreshold * 2.0);
@ -389,12 +338,26 @@ bool CollisionDetector::checkCollisionRisk(
// 计算相对速度
double vx = mv1.vx - mv2.vx;
double vy = mv1.vy - mv2.vy;
double relativeSpeed = std::sqrt(vx*vx + vy*vy);
// 计算相对运动(点积),判断是否在接近
double relativeMotion = dx*vx + dy*vy;
// 如果相对运动小于等于0表示物体正在接近
hasCollisionRisk = (relativeMotion <= 0) || prediction.willCollide || currentDistance <= alertDistance;
// 如果相对运动小于等于0且相对速度大于阈值或者预测会碰撞或者已经进入警戒区域则有碰撞风险
hasCollisionRisk = (relativeMotion <= 0 && relativeSpeed > 1.0) ||
prediction.willCollide ||
currentDistance <= alertDistance;
Logger::debug(
"碰撞风险分析: id1=", id1,
", id2=", id2,
", 当前距离=", currentDistance,
"m, 相对速度=", relativeSpeed,
"m/s, 相对运动=", relativeMotion,
", 预测碰撞=", prediction.willCollide ? "" : "",
", 警戒距离=", alertDistance,
"m, 有风险=", hasCollisionRisk ? "" : ""
);
}
if (hasCollisionRisk) {
@ -451,7 +414,7 @@ CollisionPrediction CollisionDetector::predictTrajectoryCollision(
result.minDistance = std::numeric_limits<double>::infinity();
// 计算安全距离
double safeDistance = size1 + size2;
double safeDistance = (size1 + size2) * 1.5;
// 计算速度分量
MovementVector mv1(speed1, heading1);
@ -480,7 +443,7 @@ CollisionPrediction CollisionDetector::predictTrajectoryCollision(
", 正在远离=", result.isMovingAway ? "" : ""
);
// 如果物体静止相对于此,直接返回当前状态
// 如果物体相对静止,直接返回当前状态
if (relativeSpeed < 1e-6) {
result.minDistance = currentDistance;
result.willCollide = (currentDistance <= safeDistance);
@ -494,6 +457,25 @@ CollisionPrediction CollisionDetector::predictTrajectoryCollision(
return result;
}
// 如果当前距离小于安全距离,且相对运动为负(正在接近),直接判定为碰撞
if (currentDistance <= safeDistance && relativeMotion < 0) {
result.willCollide = true;
result.timeToCollision = 0.0;
result.minDistance = currentDistance;
result.collisionPoint = {
pos2.x + dx * (size1 / (size1 + size2)),
pos2.y + dy * (size1 / (size1 + size2))
};
Logger::debug(
"预测到碰撞: 当前距离=", currentDistance,
"m < 安全距离=", safeDistance,
"m, 且正在接近, 相对运动=", relativeMotion
);
return result;
}
// 计算相对运动方程的系数
double a = dvx * dvx + dvy * dvy;
double b = 2.0 * (dx * dvx + dy * dvy);
@ -568,6 +550,9 @@ CollisionPrediction CollisionDetector::predictTrajectoryCollision(
", 正在远离=", result.isMovingAway ? "" : ""
);
}
else {
Logger::debug("没有预测到碰撞: 时间=", t, "s, 距离=", dist_t, "m, 位置=(", x2_t, ",", y2_t, ")", ", 正在远离=", result.isMovingAway ? "" : "");
}
}
}
}

View File

@ -3,7 +3,7 @@
#include "types/BasicTypes.h"
#include "spatial/QuadTree.h"
#include "spatial/AirportBounds.h"
#include "config/AirportBounds.h"
#include "vehicle/ControllableVehicles.h"
#include "config/SystemConfig.h"
#include <vector>

View File

@ -0,0 +1,202 @@
#include "detector/SimpleCollisionDetector.h"
#include "utils/Logger.h"
#include <cmath>
SimpleCollisionDetector::SimpleCollisionDetector(
const IntersectionConfig& intersectionConfig,
const ControllableVehicles& controllableVehicles)
: intersection_config_(intersectionConfig)
, controllable_vehicles_(controllableVehicles) {
Logger::info("简单冲突检测器初始化完成");
}
void SimpleCollisionDetector::updateTraffic(
const std::vector<Aircraft>& aircraft,
const std::vector<Vehicle>& vehicles) {
aircraft_data_ = aircraft;
vehicle_data_ = vehicles;
Logger::debug("更新交通数据: 航空器=", aircraft.size(), " 车辆=", vehicles.size());
}
std::vector<SimpleCollisionRisk> SimpleCollisionDetector::detectCollisions() {
std::vector<SimpleCollisionRisk> risks;
// 检查可控车辆与飞机的冲突
for (const auto& aircraft : aircraft_data_) {
for (const auto& vehicle : vehicle_data_) {
if (controllable_vehicles_.isControllable(vehicle.vehicleNo)) {
auto risk = checkAircraftVehicleCollision(aircraft, vehicle);
if (risk.level != SimpleRiskLevel::NONE) {
risks.push_back(risk);
}
}
}
}
// 检查可控车辆之间的冲突
for (size_t i = 0; i < vehicle_data_.size(); ++i) {
if (!controllable_vehicles_.isControllable(vehicle_data_[i].vehicleNo)) {
continue;
}
for (size_t j = i + 1; j < vehicle_data_.size(); ++j) {
auto risk = checkVehicleCollision(vehicle_data_[i], vehicle_data_[j]);
if (risk.level != SimpleRiskLevel::NONE) {
risks.push_back(risk);
}
}
}
return risks;
}
SimpleCollisionRisk SimpleCollisionDetector::checkAircraftVehicleCollision(
const Aircraft& aircraft, const Vehicle& vehicle) {
SimpleCollisionRisk risk;
risk.id1 = aircraft.flightNo;
risk.id2 = vehicle.vehicleNo;
risk.level = SimpleRiskLevel::NONE;
// 计算当前距离
risk.distance = calculateDistance(aircraft.position, vehicle.position);
// 检查是否在路口附近
if (!isNearIntersection(vehicle.position, risk.intersectionId)) {
return risk; // 不在路口,无风险
}
risk.isIntersection = true;
// 计算到路口的距离
double aircraftDist = calculateDistanceToIntersection(aircraft.position, risk.intersectionId);
double vehicleDist = calculateDistanceToIntersection(vehicle.position, risk.intersectionId);
// 计算相对速度(取较大值)
risk.relativeSpeed = std::max(aircraft.speed, vehicle.speed);
if (risk.relativeSpeed < MIN_SPEED) {
risk.relativeSpeed = MIN_SPEED;
}
// 计算预计碰撞时间(取较大值)
risk.timeToCollision = std::max(aircraftDist, vehicleDist) / risk.relativeSpeed;
// 安全距离 = 路口宽度 + 飞机安全缓冲
double safeDistance = INTERSECTION_WIDTH + AIRCRAFT_BUFFER;
// 判断风险等级
if (risk.distance < safeDistance || risk.timeToCollision < MIN_TIME_WINDOW) {
risk.level = SimpleRiskLevel::CRITICAL;
} else if (risk.distance < safeDistance * 1.5 || risk.timeToCollision < WARNING_TIME_WINDOW) {
risk.level = SimpleRiskLevel::WARNING;
}
return risk;
}
SimpleCollisionRisk SimpleCollisionDetector::checkVehicleCollision(
const Vehicle& v1, const Vehicle& v2) {
SimpleCollisionRisk risk;
risk.id1 = v1.vehicleNo;
risk.id2 = v2.vehicleNo;
risk.level = SimpleRiskLevel::NONE;
// 计算当前距离
risk.distance = calculateDistance(v1.position, v2.position);
// 检查是否在路口附近
if (isNearIntersection(v1.position, risk.intersectionId) ||
isNearIntersection(v2.position, risk.intersectionId)) {
// 路口场景
risk.isIntersection = true;
double v1Dist = calculateDistanceToIntersection(v1.position, risk.intersectionId);
double v2Dist = calculateDistanceToIntersection(v2.position, risk.intersectionId);
risk.relativeSpeed = std::max(v1.speed, v2.speed);
if (risk.relativeSpeed < MIN_SPEED) {
risk.relativeSpeed = MIN_SPEED;
}
risk.timeToCollision = std::max(v1Dist, v2Dist) / risk.relativeSpeed;
// 路口安全距离
double safeDistance = INTERSECTION_WIDTH + VEHICLE_BUFFER;
if (risk.distance < safeDistance || risk.timeToCollision < MIN_TIME_WINDOW) {
risk.level = SimpleRiskLevel::CRITICAL;
} else if (risk.distance < safeDistance * 1.5 || risk.timeToCollision < WARNING_TIME_WINDOW) {
risk.level = SimpleRiskLevel::WARNING;
}
} else {
// 非路口场景(对向或同向)
risk.isIntersection = false;
// 计算相对速度
risk.relativeSpeed = std::abs(v1.speed - v2.speed); // 同向
if (std::abs(v1.heading - v2.heading) > 150) { // 对向
risk.relativeSpeed = v1.speed + v2.speed;
}
if (risk.relativeSpeed < MIN_SPEED) {
risk.relativeSpeed = MIN_SPEED;
}
risk.timeToCollision = risk.distance / risk.relativeSpeed;
// 非路口安全距离
double safeDistance = VEHICLE_BUFFER * 2;
if (risk.distance < safeDistance || risk.timeToCollision < MIN_TIME_WINDOW) {
risk.level = SimpleRiskLevel::CRITICAL;
} else if (risk.distance < safeDistance * 1.5 || risk.timeToCollision < WARNING_TIME_WINDOW) {
risk.level = SimpleRiskLevel::WARNING;
}
}
return risk;
}
double SimpleCollisionDetector::calculateDistance(const Vector2D& pos1, const Vector2D& pos2) {
double dx = pos1.x - pos2.x;
double dy = pos1.y - pos2.y;
return std::sqrt(dx*dx + dy*dy);
}
double SimpleCollisionDetector::calculateDistanceToIntersection(
const Vector2D& position, const std::string& intersectionId) {
const auto* intersection = intersection_config_.findById(intersectionId);
if (!intersection) {
return std::numeric_limits<double>::max();
}
// 将 IntersectionPosition 转换为 Vector2D
Vector2D intersectionPos;
intersectionPos.x = intersection->position.longitude;
intersectionPos.y = intersection->position.latitude;
return calculateDistance(position, intersectionPos);
}
bool SimpleCollisionDetector::isNearIntersection(
const Vector2D& position, std::string& intersectionId) {
const double CHECK_DISTANCE = INTERSECTION_WIDTH * 5; // 检查范围是路口宽度的2倍
for (const auto& intersection : intersection_config_.getIntersections()) {
// 将 IntersectionPosition 转换为 Vector2D
Vector2D intersectionPos;
intersectionPos.x = intersection.position.longitude;
intersectionPos.y = intersection.position.latitude;
double distance = calculateDistance(position, intersectionPos);
if (distance < CHECK_DISTANCE) {
intersectionId = intersection.id;
return true;
}
}
return false;
}

View File

@ -0,0 +1,72 @@
#ifndef AIRPORT_DETECTOR_SIMPLE_COLLISION_DETECTOR_H
#define AIRPORT_DETECTOR_SIMPLE_COLLISION_DETECTOR_H
#include "types/BasicTypes.h"
#include "config/IntersectionConfig.h"
#include "vehicle/ControllableVehicles.h"
#include <vector>
// 简单冲突检测器的风险等级
enum class SimpleRiskLevel {
NONE = 0, // 无风险
WARNING = 1, // 预警
CRITICAL = 2 // 告警
};
// 简单冲突检测器的风险信息
struct SimpleCollisionRisk {
std::string id1, id2; // 冲突物体的ID
SimpleRiskLevel level; // 风险等级
double distance; // 当前距离
double timeToCollision; // 预计碰撞时间
double relativeSpeed; // 相对速度
bool isIntersection; // 是否在路口
std::string intersectionId; // 路口ID如果在路口
};
class SimpleCollisionDetector {
public:
SimpleCollisionDetector(const IntersectionConfig& intersectionConfig,
const ControllableVehicles& controllableVehicles);
// 更新交通数据
void updateTraffic(const std::vector<Aircraft>& aircraft,
const std::vector<Vehicle>& vehicles);
// 检测所有可能的冲突
std::vector<SimpleCollisionRisk> detectCollisions();
private:
// 检查车辆与飞机的冲突
SimpleCollisionRisk checkAircraftVehicleCollision(
const Aircraft& aircraft, const Vehicle& vehicle);
// 检查车辆与车辆的冲突
SimpleCollisionRisk checkVehicleCollision(
const Vehicle& v1, const Vehicle& v2);
// 计算到路口的距离
double calculateDistanceToIntersection(
const Vector2D& position, const std::string& intersectionId);
// 计算两点间距离
double calculateDistance(const Vector2D& pos1, const Vector2D& pos2);
// 判断是否在路口附近
bool isNearIntersection(const Vector2D& position, std::string& intersectionId);
// 配置参数
static constexpr double INTERSECTION_WIDTH = 30.0; // 路口宽度
static constexpr double AIRCRAFT_BUFFER = 20.0; // 飞机安全缓冲
static constexpr double VEHICLE_BUFFER = 10.0; // 车辆安全缓冲
static constexpr double MIN_TIME_WINDOW = 3.0; // 最小时间窗口(秒)
static constexpr double WARNING_TIME_WINDOW = 5.0; // 预警时间窗口(秒)
static constexpr double MIN_SPEED = 0.5; // 最小速度(米/秒)
const IntersectionConfig& intersection_config_;
const ControllableVehicles& controllable_vehicles_;
std::vector<Aircraft> aircraft_data_;
std::vector<Vehicle> vehicle_data_;
};
#endif // AIRPORT_DETECTOR_SIMPLE_COLLISION_DETECTOR_H

View File

@ -286,17 +286,12 @@ bool HTTPDataSource::parseVehicleResponse(const std::string& response, std::vect
}
veh.timestamp = static_cast<uint64_t>(time);
// 解析可选字段
if (item.contains("direction")) {
veh.heading = item["direction"].get<double>();
}
// 更新位置信息
veh.position = coordinateConverter_.toLocalXY(veh.geo.latitude, veh.geo.longitude);
veh.updateMotion(veh.geo, veh.timestamp); // 更新速度和航向
Logger::debug("Parsed vehicle: id=", veh.id, " vehicleNo=", veh.vehicleNo,
" timestamp=", veh.timestamp, " pos=(", veh.geo.longitude, ",", veh.geo.latitude, ")");
// Logger::debug("Parsed vehicle: id=", veh.id, " vehicleNo=", veh.vehicleNo,
// " timestamp=", veh.timestamp, " pos=(", veh.geo.longitude, ",", veh.geo.latitude, ")");
vehicles.push_back(veh);
}
@ -348,11 +343,6 @@ bool HTTPDataSource::parseAircraftResponse(const std::string& response, std::vec
}
ac.timestamp = static_cast<uint64_t>(time);
// 解析可选字段
if (item.contains("direction")) {
ac.heading = item["direction"].get<double>();
}
// 更新位置信息
ac.position = coordinateConverter_.toLocalXY(ac.geo.latitude, ac.geo.longitude);
ac.updateMotion(ac.geo, ac.timestamp); // 更新速度和航向

View File

@ -38,18 +38,21 @@ double MovingObject::calculateDistance(const GeoPosition& pos1, const GeoPositio
}
double MovingObject::calculateHeading(const GeoPosition& from, const GeoPosition& to) {
const double METERS_PER_DEGREE = 111000.0;
double lat_rad = from.latitude * M_PI / 180.0;
// 计算经纬度差值
double dlon = to.longitude - from.longitude;
double dlat = to.latitude - from.latitude;
double dx = dlon * METERS_PER_DEGREE * std::cos(lat_rad);
double dy = dlat * METERS_PER_DEGREE;
// 将经度差转换为实际距离(考虑纬度影响)
double lat_rad = from.latitude * M_PI / 180.0;
double dx = dlon * std::cos(lat_rad); // 东西方向的距离(经度)
double dy = dlat; // 南北方向的距离(纬度)
// 计算航向角正北为0度顺时针增加
double angle = std::atan2(dx, dy) * 180.0 / M_PI;
if (angle < 0) {
angle += 360.0;
}
return angle;
}
@ -82,8 +85,6 @@ bool Vehicle::isValidSpeed(double speed) const {
void MovingObject::updateMotion(const GeoPosition& newPos, uint64_t newTime) {
// 检查时间戳
if (!positionHistory.empty() && newTime <= positionHistory.back().timestamp) {
Logger::debug("[Motion] Ignore outdated data: current=", newTime,
" last=", positionHistory.back().timestamp);
return; // 忽略重复或过时的数据
}
@ -97,16 +98,17 @@ void MovingObject::updateMotion(const GeoPosition& newPos, uint64_t newTime) {
if (positionHistory.size() >= 2) {
// 使用最近的两个点来计算速度和航向
const auto& curr = positionHistory.back();
const auto& prev = positionHistory[positionHistory.size() - 2]; // 使用倒数第二个点
const auto& prev = positionHistory[positionHistory.size() - 2];
// 计算距离和时间差
double distance = calculateDistance(prev.geo, curr.geo); // 单位:米
double timeDiff = static_cast<double>(curr.timestamp - prev.timestamp) / 1000.0; // 转换为秒
Logger::debug("[Motion] Position update: ",
"\n Current: lat=", curr.geo.latitude, ", lon=", curr.geo.longitude,
"\n Previous: lat=", prev.geo.latitude, ", lon=", prev.geo.longitude,
"\n Distance=", distance, "m, TimeDiff=", timeDiff, "s");
// 只有当位置变化足够大且时间差足够长时才更新速度和航向
// Logger::debug("[Motion] Position update: ",
// "\n Current: lat=", curr.geo.latitude, ", lon=", curr.geo.longitude,
// "\n Previous: lat=", prev.geo.latitude, ", lon=", prev.geo.longitude,
// "\n Distance=", distance, "m, TimeDiff=", timeDiff, "s");
// 只有当位置变化足够大且时间差足够长时才更新速度和航向
static const double MIN_DISTANCE = 0.1; // 最小位置变化阈值(米)
@ -124,36 +126,13 @@ void MovingObject::updateMotion(const GeoPosition& newPos, uint64_t newTime) {
} else {
speed = speed * (1 - alpha) + newSpeed * alpha; // 平滑更新
}
Logger::debug("[Motion] Speed updated: distance=", distance, "m, timeDiff=", timeDiff,
"s, newSpeed=", newSpeed, "m/s, smoothedSpeed=", speed, "m/s");
} else {
Logger::debug("[Motion] Invalid speed: ", newSpeed, "m/s (exceeds limit)");
}
// 计算新的航向
double newHeading = calculateHeading(prev.geo, curr.geo);
// 使用指数移动平均来平滑航向,增大平滑因子以加快更新
const double beta = 0.8; // 增大航向平滑因子
if (heading == 0) {
heading = newHeading; // 第一次计算
} else {
// 处理航向角的循环性0-360度
double diff = newHeading - heading;
if (diff > 180) {
diff -= 360;
} else if (diff < -180) {
diff += 360;
}
heading = fmod(heading + diff * beta + 360, 360);
}
Logger::debug("[Motion] Heading updated: newHeading=", newHeading,
"deg, smoothedHeading=", heading, "deg");
// 计算并直接更新航向,不需要平滑处理
heading = calculateHeading(prev.geo, curr.geo);
} else {
Logger::debug("[Motion] No update: distance=", distance, "m < ", MIN_DISTANCE,
"m or timeDiff=", timeDiff, "s < ", MIN_TIME, "s");
// Logger::debug("[Motion] No update: distance=", distance, "m < ", MIN_DISTANCE,
// "m or timeDiff=", timeDiff, "s < ", MIN_TIME, "s");
}
}

View File

@ -1,6 +1,6 @@
#include "detector/CollisionDetector.h"
#include "vehicle/ControllableVehicles.h"
#include "spatial/AirportBounds.h"
#include "config/AirportBounds.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "utils/Logger.h"

View File

@ -62,7 +62,7 @@ NORMAL_BRAKE_DECELERATION = 0.2 # 正常制动减速度 (每次更新减速 20%
vehicle_data = [
{
"vehicleNo": "QN001", # 无人车1西路口
"latitude": WEST_INTERSECTION["latitude"] + (DIST_50M / 111319.9), # 西路口北50米
"latitude": WEST_INTERSECTION["latitude"] + (DIST_100M / 111319.9), # 西路口北50米
"longitude": WEST_INTERSECTION["longitude"],
"time": int(time.time() * 1000),
"direction": -1, # -1表示向南
@ -101,11 +101,11 @@ class VehicleState:
self.command_reason = None # 指令原因
self.last_command_time = time.time() # 最后一次指令时间
self.traffic_light_state = None # 当前红绿灯状态
self.target_lat = None # 目标纬度
self.target_lon = None # 目标经度
def can_be_overridden_by(self, command_type):
"""
判断当前指令是否可以被新指令覆盖
"""
"""判断当前指令是否可以被新指令覆盖"""
priority_map = {
"ALERT": 5, # 告警指令,最高优先级
"RED": 4, # 红灯指令,次高优先级
@ -116,7 +116,7 @@ class VehicleState:
new_priority = priority_map.get(command_type, 0)
current_priority = priority_map.get(self.current_command, 0)
# ALERT 指令只能被 RESUME 解除
# ALERT 指令可以被 RESUME 解除
if self.current_command == "ALERT":
return command_type == "RESUME"
@ -135,7 +135,7 @@ class VehicleState:
# 其他情况按优先级判断
return new_priority >= current_priority
def update_command(self, command_type):
def update_command(self, command_type, target_lat=None, target_lon=None):
"""更新指令状态"""
priority_map = {
"ALERT": 5, # 告警指令,最高优先级
@ -145,6 +145,11 @@ class VehicleState:
"RESUME": 1 # 恢复指令,最低优先级
}
# 更新目标位置
if target_lat is not None and target_lon is not None:
self.target_lat = target_lat
self.target_lon = target_lon
# 如果是红绿灯状态,只更新状态不改变当前指令
if command_type in ["RED", "GREEN"]:
self.traffic_light_state = command_type
@ -167,12 +172,14 @@ class VehicleState:
def can_move(self):
"""检查车辆是否可以移动"""
# 如果有阻塞性指令,不能移动
if self.current_command in ["ALERT", "WARNING", "RED"]:
return False
# 如果是红灯,不能移动
if self.traffic_light_state == "RED":
return False
# 如果有告警或预警指令,不能移动
if self.current_command in ["ALERT", "WARNING"]:
return False
# 其他情况可以移动
return True
@ -188,6 +195,7 @@ class VehicleState:
- 目标速度: {self.target_speed}
- 制动模式: {self.brake_mode}
- 指令原因: {self.command_reason}
- 目标位置: ({self.target_lat}, {self.target_lon})
""")
# 添加车辆状态管理
@ -216,6 +224,8 @@ def handle_vehicle_command():
command_type = data.get("type", "").upper()
reason = data.get("reason", "").upper()
signal_state = data.get("signalState", "").upper()
target_lat = data.get("latitude", None)
target_lon = data.get("longitude", None)
print(f"收到车辆控制指令: vehicle_id={vehicle_id}, type={command_type}, reason={reason}, signal_state={signal_state}")
print(f"完整请求数据: {data}")
@ -260,27 +270,33 @@ def handle_vehicle_command():
f"new_command={command_type}, can_override={can_override}")
if not can_override:
print(f"指令优先级过低,但仍继续处理: vehicle={vehicle_id}, current_priority={vehicle_state.command_priority}, "
print(f"指令优先级过低: vehicle={vehicle_id}, current_priority={vehicle_state.command_priority}, "
f"command={command_type}")
return jsonify({
"status": "error",
"message": "Command priority too low"
}), 400
# 处理不同类型的指令
if command_type == "ALERT":
print(f"执行告警指令: vehicle_id={vehicle_id}")
vehicle_state.is_running = False
vehicle_state.target_speed = 0
vehicle_state.brake_mode = "emergency" # 告警紧急制动
# 立即更新车辆速度
if command_type in ["ALERT", "WARNING"]:
# 查找当前车辆
current_vehicle = None
for v in vehicle_data:
if v["vehicleNo"] == vehicle_id:
v["speed"] = 0
print(f"车辆 {vehicle_id} 速度已设置为0")
current_vehicle = v
break
elif command_type == "WARNING":
print(f"执行预警指令: vehicle_id={vehicle_id}")
# 执行告警指令,直接停车
print(f"执行{'紧急' if command_type == 'ALERT' else '正常'}制动: vehicle={vehicle_id}")
vehicle_state.current_command = command_type
vehicle_state.command_priority = COMMAND_PRIORITIES.get(command_type, 0)
vehicle_state.is_running = False
vehicle_state.target_speed = 0
vehicle_state.brake_mode = "normal" # 预警正常制动
vehicle_state.brake_mode = "emergency" if command_type == "ALERT" else "normal"
vehicle_state.target_lat = target_lat
vehicle_state.target_lon = target_lon
# 立即更新车辆速度
current_vehicle["speed"] = 0
elif command_type in ["RED", "GREEN"]:
print(f"执行红绿灯指令: vehicle_id={vehicle_id}, state={command_type}")
@ -289,21 +305,26 @@ def handle_vehicle_command():
elif command_type == "RESUME":
print(f"执行恢复指令: vehicle_id={vehicle_id}")
# RESUME 指令只能解除 ALERT 和 WARNING
if vehicle_state.current_command not in ["ALERT", "WARNING", None]:
print(f"车辆 {vehicle_id} 当前指令({vehicle_state.current_command})不能被 RESUME 解除")
return jsonify({
"status": "error",
"message": "Current command cannot be resumed"
}), 400
# 检查当前车辆
current_vehicle = None
for v in vehicle_data:
if v["vehicleNo"] == vehicle_id:
current_vehicle = v
break
# 恢复正常行驶
vehicle_state.is_running = True
vehicle_state.target_speed = DEFAULT_VEHICLE_SPEED
vehicle_state.brake_mode = None
# 清除限制性指令
if vehicle_state.current_command in ["ALERT", "WARNING"]:
print(f"清除限制性指令: vehicle={vehicle_id}")
vehicle_state.current_command = None
vehicle_state.command_priority = 0
vehicle_state.is_running = True
vehicle_state.target_speed = DEFAULT_VEHICLE_SPEED
vehicle_state.brake_mode = None
vehicle_state.target_lat = None
vehicle_state.target_lon = None
# 更新车辆状态
vehicle_state.update_command(command_type)
vehicle_state.update_command(command_type, target_lat, target_lon)
vehicle_state.command_reason = reason
vehicle_state.last_command_time = time.time()
@ -447,7 +468,7 @@ def update_vehicle_position(vehicle, elapsed_time):
vehicle["phase"] = 1
vehicle["direction"] = 1 # 向东
print(f"QN001 到达西路口,切换到东西移动,方向=东")
elif vehicle["direction"] == 1 and new_lat >= WEST_INTERSECTION["latitude"] + (DIST_100M / 111319.9):
elif vehicle["direction"] == 1 and new_lat >= WEST_INTERSECTION["latitude"] + (DIST_50M / 111319.9):
# 返回起点
vehicle["phase"] = 0
vehicle["direction"] = -1 # 向南
@ -472,7 +493,7 @@ def update_vehicle_position(vehicle, elapsed_time):
else: # QN002
# 无人车2西向往返西路口
new_lon = vehicle["longitude"] + (dlon * vehicle["direction"])
if new_lon >= EAST_INTERSECTION["longitude"] + (DIST_100M / (111319.9 * math.cos(math.radians(vehicle["latitude"])))):
if new_lon >= EAST_INTERSECTION["longitude"] + (DIST_150M / (111319.9 * math.cos(math.radians(vehicle["latitude"])))):
vehicle["direction"] = -1 # 向西
print(f"QN002 到达东端,切换方向=西")
elif new_lon <= EAST_INTERSECTION["longitude"] - (DIST_150M / (111319.9 * math.cos(math.radians(vehicle["latitude"])))):
@ -489,7 +510,7 @@ def update_vehicle_position(vehicle, elapsed_time):
vehicle["phase"] = 1 # 切换到南北移动
vehicle["direction"] = -1 # 向南
print(f"TQ001 到达西路口,切换到南北移动,方向=南")
elif vehicle["direction"] == 1 and new_lon >= WEST_INTERSECTION["longitude"] + (DIST_100M / (111319.9 * math.cos(math.radians(vehicle["latitude"])))):
elif vehicle["direction"] == 1 and new_lon >= WEST_INTERSECTION["longitude"] + (DIST_50M / (111319.9 * math.cos(math.radians(vehicle["latitude"])))):
vehicle["direction"] = -1 # 向西
print(f"TQ001 到达东端,切换方向=西")
vehicle["longitude"] = new_lon
@ -501,9 +522,9 @@ def update_vehicle_position(vehicle, elapsed_time):
print(f"TQ001 到达南端,切换方向=北")
elif new_lat >= WEST_INTERSECTION["latitude"]: # 返回路口
vehicle["phase"] = 0 # 切换回东西移动
vehicle["direction"] = 1 # 向
vehicle["direction"] = 1 # 向
vehicle["longitude"] = WEST_INTERSECTION["longitude"] # 重置到起始位置
print(f"TQ001 返回西路口,切换到东西移动,方向=")
print(f"TQ001 返回西路口,切换到东西移动,方向=")
vehicle["latitude"] = new_lat
print(f"TQ001 南北移动: lat={new_lat}, direction={vehicle['direction']}")
@ -520,9 +541,9 @@ def update_aircraft_position(aircraft, elapsed_time):
dlat, dlon = meters_to_degrees(distance, aircraft["latitude"])
new_lat = aircraft["latitude"] + (dlat * aircraft["direction"])
if new_lat >= EAST_INTERSECTION["latitude"] + (DIST_200M / 111319.9):
if new_lat >= EAST_INTERSECTION["latitude"] + (DIST_150M / 111319.9):
aircraft["direction"] = -1 # 向南
elif new_lat <= EAST_INTERSECTION["latitude"] - (DIST_200M / 111319.9):
elif new_lat <= EAST_INTERSECTION["latitude"] - (DIST_150M / 111319.9):
aircraft["direction"] = 1 # 向北
aircraft["latitude"] = new_lat