Обновить pilot.cpp

This commit is contained in:
2025-04-05 04:18:22 +07:00
parent cb788441ad
commit 995048bfdc

148
pilot.cpp
View File

@@ -6,24 +6,29 @@
// Настройки // Настройки
constexpr float Ki = 0.03f; constexpr float Ki = 0.03f;
constexpr float target_height = 65.f; constexpr float waypoint_radius = 3.f;
constexpr float waypoint_radius = 1.5f;
constexpr float pitch_constraint = 20.f; constexpr float pitch_constraint = 20.f;
constexpr float yaw_constraint = 20.f; constexpr float yaw_constraint = 20.f;
// https://github.com/GyverLibs/AsyncStream @ 1.1
// https://github.com/bblanchon/ArduinoJson @ 7.3.1
struct WayPoint { struct WayPoint {
float x; float x;
float z; float z;
float y;
}; };
std::vector wayPoints = { std::vector<WayPoint> wayPoints = {};
WayPoint{.x = -480.f, .z = 85.f},
WayPoint{.x = -30.f, .z = 500.f},
WayPoint{.x = 150.f, .z = 330.f},
WayPoint{.x = 150.f, .z = 5.f},
};
JsonDocument doc; JsonDocument doc;
bool cargoDrop = false;
String HandleMessages();
bool ReceiveNewMessage(String &err);
void RouteNewMessage(String &err);
void HandleNewWaypoints(String &err);
void HandleDropCargo();
void Task_solution::setup(HardwareSerial *a_Serial) { void Task_solution::setup(HardwareSerial *a_Serial) {
debug_serial = a_Serial; debug_serial = a_Serial;
@@ -31,10 +36,11 @@ void Task_solution::setup(HardwareSerial *a_Serial) {
Serial2.begin(115200); Serial2.begin(115200);
} }
void printDebugMessage(const String &_) {
}
float distance(const float x1, const float y1, const float x2, const float y2) { float distance(const float x1, const float y1, const float x2, const float y2) {
return static_cast<float>( return sqrtf(powf(x2 - x1, 2.f) + powf(y2 - y1, 2.f));
sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2))
);
} }
bool isEqual(const float a, const float b, const float accuracy) { bool isEqual(const float a, const float b, const float accuracy) {
@@ -69,8 +75,10 @@ SignalBody Task_solution::loop(Skywalker2015PacketTelemetry a_telemetry) {
// _Point_Index = GetNowPointIndex(a_telemetry.L, a_telemetry.Z, a_telemetry.H); // _Point_Index = GetNowPointIndex(a_telemetry.L, a_telemetry.Z, a_telemetry.H);
const float target_x = wayPoints[_Point_Index].x; const float target_x = wayPoints[_Point_Index].x;
const float target_y = wayPoints[_Point_Index].z; const float target_y = wayPoints[_Point_Index].z;
const float target_height = wayPoints[_Point_Index].y;
const auto target_psi = static_cast<float>( const auto target_psi = static_cast<float>(
-degrees(atan2(target_y - a_telemetry.Z, target_x - a_telemetry.L)) -degrees(atan2f(target_y - a_telemetry.Z, target_x - a_telemetry.L))
); );
_ans.Gamma_direct = GammaReg(a_telemetry.Psi, target_psi); _ans.Gamma_direct = GammaReg(a_telemetry.Psi, target_psi);
@@ -84,6 +92,17 @@ SignalBody Task_solution::loop(Skywalker2015PacketTelemetry a_telemetry) {
} }
} }
if (const String err = HandleMessages(); !err.isEmpty()) {
printtoDebugSerial(err);
}
if (cargoDrop) {
// Propagate changed state
cargo_drop = cargoDrop;
cargoDrop = false;
}
// Отправляем команды на симулятор // Отправляем команды на симулятор
// БЛА будет пытаться выдерживать заданные углы крена и тангажа // БЛА будет пытаться выдерживать заданные углы крена и тангажа
return _ans; return _ans;
@@ -111,12 +130,23 @@ float Task_solution::HeightReg(float Yg, float Vy, float Hz) {
return Pitch_direct; return Pitch_direct;
} }
String HandleMessages() {
String err;
if (ReceiveNewMessage(err)) {
RouteNewMessage(err);
}
return err;
}
String uartBuffer; String uartBuffer;
bool ReceivedNewMessage(std::string &err) { bool ReceiveNewMessage(String &err) {
while (Serial.available() > 0) { while (Serial.available() > 0) {
const char c = Serial.read(); if (const char c = Serial.read(); c == '\n') { // Ожидание конца строки
uartBuffer += c; if (uartBuffer.length() <= 1) {
if (c == '\n') { // Ожидание конца строки printDebugMessage("Invalid message");
}
const DeserializationError error = deserializeJson(doc, uartBuffer); const DeserializationError error = deserializeJson(doc, uartBuffer);
uartBuffer = ""; // Очистка буфера uartBuffer = ""; // Очистка буфера
if (error.code() != DeserializationError::Ok) { if (error.code() != DeserializationError::Ok) {
@@ -124,67 +154,49 @@ bool ReceivedNewMessage(std::string &err) {
return false; return false;
} }
return true; return true;
} else {
uartBuffer += c;
} }
} }
return false; return false;
} }
void printDebugMessage(const String &_) { void RouteNewMessage(String &err) {
} if (!doc["cmd"].is<String>()) {
err = "Required 'cmd' field";
void ProcessNewMessage(std::string &err) { printDebugMessage(err);
if (!doc.containsKey("path")) {
err = "Missing 'path' key";
printDebugMessage(String(err.c_str()));
return; return;
} }
// Получение массива точек if (doc["cmd"] == "add_wp") {
HandleNewWaypoints(err);
} else if (doc["cmd"] == "drop") {
HandleDropCargo();
} else {
err = "Unknown command";
}
}
void HandleNewWaypoints(String &err) {
if (!doc["path"].is<JsonArray>()) {
err = "Required 'path' field";
printDebugMessage(err);
return;
}
const auto pointsArray = doc["path"].as<JsonArray>(); const auto pointsArray = doc["path"].as<JsonArray>();
if (pointsArray.isNull()) { for (const auto &p : pointsArray) {
err = "'wp' is not an array"; if (!p["x"].is<float>() || !p["y"].is<float>() || !p["z"].is<float>()) {
printDebugMessage(String(err.c_str())); err = "Missing point field";
return; continue;
}
std::vector<WayPoint> newWayPoints;
// Обход всех элементов массива
for (JsonVariant value : pointsArray) {
auto point = value.as<JsonObject>();
if (point.isNull()) {
err = "Invalid waypoint format";
printDebugMessage(String(err.c_str()));
return;
} }
WayPoint point{};
// Проверка наличия полей x и z point.x = p["x"].as<float>();
if (!point.containsKey("x") || !point.containsKey("z")) { point.z = p["y"].as<float>();
err = "Waypoint missing x or z field"; point.y = p["z"].as<float>();
printDebugMessage(String(err.c_str())); wayPoints.push_back(point);
return;
}
// Проверка типов данных
if (!point["x"].is<float>() || !point["z"].is<float>()) {
err = "Invalid x or z data type";
printDebugMessage(String(err.c_str()));
return;
}
// Извлечение значений
float x = point["x"];
float z = point["z"];
newWayPoints.push_back(WayPoint{.x = x, .z = z});
} }
}
// Проверка на пустой массив
if (newWayPoints.empty()) { void HandleDropCargo() {
err = "No waypoints provided"; cargoDrop = true;
printDebugMessage(String(err.c_str()));
return;
}
wayPoints = std::move(newWayPoints);
err.clear(); // Успешное выполнение без ошибок
} }