first command online
第一個版本
This commit is contained in:
+3
-2
@@ -34,6 +34,7 @@ gHandlerMask
|
||||
|
||||
|
||||
std::map<int, std::map<std::string, std::string>> gTelemetryInfo;
|
||||
std::map<int, std::map<std::string, std::array<double, 2>>> gVehicleCommand;
|
||||
std::map<int, std::map<int, std::array<double, 2>>> gVehicleCommand;
|
||||
std::map<int, std::map<std::string, int>> gHandlerMask;
|
||||
std::mutex gTeleMtx;
|
||||
std::mutex gTeleMtx;
|
||||
std::mutex gComMtx;
|
||||
+2
-1
@@ -7,8 +7,9 @@
|
||||
#include <mutex>
|
||||
|
||||
extern std::map<int, std::map<std::string, std::string>> gTelemetryInfo;
|
||||
extern std::map<int, std::map<std::string, std::array<double, 2>>> gVehicleCommand;
|
||||
extern std::map<int, std::map<int, std::array<double, 2>>> gVehicleCommand;
|
||||
extern std::map<int, std::map<std::string, int>> gHandlerMask;
|
||||
extern std::mutex gTeleMtx;
|
||||
extern std::mutex gComMtx;
|
||||
|
||||
#endif
|
||||
+56
-2
@@ -52,6 +52,44 @@ int initializeParameters(const std::string& filePath, MavInitParameter& initSett
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 這裡會對 mysql 上的指令 做第一次轉換,再放給 systemHandler 做第二次轉換
|
||||
std::map<std::string, int> commandTypeMap = {
|
||||
{"aGuided", 101},
|
||||
{"aLand", 102},
|
||||
{"aArm", 103},
|
||||
{"aSetHeight", 104},
|
||||
{"aTakeoff", 105},
|
||||
{"aGoto", 106},
|
||||
};
|
||||
|
||||
std::map<int, std::array<double, 2>> decodeMysqlCommand(std::string commandType, std::string Para1, std::string Para2) {
|
||||
// std::cout << commandType << ", " << Para1 << ", " << Para2 <<std::endl; // for Dev
|
||||
std::map<std::string, std::function<void()>> commandMapFunc;
|
||||
std::map<int, std::array<double, 2>> result;
|
||||
|
||||
switch (commandTypeMap[commandType]) {
|
||||
case 101: // aGuided
|
||||
result[1] = {4,0}; // means change mode to 4
|
||||
break;
|
||||
case 102: // aLand
|
||||
result[1] = {9,0}; // means change mode to 9
|
||||
break;
|
||||
case 103: // aArm
|
||||
result[11] = {0,0}; // means action arm
|
||||
break;
|
||||
case 104: // aSetHeight
|
||||
result[13] = {std::stof(Para1),0}; // means change height to Para1
|
||||
break;
|
||||
case 105: // aTakeoff
|
||||
result[12] = {0,0}; // means action takeoff
|
||||
break;
|
||||
case 106: // aGoto
|
||||
result[21] = {std::stof(Para1),std::stof(Para2)}; // means goto
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
@@ -226,8 +264,24 @@ int main(int argc, char** argv)
|
||||
break;
|
||||
}
|
||||
|
||||
// 把 MAVSDK 從無人機接到的 telemetry 放到 mysql
|
||||
aTelemetryInfo = gTelemetryInfo[handlerInfo.systemID];
|
||||
|
||||
// TODO: 把 mysql 的指令放給 MAVSDK 準備傳到無人機
|
||||
sqlString = "SELECT command_type,command_para1,command_para2 FROM NodeRed_one WHERE SerialNo = " \
|
||||
+ std::to_string(handlerInfo.mysqlSN) + " AND command_type IS NOT NULL;";
|
||||
res = stmt->executeQuery(sqlString);
|
||||
if (res->next()) {
|
||||
// 有讀到資料的話 就直接更新 gVehicleCommand
|
||||
gComMtx.lock();
|
||||
gVehicleCommand[handlerInfo.systemID] = decodeMysqlCommand(res->getString(1), res->getString(2), res->getString(3));
|
||||
gComMtx.unlock();
|
||||
// 本來想要把清空 mysql 的 command 欄位跟下面更新 telemetry 放一起 但是這樣會把程式複雜度弄上去 所以算了
|
||||
sqlString = "UPDATE NodeRed_one SET command_type = NULL, command_para1 = NULL, command_para2 = NULL WHERE SerialNo = " \
|
||||
+ std::to_string(handlerInfo.mysqlSN) + ";";
|
||||
stmt->execute(sqlString);
|
||||
}
|
||||
|
||||
// 把 MAVSDK 從無人機接到的 telemetry 放到 mysql
|
||||
if(aTelemetryInfo.size() != 0) {
|
||||
sqlString = "UPDATE NodeRed_one SET ";
|
||||
for(const auto& pair : aTelemetryInfo) {
|
||||
@@ -242,7 +296,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
|
||||
// TODO: 把 mysql 的指令放給 MAVSDK 準備傳到無人機
|
||||
|
||||
|
||||
|
||||
// reset = true; //debug
|
||||
|
||||
@@ -45,7 +45,10 @@ struct MavInitParameter {
|
||||
enum class systemHandlerState {
|
||||
Init, // 剛剛交給 systemHandler 去處理
|
||||
Prologue, // 建立了 mysql row 並取得 serialNo
|
||||
|
||||
Transmit, // 正在傳送指令到載具
|
||||
Ready, // 收到第一筆並放到 telemetryInfo 後
|
||||
Busy, // 載具正在執行上一次指令
|
||||
Disconnected, // mavsdk 判斷該系統斷線了
|
||||
Terminate, // 準備要從管理列表中刪除
|
||||
// Void
|
||||
|
||||
+169
-16
@@ -26,30 +26,60 @@ 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) {
|
||||
// Initialization
|
||||
auto telemetry = Telemetry{system};
|
||||
auto action = Action{system};
|
||||
auto param = Param{system};
|
||||
int sysid = static_cast<int>(system.get_system_id());
|
||||
std::cout << "(systemHandler.cpp:systemHandler) System " << sysid << " get in Thread. (debug)" << std::endl; // debug
|
||||
|
||||
// Store telemetry information
|
||||
std::map<std::string,std::string> telemetryInfo;
|
||||
// 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;
|
||||
|
||||
//
|
||||
// 程序執行時會用到的變數
|
||||
int _counter;
|
||||
|
||||
|
||||
mavlink_message_t mav_message;
|
||||
mavlink_set_position_target_global_int_t set_position_target_global_int;
|
||||
MavlinkPassthrough::CommandLong mav_command_long;
|
||||
MavlinkPassthrough::Result result_mavpass;
|
||||
Action::Result result_action;
|
||||
|
||||
//
|
||||
std::cout << "Dev Test Start" << std::endl;
|
||||
@@ -75,18 +105,46 @@ void systemHandler(System& system) {
|
||||
const Telemetry::FlightMode mode_result = telemetry.flight_mode();
|
||||
std::cerr << "Vehicle Mode: " << mode_result << '\n';
|
||||
|
||||
// auto mavlink_passthrough = MavlinkPassthrough{system};
|
||||
// mavlink_command_long_t command;
|
||||
// command.target_system = sysid;
|
||||
// command.target_component = MAV_COMP_ID_AUTOPILOT1;
|
||||
// command.command = MAV_CMD_REQUEST_MESSAGE;
|
||||
// command.param1 = 1;
|
||||
|
||||
std::cout << " Set Mode Test " << std::endl;
|
||||
sleep_for(milliseconds(1500));
|
||||
|
||||
|
||||
// sleep_for(milliseconds(1500));
|
||||
// action.set_takeoff_altitude(10);
|
||||
// std::cout << "ARM...\n";
|
||||
// action.arm();
|
||||
// sleep_for(seconds(1));
|
||||
|
||||
// std::cout << "Taking off...\n";
|
||||
// action.takeoff();
|
||||
// sleep_for(seconds(10));
|
||||
|
||||
// std::cout << "GoTo...\n";
|
||||
// // auto result_ackFromAction = action.goto_location(24.119289235158828, 120.67216137689361,30,180);
|
||||
|
||||
// 測試GOTO
|
||||
// mavlink_message_t message;
|
||||
// MavlinkPassthrough::CommandLong command;
|
||||
// command.target_sysid = sysid;
|
||||
// command.target_compid = MAV_COMP_ID_AUTOPILOT1; // 這行指 component id = 1
|
||||
// command.command = MAV_CMD_DO_REPOSITION;
|
||||
// command.param1 = 5; // Speed
|
||||
// command.param2 = 0; // IF change to GUILDED mode ?
|
||||
// command.param3 = 0; // Radius
|
||||
// command.param4 = 0; // Yaw
|
||||
// command.param5 = 24.119289235158828; // Latitude
|
||||
// command.param6 = 120.67216137689361; // Longitude
|
||||
// command.param5 = 24.11928923; // Latitude
|
||||
// command.param6 = 120.67216137; // Longitude
|
||||
// command.param7 = 25; // Altitude
|
||||
// mavlink_msg_command_long_encode(mavlink_passthrough.get_our_sysid(),
|
||||
// mavlink_passthrough.get_our_compid(),
|
||||
// &message,
|
||||
// &command);
|
||||
// mavlink_passthrough.send_command_long(command);
|
||||
// auto result_ackFromSendMessage = mavlink_passthrough.send_message(message);
|
||||
// std::cout << " ACK REL: " << result_ackFromSendMessage << std::endl;
|
||||
|
||||
// // 演示一下 如何抓到 parameter
|
||||
// auto get_result_i = param.get_param_int("VISO_TYPE"); // This function is blocking.
|
||||
@@ -130,7 +188,7 @@ void systemHandler(System& system) {
|
||||
// std::cout << "Has AutoPilot : " << system.has_autopilot() << std::endl; // debug
|
||||
|
||||
|
||||
// std::cout << "Dev Test End" << std::endl;
|
||||
std::cout << "Dev Test End" << std::endl;
|
||||
|
||||
// Put all the subscriber init in this section
|
||||
if (system.has_autopilot()) {
|
||||
@@ -236,6 +294,10 @@ void systemHandler(System& system) {
|
||||
telemetryInfo["drone_arm"] = "0";
|
||||
}
|
||||
});
|
||||
|
||||
telemetry.subscribe_flight_mode([&system, &telemetryInfo](Telemetry::FlightMode fightMode) {
|
||||
telemetryInfo["vehicle_mode"] = flightModeMap[fightMode];
|
||||
});
|
||||
}
|
||||
|
||||
// Wait Until telemetryInfo get something. and if nothing get from System for 10 sec will cut off this connection.
|
||||
@@ -257,10 +319,101 @@ void systemHandler(System& system) {
|
||||
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) {
|
||||
switch (oneVehicleCommand.first) {
|
||||
// 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); // 送出指令
|
||||
std::cout << " ACK REL: " << result_mavpass << std::endl; // dev
|
||||
#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();
|
||||
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();
|
||||
std::cout << " ACK REL: " << result_action << std::endl; // dev
|
||||
#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
|
||||
#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
|
||||
set_position_target_global_int.time_boot_ms = 0;
|
||||
set_position_target_global_int.target_system = sysid;
|
||||
set_position_target_global_int.target_component = MAV_COMP_ID_AUTOPILOT1;
|
||||
set_position_target_global_int.coordinate_frame = MAV_FRAME_GLOBAL_RELATIVE_ALT; // 對於 home 點指定相對高度
|
||||
set_position_target_global_int.type_mask = 0b110111111000; // Only latitude, longitude and altitude
|
||||
set_position_target_global_int.lat_int = oneVehicleCommand.second[0] * 1E7; // Latitude in degrees * 1E7
|
||||
set_position_target_global_int.lon_int = oneVehicleCommand.second[1] * 1E7; // Longitude in degrees * 1E7
|
||||
set_position_target_global_int.alt = 30; // Altitude in meters
|
||||
|
||||
mavlink_msg_set_position_target_global_int_pack(
|
||||
mavlink_passthrough.get_our_sysid(),
|
||||
mavlink_passthrough.get_our_compid(),
|
||||
&mav_message,
|
||||
set_position_target_global_int.time_boot_ms,
|
||||
set_position_target_global_int.target_system,
|
||||
set_position_target_global_int.target_component,
|
||||
set_position_target_global_int.coordinate_frame,
|
||||
set_position_target_global_int.type_mask,
|
||||
set_position_target_global_int.lat_int,
|
||||
set_position_target_global_int.lon_int,
|
||||
set_position_target_global_int.alt,
|
||||
0, 0, 0, 0, 0, 0, 0, 0); // vx, vy, vz, afx, afy, afz, yaw, yaw_rate are all 0
|
||||
result_mavpass = mavlink_passthrough.send_message(mav_message);
|
||||
std::cout << " ACK REL: " << result_mavpass << std::endl; // dev
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// for purpose
|
||||
sleep_for(milliseconds(100));
|
||||
|
||||
Reference in New Issue
Block a user