10#if __linux__ || __APPLE__
23 #include "mavlink/common/mavlink.h"
28NAV::MavlinkSend::MavlinkSend()
33 _guiConfigDefaultWindowSize = { 479.0, 197.0 };
38NAV::MavlinkSend::~MavlinkSend()
43std::string NAV::MavlinkSend::typeStatic()
48std::string NAV::MavlinkSend::type()
const
53std::string NAV::MavlinkSend::category()
58void NAV::MavlinkSend::guiConfig()
60 float columnWidth = 140.0F * gui::NodeEditorApplication::windowFontRatio();
61 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
62 if (ImGui::TreeNode(
"Transmission protocol"))
64 auto portType =
static_cast<int>(_portType);
65 if (ImGui::RadioButton(fmt::format(
"UDP-Port##{}",
size_t(
id)).c_str(), &portType,
static_cast<int>(PortType::UDP_Port)))
67 _portType =
static_cast<decltype(_portType)
>(portType);
68 LOG_DEBUG(
"{}: portType changed to {}", nameId(), fmt::underlying(_portType));
71 if (_portType == PortType::UDP_Port)
75 ImGui::SetNextItemWidth(150 * gui::NodeEditorApplication::windowFontRatio());
76 if (
ImGui::InputInt4L(fmt::format(
"IPv4##{}",
size_t(
id)).c_str(), _ip.data(), IP_LIMITS[0], IP_LIMITS[1]))
80 ImGui::SetNextItemWidth(150 * gui::NodeEditorApplication::windowFontRatio());
81 if (
ImGui::InputIntL(fmt::format(
"Port##{}",
size_t(
id)).c_str(), &_portNumber, PORT_LIMITS[0], PORT_LIMITS[1]))
89 if (ImGui::RadioButton(fmt::format(
"Serial-Port##{}",
size_t(
id)).c_str(), &portType,
static_cast<int>(PortType::Serial_Port)))
91 _portType =
static_cast<decltype(_portType)
>(portType);
92 LOG_DEBUG(
"{}: portType changed to {}", nameId(), fmt::underlying(_portType));
95 if (_portType == PortType::Serial_Port)
99 ImGui::SetNextItemWidth(300 * gui::NodeEditorApplication::windowFontRatio());
100 if (ImGui::InputTextWithHint(
"MavLinkPort",
"/dev/ttyACM0", &_serialPort))
102 LOG_DEBUG(
"{}: MavLinkPort changed to {}", nameId(), _serialPort);
103 flow::ApplyChanges();
107 gui::widgets::HelpMarker(
"COM port where the MavLink device is attached to\n"
108 "- \"COM1\" (Windows format for physical and virtual (USB) serial port)\n"
109 "- \"/dev/ttyS1\" (Linux format for physical serial port)\n"
110 "- \"/dev/ttyUSB0\" (Linux format for virtual (USB) serial port)\n"
111 "- \"/dev/tty.usbserial-FTXXXXXX\" (Mac OS X format for virtual (USB) serial port)\n"
112 "- \"/dev/ttyS0\" (CYGWIN format. Usually the Windows COM port number minus 1. This would connect to COM1)");
114 ImGui::SetNextItemWidth(150 * gui::NodeEditorApplication::windowFontRatio());
115 if (ImGui::BeginCombo(fmt::format(
"Baudrate##{}",
size_t(
id)).c_str(),
to_string(_baudrate)))
117 for (
size_t i = 0; i < static_cast<size_t>(Baudrate::COUNT); i++)
119 const bool is_selected = (
static_cast<size_t>(_baudrate) == i);
120 if (ImGui::Selectable(
to_string(
static_cast<Baudrate
>(i)), is_selected))
122 _baudrate =
static_cast<Baudrate
>(i);
123 LOG_DEBUG(
"{}: Baudrate changed to {}", nameId(), fmt::underlying(_baudrate));
124 flow::ApplyChanges();
130 ImGui::SetItemDefaultFocus();
137 if (NAV::MavlinkSend::isInitialized())
143 if (ImGui::TreeNode(
"MavLink Messages"))
145 if (ImGui::Checkbox(fmt::format(
"Send GPS_INPUT (#232) ##{}",
size_t(
id)).c_str(), &_GPS_INPUT_Active))
147 flow::ApplyChanges();
148 LOG_DEBUG(
"{}: GPS_INPUT changed to {}", nameId(), _GPS_INPUT_Active);
149 autopilot_interface.setGPS_Active(_GPS_INPUT_Active);
151 if (_GPS_INPUT_Active)
154 ImGui::SetNextItemWidth(columnWidth);
155 if (
ImGui::InputDoubleL(fmt::format(
"GPS output rate##{}",
size_t(
id)).c_str(), &_GPS_INPUT_Frequency, 0, 100, 0, 0,
"%.3f Hz"))
157 LOG_DEBUG(
"{}: GPS_INPUT_Frequency changed to {}", nameId(), _GPS_INPUT_Frequency);
158 autopilot_interface.setGPS_Frequency(_GPS_INPUT_Frequency);
159 flow::ApplyChanges();
164 if (ImGui::Checkbox(fmt::format(
"Send ATT_POS_MOCAP (#138) ##{}",
size_t(
id)).c_str(), &_ATT_POS_MOCAP_Active))
166 flow::ApplyChanges();
167 LOG_DEBUG(
"{}: ATT_POS_MOCAP changed to {}", nameId(), _ATT_POS_MOCAP_Active);
168 autopilot_interface.setMOCAP_Active(_ATT_POS_MOCAP_Active);
170 if (_ATT_POS_MOCAP_Active)
173 ImGui::SetNextItemWidth(columnWidth);
174 if (
ImGui::InputDoubleL(fmt::format(
"MOCAP output rate##{}",
size_t(
id)).c_str(), &_ATT_POS_MOCAP_Frequency, 0, 10000, 0, 0,
"%.3f Hz"))
176 LOG_DEBUG(
"{}: ATT_POS_MOCAP_Frequency changed to {}", nameId(), _ATT_POS_MOCAP_Frequency);
177 autopilot_interface.setMOCAP_Frequency(_ATT_POS_MOCAP_Frequency);
178 flow::ApplyChanges();
186bool NAV::MavlinkSend::resetNode()
191json NAV::MavlinkSend::save()
const
197 j[
"portType"] = _portType;
200 j[
"portNumber"] = _portNumber;
202 j[
"serialPort"] = _serialPort;
203 j[
"baudrate"] = _baudrate;
205 j[
"GPS_INPUT_Active"] = _GPS_INPUT_Active;
206 j[
"GPS_INPUT_Frequency"] = _GPS_INPUT_Frequency;
208 j[
"ATT_POS_MOCAP_Active"] = _ATT_POS_MOCAP_Active;
209 j[
"ATT_POS_MOCAP_Frequency"] = _ATT_POS_MOCAP_Frequency;
213void NAV::MavlinkSend::restore(
json const& j)
217 if (j.contains(
"portType"))
219 j.at(
"portType").get_to(_portType);
222 if (j.contains(
"ip"))
224 j.at(
"ip").get_to(_ip);
226 if (j.contains(
"portNumber"))
228 j.at(
"portNumber").get_to(_portNumber);
231 if (j.contains(
"serialPort"))
233 j.at(
"serialPort").get_to(_serialPort);
235 if (j.contains(
"baudrate"))
237 j.at(
"baudrate").get_to(_baudrate);
240 if (j.contains(
"GPS_INPUT_Active"))
242 j.at(
"GPS_INPUT_Active").get_to(_GPS_INPUT_Active);
244 if (j.contains(
"GPS_INPUT_Frequency"))
246 j.at(
"GPS_INPUT_Frequency").get_to(_GPS_INPUT_Frequency);
249 if (j.contains(
"ATT_POS_MOCAP_Active"))
251 j.at(
"ATT_POS_MOCAP_Active").get_to(_ATT_POS_MOCAP_Active);
253 if (j.contains(
"ATT_POS_MOCAP_Frequency"))
255 j.at(
"ATT_POS_MOCAP_Frequency").get_to(_ATT_POS_MOCAP_Frequency);
259bool NAV::MavlinkSend::initialize()
261 if (_portType == PortType::UDP_Port)
263 port = std::make_shared<UDP_Port>(convertArrayToIPAddress(_ip).c_str(), _portNumber);
265 if (_portType == PortType::Serial_Port)
267 port = std::make_shared<Serial_Port>(_serialPort.c_str(), getBaudrateValue(_baudrate));
269 autopilot_interface.setPort(port);
270 autopilot_interface.setGPS_Active(_GPS_INPUT_Active);
271 autopilot_interface.setMOCAP_Active(_ATT_POS_MOCAP_Active);
272 autopilot_interface.setGPS_Frequency(_GPS_INPUT_Frequency);
273 autopilot_interface.setMOCAP_Frequency(_ATT_POS_MOCAP_Frequency);
280 LOG_ERROR(
"{} could not connect", nameId());
285 autopilot_interface.start();
290 LOG_ERROR(
"{} could not start autopilot_interface", nameId());
297void NAV::MavlinkSend::deinitialize()
300 autopilot_interface.stop();
307 if (port->cabelCheck == 1)
311 auto posVelAtt = std::make_shared<PosVelAtt>(*std::static_pointer_cast<const PosVelAtt>(queue.
extract_front()));
314 auto quat = posVelAtt->n_Quat_b();
315 auto w =
static_cast<float>(quat.w());
316 auto x =
static_cast<float>(quat.x());
317 auto y =
static_cast<float>(quat.y());
318 auto z =
static_cast<float>(quat.z());
319 autopilot_interface.setMOCAP(w, x, y, z);
322 auto lat_d =
static_cast<int32_t
>(((posVelAtt->latitude()) * 180.0 / std::numbers::pi_v<double>)*10000000);
323 auto lon_d =
static_cast<int32_t
>(((posVelAtt->longitude()) * 180.0 / std::numbers::pi_v<double>)*10000000);
324 auto alt =
static_cast<float>(posVelAtt->altitude());
325 auto time_week =
static_cast<uint16_t
>(posVelAtt->insTime.toGPSweekTow().gpsWeek);
326 auto time_week_ms =
static_cast<uint32_t
>((posVelAtt->insTime.toGPSweekTow().tow) / 1000);
328 auto vn =
static_cast<float>(posVelAtt->n_velocity().x());
329 auto ve =
static_cast<float>(posVelAtt->n_velocity().y());
330 auto vd =
static_cast<float>(posVelAtt->n_velocity().z());
331 autopilot_interface.setGPS(lat_d, lon_d, alt,
vn, ve, vd, time_week_ms, time_week);
334std::string NAV::MavlinkSend::convertArrayToIPAddress(
const std::array<int, 4>& ipArray)
336 return fmt::format(
"{}", fmt::join(ipArray,
"."));
339const char* NAV::MavlinkSend::to_string(Baudrate value)
341 static const std::unordered_map<Baudrate, const char*> baudrateMap = {
342 { Baudrate::BAUDRATE_1200,
"1200" },
343 { Baudrate::BAUDRATE_2400,
"2400" },
344 { Baudrate::BAUDRATE_4800,
"4800" },
345 { Baudrate::BAUDRATE_9600,
"9600" },
346 { Baudrate::BAUDRATE_19200,
"19200" },
347 { Baudrate::BAUDRATE_38400,
"38400" },
348 { Baudrate::BAUDRATE_57600,
"57600" },
349 { Baudrate::BAUDRATE_111100,
"111100" },
350 { Baudrate::BAUDRATE_115200,
"115200" },
351 { Baudrate::BAUDRATE_230400,
"230400" },
352 { Baudrate::BAUDRATE_256000,
"256000" },
353 { Baudrate::BAUDRATE_460800,
"460800" },
354 { Baudrate::BAUDRATE_500000,
"500000" },
355 { Baudrate::BAUDRATE_921600,
"921600" },
356 { Baudrate::BAUDRATE_1500000,
"1500000" },
357 { Baudrate::COUNT,
"" }
359 return baudrateMap.at(value);
362int NAV::MavlinkSend::getBaudrateValue(Baudrate value)
364 static const std::unordered_map<Baudrate, int> baudrateMap = {
365 { Baudrate::BAUDRATE_1200, 1200 },
366 { Baudrate::BAUDRATE_2400, 2400 },
367 { Baudrate::BAUDRATE_4800, 4800 },
368 { Baudrate::BAUDRATE_9600, 9600 },
369 { Baudrate::BAUDRATE_19200, 19200 },
370 { Baudrate::BAUDRATE_38400, 38400 },
371 { Baudrate::BAUDRATE_57600, 57600 },
372 { Baudrate::BAUDRATE_111100, 111100 },
373 { Baudrate::BAUDRATE_115200, 115200 },
374 { Baudrate::BAUDRATE_230400, 230400 },
375 { Baudrate::BAUDRATE_256000, 256000 },
376 { Baudrate::BAUDRATE_460800, 460800 },
377 { Baudrate::BAUDRATE_500000, 500000 },
378 { Baudrate::BAUDRATE_921600, 921600 },
379 { Baudrate::BAUDRATE_1500000, 1500000 }
381 return baudrateMap.at(value);
nlohmann::json json
json namespace
Text Help Marker (?) with Tooltip.
Utility class for logging to console and file.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
#define LOG_ERROR
Error occurred, which stops part of the program to work, but not everything.
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
Autopilot interface definition.
static std::string type()
Returns the type of the data class.
auto extract_front()
Returns a copy of the first element in the container and removes it from the container.
Sends a navigation solution via the MAVLink protocol.
bool InputIntL(const char *label, int *v, int v_min, int v_max, int step, int step_fast, ImGuiInputTextFlags flags)
Shows a value limited InputText GUI element for 'int'.
bool InputInt4L(const char *label, int v[4], int v_min, int v_max, ImGuiInputTextFlags flags)
Shows a value limited InputText GUI element for an array of 'int[4]'.
bool InputDoubleL(const char *label, double *v, double v_min, double v_max, double step, double step_fast, const char *format, ImGuiInputTextFlags flags)
Shows a value limited InputText GUI element for 'double'.
InputPin * CreateInputPin(Node *node, const char *name, Pin::Type pinType, const std::vector< std::string > &dataIdentifier={}, InputPin::Callback callback=static_cast< InputPin::FlowFirableCallbackFunc >(nullptr), InputPin::FlowFirableCheckFunc firable=nullptr, int priority=0, int idx=-1)
Create an Input Pin object.
const char * to_string(gui::widgets::PositionWithFrame::ReferenceFrame refFrame)
Converts the enum to a string.