|
|
|
|
|
|
|
|
|
|
|
#include <mavsdk/mavsdk.h>
|
|
|
|
|
|
#include <mavsdk/plugins/info/info.h>
|
|
|
|
|
|
#include <mavsdk/plugins/param/param.h>
|
|
|
|
|
|
#include <mavsdk/plugins/action/action.h>
|
|
|
|
|
|
#include <mavsdk/plugins/telemetry/telemetry.h>
|
|
|
|
|
|
#include <mavsdk/plugins/mavlink_passthrough/mavlink_passthrough.h>
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
#include <iomanip>
|
|
|
|
|
|
#include <future>
|
|
|
|
|
|
#include <thread>
|
|
|
|
|
|
#include <chrono>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <mutex>
|
|
|
|
|
|
#include <map>
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "globals.h"
|
|
|
|
|
|
|
|
|
|
|
|
using namespace mavsdk;
|
|
|
|
|
|
using std::chrono::seconds;
|
|
|
|
|
|
using std::chrono::milliseconds;
|
|
|
|
|
|
using std::this_thread::sleep_for;
|
|
|
|
|
|
|
|
|
|
|
|
std::map<Telemetry::FlightMode, std::string> flightModeMap = {
|
|
|
|
|
|
{Telemetry::FlightMode::Unknown, "Unknown"},
|
|
|
|
|
|
{Telemetry::FlightMode::Takeoff, "Takeoff"},
|
|
|
|
|
|
{Telemetry::FlightMode::Ready, "Ready"},
|
|
|
|
|
|
{Telemetry::FlightMode::Hold, "Hold"},
|
|
|
|
|
|
{Telemetry::FlightMode::ReturnToLaunch, "Return To Launch"},
|
|
|
|
|
|
{Telemetry::FlightMode::Land, "Land"},
|
|
|
|
|
|
{Telemetry::FlightMode::Offboard, "Offboard"},
|
|
|
|
|
|
{Telemetry::FlightMode::FollowMe, "FollowMe"},
|
|
|
|
|
|
{Telemetry::FlightMode::Manual, "Manual"},
|
|
|
|
|
|
{Telemetry::FlightMode::Altctl, "Altctl"},
|
|
|
|
|
|
{Telemetry::FlightMode::Posctl, "Posctl"},
|
|
|
|
|
|
{Telemetry::FlightMode::Acro, "Acro"},
|
|
|
|
|
|
{Telemetry::FlightMode::Stabilized, "Stabilized"},
|
|
|
|
|
|
{Telemetry::FlightMode::Rattitude, "Rattitude"}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define VEHICLE_CONTROL_ACTIVE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Important multi-threaded functions,
|
|
|
|
|
|
* handling system initialization, receiving messages and sending messages.
|
|
|
|
|
|
*/
|
|
|
|
|
|
void systemHandler(System& system) {
|
|
|
|
|
|
int sysid = static_cast<int>(system.get_system_id());
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " get in Thread. (debug)" << std::endl; // debug
|
|
|
|
|
|
|
|
|
|
|
|
// Initialization
|
|
|
|
|
|
auto mavlink_passthrough = MavlinkPassthrough{system};
|
|
|
|
|
|
auto telemetry = Telemetry{system};
|
|
|
|
|
|
auto action = Action{system};
|
|
|
|
|
|
auto param = Param{system};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Store telemetry information that will pass to main thread.
|
|
|
|
|
|
std::map<std::string,std::string> telemetryInfo;
|
|
|
|
|
|
|
|
|
|
|
|
// 控制指令 已經被主迴圈轉換過一次
|
|
|
|
|
|
std::map<int, std::array<double, 2>> vehicleCommand;
|
|
|
|
|
|
|
|
|
|
|
|
// 這些變數監控 handler 的行為
|
|
|
|
|
|
gHandlerMask[sysid]["cutoff"] = 0;
|
|
|
|
|
|
gHandlerMask[sysid]["is_connected"] = 1;
|
|
|
|
|
|
bool reset = false;
|
|
|
|
|
|
|
|
|
|
|
|
// 程序執行時會用到的變數
|
|
|
|
|
|
mavlink_message_t mav_message;
|
|
|
|
|
|
mavlink_command_int_t mav_command_int;
|
|
|
|
|
|
MavlinkPassthrough::CommandLong mav_command_long;
|
|
|
|
|
|
MavlinkPassthrough::Result result_mavpass;
|
|
|
|
|
|
Action::Result result_action;
|
|
|
|
|
|
int vehicle_type;
|
|
|
|
|
|
|
|
|
|
|
|
int _counter;
|
|
|
|
|
|
double _target_lon;
|
|
|
|
|
|
double _target_lat;
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
// std::cout << "Dev Test Start" << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// // Get the info plugin for this drone
|
|
|
|
|
|
// auto atvData = system.get_autopilot_version_data();
|
|
|
|
|
|
// std::cout << "Autopilot Version Data:" << std::endl;
|
|
|
|
|
|
// std::cout << " Vendor ID: " << atvData.vendor_id << std::endl;
|
|
|
|
|
|
// std::cout << " Product ID: " << atvData.product_id << std::endl;
|
|
|
|
|
|
// std::cout << " Capabilities: " << atvData.capabilities << std::endl;
|
|
|
|
|
|
// std::cout << " Flight SW Version: " << atvData.flight_sw_version << std::endl;
|
|
|
|
|
|
// std::cout << " Middleware SW Version: " << atvData.middleware_sw_version << std::endl;
|
|
|
|
|
|
// std::cout << " OS SW Version: " << atvData.os_sw_version << std::endl;
|
|
|
|
|
|
// std::cout << " Board Version: " << atvData.board_version << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// std::array<uint8_t, 18> uid = atvData.uid2;
|
|
|
|
|
|
// std::cout << "UID: ";
|
|
|
|
|
|
// for (const auto& byte : uid) {
|
|
|
|
|
|
// std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
|
|
|
|
|
|
// }
|
|
|
|
|
|
// std::cout << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// const Telemetry::FlightMode mode_result = telemetry.flight_mode();
|
|
|
|
|
|
// std::cerr << "Vehicle Mode: " << mode_result << '\n';
|
|
|
|
|
|
|
|
|
|
|
|
// sleep_for(milliseconds(500));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // 演示一下 如何抓到 parameter
|
|
|
|
|
|
// auto get_result_i = param.get_param_int("VISO_TYPE"); // This function is blocking.
|
|
|
|
|
|
// std::cout << "Para Read: " << get_result_i.first << " : " << get_result_i.second << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// std::pair<Param::Result, float> get_result_f = {Param::Result::Unknown , 0};
|
|
|
|
|
|
// get_result_f = param.get_param_float("RNGFND_FILT"); // This function is blocking.
|
|
|
|
|
|
// std::cout << "Para Read: " << get_result_f.first << " : " << get_result_f.second << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// auto get_result = param.get_all_params(); // This function is blocking.
|
|
|
|
|
|
// auto int_p = get_result.int_params;
|
|
|
|
|
|
// for(const auto& item : int_p) {
|
|
|
|
|
|
// std::cout << item << std::endl;
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// // 抓一下 health
|
|
|
|
|
|
// auto health = telemetry.health();
|
|
|
|
|
|
// std::cout << "GYRO: " << (health.is_gyrometer_calibration_ok ? "OK" : "NG") << std::endl;
|
|
|
|
|
|
// std::cout << "Accelerometer: " << (health.is_accelerometer_calibration_ok ? "OK" : "NG") << std::endl;
|
|
|
|
|
|
// std::cout << "Magnetometer: " << (health.is_magnetometer_calibration_ok ? "OK" : "NG") << std::endl;
|
|
|
|
|
|
// std::cout << "Local position NED: " << (health.is_local_position_ok ? "OK" : "NG") << std::endl;
|
|
|
|
|
|
// std::cout << "Global position (Int): " << (health.is_global_position_ok ? "OK" : "NG") << std::endl;
|
|
|
|
|
|
// std::cout << "Home position: " << (health.is_home_position_ok ? "OK" : "NG") << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // 如果對接另一邊也是 mavsdk 這幾個 Parameter 要 provide,這邊讀看看
|
|
|
|
|
|
// get_result_i = {Param::Result::Unknown , 0};
|
|
|
|
|
|
// get_result_i = param.get_param_int("SYS_HITL"); // This function is blocking.
|
|
|
|
|
|
// std::cout << "Para Read: " << get_result_i.first << " : " << get_result_i.second << std::endl;
|
|
|
|
|
|
// get_result_i = {Param::Result::Unknown , 0};
|
|
|
|
|
|
// get_result_i = param.get_param_int("CAL_GYRO0_ID"); // This function is blocking.
|
|
|
|
|
|
// std::cout << "Para Read: " << get_result_i.first << " : " << get_result_i.second << std::endl;
|
|
|
|
|
|
// get_result_i = {Param::Result::Unknown , 0};
|
|
|
|
|
|
// get_result_i = param.get_param_int("CAL_ACC0_ID"); // This function is blocking.
|
|
|
|
|
|
// std::cout << "Para Read: " << get_result_i.first << " : " << get_result_i.second << std::endl;
|
|
|
|
|
|
// get_result_i = {Param::Result::Unknown , 0};
|
|
|
|
|
|
// get_result_i = param.get_param_int("CAL_MAG0_ID"); // This function is blocking.
|
|
|
|
|
|
// std::cout << "Para Read: " << get_result_i.first << " : " << get_result_i.second << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// // 看看 has_autopilot() 的值
|
|
|
|
|
|
// std::cout << "Has AutoPilot : " << system.has_autopilot() << std::endl; // debug
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// std::cout << "Dev Test End" << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// Put all the subscriber init in this section
|
|
|
|
|
|
if (system.has_autopilot()) {
|
|
|
|
|
|
|
|
|
|
|
|
// 用 param 去判斷是什麼種類的 system
|
|
|
|
|
|
std::pair< Param::Result, int32_t > param_int_result;
|
|
|
|
|
|
|
|
|
|
|
|
vehicle_type = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 實體機驗證
|
|
|
|
|
|
// param_int_result = param.get_param_int("BATT_OPTIONS"); // 都有的
|
|
|
|
|
|
param_int_result = param.get_param_int("BRD_SBUS_OUT"); // 只有實體機
|
|
|
|
|
|
std::cout << "BRD_SBUS_OUT Para Read: " << param_int_result.first << " : " << param_int_result.second << std::endl; // debug
|
|
|
|
|
|
if (param_int_result.first == Param::Result::Success) { vehicle_type = 2; }
|
|
|
|
|
|
// 虛擬機驗證
|
|
|
|
|
|
param_int_result = param.get_param_int("INS_USE3"); // 只有虛擬機
|
|
|
|
|
|
std::cout << "INS_USE3 Para Read: " << param_int_result.first << " : " << param_int_result.second << std::endl; // debug
|
|
|
|
|
|
if (param_int_result.first == Param::Result::Success) { vehicle_type = 1; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// =======================都用的==============================
|
|
|
|
|
|
auto set_rate_result = telemetry.set_rate_position(1.0);
|
|
|
|
|
|
// if (set_rate_result != mavsdk::Telemetry::Result::Success) {
|
|
|
|
|
|
// std::cout << "(systemHandler.cpp:systemHandler) Setting position rate failed:" << set_rate_result << std::endl;
|
|
|
|
|
|
// }
|
|
|
|
|
|
telemetry.subscribe_position([&system, &telemetryInfo](Telemetry::Position position) {
|
|
|
|
|
|
// 轉換數字到字串用的暫存變數
|
|
|
|
|
|
std::ostringstream num_str_ss;
|
|
|
|
|
|
|
|
|
|
|
|
// std::cout << "System ID: " << sysid << " Altitude: " << position.relative_altitude_m << " m\n"; // debug
|
|
|
|
|
|
// Store telemetry information
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(4) << position.relative_altitude_m;
|
|
|
|
|
|
telemetryInfo["drone_alt"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(8) << position.latitude_deg;
|
|
|
|
|
|
telemetryInfo["vehicle_lat"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(8) << position.longitude_deg;
|
|
|
|
|
|
telemetryInfo["vehicle_lon"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
telemetry.subscribe_raw_gps([&system, &telemetryInfo](Telemetry::RawGps rawGps) {
|
|
|
|
|
|
// 轉換數字到字串用的暫存變數
|
|
|
|
|
|
std::ostringstream num_str_ss;
|
|
|
|
|
|
|
|
|
|
|
|
// Store telemetry information
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(4) << rawGps.velocity_m_s;
|
|
|
|
|
|
telemetryInfo["vehicle_speed"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
telemetry.subscribe_heading([&system, &telemetryInfo](Telemetry::Heading heading) {
|
|
|
|
|
|
// 轉換數字到字串用的暫存變數
|
|
|
|
|
|
std::ostringstream num_str_ss;
|
|
|
|
|
|
|
|
|
|
|
|
// Store telemetry information
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(4) << heading.heading_deg;
|
|
|
|
|
|
telemetryInfo["vehicle_head"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (vehicle_type == 2) {
|
|
|
|
|
|
set_rate_result = telemetry.set_rate_battery(1.0);
|
|
|
|
|
|
if (set_rate_result != mavsdk::Telemetry::Result::Success) {
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) Setting battery rate failed:" << set_rate_result << std::endl;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
telemetry.subscribe_battery([&system, &telemetryInfo](Telemetry::Battery battery) {
|
|
|
|
|
|
// 轉換數字到字串用的暫存變數
|
|
|
|
|
|
std::ostringstream num_str_ss;
|
|
|
|
|
|
|
|
|
|
|
|
// Store telemetry information
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(4) << battery.remaining_percent;
|
|
|
|
|
|
telemetryInfo["vehicle_bat_perc"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(4) << battery.voltage_v;
|
|
|
|
|
|
telemetryInfo["vehicle_bat_volt"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
telemetry.subscribe_armed([&system, &telemetryInfo](bool is_armed) {
|
|
|
|
|
|
if(is_armed){
|
|
|
|
|
|
telemetryInfo["drone_arm"] = "1";
|
|
|
|
|
|
}else{
|
|
|
|
|
|
telemetryInfo["drone_arm"] = "0";
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// =======================只有無人機==============================
|
|
|
|
|
|
if (vehicle_type >= 1) {
|
|
|
|
|
|
// set_rate_result = telemetry.set_rate_attitude_euler(1.0); // only in v2.0
|
|
|
|
|
|
// if (set_rate_result != mavsdk::Telemetry::Result::Success) {
|
|
|
|
|
|
// std::cout << "(systemHandler.cpp:systemHandler) Setting euler rate failed:" << set_rate_result << std::endl;
|
|
|
|
|
|
// }
|
|
|
|
|
|
telemetry.subscribe_attitude_euler([&system, &telemetryInfo](Telemetry::EulerAngle eulerAngle) {
|
|
|
|
|
|
// 轉換數字到字串用的暫存變數
|
|
|
|
|
|
std::ostringstream num_str_ss;
|
|
|
|
|
|
|
|
|
|
|
|
// Store telemetry information
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(4) << eulerAngle.roll_deg;
|
|
|
|
|
|
telemetryInfo["drone_roll"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(4) << eulerAngle.pitch_deg;
|
|
|
|
|
|
telemetryInfo["drone_pitch"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(4) << eulerAngle.yaw_deg;
|
|
|
|
|
|
telemetryInfo["drone_yaw"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
set_rate_result = telemetry.set_rate_in_air(1.0);
|
|
|
|
|
|
if (set_rate_result != mavsdk::Telemetry::Result::Success) {
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) Setting in_air rate failed:" << set_rate_result << std::endl;
|
|
|
|
|
|
}
|
|
|
|
|
|
telemetry.subscribe_in_air([&system, &telemetryInfo](bool in_air) {
|
|
|
|
|
|
if(in_air){
|
|
|
|
|
|
telemetryInfo["drone_air"] = "1";
|
|
|
|
|
|
}else{
|
|
|
|
|
|
telemetryInfo["drone_air"] = "0";
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
telemetry.subscribe_flight_mode([&system, &telemetryInfo](Telemetry::FlightMode fightMode) {
|
|
|
|
|
|
telemetryInfo["vehicle_mode"] = flightModeMap[fightMode];
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// =======================只有車子載具==============================
|
|
|
|
|
|
|
|
|
|
|
|
if (vehicle_type == 0) {
|
|
|
|
|
|
telemetry.subscribe_status_text([&system, &telemetryInfo]
|
|
|
|
|
|
(Telemetry::StatusText statusText) {
|
|
|
|
|
|
// 轉換數字到字串用的暫存變數
|
|
|
|
|
|
std::ostringstream num_str_ss;
|
|
|
|
|
|
std::istringstream _iss(statusText.text);
|
|
|
|
|
|
// 為了分析 statusText 字串的兩個暫存變數
|
|
|
|
|
|
std::string _token;
|
|
|
|
|
|
|
|
|
|
|
|
// std::cout << "(systemHandler.cpp:systemHandler) status_text: " << statusText.type << " ; " << statusText.text << std::endl; // debug
|
|
|
|
|
|
if(statusText.type == Telemetry::StatusTextType::Info) {
|
|
|
|
|
|
while (std::getline(_iss, _token, ',')) {
|
|
|
|
|
|
if (_token.at(0) == 'T') {
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(2) << std::stof(_token.substr(1));
|
|
|
|
|
|
telemetryInfo["vehicle_bat_Temp"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
} else if (_token.at(0) == 'I') {
|
|
|
|
|
|
num_str_ss << std::fixed << std::setprecision(2) << std::stof(_token.substr(1));
|
|
|
|
|
|
telemetryInfo["vehicle_bat_current"] = num_str_ss.str();
|
|
|
|
|
|
num_str_ss.str("");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// std::string testA;
|
|
|
|
|
|
std::ostringstream testA;
|
|
|
|
|
|
|
|
|
|
|
|
// Wait Until telemetryInfo get something. and if nothing get from System for 10 sec will cut off this connection.
|
|
|
|
|
|
_counter = 0;
|
|
|
|
|
|
while(telemetryInfo.empty()){
|
|
|
|
|
|
sleep_for(seconds(1));
|
|
|
|
|
|
if(_counter++ > 10) {
|
|
|
|
|
|
reset = true;
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " waiting too long without any coming info." << std::endl;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (vehicle_type) {
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
telemetryInfo["vehicle_type"] = "Real";
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
telemetryInfo["vehicle_type"] = "SITL";
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
telemetryInfo["vehicle_type"] = "Self";
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Loop
|
|
|
|
|
|
while(system.is_connected() & !reset) {
|
|
|
|
|
|
|
|
|
|
|
|
// Send Telemetry Data
|
|
|
|
|
|
gTeleMtx.lock();
|
|
|
|
|
|
gTelemetryInfo[sysid] = telemetryInfo;
|
|
|
|
|
|
gTeleMtx.unlock();
|
|
|
|
|
|
|
|
|
|
|
|
// 取得來自主迴圈的指令 並清空
|
|
|
|
|
|
vehicleCommand = gVehicleCommand[sysid];
|
|
|
|
|
|
gComMtx.lock();
|
|
|
|
|
|
gVehicleCommand[sysid].clear();
|
|
|
|
|
|
gComMtx.unlock();
|
|
|
|
|
|
|
|
|
|
|
|
// Handler Command
|
|
|
|
|
|
reset = (gHandlerMask[sysid]["cutoff"] != 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Vehicle Command
|
|
|
|
|
|
for ( auto& oneVehicleCommand : vehicleCommand ) {
|
|
|
|
|
|
if (vehicle_type == 0) { break; } // 不是飛機不吃指令
|
|
|
|
|
|
switch (oneVehicleCommand.first) {
|
|
|
|
|
|
case -1 :
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " Get Error command_type! " << std::endl;
|
|
|
|
|
|
telemetryInfo["StatusText"] = "command_type Error!";
|
|
|
|
|
|
break;
|
|
|
|
|
|
case -2 :
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " Get Error command_para! " << std::endl;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
// Here deal with the function of Change Mode
|
|
|
|
|
|
case 1 :
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " Get Command Change Mode , " \
|
|
|
|
|
|
<< "Para1 : " << std::to_string(oneVehicleCommand.second[0]) \
|
|
|
|
|
|
<< ", Para2 : " << std::to_string(oneVehicleCommand.second[1]) << std::endl; // debug
|
|
|
|
|
|
#ifdef VEHICLE_CONTROL_ACTIVE
|
|
|
|
|
|
mav_command_long.target_sysid = sysid;
|
|
|
|
|
|
mav_command_long.target_compid = MAV_COMP_ID_AUTOPILOT1; // 這行指 component id = 1
|
|
|
|
|
|
mav_command_long.command = 176; // MAV_CMD_DO_SET_MODE
|
|
|
|
|
|
mav_command_long.param1 = 1; // 固定是 1
|
|
|
|
|
|
mav_command_long.param2 = static_cast<int>(oneVehicleCommand.second[0]); // mode
|
|
|
|
|
|
|
|
|
|
|
|
result_mavpass = mavlink_passthrough.send_command_long(mav_command_long); // 送出指令
|
|
|
|
|
|
// telemetryInfo["StatusText"] = result_mavpass;
|
|
|
|
|
|
std::cout << " ACK REL: " << result_mavpass << std::endl; // dev
|
|
|
|
|
|
// testA << result_mavpass;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
// Here deal with the function of Action Arm
|
|
|
|
|
|
case 11 :
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " Get Command Arm, " \
|
|
|
|
|
|
<< "Para1 : " << std::to_string(oneVehicleCommand.second[0]) \
|
|
|
|
|
|
<< ", Para2 : " << std::to_string(oneVehicleCommand.second[1]) << std::endl; // debug
|
|
|
|
|
|
#ifdef VEHICLE_CONTROL_ACTIVE
|
|
|
|
|
|
result_action = action.arm();
|
|
|
|
|
|
// telemetryInfo["StatusText"] = result_mavpass;
|
|
|
|
|
|
std::cout << " ACK REL: " << result_action << std::endl; // dev
|
|
|
|
|
|
#endif
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
// Here deal with the function of Action Takeoff
|
|
|
|
|
|
case 12 :
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " Get Command Takeoff, " \
|
|
|
|
|
|
<< "Para1 : " << std::to_string(oneVehicleCommand.second[0]) \
|
|
|
|
|
|
<< ", Para2 : " << std::to_string(oneVehicleCommand.second[1]) << std::endl; // debug
|
|
|
|
|
|
#ifdef VEHICLE_CONTROL_ACTIVE
|
|
|
|
|
|
result_action = action.takeoff();
|
|
|
|
|
|
// telemetryInfo["StatusText"] = result_mavpass;
|
|
|
|
|
|
std::cout << " ACK REL: " << result_action << std::endl; // dev
|
|
|
|
|
|
_target_lat = std::stof(telemetryInfo["vehicle_lat"]);
|
|
|
|
|
|
_target_lon = std::stof(telemetryInfo["vehicle_lon"]);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
// Here deal with the function of change height
|
|
|
|
|
|
case 13 :
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " Get Command Change Height, " \
|
|
|
|
|
|
<< "Para1 : " << std::to_string(oneVehicleCommand.second[0]) \
|
|
|
|
|
|
<< ", Para2 : " << std::to_string(oneVehicleCommand.second[1]) << std::endl; // debug
|
|
|
|
|
|
#ifdef VEHICLE_CONTROL_ACTIVE
|
|
|
|
|
|
// 若飛機滯空時 用 goto 方法到指定高度
|
|
|
|
|
|
// 若飛機在地時 用 set_takeoff_altitude 設定起飛高度
|
|
|
|
|
|
if (telemetryInfo["drone_air"] == "0") {
|
|
|
|
|
|
action.set_takeoff_altitude(static_cast<int>(oneVehicleCommand.second[0])); // mavsdk show error but still effect well (?)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
mav_command_int.target_system = sysid; // Target system ID
|
|
|
|
|
|
mav_command_int.target_component = MAV_COMP_ID_AUTOPILOT1; // Target component ID
|
|
|
|
|
|
mav_command_int.command = MAV_CMD_DO_REPOSITION; // Command ID
|
|
|
|
|
|
mav_command_int.frame = MAV_FRAME_GLOBAL_RELATIVE_ALT; // Coordinate system
|
|
|
|
|
|
mav_command_int.x = _target_lat * 1E7; // Target latitude
|
|
|
|
|
|
mav_command_int.y = _target_lon * 1E7; // Target longitude
|
|
|
|
|
|
mav_command_int.z = static_cast<float>(oneVehicleCommand.second[0]); // Target altitude
|
|
|
|
|
|
mavlink_msg_command_int_encode(mavlink_passthrough.get_our_sysid(),
|
|
|
|
|
|
mavlink_passthrough.get_our_compid(),
|
|
|
|
|
|
&mav_message,
|
|
|
|
|
|
&mav_command_int);
|
|
|
|
|
|
// mavlink_passthrough.send_message(mav_message);
|
|
|
|
|
|
result_mavpass = mavlink_passthrough.send_message(mav_message);
|
|
|
|
|
|
std::cout << " ACK REL: " << result_mavpass << std::endl; // dev
|
|
|
|
|
|
std::cout << "x: " << std::to_string(_target_lon) << std::endl; // dev
|
|
|
|
|
|
std::cout << "y: " << std::to_string(_target_lat) << std::endl; // dev
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
// Here deal with the function of GOTO
|
|
|
|
|
|
case 21 :
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " Get Command GoTo, " \
|
|
|
|
|
|
<< "Para1 : " << std::to_string(oneVehicleCommand.second[0]) \
|
|
|
|
|
|
<< ", Para2 : " << std::to_string(oneVehicleCommand.second[1]) << std::endl; // debug
|
|
|
|
|
|
#ifdef VEHICLE_CONTROL_ACTIVE
|
|
|
|
|
|
mav_command_int.target_system = sysid; // Target system ID
|
|
|
|
|
|
mav_command_int.target_component = MAV_COMP_ID_AUTOPILOT1; // Target component ID
|
|
|
|
|
|
mav_command_int.command = MAV_CMD_DO_REPOSITION; // Command ID
|
|
|
|
|
|
mav_command_int.frame = MAV_FRAME_GLOBAL_RELATIVE_ALT; // Coordinate system
|
|
|
|
|
|
mav_command_int.x = oneVehicleCommand.second[0] * 1E7; // Target latitude
|
|
|
|
|
|
mav_command_int.y = oneVehicleCommand.second[1] * 1E7; // Target longitude
|
|
|
|
|
|
mav_command_int.z = std::stof(telemetryInfo["drone_alt"]); // Target altitude
|
|
|
|
|
|
mavlink_msg_command_int_encode(mavlink_passthrough.get_our_sysid(),
|
|
|
|
|
|
mavlink_passthrough.get_our_compid(),
|
|
|
|
|
|
&mav_message,
|
|
|
|
|
|
&mav_command_int);
|
|
|
|
|
|
result_mavpass = mavlink_passthrough.send_message(mav_message);
|
|
|
|
|
|
_target_lon = oneVehicleCommand.second[1];
|
|
|
|
|
|
_target_lat = oneVehicleCommand.second[0];
|
|
|
|
|
|
// telemetryInfo["StatusText"] = result_mavpass;
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << " ACK REL: " << result_mavpass << std::endl; // dev
|
|
|
|
|
|
#endif
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// for purpose
|
|
|
|
|
|
sleep_for(milliseconds(100));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Thread Terminate
|
|
|
|
|
|
std::cout << "(systemHandler.cpp:systemHandler) Thread Out " << sysid << std::endl; //debug
|
|
|
|
|
|
|
|
|
|
|
|
// Destroy
|
|
|
|
|
|
gHandlerMask[sysid]["is_connected"] = 0;
|
|
|
|
|
|
}
|