QDAirPortTestSystemBackend/src/vehicle/ControllableVehicles.cpp
2026-01-27 15:24:05 +08:00

111 lines
4.0 KiB
C++

#include "ControllableVehicles.h"
#include "utils/Logger.h"
#include <fstream>
#include <stdexcept>
// 定义静态成员变量
ControllableVehicles* ControllableVehicles::instance_ = nullptr;
ControllableVehicles& ControllableVehicles::getInstance() {
if (instance_ == nullptr) {
instance_ = new ControllableVehicles("config/unmanned_vehicles.json");
}
return *instance_;
}
ControllableVehicles::ControllableVehicles(const std::string& configFile)
: http_client_(std::make_unique<HTTPClient>()) {
if (!configFile.empty()) {
loadConfig(configFile);
}
}
ControllableVehicles::~ControllableVehicles() {
if (instance_ != nullptr) {
delete instance_;
instance_ = nullptr;
}
}
const std::vector<ControllableVehicleConfig>& ControllableVehicles::getVehicles() const {
return vehicles_;
}
const ControllableVehicleConfig* ControllableVehicles::findVehicle(const std::string& vehicleNo) const {
auto iter = std::find_if(vehicles_.begin(), vehicles_.end(),
[&](const ControllableVehicleConfig& config) {
return config.vehicleNo == vehicleNo;
});
return iter != vehicles_.end() ? &(*iter) : nullptr;
}
bool ControllableVehicles::isControllable(const std::string& vehicleNo) const {
// 查找车辆配置
auto* config = findVehicle(vehicleNo);
if (!config) {
return false;
}
// 只有无人车类型是可控的
return config->type == "UNMANNED";
}
bool ControllableVehicles::loadConfig(const std::string& configFile) {
try {
std::ifstream file(configFile);
if (!file.is_open()) {
Logger::error("Failed to open controllable vehicles config file: ", configFile);
return false;
}
nlohmann::json jsonConfig;
file >> jsonConfig;
for (const auto& item : jsonConfig["vehicles"]) {
ControllableVehicleConfig config;
config.vehicleNo = item["vehicleNo"].get<std::string>();
config.type = item["type"].get<std::string>();
config.ip = item["ip"].get<std::string>();
config.port = item["port"].get<int>();
vehicles_.push_back(config);
Logger::info("Added vehicle: ", config.vehicleNo, ", type: ", config.type);
}
Logger::info("Loaded ", vehicles_.size(), " controllable vehicles");
return true;
} catch (const std::exception& e) {
Logger::error("Failed to parse controllable vehicles config: ", e.what());
return false;
}
}
bool ControllableVehicles::sendCommand(const std::string& vehicleNo, const VehicleCommand& command) {
auto vehicle = findVehicle(vehicleNo);
if (!vehicle) {
Logger::error("Vehicle ", vehicleNo, " not found in controllable vehicles");
return false;
}
try {
bool success = http_client_->sendCommand(vehicle->ip, vehicle->port, command);
if (success) {
Logger::info("Successfully sent command to vehicle ", vehicleNo, ": ",
command.type == CommandType::SIGNAL ? "SIGNAL" :
command.type == CommandType::ALERT ? "ALERT" :
command.type == CommandType::WARNING ? "WARNING" :
command.type == CommandType::PARKING ? "PARKING" : "RESUME",
"/",
command.reason == CommandReason::TRAFFIC_LIGHT ? "TRAFFIC_LIGHT" :
command.reason == CommandReason::AIRCRAFT_CROSSING ? "AIRCRAFT_CROSSING" :
command.reason == CommandReason::SPECIAL_VEHICLE ? "SPECIAL_VEHICLE" :
command.reason == CommandReason::AIRCRAFT_PUSH ? "AIRCRAFT_PUSH" :
command.reason == CommandReason::PARKING_SIDE ? "PARKING_SIDE" : "RESUME_TRAFFIC");
} else {
Logger::error("Failed to send command to vehicle ", vehicleNo);
}
return success;
} catch (const std::exception& e) {
Logger::error("Exception while sending command to vehicle ", vehicleNo, ": ", e.what());
return false;
}
}