111 lines
4.0 KiB
C++
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;
|
|
}
|
|
} |