Files
Trinity-Control/main.cpp
T

193 lines
6.4 KiB
C++

#include <cstdint>
#include <ios>
#include <iostream>
#include "raylib.h"
#include <raymath.h>
#include <uchar.h>
#include "serialcomm.hpp"
#include <vector>
#include <iomanip>
#include <thread>
#include <mutex>
//#define RAYGUI_IMPLEMENTATION
//#include "ressources/raygui/raygui.h"
#include "imgui.h"
#include "ressources/rlImGui-Raylib_6_0/rlImGui.h"
#include "rlImGui.h"
//#include "glm/glm.hpp"
// global variables for the communication between parsing and main thread
std::mutex quaternion_mutex;
Quaternion newest_quaternion = {0.0f};
std::vector<Quaternion> quaternion_history;
bool read_new_quaternion_data = true;
const int WIDTH = 1280;
const int HEIGTH = 720;
// seperate thread for the serial parsing of the incoming binary data from the mcu
void serial_parser_thread() {
// define data variables and open serial port
int serPort = linux_initSerialPort();
size_t bytes_read;
std::vector<uint8_t> binary_data_buffer(64);
std::vector<uint8_t> binary_Packet_Buffer;
while (read_new_quaternion_data) {
if (linux_readSerialData(serPort, binary_data_buffer, bytes_read)) {
binary_Packet_Buffer.insert(binary_Packet_Buffer.end(), binary_data_buffer.begin(), binary_data_buffer.begin() + bytes_read); //binary_data_buffer.end());
while(true) {
std::vector<uint8_t>packet = extractPacket(binary_Packet_Buffer);
if (packet.empty()) break;
Quaternion quat;
if (parseBinaryPacket(packet,quat)) {
// lock the mutex to update quaternion and add to quaternion_history
std::lock_guard<std::mutex> lock(quaternion_mutex);
newest_quaternion = quat;
quaternion_history.push_back(quat);
if (quaternion_history.size() > 200) {
quaternion_history.erase((quaternion_history.begin()));
}
// now print the quaternions formatted into the console for debugging
std::cout << std::fixed << std::setprecision(6) <<
"w: " << std::setw(10) << quat.w <<
" x: " << std::setw(10) << quat.x <<
" y: " << std::setw(10) << quat.y <<
" z: " << std::setw(10) << quat.z << std::endl;
}
}
} else break;
}
if (linux_close_serial_port(serPort)) {
std::cout << "Serial port " << serPort << " succesfully closed" << std::endl;
} else {
std::cout << "[ERROR] closing Serial port " << serPort << std::endl;
}
std::cout << "Serial communication thread exiting" << std::endl;
}
int main() {
// start the parsing thread
std::thread *serial_parsing_thread = nullptr;
serial_parsing_thread = new std::thread(serial_parser_thread);
Quaternion cube_movement_quaternion;
std::vector<Quaternion> quat_history;
// setup dear imgui for the UI
rlImGuiSetup(true);
// Create the window
InitWindow(WIDTH, HEIGTH, "Trinity Control");
SetTargetFPS(60);
// define 3D camecra
Camera camera = {0};
camera.position = (Vector3){3.0f, 10.0f, 10.0f};
camera.target = (Vector3){0.0f, 0.0f, 0.0f};
camera.up = (Vector3){0.0f, 1.0f, 0.0f};
camera.fovy = 45.0f;
camera.projection = CAMERA_PERSPECTIVE;
Vector3 CubePosition = {0.0f, 0.0f, 0.0f};
Vector3 CubeDimensions = {4.0f, 4.0f, 4.0f};
// load image for the cube texture
Model model = LoadModelFromMesh(GenMeshCube(CubeDimensions.x, CubeDimensions.y, CubeDimensions.z));
if (!IsModelValid(model)){
std::cout << "Loaded model is not valid" << std::endl;
}
Mesh mesh = model.meshes[0];
Image img = LoadImage("kekusmaximus.png");
Texture2D texture = LoadTextureFromImage(img);
UnloadImage(img);
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
while (!WindowShouldClose()) {
// get the newest quaternion and quaternion_history from parsing thread
Quaternion cube_movement_quaternion;
{
std::lock_guard<std::mutex> lock(quaternion_mutex);
cube_movement_quaternion = newest_quaternion;
quat_history = quaternion_history;
}
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("BIG TITTY GOTH GIRLS", 190, 200, 20, LIGHTGRAY);
BeginMode3D(camera);
Matrix rot_matrix = QuaternionToMatrix(cube_movement_quaternion);
model.transform = MatrixMultiply(rot_matrix, MatrixTranslate(CubePosition.x, CubePosition.y, CubePosition.z));
DrawMesh(mesh, model.materials[0], model.transform);
DrawModel(model,CubePosition, 1.0f , WHITE);
EndMode3D();
rlImGuiBegin();
ImGui::Text("Im a good little slut, daddy");
ImGui::Text("w: %.4f x: %.4f y: %.4f z: %.4f", cube_movement_quaternion.w, cube_movement_quaternion.x, cube_movement_quaternion.y, cube_movement_quaternion.z);
ImGui::Text("Connection to MCU: ");
ImGui::BeginDisabled(serial_parsing_thread != nullptr);
if (ImGui::Button("Connect")) {
read_new_quaternion_data = true;
serial_parsing_thread = new std::thread(serial_parser_thread);
} ImGui::EndDisabled();
ImGui::SameLine();
ImGui::BeginDisabled(serial_parsing_thread == nullptr);
if (ImGui::Button("Disconnect")) {
read_new_quaternion_data = false;
serial_parsing_thread -> join();
delete serial_parsing_thread;
serial_parsing_thread = nullptr;
} ImGui::EndDisabled();
// create scrolling section for last 200 measurements
ImGui::BeginChild("History", ImVec2(0, 300), true, ImGuiWindowFlags_HorizontalScrollbar);
// loop through quadHistory vector and display each element as line
for (uint32_t i = 0; i < quat_history.size(); i++) {
const Quaternion& q = quat_history[i];
ImGui::Text("w: %.4f x: %.4f y: %.4f z: %.4f", q.w, q.x, q.y, q.z);
}
// enable autoscroll to newest entry
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
ImGui::SetScrollHereY(1.0f);
}
ImGui::EndChild();
rlImGuiEnd();
EndDrawing();
}
//close parser thread and unload texture/model
serial_parsing_thread -> join();
delete serial_parsing_thread;
UnloadTexture(texture);
UnloadModel(model);
CloseWindow();
return 0;
}