From 98bc1fa217eae655ba9f7fb78b99a151f1b69f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=BCseyin=20Karakaya?= Date: Tue, 8 Oct 2024 20:51:06 +0300 Subject: [PATCH] mavsdk connection test --- .gitignore | 1 + .gitmodules | 3 ++ .vscode/launch.json | 23 +++++++++ .vscode/settings.json | 7 +++ CMakeLists.txt | 57 +++++++++++++++++++++ lib/imgui | 1 + src/main.cpp | 100 +++++++++++++++++++++++++++++++++++++ src/mavlink_connection.cpp | 76 ++++++++++++++++++++++++++++ src/mavlink_connection.hpp | 52 +++++++++++++++++++ 9 files changed, 320 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 CMakeLists.txt create mode 160000 lib/imgui create mode 100644 src/main.cpp create mode 100644 src/mavlink_connection.cpp create mode 100644 src/mavlink_connection.hpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2d90e46 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/imgui"] + path = lib/imgui + url = https://github.com/ocornut/imgui.git diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c3b27c8 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,23 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Debug", + "type": "cppdbg", + "request": "launch", + "cwd": "${workspaceFolder}", + "program": "${workspaceFolder}/build/mavlink_access", + "args": [], + "miDebuggerPath": "/usr/bin/gdb", + "MIMode": "gdb", + "launchCompleteCommand": "exec-run", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + }, + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..263c2bf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "new": "cpp", + "chrono": "cpp", + "*.tcc": "cpp" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b9b0360 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.10.2) + +project(mavlink-access) + +set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src") +set(LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib") + +set(SOURCES + "${SRC_DIR}/main.cpp" + "${SRC_DIR}/mavlink_connection.hpp" + "${SRC_DIR}/mavlink_connection.cpp" +) + +add_executable(${PROJECT_NAME} ${SOURCES}) + +find_package(MAVSDK REQUIRED) + +add_library(imgui STATIC + ${LIB_DIR}/imgui/imgui.cpp + ${LIB_DIR}/imgui/imgui_draw.cpp + ${LIB_DIR}/imgui/imgui_demo.cpp + ${LIB_DIR}/imgui/imgui_tables.cpp + ${LIB_DIR}/imgui/imgui_widgets.cpp +) + +target_include_directories(imgui PUBLIC ${LIB_DIR}/imgui) + +add_library(imgui_backend STATIC + ${LIB_DIR}/imgui/backends/imgui_impl_glfw.cpp + ${LIB_DIR}/imgui/backends/imgui_impl_opengl3.cpp +) + +target_include_directories(imgui_backend PUBLIC + ${LIB_DIR}/imgui + ${LIB_DIR}/imgui/backends +) + +find_package(OpenGL REQUIRED) +find_package(glfw3 REQUIRED) + +target_link_libraries(imgui_backend imgui glfw OpenGL::GL) + +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) + +target_link_libraries(${PROJECT_NAME} PRIVATE MAVSDK::mavsdk imgui_backend) + +if(NOT MSVC) + target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra) +else() + target_compile_options(${PROJECT_NAME} PRIVATE /W2) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message("Configuring Debug build") + add_compile_options(-g) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") +endif() \ No newline at end of file diff --git a/lib/imgui b/lib/imgui new file mode 160000 index 0000000..f7ba645 --- /dev/null +++ b/lib/imgui @@ -0,0 +1 @@ +Subproject commit f7ba6453980824aa4a7d096841576285efa7f6ec diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..6b0622a --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,100 @@ +#include "imgui.h" +#include "backends/imgui_impl_glfw.h" +#include "backends/imgui_impl_opengl3.h" +#include + +#include "mavlink_connection.hpp" + +int main() { + + char connection_url[20] {}; + bool is_connected = false; + + if (!glfwInit()) + return -1; + + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui Window", NULL, NULL); + if (window == NULL) + return -1; + + glfwMakeContextCurrent(window); + // glfwSwapInterval(1); // Vsync + + // ImGui Contexti Başlatma + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + + // Platform ve Renderer bağlama + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplOpenGL3_Init("#version 130"); + + // Stil ayarlama + ImGui::StyleColorsDark(); + + MavlinkConnection* mavlink_connection = MavlinkConnection::get_singleton(); + + // Ana döngü + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + // Yeni bir ImGui frame'i başlatma + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + ImGui::SetNextWindowSize(ImVec2(400,100)); + ImGui::SetNextWindowPos(ImVec2(10,10)); + + if (ImGui::Begin("Mavlink Access", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove)) + { + ImGui::InputText("Connection url", connection_url, 20); + if(ImGui::Button("Connect")) + { + if (mavlink_connection->init(connection_url)) { + is_connected = true; + } + } + ImGui::End(); + } + + ImGui::SetNextWindowSize(ImVec2(400,500)); + ImGui::SetNextWindowPos(ImVec2(10,120)); + if (ImGui::Begin("Info", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove)) + { + if (is_connected) { + ImGui::Text("Connected"); + if (mavlink_connection->status_text()) + { + const char* status_text = mavlink_connection->status_text(); + ImGui::Text("%s", status_text); + } + } else { + ImGui::Text("Not Connected"); + } + + ImGui::End(); + } + + // Render + ImGui::Render(); + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(0.45f, 0.55f, 0.60f, 1.00f); + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + glfwSwapBuffers(window); + } + + // Clean + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(window); + glfwTerminate(); + + return 0; +} \ No newline at end of file diff --git a/src/mavlink_connection.cpp b/src/mavlink_connection.cpp new file mode 100644 index 0000000..52bdb77 --- /dev/null +++ b/src/mavlink_connection.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +#include + +using namespace mavsdk; + +MavlinkConnection* MavlinkConnection::_singleton = nullptr; +char* MavlinkConnection::_status_text = nullptr; + + +MavlinkConnection::MavlinkConnection() {} + +MavlinkConnection::~MavlinkConnection() {} + + +MavlinkConnection* MavlinkConnection::get_singleton() +{ + if (_singleton == nullptr) { + _singleton = new MavlinkConnection(); + } + return _singleton; +} + +bool MavlinkConnection::init(char* connection_url) +{ + _mavsdk = new Mavsdk(Mavsdk::Configuration(SYSTEM_ID, COMP_ID, true)); + ConnectionResult connection_result; + connection_result = _mavsdk->add_any_connection(connection_url); + + if (connection_result != ConnectionResult::Success) { + return false; + } + + while (_mavsdk->systems().size() == 0) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + for (auto system : _mavsdk->systems()) { + // create MavlinkPassthrough instances for vehicle and ground station + if (system->has_autopilot()) { + if (system->is_connected()) { + _vehicle = system; + } + } + } + + start_telemetry(); + return true; +} + +void MavlinkConnection::start_telemetry() +{ + if (_vehicle == nullptr) { + return; + } + + _telemetry = new Telemetry(_vehicle); + _telemetry->subscribe_status_text(update_status_text); +} + +void MavlinkConnection::update_status_text(Telemetry::StatusText status_text) +{ + // Free the previous memory if _status_text already points to something + if (_status_text != nullptr) { + delete[] _status_text; + } + + std::string str = status_text.text; + + // Allocate memory for the new status text + _status_text = new char[str.size() + 1]; // +1 for the null terminator + + // Copy the content of status_text.text to _status_text + std::strcpy(_status_text, str.c_str()); +} \ No newline at end of file diff --git a/src/mavlink_connection.hpp b/src/mavlink_connection.hpp new file mode 100644 index 0000000..88ce130 --- /dev/null +++ b/src/mavlink_connection.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include + +#include +#include "mavsdk/system.h" +#include "mavsdk/plugins/mavlink_passthrough/mavlink_passthrough.h" +#include + +#define SYSTEM_ID 2 +#define COMP_ID 2 + +using namespace mavsdk; + +struct TelemetryData { + double latitude; + double longitude; + double altitude; + double velocity_x; + double velocity_y; + double velocity_z; + double heading; + double battery_voltage; + double battery_percentage; +}; + +class MavlinkConnection +{ +public: + + static MavlinkConnection* get_singleton(); + bool init(char* connection_url); + + char* status_text() { return _status_text; } + + +private: + + MavlinkConnection(); + ~MavlinkConnection(); + + static void update_status_text(Telemetry::StatusText status_text); + void start_telemetry(); + + static MavlinkConnection* _singleton; + + Mavsdk* _mavsdk; + std::shared_ptr _vehicle; + Telemetry* _telemetry; + + static char* _status_text; +}; \ No newline at end of file