From a4f27d10f6a9424afe267d15e112a3380e7586f6 Mon Sep 17 00:00:00 2001 From: iTassadar <62787514+iTassadar@users.noreply.github.com> Date: Thu, 14 Aug 2025 21:39:09 +0300 Subject: [PATCH 1/3] Delete UMAS_GUI-develop directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit удоление --- UMAS_GUI-develop/.gitignore | 74 - UMAS_GUI-develop/.vscode/launch.json | 10 - UMAS_GUI-develop/.vscode/settings.json | 15 - UMAS_GUI-develop/CMakeLists.txt | 134 - UMAS_GUI-develop/communication/pc_protocol.h | 62 - UMAS_GUI-develop/communication/udp_protocol.h | 176 - UMAS_GUI-develop/compass/compass.cpp | 60 - UMAS_GUI-develop/compass/compass.h | 53 - UMAS_GUI-develop/compass/compass.ui | 19 - UMAS_GUI-develop/img.qrc | 5 - UMAS_GUI-develop/img/setupIMU_for_agent.png | Bin 75333 -> 0 bytes UMAS_GUI-develop/interface/i_basic_data.cpp | 9 - UMAS_GUI-develop/interface/i_basic_data.h | 24 - UMAS_GUI-develop/interface/i_control_data.cpp | 70 - UMAS_GUI-develop/interface/i_control_data.h | 36 - UMAS_GUI-develop/interface/i_server_data.cpp | 40 - UMAS_GUI-develop/interface/i_server_data.h | 31 - .../interface/i_user_interface_data.cpp | 225 - .../interface/i_user_interface_data.h | 53 - UMAS_GUI-develop/main.cpp | 11 - UMAS_GUI-develop/mainwindow.cpp | 1049 ----- UMAS_GUI-develop/mainwindow.h | 182 - UMAS_GUI-develop/mainwindow.ui | 3822 ----------------- UMAS_GUI-develop/map/map.cpp | 189 - UMAS_GUI-develop/map/map.h | 127 - UMAS_GUI-develop/map/map.ui | 110 - .../remote_control/.vscode/tasks.json | 28 - UMAS_GUI-develop/remote_control/joy_stick.cpp | 87 - UMAS_GUI-develop/remote_control/joy_stick.h | 32 - UMAS_GUI-develop/remote_control/key_board.cpp | 95 - UMAS_GUI-develop/remote_control/key_board.h | 24 - .../remote_control/remote_control.cpp | 13 - .../remote_control/remote_control.h | 42 - UMAS_GUI-develop/remote_control/test.cpp | 28 - UMAS_GUI-develop/ui_utils/dataIMU_magn.db | Bin 24576 -> 0 bytes UMAS_GUI-develop/ui_utils/database.cpp | 128 - UMAS_GUI-develop/ui_utils/database.h | 98 - UMAS_GUI-develop/ui_utils/list_uwb.db | Bin 12288 -> 0 bytes UMAS_GUI-develop/ui_utils/setup_imu.cpp | 26 - UMAS_GUI-develop/ui_utils/setup_imu.h | 38 - UMAS_GUI-develop/ui_utils/setup_imu.ui | 67 - UMAS_GUI-develop/ui_utils/setupimu_check.cpp | 238 - UMAS_GUI-develop/ui_utils/setupimu_check.h | 128 - UMAS_GUI-develop/ui_utils/setupimu_check.ui | 196 - UMAS_GUI-develop/ui_utils/setupimu_start.cpp | 125 - UMAS_GUI-develop/ui_utils/setupimu_start.h | 90 - UMAS_GUI-develop/ui_utils/setupimu_start.ui | 172 - UMAS_GUI-develop/uv/uv_state.cpp | 55 - UMAS_GUI-develop/uv/uv_state.h | 279 -- 49 files changed, 8575 deletions(-) delete mode 100755 UMAS_GUI-develop/.gitignore delete mode 100755 UMAS_GUI-develop/.vscode/launch.json delete mode 100755 UMAS_GUI-develop/.vscode/settings.json delete mode 100755 UMAS_GUI-develop/CMakeLists.txt delete mode 100755 UMAS_GUI-develop/communication/pc_protocol.h delete mode 100755 UMAS_GUI-develop/communication/udp_protocol.h delete mode 100755 UMAS_GUI-develop/compass/compass.cpp delete mode 100755 UMAS_GUI-develop/compass/compass.h delete mode 100755 UMAS_GUI-develop/compass/compass.ui delete mode 100755 UMAS_GUI-develop/img.qrc delete mode 100755 UMAS_GUI-develop/img/setupIMU_for_agent.png delete mode 100755 UMAS_GUI-develop/interface/i_basic_data.cpp delete mode 100755 UMAS_GUI-develop/interface/i_basic_data.h delete mode 100755 UMAS_GUI-develop/interface/i_control_data.cpp delete mode 100755 UMAS_GUI-develop/interface/i_control_data.h delete mode 100755 UMAS_GUI-develop/interface/i_server_data.cpp delete mode 100755 UMAS_GUI-develop/interface/i_server_data.h delete mode 100755 UMAS_GUI-develop/interface/i_user_interface_data.cpp delete mode 100755 UMAS_GUI-develop/interface/i_user_interface_data.h delete mode 100755 UMAS_GUI-develop/main.cpp delete mode 100755 UMAS_GUI-develop/mainwindow.cpp delete mode 100755 UMAS_GUI-develop/mainwindow.h delete mode 100755 UMAS_GUI-develop/mainwindow.ui delete mode 100755 UMAS_GUI-develop/map/map.cpp delete mode 100755 UMAS_GUI-develop/map/map.h delete mode 100755 UMAS_GUI-develop/map/map.ui delete mode 100644 UMAS_GUI-develop/remote_control/.vscode/tasks.json delete mode 100755 UMAS_GUI-develop/remote_control/joy_stick.cpp delete mode 100755 UMAS_GUI-develop/remote_control/joy_stick.h delete mode 100755 UMAS_GUI-develop/remote_control/key_board.cpp delete mode 100755 UMAS_GUI-develop/remote_control/key_board.h delete mode 100755 UMAS_GUI-develop/remote_control/remote_control.cpp delete mode 100755 UMAS_GUI-develop/remote_control/remote_control.h delete mode 100644 UMAS_GUI-develop/remote_control/test.cpp delete mode 100755 UMAS_GUI-develop/ui_utils/dataIMU_magn.db delete mode 100755 UMAS_GUI-develop/ui_utils/database.cpp delete mode 100755 UMAS_GUI-develop/ui_utils/database.h delete mode 100755 UMAS_GUI-develop/ui_utils/list_uwb.db delete mode 100755 UMAS_GUI-develop/ui_utils/setup_imu.cpp delete mode 100755 UMAS_GUI-develop/ui_utils/setup_imu.h delete mode 100755 UMAS_GUI-develop/ui_utils/setup_imu.ui delete mode 100755 UMAS_GUI-develop/ui_utils/setupimu_check.cpp delete mode 100755 UMAS_GUI-develop/ui_utils/setupimu_check.h delete mode 100755 UMAS_GUI-develop/ui_utils/setupimu_check.ui delete mode 100755 UMAS_GUI-develop/ui_utils/setupimu_start.cpp delete mode 100755 UMAS_GUI-develop/ui_utils/setupimu_start.h delete mode 100755 UMAS_GUI-develop/ui_utils/setupimu_start.ui delete mode 100755 UMAS_GUI-develop/uv/uv_state.cpp delete mode 100755 UMAS_GUI-develop/uv/uv_state.h diff --git a/UMAS_GUI-develop/.gitignore b/UMAS_GUI-develop/.gitignore deleted file mode 100755 index 4a0b530..0000000 --- a/UMAS_GUI-develop/.gitignore +++ /dev/null @@ -1,74 +0,0 @@ -# This file is used to ignore files which are generated -# ---------------------------------------------------------------------------- - -*~ -*.autosave -*.a -*.core -*.moc -*.o -*.obj -*.orig -*.rej -*.so -*.so.* -*_pch.h.cpp -*_resource.rc -*.qm -.#* -*.*# -core -!core/ -tags -.DS_Store -.directory -*.debug -Makefile* -*.prl -*.app -moc_*.cpp -ui_*.h -qrc_*.cpp -Thumbs.db -*.res -*.rc -/.qmake.cache -/.qmake.stash - -# qtcreator generated files -*.pro.user* -CMakeLists.txt.user* - -# xemacs temporary files -*.flc - -# Vim temporary files -.*.swp - -# Visual Studio generated files -*.ib_pdb_index -*.idb -*.ilk -*.pdb -*.sln -*.suo -*.vcproj -*vcproj.*.*.user -*.ncb -*.sdf -*.opensdf -*.vcxproj -*vcxproj.* - -# MinGW generated files -*.Debug -*.Release - -# Python byte code -*.pyc - -# Binaries -# -------- -*.dll -*.exe - diff --git a/UMAS_GUI-develop/.vscode/launch.json b/UMAS_GUI-develop/.vscode/launch.json deleted file mode 100755 index 97b986a..0000000 --- a/UMAS_GUI-develop/.vscode/launch.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - - - ] -} \ No newline at end of file diff --git a/UMAS_GUI-develop/.vscode/settings.json b/UMAS_GUI-develop/.vscode/settings.json deleted file mode 100755 index 25d4a7b..0000000 --- a/UMAS_GUI-develop/.vscode/settings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ -"cmake.configureArgs": [ - "-DCMAKE_PREFIX_PATH=/home/shakuevda/Qt/6.4.2/gcc_64/lib/cmake" // my - // "-DCMAKE_PREFIX_PATH=/home/hydro/Qt/5.15.2/gcc_64/lib/cmake" // laptop - // "-DCMAKE_PREFIX_PATH=/home/hydronautics/Qt/5.15.2/gcc_64/lib/cmake" // station - -], -"files.associations": { - "qabstractseries": "cpp", - "qabstractaxis": "cpp", - "qpainter": "cpp", - "qchartview": "cpp", - "qtmath": "cpp" -} -} \ No newline at end of file diff --git a/UMAS_GUI-develop/CMakeLists.txt b/UMAS_GUI-develop/CMakeLists.txt deleted file mode 100755 index 338e136..0000000 --- a/UMAS_GUI-develop/CMakeLists.txt +++ /dev/null @@ -1,134 +0,0 @@ -cmake_minimum_required(VERSION 3.5) - -project(UMAS_GUI VERSION 0.1 LANGUAGES CXX) - -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Charts Core Network Sql Gui) - -# === GStreamer и GLib === -find_package(PkgConfig REQUIRED) - -pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0>=1.0) -pkg_check_modules(GSTREAMER_VIDEO REQUIRED gstreamer-video-1.0>=1.0) -pkg_check_modules(GLIB REQUIRED glib-2.0>=2.0) - -include_directories( - ${GSTREAMER_INCLUDE_DIRS} - ${GSTREAMER_VIDEO_INCLUDE_DIRS} - ${GLIB_INCLUDE_DIRS} -) - -link_directories( - ${GSTREAMER_LIBRARY_DIRS} - ${GSTREAMER_VIDEO_LIBRARY_DIRS} - ${GLIB_LIBRARY_DIRS} -) -# ============================ - -include_directories( - "${PROJECT_SOURCE_DIR}/compass" - "${PROJECT_SOURCE_DIR}/remote_control" - "${PROJECT_SOURCE_DIR}/uv" - "${PROJECT_SOURCE_DIR}/interface" - "${PROJECT_SOURCE_DIR}/map" - "${PROJECT_SOURCE_DIR}/communication" - "${PROJECT_SOURCE_DIR}/ui_utils" - "${PROJECT_SOURCE_DIR}" -) - -set(PROJECT_SOURCES - main.cpp - mainwindow.cpp - mainwindow.h - mainwindow.ui - remote_control/remote_control.h - remote_control/remote_control.cpp - compass/compass.cpp - compass/compass.h - compass/compass.ui - uv/uv_state.cpp - uv/uv_state.h - interface/i_control_data.cpp - interface/i_control_data.h - interface/i_basic_data.cpp - interface/i_basic_data.h - interface/i_user_interface_data.cpp - interface/i_user_interface_data.h - interface/i_server_data.h - interface/i_server_data.cpp - communication/pc_protocol.h - communication/udp_protocol.h - ui_utils/setup_imu.h - ui_utils/setup_imu.cpp - ui_utils/setup_imu.ui - ui_utils/setupimu_start.h - ui_utils/setupimu_start.cpp - ui_utils/setupimu_start.ui - map/map.h - map/map.cpp - map/map.ui - img.qrc - ui_utils/setupimu_check.h - ui_utils/setupimu_check.cpp - ui_utils/setupimu_check.ui - ui_utils/database.h - ui_utils/database.cpp - remote_control/key_board.h - remote_control/key_board.cpp - remote_control/joy_stick.h - remote_control/joy_stick.cpp -) - -if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) - qt_add_executable(UMAS_GUI - MANUAL_FINALIZATION - ${PROJECT_SOURCES} - ) -else() - if(ANDROID) - add_library(UMAS_GUI SHARED - ${PROJECT_SOURCES} - ) - else() - add_executable(UMAS_GUI - ${PROJECT_SOURCES} - ) - endif() -endif() - -target_link_libraries(UMAS_GUI PRIVATE - sfml-graphics sfml-window sfml-system - Qt${QT_VERSION_MAJOR}::Widgets - Qt${QT_VERSION_MAJOR}::Charts - Qt${QT_VERSION_MAJOR}::Network - Qt${QT_VERSION_MAJOR}::Sql - Qt${QT_VERSION_MAJOR}::Gui - ${GSTREAMER_LIBRARIES} - ${GSTREAMER_VIDEO_LIBRARIES} - ${GLIB_LIBRARIES} -) - -set_target_properties(UMAS_GUI PROPERTIES - MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com - MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} - MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} - MACOSX_BUNDLE TRUE - WIN32_EXECUTABLE TRUE -) - -install(TARGETS UMAS_GUI - BUNDLE DESTINATION . - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) - -if(QT_VERSION_MAJOR EQUAL 6) - qt_finalize_executable(UMAS_GUI) -endif() diff --git a/UMAS_GUI-develop/communication/pc_protocol.h b/UMAS_GUI-develop/communication/pc_protocol.h deleted file mode 100755 index 4e8b44d..0000000 --- a/UMAS_GUI-develop/communication/pc_protocol.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef PC_PROTOCOL_H -#define PC_PROTOCOL_H - -#include "udp_protocol.h" -#include "uv_state.h" -#include "i_server_data.h" - - -namespace Pult { -class PC_Protocol: public QObject, public MetaUdpProtocol { - Q_OBJECT -public: -explicit PC_Protocol(QHostAddress _receiverIP, int _receiverPort, QHostAddress _senderIP, \ - int _senderPort, int freq, int selectAgent, QObject *parent = 0) -{ - udpProtocol = new UdpProtocol (_receiverIP, _receiverPort, _senderIP, _senderPort, \ - freq, selectAgent, parent); - connect(timer,SIGNAL(timeout()),SLOT(sendData())); - connect(udpProtocol->getReceiveSocket(),SIGNAL(readyRead()),SLOT(receiveData())); - set_ip_receiver(udpProtocol->ip_receiver()); - set_ip_sender (udpProtocol->ip_sender()); - set_port_receiver(udpProtocol->port_receiver()); - set_port_sender (udpProtocol->port_sender()); - nmbAgent = selectAgent; -} - int nmbAgent; -signals: - void dataReceived(); -public slots: - //запуск обмена - void startExchange(){ - timer->start(1000/udpProtocol->getFrequency()); - } - //остановить обмен - void stopExhange(){ - timer->stop(); - } - void sendData(){ - send_data = uv_server.generateFullMessage(nmbAgent); - udpProtocol->send_data = send_data; - udpProtocol->sendData(); - } - - void receiveData(){ - udpProtocol->receiveData(); - rec_data = udpProtocol->rec_data; - uv_server.parseFullMessage(rec_data, nmbAgent); - emit dataReceived(); - } - -public: - ToPult rec_data; - FromPult send_data; - UdpProtocol *udpProtocol; - IServerData uv_server; - - bool bindState(){return udpProtocol->bindState();} -}; -} //namespace Pult - - -#endif // PC_PROTOCOL_H diff --git a/UMAS_GUI-develop/communication/udp_protocol.h b/UMAS_GUI-develop/communication/udp_protocol.h deleted file mode 100755 index 30be5dc..0000000 --- a/UMAS_GUI-develop/communication/udp_protocol.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef UDP_PROTOCOL_H -#define UDP_PROTOCOL_H - -#include -#include -#include -#include - - -template - -class UdpProtocol : public QObject { -public: - ReceiveStruct rec_data; //структура для приема данных - SendStruct send_data; //структура для отпарвки данных - explicit UdpProtocol(QHostAddress _receiverIP, int _receiverPort, QHostAddress _senderIP, \ - int _senderPort, int freq, int selectAgent, QObject *parent = 0) : QObject(parent) { - m_ip_sender = _senderIP; //ip ПУ - m_ip_receiver = _receiverIP; //ip ROV_Model - m_port_sender = _senderPort; //порт ПУ - m_port_receiver = _receiverPort; //порт ROV_Model - m_frequency = freq; //частота передачи данных - - qInfo() << "Sender (ROV) ip:" << m_ip_sender << "port:" << m_port_sender; - qInfo() << "Receiver (Pult) ip:" << m_ip_receiver << "port:" << m_port_receiver; - qInfo() << "Frequency:" << m_frequency; - - receiveSocket = new QUdpSocket(); //создаем сокет на прием данных - bindState_ = receiveSocket->bind(m_ip_receiver, m_port_receiver); - qInfo() << "bind receive socket: " << bindState_; - qInfo() << "socket error: " << receiveSocket->errorString(); - //слушаем данные приходящие на ip-адрес ip_receiver, - //на порт port_receiver - sendSocket = new QUdpSocket(); //создаем сокет на передачу данных - qInfo() << "Sends to ip:" << m_ip_sender << "port:" << m_port_sender; - //соединим сигнал таймера с функцией sendData, отсылающей данные - //connect(timer, SIGNAL(timeout()), SLOT(sendData())); - //соединим сигнал сокета receiveSocket о том, что данные готовы для - //чтения с функцией receiveData() - //connect(receiveSocket, SIGNAL(readyRead()),SLOT(receiveData())); - - //send_data.mode=Ruchnoi; - } - - ~UdpProtocol(){ - delete receiveSocket; - delete sendSocket; - } - - float getFrequency(){ - return m_frequency; - } - - QUdpSocket *getReceiveSocket(){ - return receiveSocket; - } - - QHostAddress ip_receiver(){return m_ip_receiver;} - QHostAddress ip_sender(){return m_ip_sender;} - int port_receiver(){return m_port_receiver;} - int port_sender(){return m_port_sender;} - float frequency(){return m_frequency;} - bool bindState(){return bindState_;} - void setCheckState(bool state) {checkState = state;} - -private: - bool bindState_=false; - bool checkState = true; - QUdpSocket *receiveSocket; //UDP-socket для приема данных - QUdpSocket *sendSocket; //UDP-socket для отпарвки данных - QHostAddress m_ip_receiver, m_ip_sender; - int m_port_receiver, m_port_sender; //номера портов приема и передачи - float m_frequency; //частота обмена данными ТНПА с ПУ - //функция вычисления контрольной суммы - uint checksum_i(const void * data, int size){ // function for checksum (uint) - uint c = 0; - for (int i = 0; i < size; ++i) - c += ((const uchar*)data)[i]; - return ~(c + 1); - } - - //проверка верна ли контрольная сумма - bool validate(const ReceiveStruct & data) { - if (!checkState) {return true;} - else { - uint crc= checksum_i(&data, sizeof(data) - 4); - return (data.checksum == crc); - } - } - bool validate(const SendStruct & data) { - if (!checkState) {return true;} - else return (data.checksum == checksum_i(&data, sizeof(data) - 4)); - } - void aboutSend() { - send_data.checksum = checksum_i(&send_data, sizeof(send_data) - 4); - } //функция, которая вычисляет контрольную сумму и записывает - //ее в переменную checksum структуры отправки - -public slots: - void sendData(){ - aboutSend();//считаем контрольную сумму и записываем ее в переменную checksum структуры send_data (типа SendStruct) - //Отсылаем структуру send_data на ip_sender на порт port_sender - sendSocket->writeDatagram((char *)&send_data, sizeof(send_data),m_ip_sender, m_port_sender); - // qDebug() <<"send to ip:" << m_ip_sender << "port:" << m_port_sender; - } //метод для отправки данных, который можно вызывать по сигналу таймера - void receiveData(){ - while(receiveSocket->hasPendingDatagrams()) { - ReceiveStruct rec;// создаем локальную переменную для приема данных до проверки - receiveSocket->pendingDatagramSize(); - receiveSocket->readDatagram((char *)&rec, sizeof(rec)); //считываем данные - - if (!validate(rec)) { - //Функция validate возвращает true - если контрольная сумма верна - //и возвращает false, если это не так - //в этой части функции контрольная сумма не верна - qDebug() << "Checksum validate" << validate(rec); - continue; - //оператор continue выполняет пропуск оставшейся части кода - // тела цикла и переходит к следующей итерации цикла - } - rec_data = rec;//Если контрльная сумма верна, то записываем - //принятые данные в структуру rec_data - } - } //слот для приема данных, который соединим с - //сигналом readyRead() сокета receiveSocket, который создается - //при наличии принятых пакетов - - - - int sendMessage(QByteArray ba){ - return (sendSocket->writeDatagram(ba,m_ip_sender,m_port_sender)); - } - }; - - class MetaUdpProtocol { - public: - MetaUdpProtocol(){ - timer = new QTimer(); - } - virtual QHostAddress ip_receiver(){ - return m_ip_receiver; - } - virtual QHostAddress ip_sender(){ - return m_ip_sender; - } - virtual int port_receiver(){ - return m_port_receiver; - } - virtual int port_sender(){ - return m_port_sender; - } - virtual QString errorReceiverPort(){ - return m_errorReceiverPort; - } - virtual QString errorSenderPort(){ - return m_errorSenderPort; - } - virtual int frequency(){ - return m_frequency; - } - QTimer *timer; //таймер для отправки данных с определенной частотой - virtual void set_ip_receiver (QHostAddress ip) {m_ip_receiver = ip;} - virtual void set_ip_sender (QHostAddress ip) {m_ip_sender = ip; } - virtual void set_port_receiver (int port) {m_port_receiver=port;} - virtual void set_port_sender (int port) {m_port_sender = port;} - private: - QString m_errorReceiverPort, m_errorSenderPort; - QHostAddress m_ip_receiver, m_ip_sender; //receiver - наше приложение - //sender - модель ТНПА - int m_port_receiver, m_port_sender; //номера портов приема и передачи - float m_frequency; //частота обмена данными ТНПА с ПУ - - -}; - -#endif // UDP_PROTOCOL_H diff --git a/UMAS_GUI-develop/compass/compass.cpp b/UMAS_GUI-develop/compass/compass.cpp deleted file mode 100755 index e4f9790..0000000 --- a/UMAS_GUI-develop/compass/compass.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "compass.h" - -Compass::Compass(QWidget *parent) : - QFrame(parent) { - setupUi(this); - setYaw(0); - setYawDesirable(0, 0, e_CSMode::MODE_MANUAL); -} - -void Compass::paintEvent(QPaintEvent *e) { - QPainter painter; - painter.begin(this); - QFont font; - painter.setRenderHint(QPainter::Antialiasing, true); // сглаживание - painter.translate(width() / 2, height() / 2); // перенос системы координат - int side = qMin(width(), height()); - painter.scale(side / 170, side / 170); // масштабирование СК - painter.save(); - painter.rotate(yaw); - painter.drawConvexPolygon(arrowCompass, 6); - painter.restore(); - painter.save(); - painter.setPen(Qt::NoPen); - painter.setBrush(Qt::red); - painter.rotate(yawDesirable); - painter.drawConvexPolygon(arrowDesirable, 4); - painter.restore(); - painter.save(); - painter.drawEllipse(-60, -60, 120, 120); - painter.drawEllipse(-70, -70, 140, 140); - for (int i = 0; i < 60; i++) { - if ((i % 5) != 0) - painter.drawLine(0, -55, 0, -60); - else { - painter.drawLine(0, -50, 0, -60); - font.setPointSize(5); - painter.setFont(font); - painter.drawText(-20, -85, 40, 40, Qt::AlignCenter | Qt::AlignTop, QString::number(i * 6)); - } - painter.rotate(6.0); - } - painter.setBrush(Qt::gray); - painter.drawRect(-15, -5, 30, 10); - font.setPointSize(10); - painter.drawText(-20, -10, 40, 20, Qt::AlignCenter, QString::number(yaw)); - painter.restore(); -} - -void Compass::setYaw(double yawNew) { - yaw = yawNew; - update(); -} - -void Compass::setYawDesirable(double yawDesirableNew, double YawFromIMU, e_CSMode mode) { - if (mode == e_CSMode::MODE_AUTOMATED) - yawDesirable = yawDesirableNew + YawFromIMU; - else - yawDesirable = yawDesirableNew; - update(); -} diff --git a/UMAS_GUI-develop/compass/compass.h b/UMAS_GUI-develop/compass/compass.h deleted file mode 100755 index 50a0850..0000000 --- a/UMAS_GUI-develop/compass/compass.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef COMPASS_H -#define COMPASS_H - -#include -#include -#include -#include -#include -#include "uv_state.h" - -class Compass : public QFrame, private Ui::Compass{ -Q_OBJECT - -public: - explicit Compass(QWidget *parent = nullptr); - -public slots: - /*! - * \brief setYaw метод установки текущего значения компаса. - * \param yawNew текущее значение компаса. - */ - void setYaw(double yawNew); - /*! - * \brief setYawDesirable метод установки управляющего значения компаса. - * \param yawDesirableNew управляющего значения компаса - * \param YawFromIMU текущее значение курса. - * \param mode ручной или - */ - void setYawDesirable(double yawDesirableNew, double YawFromIMU, e_CSMode mode); - -protected: - void paintEvent(QPaintEvent *e); - -private: - double yaw; - double yawDesirable; - QPoint arrowCompass[6] = { - QPoint(0, 50), - QPoint(0, -50), - QPoint(3, -40), - QPoint(0, -50), - QPoint(-3, -40), - QPoint(0, -50), - }; - QPoint arrowDesirable[4] = { - QPoint(0, -70), - QPoint(5, -85), - QPoint(-5, -85), - QPoint(0, -70) - }; -}; - -#endif // COMPASS_H diff --git a/UMAS_GUI-develop/compass/compass.ui b/UMAS_GUI-develop/compass/compass.ui deleted file mode 100755 index 80e638e..0000000 --- a/UMAS_GUI-develop/compass/compass.ui +++ /dev/null @@ -1,19 +0,0 @@ - - - Compass - - - - 0 - 0 - 600 - 400 - - - - Frame - - - - - diff --git a/UMAS_GUI-develop/img.qrc b/UMAS_GUI-develop/img.qrc deleted file mode 100755 index cedf7f0..0000000 --- a/UMAS_GUI-develop/img.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - img/setupIMU_for_agent.png - - diff --git a/UMAS_GUI-develop/img/setupIMU_for_agent.png b/UMAS_GUI-develop/img/setupIMU_for_agent.png deleted file mode 100755 index c7a40b72ef661175620c0de7dbbea9ab66e6222b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75333 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 z 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%0AwOiUwsN{+x~doPo6+TU8O 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 GU-=(ga0`b3 diff --git a/UMAS_GUI-develop/interface/i_basic_data.cpp b/UMAS_GUI-develop/interface/i_basic_data.cpp deleted file mode 100755 index 3f658d9..0000000 --- a/UMAS_GUI-develop/interface/i_basic_data.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "i_basic_data.h" - -UVState IBasicData::agent[2]; -int IBasicData::currentAgent; - - -IBasicData::IBasicData(QObject *parent) - : QObject{parent} -{} diff --git a/UMAS_GUI-develop/interface/i_basic_data.h b/UMAS_GUI-develop/interface/i_basic_data.h deleted file mode 100755 index 61d0333..0000000 --- a/UMAS_GUI-develop/interface/i_basic_data.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef IBASICDATA_H -#define IBASICDATA_H - -#include -#include - -#include "uv_state.h" - -/*! - * \brief IBasicData базовый информационный класс, имеющий глобальную переменную, - * которая хранит получаемую и передаваемую информацию о всех состояниях аппарата. - */ -class IBasicData : public QObject -{ - Q_OBJECT -public: - explicit IBasicData(QObject *parent = nullptr); - - // Static UV_State variable, which we will be accessing - static UVState agent[2]; - static int currentAgent; -}; - -#endif // IBASICDATA_H diff --git a/UMAS_GUI-develop/interface/i_control_data.cpp b/UMAS_GUI-develop/interface/i_control_data.cpp deleted file mode 100755 index 611cafc..0000000 --- a/UMAS_GUI-develop/interface/i_control_data.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "i_control_data.h" - -IControlData::IControlData() : - IBasicData() { - -} - -void IControlData::setControlData(ControlData data) { - agent[getCurrentAgent()].control = data; -} - -void IControlData::setMarch(double march) { - agent[getCurrentAgent()].control.march = march; -} - -void IControlData::setLag(double lag) { - agent[getCurrentAgent()].control.lag = lag; -} - -void IControlData::setDepth(double depth) { - agent[getCurrentAgent()].control.depth = depth; -} - -void IControlData::setRoll(double roll) { - agent[getCurrentAgent()].control.roll = roll; -} - -void IControlData::setPitch(double pitch) { - agent[getCurrentAgent()].control.pitch = pitch; -} - -void IControlData::setYaw(double yaw) { - agent[getCurrentAgent()].control.yaw = yaw; -} - -void IControlData::setGripping(quint8 gripping) { - agent[getCurrentAgent()].control.gripping = gripping; -} - -void IControlData::setRotman(quint8 rotman) { - agent[getCurrentAgent()].control.rotman = rotman; -} - -void IControlData::setOffPower(quint8 offPower) { - agent[getCurrentAgent()].control.offPower = offPower; -} - - - -int IControlData::getCurrentAgent() -{ - return currentAgent; -} - -bool IControlData::getCSMode() -{ - if (agent[getCurrentAgent()].cSMode == e_CSMode::MODE_AUTOMATED) - return true; - else - return false; -} - -DataAH127C IControlData::getImuData() { - return agent[getCurrentAgent()].imuData; -} - -ControlData IControlData::getControlData() -{ - return agent[getCurrentAgent()].control; -} diff --git a/UMAS_GUI-develop/interface/i_control_data.h b/UMAS_GUI-develop/interface/i_control_data.h deleted file mode 100755 index 5a646e5..0000000 --- a/UMAS_GUI-develop/interface/i_control_data.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef ICONTROLDATA_H -#define ICONTROLDATA_H - -#include "i_basic_data.h" - -/*! - * \brief IControlData class класс для получения и установки данных связанных - * с управляющими воздействиями и пультом управления. - */ -class IControlData : public IBasicData -{ -public: - IControlData(); - - - - void setControlData(ControlData data); - - void setMarch(double march); - void setLag(double lag); - void setDepth(double depth); - void setRoll(double roll); - void setPitch(double pitch); - void setYaw(double yaw); - - void setGripping(quint8 gripping); - void setRotman(quint8 rotman); - void setOffPower(quint8 offPower); - - int getCurrentAgent(); - bool getCSMode(); - DataAH127C getImuData(); - ControlData getControlData(); -}; - -#endif // ICONTROLDATA_H diff --git a/UMAS_GUI-develop/interface/i_server_data.cpp b/UMAS_GUI-develop/interface/i_server_data.cpp deleted file mode 100755 index a7c6cdb..0000000 --- a/UMAS_GUI-develop/interface/i_server_data.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "i_server_data.h" - -IServerData::IServerData() -{ - -} - -FromPult IServerData::generateFullMessage(int nmbAgent) { - FromPult data; - - data.controlData = agent[nmbAgent].control; - data.cSMode = agent[nmbAgent].cSMode; - data.pultUWB = agent[nmbAgent].pultUWB; - data.controlContoursFlags = agent[nmbAgent].controlContoursFlags; - data.modeAUV_selection = agent[nmbAgent].modeAUV_selection; - data.pMode = agent[nmbAgent].pMode; - data.flagAH127C_pult = agent[nmbAgent].flagAH127C_pult; - - - agent[nmbAgent].checksum_msg_gui_send = sizeof(data); - - return data; -} - -void IServerData::parseFullMessage(ToPult message, int nmbAgent) { - agent[nmbAgent].header = message.header; - - agent[nmbAgent].imuData = message.dataAH127C; - agent[nmbAgent].dataPressure = message.dataPressure; - agent[nmbAgent].flagAH127C_bort = message.flagAH127C_bort; - - agent[nmbAgent].auvData.modeReal = message.auvData.modeReal; - agent[nmbAgent].auvData.controlReal = message.auvData.controlReal; - agent[nmbAgent].auvData.modeAUV_Real = message.auvData.modeAUV_Real; - agent[nmbAgent].auvData.signalVMA_real = message.auvData.signalVMA_real; - agent[nmbAgent].auvData.ControlDataReal = message.auvData.ControlDataReal; - - agent[nmbAgent].checksum_msg_agent_send = message.checksum; - agent[nmbAgent].checksum_msg_gui_received = sizeof(message); -} diff --git a/UMAS_GUI-develop/interface/i_server_data.h b/UMAS_GUI-develop/interface/i_server_data.h deleted file mode 100755 index ae65eee..0000000 --- a/UMAS_GUI-develop/interface/i_server_data.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef ISERVERDATA_H -#define ISERVERDATA_H - -#include -#include -#include - -#include "i_basic_data.h" - -/*! - * \brief IServerData class класс обработки принимаемых и отправляемых значений. - */ -class IServerData : public IBasicData -{ -public: - IServerData(); - - /*! - * \brief generateFullMessage метод формирование посылки на агента. - * \return сформированная к отправке посылка. - */ - FromPult generateFullMessage(int nmbAgent); - - /*! - * \brief parseFullMessage метод распоковки посылки от агента. - * \param message посылка от агента. - */ - void parseFullMessage(ToPult message, int nmbAgent); -}; - -#endif // ISERVERDATA_H diff --git a/UMAS_GUI-develop/interface/i_user_interface_data.cpp b/UMAS_GUI-develop/interface/i_user_interface_data.cpp deleted file mode 100755 index 5c858b2..0000000 --- a/UMAS_GUI-develop/interface/i_user_interface_data.cpp +++ /dev/null @@ -1,225 +0,0 @@ -#include "i_user_interface_data.h" - -IUserInterfaceData::IUserInterfaceData() : IBasicData() -{ - -} - -// set-функции - -void IUserInterfaceData::setCurrentAgent(int newAgent) -{ - currentAgent = newAgent; -} - -void IUserInterfaceData::setFlagAH127C_pult(FlagAH127C_pult flagAH127C_pult) -{ - agent[getCurrentAgent()].flagAH127C_pult = flagAH127C_pult; -} - -void IUserInterfaceData::setPowerMode(power_Mode mode) { - agent[getCurrentAgent()].pMode = mode; - displayText_toConsole("Включен " + QString::number(static_cast(mode) + 2) + " режим питания"); -} - -void IUserInterfaceData::setControlContoursFlags(e_StabilizationContours contour, bool value) { - switch (contour) { - case e_StabilizationContours::CONTOUR_DEPTH: - agent[getCurrentAgent()].controlContoursFlags.depth = value; - if (value) - emit displayText_toConsole("Контур глубины замкнут"); - else - emit displayText_toConsole("Контур глубины разомкнут"); - break; - - case e_StabilizationContours::CONTOUR_LAG: - agent[getCurrentAgent()].controlContoursFlags.lag = value; - if (value){ - emit displayText_toConsole("Контур лага замкнут"); - }else - emit displayText_toConsole("Контур лага разомкнут"); - break; - - case e_StabilizationContours::CONTOUR_MARCH: - agent[getCurrentAgent()].controlContoursFlags.march = value; - if (value) - emit displayText_toConsole("Контур марша замкнут"); - else - emit displayText_toConsole("Контур марша разомкнут"); - break; - - case e_StabilizationContours::CONTOUR_PITCH: - agent[getCurrentAgent()].controlContoursFlags.pitch = value; - if (value) - emit displayText_toConsole("Контур дифферента замкнут"); - else - emit displayText_toConsole("Контур дифферента разомкнут"); - break; - - case e_StabilizationContours::CONTOUR_ROLL: - agent[getCurrentAgent()].controlContoursFlags.roll = value; - if (value) - emit displayText_toConsole("Контур крена замкнут"); - else - emit displayText_toConsole("Контур крена разомкнут"); - break; - - case e_StabilizationContours::CONTOUR_YAW: - agent[getCurrentAgent()].controlContoursFlags.yaw = value; - if (value) - emit displayText_toConsole("Контур курса замкнут"); - else - emit displayText_toConsole("Контур курса разомкнут"); - break; - } -} - -void IUserInterfaceData::setCSMode(e_CSMode mode) { - agent[getCurrentAgent()].cSMode = mode; - switch (static_cast(mode)) { - case 0: - emit displayText_toConsole("Включен ручной режим"); - break; - case 1: - emit displayText_toConsole("Включен автоматизированный режим"); - break; - case 2: - emit displayText_toConsole("Включен автоматический режим"); - break; - } -} - -void IUserInterfaceData::setModeSelection(bool mode) -{ - agent[getCurrentAgent()].modeAUV_selection = mode; - if (static_cast(mode)) - emit displayText_toConsole("Установлен вывод данных на модель"); - else - emit displayText_toConsole("Установлен вывод данных на агента"); -} - -void IUserInterfaceData::setDataPultUWB(PultUWB pultUWB) -{ - agent[getCurrentAgent()].pultUWB = pultUWB; -} - -void IUserInterfaceData::setMissionControl(mission_Control missionControl) -{ - agent[getCurrentAgent()].missionControl = missionControl; - switch (static_cast(missionControl)) { - case 0: - emit displayText_toConsole("Включен режим ожидания команд в автоматическом режиме"); - break; - case 1: - emit displayText_toConsole("Отправлен запрос на выполнение миссии"); - break; - case 2: - emit displayText_toConsole("Выполнение миссии отменено"); - break; - case 3: - emit displayText_toConsole("Выполнение миссии приостановлено"); - break; - } -} - -void IUserInterfaceData::setID_mission_AUV(quint8 ID_mission_AUV) -{ - agent[getCurrentAgent()].ID_mission_AUV = ID_mission_AUV; - switch (static_cast(ID_mission_AUV)) { - case 0: - emit displayText_toConsole("Миссия завершена, флаг сброшен"); - break; - case 1: - emit displayText_toConsole("Запущена миссия выхода в точку"); - break; - case 2: - emit displayText_toConsole("Запущена миссия следования"); - break; - case 3: - emit displayText_toConsole("Запущена миссия движения по траектории"); - break; - } -} - -// get-функции - -int IUserInterfaceData::getCurrentAgent() -{ - return currentAgent; -} - -int IUserInterfaceData::getChecksumMsgAgentSend() { - return agent[getCurrentAgent()].checksum_msg_agent_send; -} - -int IUserInterfaceData::getChecksumMsgGuiSend() { - return agent[getCurrentAgent()].checksum_msg_gui_send; -} - -int IUserInterfaceData::getChecksumMsgGuiReceived() { - return agent[getCurrentAgent()].checksum_msg_gui_received; -} - -ControlContoursFlags IUserInterfaceData::getControlContoursFlags() -{ - return agent[getCurrentAgent()].controlContoursFlags; -} - -bool IUserInterfaceData::getModeSelection() -{ - return agent[getCurrentAgent()].modeAUV_selection; -} - -FlagAH127C_bort IUserInterfaceData::getFlagAH127C_bort() -{ - return agent[getCurrentAgent()].flagAH127C_bort; -} - -FlagAH127C_pult IUserInterfaceData::getFlagAH127C_pult() -{ - return agent[getCurrentAgent()].flagAH127C_pult; -} - -power_Mode IUserInterfaceData::getPowerMode() -{ - return agent[getCurrentAgent()].pMode; -} - -e_CSMode IUserInterfaceData::getCSMode() -{ - return agent[getCurrentAgent()].cSMode; -} - -ControlData IUserInterfaceData::getControlData() { - return agent[getCurrentAgent()].control; -} - -DataAH127C IUserInterfaceData::getImuData() { - return agent[getCurrentAgent()].imuData; -} - -Header IUserInterfaceData::getHeader() { - return agent[getCurrentAgent()].header; -} - -AUVCurrentData IUserInterfaceData::getAUVCurrentData() { - return agent[getCurrentAgent()].auvData; -} - -DataPressure IUserInterfaceData::getDataPressure() { - return agent[getCurrentAgent()].dataPressure; -} - -DataUWB IUserInterfaceData::getDataUWB() { - return agent[getCurrentAgent()].dataUWB; -} - -DataUWB IUserInterfaceData::getDataUWB(int selectAgent) -{ - return agent[selectAgent].dataUWB; -} - -mission_Status IUserInterfaceData::getMissionStatus() -{ - return agent[getCurrentAgent()].missionStatus; -} diff --git a/UMAS_GUI-develop/interface/i_user_interface_data.h b/UMAS_GUI-develop/interface/i_user_interface_data.h deleted file mode 100755 index 98ffcd0..0000000 --- a/UMAS_GUI-develop/interface/i_user_interface_data.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef IUSERINTERFACEDATA_H -#define IUSERINTERFACEDATA_H - -#include "i_basic_data.h" -#include - - -/*! - * \brief IUserInterfaceData class класс для взаимодействия глобальной переменной - * состояний с главной формой. - */ -class IUserInterfaceData : public IBasicData -{ - Q_OBJECT -signals: - void displayText_toConsole(QString str); - -public: - IUserInterfaceData(); - - void setCurrentAgent(int newAgent); - void setFlagAH127C_pult(FlagAH127C_pult flagAH127C_pult); - void setPowerMode(power_Mode mode); - void setControlContoursFlags(e_StabilizationContours contour, bool value); - void setCSMode(e_CSMode mode); - void setModeSelection(bool mode); - void setDataPultUWB(PultUWB pultUWB); - void setMissionControl(mission_Control missionControl); - void setID_mission_AUV(quint8 ID_mission_AUV); - - - int getCurrentAgent(); - int getChecksumMsgAgentSend(); - int getChecksumMsgGuiSend(); - int getChecksumMsgGuiReceived(); - ControlContoursFlags getControlContoursFlags(); - bool getModeSelection(); - FlagAH127C_bort getFlagAH127C_bort(); - FlagAH127C_pult getFlagAH127C_pult(); - power_Mode getPowerMode(); - e_CSMode getCSMode(); - ControlData getControlData(); - DataAH127C getImuData(); - Header getHeader(); - AUVCurrentData getAUVCurrentData(); - DataPressure getDataPressure(); - DataUWB getDataUWB(); - DataUWB getDataUWB(int selectAgent); - mission_Status getMissionStatus(); - -}; - -#endif // IUSERINTERFACEDATA_H diff --git a/UMAS_GUI-develop/main.cpp b/UMAS_GUI-develop/main.cpp deleted file mode 100755 index fd3e533..0000000 --- a/UMAS_GUI-develop/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "mainwindow.h" - -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - MainWindow w; - w.show(); - return a.exec(); -} diff --git a/UMAS_GUI-develop/mainwindow.cpp b/UMAS_GUI-develop/mainwindow.cpp deleted file mode 100755 index 74c0c78..0000000 --- a/UMAS_GUI-develop/mainwindow.cpp +++ /dev/null @@ -1,1049 +0,0 @@ - #include "mainwindow.h" -#include "./ui_mainwindow.h" - -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) - , ui(new Ui::MainWindow) -{ - ui->setupUi(this); - - setConsole(); - setTimer_updateImpact(20); - setBottom(); - setTab(); - setMap(); - setUpdateUI(); - - pipeline = nullptr; // Инициализируем пайплайн как неактивный - - // Инициализация GStreamer - gst_init(nullptr, nullptr); - - // Получаем "внутренний" идентификатор нашего виджета для видео - videoWindowId = ui->videoWidget->winId(); - - ui->pushButton_Play_Pause->setText("Начать прием"); -} - -// - -void MainWindow::on_pushButton_Play_Pause_clicked() -{ - // Отправка видео с Raspberry Pi - QString command = "ssh -X agent1@192.168.1.11 " - "\"gst-launch-1.0 v4l2src device=/dev/video0 ! " - "image/jpeg,width=100,height=100,framerate=30/1 ! " - "jpegparse ! rtpjpegpay ! udpsink host=192.168.1.6 port=5000\""; - - QProcess *sshProcess = new QProcess(this); - sshProcess->start(command); - - if (!pipeline) { // Если пайплайн не запущен, запускаем его - qDebug() << "Starting pipeline..."; - - // Приём видео на ПК через xvimagesink - const char *pipeline_str = - "udpsrc port=5000 ! application/x-rtp,encoding-name=JPEG,payload=96 ! " - "rtpjpegdepay ! jpegdec ! videoconvert ! xvimagesink name=sink"; - - GError *error = nullptr; - pipeline = gst_parse_launch(pipeline_str, &error); - - if (error) { - qWarning() << "Failed to create pipeline:" << error->message; - g_error_free(error); - return; - } - - // Находим элемент sink и привязываем к нашему QWidget - GstElement *sink = gst_bin_get_by_name(GST_BIN(pipeline), "sink"); - if (!sink) { - qWarning() << "Could not find sink element"; - gst_object_unref(pipeline); - pipeline = nullptr; - return; - } - - if (GST_IS_VIDEO_OVERLAY(sink)) { - gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink), videoWindowId); - } else { - qWarning() << "Sink is not video overlay capable!"; - } - gst_object_unref(sink); - - // Запускаем пайплайн - gst_element_set_state(pipeline, GST_STATE_PLAYING); - ui->pushButton_Play_Pause->setText("Остановить прием"); - - } else { // Если пайплайн уже работает, останавливаем его - qDebug() << "Stopping pipeline..."; - gst_element_set_state(pipeline, GST_STATE_NULL); - gst_object_unref(pipeline); - pipeline = nullptr; - ui->pushButton_Play_Pause->setText("Начать прием"); - } -} - - -void MainWindow::setConsole() -{ - displayText("Приложение работает"); - displayText("Установите соединение для работы с агентом"); - - connect(&uv_interface, SIGNAL(displayText_toConsole(QString)), - this, SLOT(displayText(QString))); -} - -void MainWindow::displayText(QString str) -{ - QString currentTime = QTime::currentTime().toString("HH:mm:ss"); - qInfo() << currentTime << str; - ui->textEdit_console->append(currentTime + " " + str); -} - -// - -void MainWindow::setTimer_updateImpact(int periodUpdateMsec) -{ - joyStick = new JoyStick(this); - connect(ui->radioButton_useJoyStick, &QRadioButton::clicked, - this, &MainWindow::useJoyStick); - connect(ui->radioButton_useKeyBoard, &QRadioButton::clicked, - this, &MainWindow::useKeyBoard); - QTimer *updateTimer = new QTimer(this); - connect( - updateTimer, SIGNAL(timeout()), - this, SLOT(updateUi_fromControl()) - ); - updateTimer->start(periodUpdateMsec); - displayText("Таймер обновления джойстика запущен"); -} - -void MainWindow::useKeyBoard() -{ - delete joyStick; - - keyBoard = new KeyBoard(this); - displayText("Используемые клавиши(должна быть английская раскладка):\n" - "Клавиша O - вперед по маршу\n" - "Клавиша L - назад по маршу\n" - "Клавиша W - вниз по дифференту\n" - "Клавиша S - вверх по дифференту\n" - "Клавиша A - влево по курсу\n" - "Клавиша D - вправо по курсу\n" - "Клавиша C - вниз по глубине\n" - "Клавиша V - вверх по глубине\n" - "Клавиша Q - влево по крену\n" - "Клавиша E - вправо по крену\n" - "Клавиша K - влево по лагу\n" - "Клавиша ; - вправо по лагу\n"); - -} - -void MainWindow::useJoyStick() -{ - delete keyBoard; - - joyStick = new JoyStick(this); - - connect( - joyStick, SIGNAL(offPower()), - this, SLOT(pushButton_on_powerMode_2()) - ); -} - -void MainWindow::keyPressEvent(QKeyEvent *event) -{ - keyBoard->keyPressEvent(event); - -} - -void MainWindow::keyReleaseEvent(QKeyEvent *event) -{ - keyBoard->keyReleaseEvent(event); -} - -void MainWindow::updateUi_fromControl(){ - - ControlData control = uv_interface.getControlData(); - DataAH127C imuData = uv_interface.getImuData(); - - ui->label_impactDataDepth->setText(QString::number(control.depth, 'f', 2)); - ui->label_impactDataRoll->setText(QString::number(control.roll, 'f', 2)); - ui->label_impactDataPitch->setText(QString::number(control.pitch, 'f', 2)); - ui->label_impactDataYaw->setText(QString::number(control.yaw, 'f', 2)); - ui->label_impactDataMarch->setText(QString::number(control.march, 'f', 2)); - ui->label_impactDataLag->setText(QString::number(control.lag, 'f', 2)); - - ui->compass->setYawDesirable(control.yaw, imuData.yaw, uv_interface.getCSMode()); -} - -// - -void MainWindow::setBottom() -{ - setBottom_mode(); - setBottom_modeAutomated(); - setBottom_modeAutomatic(); - setBottom_powerMode(); - setBottom_connection(); - setBottom_modeSelection(); - setBottom_setupIMU(); - setBottom_setupIMU_check(); - setBottom_selectAgent(); -} - -void MainWindow::setBottom_mode() -{ - ui->pushButton_modeManual->setCheckable(true); - ui->pushButton_modeAutomated->setCheckable(true); - ui->pushButton_modeAutomatic->setCheckable(true); - QButtonGroup *mode = new QButtonGroup(this); - mode->addButton(ui->pushButton_modeManual); - mode->addButton(ui->pushButton_modeAutomated); - mode->addButton(ui->pushButton_modeAutomatic); - mode->setExclusive(true); - - ui->pushButton_modeManual->setChecked(true); - e_CSModeManualToggled(); - - connect( - ui->pushButton_modeManual, SIGNAL(clicked()), - this, SLOT(e_CSModeManualToggled())); - - connect( - ui->pushButton_modeAutomated, SIGNAL(clicked()), - this, SLOT(e_CSModeAutomatedToggled())); - - connect( - ui->pushButton_modeAutomatic, SIGNAL(clicked()), - this, SLOT(e_CSModeAutomaticToggled())); -} - -void MainWindow::e_CSModeManualToggled() { - uv_interface.setCSMode(e_CSMode::MODE_MANUAL); -} - -void MainWindow::e_CSModeAutomatedToggled() { - uv_interface.setCSMode(e_CSMode::MODE_AUTOMATED); -} - -void MainWindow::e_CSModeAutomaticToggled() -{ - uv_interface.setCSMode(e_CSMode::MODE_AUTOMATIC); - ui->stackedWidget_mode->setCurrentIndex(1); -} - -void MainWindow::setBottom_modeAutomatic() -{ - connect( - ui->pushButton_after, SIGNAL(clicked()), - this, SLOT(test_automatic_after())); - - connect( - ui->pushButton_missionControl_modeIdle, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionControl_modeIdle); - connect( - ui->pushButton_missionControl_modeStart, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionControl_modeStart); - connect( - ui->pushButton_missionControl_modeCancel, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionControl_modeCancel); - connect( - ui->pushButton_missionControl_modeStop, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionControl_modeStop); - connect( - ui->pushButton_missionControl_modeComplete, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionControl_modeComplete); - - connect( - ui->pushButton_missionPlanning_goto, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionPlanning_goto); - connect( - ui->pushButton_missionPlanning_goto_update, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionPlanning_goto_update); - connect( - this, &MainWindow::signal_pushButton_missionPlanning_goto_updateMap, - ui->map, &Map::updateUi_missionPlanning_goto_goal); - connect( - ui->pushButton_missionPlanning_goto_back, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionPlanning_goto_back); - connect( - ui->pushButton_missionPlanning_goto_clean, &QPushButton::clicked, - ui->map, &Map::updateUi_missionPlanning_goto_goal_clear); - connect( - ui->pushButton_missionPlanning_goto_on_trajectory, &QPushButton::clicked, - ui->map, &Map::updateUi_missionPlanning_goto_traj_onoff); - connect( - ui->pushButton_missionPlanning_goto_on_trajectory_clear, &QPushButton::clicked, - ui->map, &Map::updateUi_missionPlanning_goto_traj_clear); - - connect( - ui->pushButton_missionPlanning_go_trajectory_update, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionPlanning_go_trajectory_update); - connect( - this, &MainWindow::signal_pushButton_missionPlanning_go_trajectory_updateMap, - ui->map, &Map::updateUi_missionPlanning_goto_goal); - connect( - ui->pushButton_missionPlanning_go_trajectory_back, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionPlanning_go_trajectory_back); - connect( - ui->pushButton_missionPlanning_go_trajectory_clean, &QPushButton::clicked, - ui->map, &Map::updateUi_missionPlanning_goto_goal_clear); - - - connect( - ui->pushButton_missionPlanning_following, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionPlanning_following); - connect( - ui->pushButton_missionPlanning_go_trajectory, &QPushButton::clicked, - this, &MainWindow::slot_pushButton_missionPlanning_go_trajectory); - -} - -void MainWindow::test_automatic_after() -{ - ui->stackedWidget_mode->setCurrentIndex(0); - ui->stackedWidget_missionPlanning->setCurrentIndex(0); -} - -void MainWindow::slot_pushButton_missionControl_modeIdle() -{ - uv_interface.setMissionControl(mission_Control::MODE_IDLE); -} -void MainWindow::slot_pushButton_missionControl_modeStart() -{ - uv_interface.setMissionControl(mission_Control::MODE_START); -} -void MainWindow::slot_pushButton_missionControl_modeCancel() -{ - uv_interface.setMissionControl(mission_Control::MODE_CANCEL); -} -void MainWindow::slot_pushButton_missionControl_modeStop() -{ - uv_interface.setMissionControl(mission_Control::MODE_STOP); -} -void MainWindow::slot_pushButton_missionControl_modeComplete() -{ - uv_interface.setMissionControl(mission_Control::MODE_COMPLETE); - uv_interface.setID_mission_AUV(0); -} - -void MainWindow::slot_pushButton_missionPlanning_goto() -{ - uv_interface.setID_mission_AUV(1); - ui->stackedWidget_missionPlanning->setCurrentIndex(2); - displayText("Задайте параметры для выхода в точку"); -} - -void MainWindow::slot_pushButton_missionPlanning_goto_update() -{ - double x = ui->doubleSpinBox_missionPlanning_goto_x->value(); - double y = ui->doubleSpinBox_missionPlanning_goto_y->value(); - double r = ui->doubleSpinBox_missionPlanning_goto_r->value(); - - emit signal_pushButton_missionPlanning_goto_updateMap(x,y,r,0); - displayText("Установлена координата для выхода в точку и" - " радиус удержания позиции"); -} - -void MainWindow::slot_pushButton_missionPlanning_goto_back() -{ - ui->stackedWidget_missionPlanning->setCurrentIndex(0); -} - -void MainWindow::slot_pushButton_missionPlanning_go_trajectory_update() -{ - double x1 = ui->doubleSpinBox_missionPlanning_go_trajectory_x_1->value(); - double y1 = ui->doubleSpinBox_missionPlanning_go_trajectory_y_1->value(); - double r1 = ui->doubleSpinBox_missionPlanning_go_trajectory_r_1->value(); - - double x2 = ui->doubleSpinBox_missionPlanning_go_trajectory_x_2->value(); - double y2 = ui->doubleSpinBox_missionPlanning_go_trajectory_y_2->value(); - double r2 = ui->doubleSpinBox_missionPlanning_go_trajectory_r_2->value(); - - double x3 = ui->doubleSpinBox_missionPlanning_go_trajectory_x_3->value(); - double y3 = ui->doubleSpinBox_missionPlanning_go_trajectory_y_3->value(); - double r3 = ui->doubleSpinBox_missionPlanning_go_trajectory_r_3->value(); - - emit signal_pushButton_missionPlanning_go_trajectory_updateMap(x1,y1,r1,0); - emit signal_pushButton_missionPlanning_go_trajectory_updateMap(x2,y2,r2,0); - emit signal_pushButton_missionPlanning_go_trajectory_updateMap(x3,y3,r3,0); - displayText("Установлены координаты для движения по траектории и" - " радиус удержания позиций"); -} - -void MainWindow::slot_pushButton_missionPlanning_go_trajectory_back() -{ - ui->stackedWidget_missionPlanning->setCurrentIndex(0); -} - -void MainWindow::slot_pushButton_missionPlanning_following() -{ - uv_interface.setID_mission_AUV(2); -} - -void MainWindow::slot_pushButton_missionPlanning_go_trajectory() -{ - uv_interface.setID_mission_AUV(3); - ui->stackedWidget_missionPlanning->setCurrentIndex(1); -} - -void MainWindow::updateUi_DataMission() -{ - int missionStatus = static_cast(uv_interface.getMissionStatus()); - switch (missionStatus) { - case 0: - ui->label_missonStatus->setText("ожидание"); - break; - case 1: - ui->label_missonStatus->setText("ошибка инициализации миссии"); - break; - case 2: - ui->label_missonStatus->setText("миссия запущена и выполняется"); - break; - case 3: - ui->label_missonStatus->setText("миссия приостановлена, на паузе"); - break; - case 4: - ui->label_missonStatus->setText("миссия завершена"); - break; - } -} - - - -void MainWindow::setBottom_modeAutomated() -{ - ui->pushButton_modeAutomated_march->setCheckable(true); - ui->pushButton_modeAutomated_lag->setCheckable(true); - ui->pushButton_modeAutomated_psi->setCheckable(true); - ui->pushButton_modeAutomated_tetta->setCheckable(true); - ui->pushButton_modeAutomated_gamma->setCheckable(true); - ui->pushButton_modeAutomated_depth->setCheckable(true); - QButtonGroup *modeAutomated = new QButtonGroup(this); - modeAutomated->addButton(ui->pushButton_modeAutomated_march); - modeAutomated->addButton(ui->pushButton_modeAutomated_lag); - modeAutomated->addButton(ui->pushButton_modeAutomated_psi); - modeAutomated->addButton(ui->pushButton_modeAutomated_tetta); - modeAutomated->addButton(ui->pushButton_modeAutomated_gamma); - modeAutomated->addButton(ui->pushButton_modeAutomated_depth); - modeAutomated->setExclusive(false); - - ui->pushButton_modeAutomated_gamma->setChecked(true); - ui->pushButton_modeAutomated_lag->setChecked(true); - ui->pushButton_modeAutomated_march->setChecked(true); - ui->pushButton_modeAutomated_psi->setChecked(true); - ui->pushButton_modeAutomated_tetta->setChecked(true); - ui->pushButton_modeAutomated_depth->setChecked(true); - - connect( - ui->pushButton_modeAutomated_gamma, SIGNAL(toggled(bool)), - this, SLOT(stabilizeRollToggled(bool))); - - connect( - ui->pushButton_modeAutomated_lag, SIGNAL(toggled(bool)), - this, SLOT(stabilizeLagToggled(bool))); - - connect( - ui->pushButton_modeAutomated_march, SIGNAL(toggled(bool)), - this, SLOT(stabilizeMarchToggled(bool))); - - connect( - ui->pushButton_modeAutomated_psi, SIGNAL(toggled(bool)), - this, SLOT(stabilizeYawToggled(bool))); - - connect( - ui->pushButton_modeAutomated_tetta, SIGNAL(toggled(bool)), - this, SLOT(stabilizePitchToggled(bool))); - - connect( - ui->pushButton_modeAutomated_depth, SIGNAL(toggled(bool)), - this, SLOT(stabilizeDepthToggled(bool))); -} - -void MainWindow::stabilizeRollToggled(bool state) { - uv_interface.setControlContoursFlags(e_StabilizationContours::CONTOUR_ROLL, state); -} - -void MainWindow::stabilizeLagToggled(bool state) { - uv_interface.setControlContoursFlags(e_StabilizationContours::CONTOUR_LAG, state); -} - -void MainWindow::stabilizeMarchToggled(bool state) { - uv_interface.setControlContoursFlags(e_StabilizationContours::CONTOUR_MARCH, state); -} - -void MainWindow::stabilizeYawToggled(bool state) { - uv_interface.setControlContoursFlags(e_StabilizationContours::CONTOUR_YAW, state); -} - -void MainWindow::stabilizePitchToggled(bool state) { - uv_interface.setControlContoursFlags(e_StabilizationContours::CONTOUR_PITCH, state); -} - -void MainWindow::stabilizeDepthToggled(bool state) { - uv_interface.setControlContoursFlags(e_StabilizationContours::CONTOUR_DEPTH, state); -} - -void MainWindow::setBottom_powerMode() -{ - QButtonGroup *powerMode = new QButtonGroup(this); - powerMode->addButton(ui->pushButton_powerMode_2); - powerMode->addButton(ui->pushButton_powerMode_3); - powerMode->addButton(ui->pushButton_powerMode_4); - powerMode->addButton(ui->pushButton_powerMode_5); - - ui->pushButton_powerMode_2->setCheckable(true); - ui->pushButton_powerMode_3->setCheckable(true); - ui->pushButton_powerMode_4->setCheckable(true); - ui->pushButton_powerMode_5->setCheckable(true); - - uv_interface.setPowerMode(power_Mode::MODE_2); - ui->pushButton_powerMode_2->setChecked(true); - - connect( - ui->pushButton_powerMode_2, SIGNAL(clicked()), - this, SLOT(pushButton_on_powerMode_2())); - - connect( - ui->pushButton_powerMode_3, SIGNAL(clicked()), - this, SLOT(pushButton_on_powerMode_3())); - - connect( - ui->pushButton_powerMode_4, SIGNAL(clicked()), - this, SLOT(pushButton_on_powerMode_4())); - - connect( - ui->pushButton_powerMode_5, SIGNAL(clicked()), - this, SLOT(pushButton_on_powerMode_5())); -} - -void MainWindow::pushButton_on_powerMode_2() -{ - uv_interface.setPowerMode(power_Mode::MODE_2); -} - -void MainWindow::pushButton_on_powerMode_3() -{ - uv_interface.setPowerMode(power_Mode::MODE_3); -} - -void MainWindow::pushButton_on_powerMode_4() -{ - uv_interface.setPowerMode(power_Mode::MODE_4); -} - -void MainWindow::pushButton_on_powerMode_5() -{ - before_powerMode = uv_interface.getPowerMode(); - uv_interface.setPowerMode(power_Mode::MODE_5); - - ui->pushButton_powerMode_2->setEnabled(false); - ui->pushButton_powerMode_3->setEnabled(false); - ui->pushButton_powerMode_4->setEnabled(false); - ui->pushButton_powerMode_5->setEnabled(false); - - timer_off_powerMode_5 = new QTimer(this); - connect( - timer_off_powerMode_5, SIGNAL(timeout()), - this, SLOT(off_powerMode_5())); - timer_off_powerMode_5->start(5000); -} - -void MainWindow::off_powerMode_5() -{ - timer_off_powerMode_5->stop(); - uv_interface.setPowerMode(before_powerMode); - - switch (before_powerMode) { - case power_Mode::MODE_2: - ui->pushButton_powerMode_2->setChecked(true); - break; - - case power_Mode::MODE_3: - ui->pushButton_powerMode_3->setChecked(true); - break; - - case power_Mode::MODE_4: - ui->pushButton_powerMode_4->setChecked(true); - break; - } - - ui->pushButton_powerMode_2->setEnabled(true); - ui->pushButton_powerMode_3->setEnabled(true); - ui->pushButton_powerMode_4->setEnabled(true); - ui->pushButton_powerMode_5->setEnabled(true); -} - -void MainWindow::setBottom_connection() -{ - ui->pushButton_breakConnection->setEnabled(false); - - connect( - ui->pushButton_connection, SIGNAL(clicked()), - this, SLOT(setConnection())); - connect( - ui->pushButton_breakConnection, SIGNAL(clicked()), - this, SLOT(breakConnection())); -} - -void MainWindow::setConnection() -{ - ui->pushButton_connection->setEnabled(false); - ui->pushButton_breakConnection->setEnabled(true); - communicationAgent1 = new Pult::PC_Protocol(QHostAddress("192.168.1.111"), 13053, - QHostAddress("192.168.1.11"), 13052, 10, 0); - communicationAgent2 = new Pult::PC_Protocol(QHostAddress("192.168.13.102"), 13057, - QHostAddress("192.168.13.3"), 13058, 10, 1); - -// communicationAgent1 = new Pult::PC_Protocol(QHostAddress("192.168.1.10"), 13055, -// QHostAddress("192.168.1.3"), 13054, 10, 0); -// communicationAgent2 = new Pult::PC_Protocol(QHostAddress("192.168.1.10"), 13053, -// QHostAddress("192.168.1.11"), 13052, 10, 1); - - - communicationAgent1->startExchange(); - communicationAgent2->startExchange(); - - if (communicationAgent1->bindState() || communicationAgent2->bindState()) { - displayText("Соединение установлено"); - - connect(communicationAgent1, SIGNAL(dataReceived()), - this, SLOT(updateUi_fromAgent1())); - connect(communicationAgent2, SIGNAL(dataReceived()), - this, SLOT(updateUi_fromAgent2())); - updateStatePushButton(); - - } else { - ui->pushButton_connection->setEnabled(true); - ui->pushButton_breakConnection->setEnabled(false); - displayText("Попробуйте снова"); - } - - if (communicationAgent1->bindState()){ - ui->pushButton_selectAgent1->setStyleSheet("background-color: green"); - displayText("Соединение c 1 агентом установлено"); - } else { - ui->pushButton_selectAgent1->setStyleSheet("background-color: red"); - displayText("Соединение c 1 агентом не установлено"); - } - if (communicationAgent2->bindState()){ - ui->pushButton_selectAgent2->setStyleSheet("background-color: green"); - displayText("Соединение c 2 агентом установлено"); - } else { - ui->pushButton_selectAgent2->setStyleSheet("background-color: red"); - displayText("Соединение c 2 агентом не установлено"); - } -} - -void MainWindow::updateUi_fromAgent1() { - DataAH127C imuData = uv_interface.getImuData(); - DataUWB dataUWB = uv_interface.getDataUWB(); - - emit updateCompass(imuData.yaw); - emit updateIMU(imuData); - emit updateSetupMsg(); - emit updateMap(dataUWB); - emit updateDataMission(); -} - -void MainWindow::updateUi_fromAgent2() -{ - DataUWB dataUWB_agent2 = uv_interface.getDataUWB(1); - emit updateMapForAgent2(dataUWB_agent2); -} - -void MainWindow::breakConnection() -{ - ui->pushButton_connection->setEnabled(true); - - displayText("Соединение разорвано"); - communicationAgent1->stopExhange(); - - delete communicationAgent1; - - ui->pushButton_breakConnection->setEnabled(false); -} - -// - -void MainWindow::setBottom_modeSelection() -{ - setModeSelection(0); - connect( - ui->comboBox_modeSelection, SIGNAL(activated(int)), - this, SLOT(setModeSelection(int))); -} - -void MainWindow::setModeSelection(int index) -{ - - if (index == 1){ - uv_interface.setModeSelection(0); //агент - } - else{ - uv_interface.setModeSelection(1); //модель - } -} - -void MainWindow::setBottom_setupIMU() -{ - connect( - ui->pushButton_setupIMU, SIGNAL(clicked()), - this, SLOT(getWindow_setupIMU())); -} - -void MainWindow::getWindow_setupIMU() -{ - SetupIMU window_setupIMU; - window_setupIMU.setModal(false); - window_setupIMU.exec(); -} - -// - -void MainWindow::setBottom_setupIMU_check() -{ - connect( - ui->pushButton_setupIMU_check, SIGNAL(clicked()), - this, SLOT(getWindow_setupIMU_check())); -} - -void MainWindow::setBottom_selectAgent() -{ - ui->pushButton_selectAgent1->setCheckable(true); - ui->pushButton_selectAgent2->setCheckable(true); - QButtonGroup *buttonGroup_selectAgent = new QButtonGroup(this); - buttonGroup_selectAgent->addButton(ui->pushButton_selectAgent1); - buttonGroup_selectAgent->addButton(ui->pushButton_selectAgent2); - buttonGroup_selectAgent->setExclusive(true); - - ui->pushButton_selectAgent1->setChecked(true); - - connect(ui->pushButton_selectAgent1, &QAbstractButton::toggled, - this, &MainWindow::pushButton_selectAgent1); - connect(ui->pushButton_selectAgent2, &QAbstractButton::toggled, - this, &MainWindow::pushButton_selectAgent2); - connect(this, &MainWindow::updateStatePushButton, - this, &MainWindow::updateUi_statePushButton); -} - -void MainWindow::pushButton_selectAgent1(bool stateBottom) -{ - if (stateBottom){ - uv_interface.setCurrentAgent(0); - displayText("Установлен ввод и вывод данных с агента 1"); - } - updateStatePushButton(); -} - -void MainWindow::pushButton_selectAgent2(bool stateBottom) -{ - if (stateBottom){ - uv_interface.setCurrentAgent(1); - displayText("Установлен ввод и вывод данных с агента 2"); - } - updateStatePushButton(); -} - -void MainWindow::updateUi_statePushButton() -{ - // вывод данных: модель/агент - if (uv_interface.getModeSelection()) - ui->comboBox_modeSelection->setCurrentIndex(0); - else - ui->comboBox_modeSelection->setCurrentIndex(1); - - // режим питания - switch (uv_interface.getPowerMode()) { - case power_Mode::MODE_2: - ui->pushButton_powerMode_2->setChecked(true); - break; - case power_Mode::MODE_3: - ui->pushButton_powerMode_3->setChecked(true); - break; - case power_Mode::MODE_4: - ui->pushButton_powerMode_4->setChecked(true); - break; - case power_Mode::MODE_5: - ui->pushButton_powerMode_5->setChecked(true); - break; - } - - // - switch (uv_interface.getCSMode()) { - case e_CSMode::MODE_MANUAL: - ui->pushButton_modeManual->setChecked(true); - break; - case e_CSMode::MODE_AUTOMATED: - ui->pushButton_modeAutomated->setChecked(true); - break; - case e_CSMode::MODE_AUTOMATIC: - ui->pushButton_modeAutomatic->setChecked(true); - break; - } - - ControlContoursFlags state_controlContoursFlags = uv_interface.getControlContoursFlags(); - if (state_controlContoursFlags.yaw) - ui->pushButton_modeAutomated_psi->setChecked(true); - else - ui->pushButton_modeAutomated_psi->setChecked(false); - if (state_controlContoursFlags.roll) - ui->pushButton_modeAutomated_gamma->setChecked(true); - else - ui->pushButton_modeAutomated_gamma->setChecked(false); - if (state_controlContoursFlags.pitch) - ui->pushButton_modeAutomated_tetta->setChecked(true); - else - ui->pushButton_modeAutomated_tetta->setChecked(false); - if (state_controlContoursFlags.march) - ui->pushButton_modeAutomated_march->setChecked(true); - else - ui->pushButton_modeAutomated_march->setChecked(false); - if (state_controlContoursFlags.lag) - ui->pushButton_modeAutomated_lag->setChecked(true); - else - ui->pushButton_modeAutomated_lag->setChecked(false); - if (state_controlContoursFlags.depth) - ui->pushButton_modeAutomated_depth->setChecked(true); - else - ui->pushButton_modeAutomated_depth->setChecked(false); - - - - -} - -void MainWindow::getWindow_setupIMU_check() -{ - SetupIMU_check window_setupIMU_check; - window_setupIMU_check.setModal(false); - window_setupIMU_check.exec(); -} - -// - -void MainWindow::setTab() -{ - ui->tabWidget->setTabText(0, "Карта"); - ui->tabWidget->setTabText(1, "БСО"); - ui->tabWidget->setTabText(2, "Контроль сообщений"); - ui->tabWidget->setTabText(3, "Режимы питания"); - ui->tabWidget->setTabText(4, "Видео"); // таб с видео -} - -// - -void MainWindow::setMap() -{ - connect(ui->map, SIGNAL(sendLocationUWB(double*,double*)), - this, SLOT(setLocationUWB(double*,double*))); -} - -void MainWindow::setLocationUWB(double *x, double *y) -{ - PultUWB pultUWB; - - for (int count = 0; count < 2; count++) - { - pultUWB.beacon_x[count] = *x; - pultUWB.beacon_y[count] = *y; - x++; - y++; - } - - uv_interface.setDataPultUWB(pultUWB); -} - -// - -void MainWindow::setUpdateUI() -{ - connect(this, SIGNAL(updateCompass(float)), - this, SLOT(updateUi_Compass(float))); - connect(this, SIGNAL(updateIMU(DataAH127C)), - this, SLOT(updateUi_IMU(DataAH127C))); - connect(this, SIGNAL(updateSetupMsg()), - this, SLOT(updateUi_SetupMsg())); - connect(this, SIGNAL(updateDataMission()), - this, SLOT(updateUi_DataMission())); - - connect(this, SIGNAL(updateMap(DataUWB)), - ui->map,SLOT(updateUi_map(DataUWB))); - connect(this, SIGNAL(updateMapForAgent2(DataUWB)), - ui->map,SLOT(updateUi_map2(DataUWB))); -} - -void MainWindow::updateUi_Compass(float yaw) { - ui->compass->setYaw(yaw); -} - -void MainWindow::updateUi_IMU(DataAH127C imuData){ - ui->label_IMUdata_accel_X->setText(QString::number(imuData.X_accel, 'f', 2)); - ui->label_IMUdata_accel_Y->setText(QString::number(imuData.Y_accel, 'f', 2)); - ui->label_IMUdata_accel_Z->setText(QString::number(imuData.Z_accel, 'f', 2)); - - ui->label_IMUdata_rate_X->setText(QString::number(imuData.X_rate, 'f', 2)); - ui->label_IMUdata_rate_Y->setText(QString::number(imuData.Y_rate, 'f', 2)); - ui->label_IMUdata_rate_Z->setText(QString::number(imuData.Z_rate, 'f', 2)); - - ui->label_IMUdata_magn_X->setText(QString::number(imuData.X_magn, 'f', 2)); - ui->label_IMUdata_magn_Y->setText(QString::number(imuData.Y_magn, 'f', 2)); - ui->label_IMUdata_magn_Z->setText(QString::number(imuData.Z_magn, 'f', 2)); - - ui->label_IMUdata_q0->setText(QString::number(imuData.quat[0], 'f', 2)); - ui->label_IMUdata_q1->setText(QString::number(imuData.quat[1], 'f', 2)); - ui->label_IMUdata_q2->setText(QString::number(imuData.quat[2], 'f', 2)); - ui->label_IMUdata_q3->setText(QString::number(imuData.quat[3], 'f', 2)); - - ui->label_IMUdata_yaw->setText(QString::number(imuData.yaw, 'f', 2)); - ui->label_IMUdata_pitch->setText(QString::number(imuData.pitch, 'f', 2)); - ui->label_IMUdata_roll->setText(QString::number(imuData.roll, 'f', 2)); -} - -void MainWindow::updateUi_SetupMsg() -{ - power_Mode pMode = uv_interface.getPowerMode(); - bool modeSelection = uv_interface.getModeSelection(); - - ControlContoursFlags controlContoursFlags = uv_interface.getControlContoursFlags(); - ControlData control = uv_interface.getControlData(); - AUVCurrentData auvData = uv_interface.getAUVCurrentData(); - FlagAH127C_bort flagAH127C_bort = uv_interface.getFlagAH127C_bort(); - FlagAH127C_pult flagAH127C_pult = uv_interface.getFlagAH127C_pult(); - int checksum_msg_gui_send = uv_interface.getChecksumMsgGuiSend(); - int checksum_msg_agent_send = uv_interface.getChecksumMsgAgentSend(); - int checksum_msg_gui_received = uv_interface.getChecksumMsgGuiReceived(); - -// send - - ui->label_tab_setupMsg_send_powerMode_count->setNum(2+static_cast(pMode)); - - if (modeSelection == 1) - ui->label_tab_setupMsg_send_modeAUV_selection_mode->setText("модель"); - else - ui->label_tab_setupMsg_send_modeAUV_selection_mode->setText("агент"); - - switch (uv_interface.getCSMode()) { - case e_CSMode::MODE_MANUAL: - ui->label_tab_setupMsg_send_cSMode_count->setText("ручной"); - break; - case e_CSMode::MODE_AUTOMATED: - ui->label_tab_setupMsg_send_cSMode_count->setText("автоматизированный"); - break; - case e_CSMode::MODE_AUTOMATIC: - ui->label_tab_setupMsg_send_cSMode_count->setText("автоматический"); - break; - } - - if (controlContoursFlags.yaw) { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_yaw->setText("замкнут"); - } else { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_yaw->setText("незамкнут"); - } - - if (controlContoursFlags.pitch) { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_pitch->setText("замкнут"); - } else { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_pitch->setText("незамкнут"); - } - - if (controlContoursFlags.roll) { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_roll->setText("замкнут"); - } else { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_roll->setText("незамкнут"); - } - - if (controlContoursFlags.march) { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_march->setText("замкнут"); - } else { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_march->setText("незамкнут"); - } - - if (controlContoursFlags.lag) { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_lag->setText("замкнут"); - } else { - ui->label_tab_setupMsg_send_controlContoursFlags_data_flags_lag->setText("незамкнут"); - } - - ui->label_tab_setupMsg_send_Impact_data_count_yaw->setNum(control.yaw); - ui->label_tab_setupMsg_send_Impact_data_count_pitch->setNum(control.pitch); - ui->label_tab_setupMsg_send_Impact_data_count_roll->setNum(control.roll); - ui->label_tab_setupMsg_send_Impact_data_count_march->setNum(control.march); - ui->label_tab_setupMsg_send_Impact_data_count_lag->setNum(control.lag); - ui->label_tab_setupMsg_send_Impact_data_count_depth->setNum(control.depth); - -// received - - if (auvData.modeAUV_Real == 1) - ui->labelt_tab_setupMsg_received_modeAUV_selection_mode->setText("модель"); - else - ui->labelt_tab_setupMsg_received_modeAUV_selection_mode->setText("агент"); - - if (auvData.modeReal) { - ui->label_tab_setupMsg_received_cSMode_count->setText("автоматизированный"); - } else { - ui->label_tab_setupMsg_received_cSMode_count->setText("ручной"); - } - - if (auvData.controlReal.yaw) { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_yaw->setText("замкнут"); - } else { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_yaw->setText("незамкнут"); - } - - if (auvData.controlReal.pitch) { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_pitch->setText("замкнут"); - } else { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_pitch->setText("незамкнут"); - } - - if (auvData.controlReal.roll) { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_roll->setText("замкнут"); - } else { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_roll->setText("незамкнут"); - } - - if (auvData.controlReal.march) { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_march->setText("замкнут"); - } else { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_march->setText("незамкнут"); - } - - if (auvData.controlReal.lag) { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_lag->setText("замкнут"); - } else { - ui->label_tab_setupMsg_received_controlContoursFlags_data_flags_lag->setText("незамкнут"); - } - - ui->label_tab_setupMsg_received_Impact_data_count_vma1->setNum(auvData.signalVMA_real.VMA1); - ui->label_tab_setupMsg_received_Impact_data_count_vma2->setNum(auvData.signalVMA_real.VMA2); - ui->label_tab_setupMsg_received_Impact_data_count_vma3->setNum(auvData.signalVMA_real.VMA3); - ui->label_tab_setupMsg_received_Impact_data_count_vma4->setNum(auvData.signalVMA_real.VMA4); - ui->label_tab_setupMsg_received_Impact_data_count_vma5->setNum(auvData.signalVMA_real.VMA5); - ui->label_tab_setupMsg_received_Impact_data_count_vma6->setNum(auvData.signalVMA_real.VMA6); - -// флаги для настройки БСО - - ui->label_tab_setupMsg_flagsSetupIMU_pult_init->setNum(flagAH127C_pult.initCalibration); - ui->label_tab_setupMsg_flagsSetupIMU_pult_save->setNum(flagAH127C_pult.saveCalibration); - ui->label_tab_setupMsg_flagsSetupIMU_bort_end->setNum(flagAH127C_bort.startCalibration); - ui->label_tab_setupMsg_flagsSetupIMU_bort_start->setNum(flagAH127C_bort.endCalibration); - -// количество посылок - - ui->label_tab_setupMsg_send_checksum_count->setNum(checksum_msg_gui_send); - ui->label_tab_setupMsg_received_checksum_send_count->setNum(checksum_msg_agent_send); - ui->labe_tab_setupMsg_received_checksum_received_count_->setNum(checksum_msg_gui_received); -} - -MainWindow::~MainWindow() -{ - if (pipeline) { - gst_element_set_state(pipeline, GST_STATE_NULL); - gst_object_unref(pipeline); - pipeline = nullptr; - } - delete ui; -} diff --git a/UMAS_GUI-develop/mainwindow.h b/UMAS_GUI-develop/mainwindow.h deleted file mode 100755 index 4b4febf..0000000 --- a/UMAS_GUI-develop/mainwindow.h +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "remote_control.h" -#include "uv_state.h" -#include "i_user_interface_data.h" -#include "pc_protocol.h" -#include "i_server_data.h" - -#include "setup_imu.h" -#include "setupimu_check.h" -#include "map.h" - -#include "i_basic_data.h" - -#include "joy_stick.h" -#include "key_board.h" - -QT_BEGIN_NAMESPACE -namespace Ui { class MainWindow; } -QT_END_NAMESPACE - -/*! - * \brief MainWindow - класс формы главного окна, в котором - * реализованы основные методы для работы с ним. - */ -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - /*! - * \brief MainWindow конструктор, в котором создается главная UI форма. - */ - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); - - /*! - * \brief setConsole устанавливает настройки для консоли. - */ - void setConsole(); - -private: - /*! - * \brief setTimer_updateImpact устанавливает таймер - * обработки пульта управления. - * \param periodUpdateMsec период обновления таймера - * обработки значений пульта управления. - */ - void setTimer_updateImpact(int periodUpdateMsec); - - /*! - * \brief setBottom устанавливает все используемые кнопки. - */ - void setBottom(); - void setBottom_mode(); - void setBottom_modeAutomated(); - void setBottom_modeAutomatic(); - void setBottom_powerMode(); - void setBottom_connection(); - void setBottom_modeSelection(); - void setBottom_setupIMU(); - void setBottom_setupIMU_check(); - void setBottom_selectAgent(); - - void setTab(); - void setMap(); - void setUpdateUI(); - -private slots: - void displayText(QString str); - void test_automatic_after(); - void setLocationUWB(double *x, double *y); - void updateUi_fromControl(); - - void e_CSModeManualToggled(); - void e_CSModeAutomatedToggled(); - void e_CSModeAutomaticToggled(); - - void stabilizeYawToggled(bool state); - void stabilizePitchToggled(bool state); - void stabilizeRollToggled(bool state); - void stabilizeMarchToggled(bool state); - void stabilizeLagToggled(bool state); - void stabilizeDepthToggled(bool state); - - void pushButton_on_powerMode_2(); - void pushButton_on_powerMode_3(); - void pushButton_on_powerMode_4(); - void pushButton_on_powerMode_5(); - void off_powerMode_5(); - - void setConnection(); - void updateUi_fromAgent1(); - void updateUi_fromAgent2(); - void breakConnection(); - - void setModeSelection(int index); - - void getWindow_setupIMU(); - void getWindow_setupIMU_check(); - - void updateUi_Compass(float yaw); - void updateUi_IMU(DataAH127C imuData); - void updateUi_SetupMsg(); - - void useKeyBoard(); - void useJoyStick(); - - void pushButton_selectAgent1(bool stateBottom); - void pushButton_selectAgent2(bool stateBottom); - - void slot_pushButton_missionControl_modeIdle(); - void slot_pushButton_missionControl_modeStart(); - void slot_pushButton_missionControl_modeCancel(); - void slot_pushButton_missionControl_modeStop(); - void slot_pushButton_missionControl_modeComplete(); - - void slot_pushButton_missionPlanning_goto(); - void slot_pushButton_missionPlanning_goto_update(); - void slot_pushButton_missionPlanning_goto_back(); - - void slot_pushButton_missionPlanning_go_trajectory_update(); - void slot_pushButton_missionPlanning_go_trajectory_back(); - - void slot_pushButton_missionPlanning_following(); - void slot_pushButton_missionPlanning_go_trajectory(); - - void updateUi_DataMission(); - void updateUi_statePushButton(); - - void on_pushButton_Play_Pause_clicked(); - -signals: - void updateCompass(float yaw); - void updateIMU(DataAH127C imuData); - void updateSetupMsg(); - void updateDataMission(); - void updateMap(DataUWB dataUWB); - void updateMapForAgent2(DataUWB dataUWB_agent2); - void signal_pushButton_missionPlanning_goto_updateMap(double x, double y, double r, int flag_clear); - void signal_pushButton_missionPlanning_go_trajectory_updateMap(double x, double y, double r, int flag_clear); - void updateStatePushButton(); - -protected: - Ui::MainWindow *ui; - - QTimer *updateTimer = nullptr; - - JoyStick *joyStick = nullptr; - KeyBoard *keyBoard = nullptr; - void keyPressEvent(QKeyEvent *event); - void keyReleaseEvent(QKeyEvent *event); - - QTimer *timer_off_powerMode_5; - power_Mode before_powerMode; - - IUserInterfaceData uv_interface; - Pult::PC_Protocol *communicationAgent1; - Pult::PC_Protocol *communicationAgent2; - - RemoteControl pult; - - // === Добавлено из второго файла === - GstElement *pipeline = nullptr; - WId videoWindowId = 0; - // =================================== -}; - -#endif // MAINWINDOW_H diff --git a/UMAS_GUI-develop/mainwindow.ui b/UMAS_GUI-develop/mainwindow.ui deleted file mode 100755 index 0320463..0000000 --- a/UMAS_GUI-develop/mainwindow.ui +++ /dev/null @@ -1,3822 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 1920 - 1080 - - - - UMAS GUI - - - - - - - - - - - - 0 - 0 - - - - - Модель - - - - - Агент - - - - - - - - - 0 - 0 - - - - Установить соединение - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Разорвать соединение - - - - - - - - - - - - - true - - - - 0 - 0 - - - - - 50 - 50 - - - - 1 - - - - - - - true - - - - 0 - 0 - - - - - 50 - 50 - - - - 2 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - 4 - - - - Tab 1 - - - - - - - - - - Tab 2 - - - - - 9 - 9 - 351 - 241 - - - - - - - - - Bx = - - - - - - - 0 - - - - - - - By = - - - - - - - 0 - - - - - - - Bz = - - - - - - - 0 - - - - - - - - - Гироскоп: - - - - - - - - - Ax = - - - - - - - 0 - - - - - - - Ay = - - - - - - - 0 - - - - - - - Az = - - - - - - - 0 - - - - - - - - - - - Wx = - - - - - - - 0 - - - - - - - 0 - - - - - - - Wz = - - - - - - - 0 - - - - - - - Wy = - - - - - - - - - - - q0 = - - - - - - - 0 - - - - - - - q1 = - - - - - - - 0 - - - - - - - q2 = - - - - - - - 0 - - - - - - - q3 = - - - - - - - 0 - - - - - - - - - Акселерометр: - - - - - - - Магнитометр: - - - - - - - Кватернионы: - - - - - - - - - 10 - 280 - 351 - 51 - - - - - 0 - 0 - - - - Настроить БСО - - - - - - 10 - 340 - 351 - 51 - - - - - 0 - 0 - - - - Проверить настройку БСО - - - - - - Page - - - - - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - Количество отправленных: - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - Полученные - - - Qt::AlignCenter - - - - - - - 5 - - - QLayout::SetDefaultConstraint - - - - - - 0 - 0 - - - - Количество: - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - Флаги настройки БСО - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - Текущий режим: - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - - - - 0 - 0 - - - - Замкнутые контуры: - - - - - - - - - - 0 - 0 - - - - ψ: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - θ: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - γ: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - x: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - y: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - Отправленные - - - Qt::AlignCenter - - - - - - - - - - 0 - 0 - - - - Задающие воздействия: - - - - - - - - - - 0 - 0 - - - - ψ: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - θ: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - γ: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - x: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - y: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - z: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - Количество полученных: - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - - - - 0 - 0 - - - - Режим: - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - - - - 0 - 0 - - - - Текущий вывод данных: - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - Qt::Vertical - - - - - - - 5 - - - QLayout::SetDefaultConstraint - - - - - - 0 - 0 - - - - Режим питания: - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - Qt::Vertical - - - - - - - - - - - pult_init: - - - - - - - нет сигнала - - - - - - - pult_save: - - - - - - - нет сигнала - - - - - - - - - - - bort_start: - - - - - - - нет сигнала - - - - - - - bort_end: - - - - - - - нет сигнала - - - - - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - - - - 0 - 0 - - - - Текущие замкнутые контуры: - - - - - - - - - - 0 - 0 - - - - ψ: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - θ: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - γ: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - x: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - y: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - - - - 0 - 0 - - - - Текущие воздействия на ВМА: - - - - - - - - - - 0 - 0 - - - - ВМА1: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - ВМА2: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - ВМА3: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - ВМА4: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - ВМА5: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - ВМА6: - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - - - - - - 0 - 0 - - - - Вывод данных: - - - - - - - - 0 - 0 - - - - нет сигнала - - - Qt::AlignCenter - - - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - - - - Page - - - - - - - - - 0 - 0 - - - - Перезагрузка -5 секунд - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Vertical - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - - 0 - 0 - - - - 2 - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - 4 - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#cc0000;">-</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#cc0000;">-</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Вычислитель - - - Qt::AlignCenter - - - - - - - ВМА - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Vertical - - - - - - - - 0 - 0 - - - - 3 - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Wi-fi - - - Qt::AlignCenter - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#cc0000;">-</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Horizontal - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#cc0000;">-</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Гидроакустика - - - Qt::AlignCenter - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#cc0000;">-</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#cc0000;">-</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#73d216;">+</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#cc0000;">-</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - UWB - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - <html><head/><body><p align="center"><span style=" font-size:28pt; color:#cc0000;">-</span></p></body></html> - - - Qt::AlignCenter - - - false - - - - - - - - - - Page - - - - - 10 - 10 - 831 - 601 - - - - - - - 20 - 750 - 101 - 91 - - - - PushButton - - - - - - - - - true - - - false - - - - - - - - - - - - - - - 0 - - - - - - - Информация - - - - - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - - - - - - - true - - - Джойстик - - - true - - - true - - - false - - - - - - - Клавиатура - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Horizontal - - - - - - - - - Qt::Vertical - - - - - - - З - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - γ - - - - - - - 0 - - - - - - - Qt::Horizontal - - - - - - - 0 - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - 0 - - - - - - - Qt::Horizontal - - - - - - - 0 - - - - - - - - - - - - - - Т - - - - - - - 0 - - - - - - - Qt::Horizontal - - - - - - - θ - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - ψ - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - 0 - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - - - Qt::Horizontal - - - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Т - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - 0 - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - 0 - - - - - - - 0 - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - z - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - - - - З - - - - - - - Qt::Horizontal - - - - - - - x - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - 0 - - - - - - - y - - - - - - - 0 - - - - - - - Qt::Horizontal - - - - - - - 0 - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - Ручной - - - false - - - false - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - Автоматизированный - - - - - - - - - true - - - - 0 - 0 - - - - ψ - - - - - - - - 0 - 0 - - - - θ - - - - - - - - 0 - 0 - - - - γ - - - - - - - - 0 - 0 - - - - x - - - - - - - - 0 - 0 - - - - y - - - - - - - - 0 - 0 - - - - z - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - Автоматический - - - - - - - - - - - - - - - - 0 - 0 - - - - Автоматический режим - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - - - - 0 - - - - - - - - 0 - 0 - - - - Выбор миссии - - - Qt::AlignCenter - - - - - - - Выход в точку - - - - - - - Следование - - - - - - - Движение по траектории - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Введите параметры 3 точек - - - Qt::AlignCenter - - - - - - - - - x1, см - - - - - - - 10000.000000000000000 - - - - - - - y1, см - - - - - - - 10000.000000000000000 - - - - - - - r1, см - - - - - - - 10000.000000000000000 - - - - - - - - - - - x2, см - - - - - - - 10000.000000000000000 - - - - - - - y2, см - - - - - - - 10000.000000000000000 - - - - - - - r2, см - - - - - - - 10000.000000000000000 - - - - - - - - - - - x3, см - - - - - - - 10000.000000000000000 - - - - - - - y3, см - - - - - - - 10000.000000000000000 - - - - - - - r3, см - - - - - - - 10000.000000000000000 - - - - - - - - - Обновить - - - - - - - Очистить цель - - - - - - - Вернуться к выбору миссий - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Введите параметры точки - - - Qt::AlignCenter - - - - - - - - - x, см - - - - - - - 10000.000000000000000 - - - - - - - y, см - - - - - - - 10000.000000000000000 - - - - - - - Радиус, см - - - - - - - 10000.000000000000000 - - - - - - - - - Обновить - - - - - - - Очистить цель - - - - - - - Вернуться к выбору миссий - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Включить/выключить запись траектории - - - - - - - Очистить траекторию - - - - - - - Qt::Horizontal - - - - - - - - - Состояние агента - - - - - - - - - Ожидание - - - - - - - Старт - - - - - - - Отмена - - - - - - - Пауза - - - - - - - Завершение - - - - - - - - - - - - - Текущие состояние: - - - - - - - - Отсутствует - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Обратно - - - - - - - - - - - - - - - 0 - 0 - 1920 - 24 - - - - - - - - Compass - QWidget -
compass.h
- 1 -
- - Map - QWidget -
map.h
- 1 -
-
- - -
diff --git a/UMAS_GUI-develop/map/map.cpp b/UMAS_GUI-develop/map/map.cpp deleted file mode 100755 index aa12551..0000000 --- a/UMAS_GUI-develop/map/map.cpp +++ /dev/null @@ -1,189 +0,0 @@ - #include "map.h" -#include "ui_map.h" -#include "math.h" -#include - -Map::Map(QWidget *parent) : - QWidget(parent), - ui(new Ui::Map) -{ - ui->setupUi(this); - - db = new DataBase("list_uwb.db", "Location_UWB", "Color", "x", "y"); - db->connectToDataBase(); - db->createTable(ui->tableWidget_listUWB); - - range[0] = 1; - range[1] = 1; - range[2] = 1; - - createPlot(); - - connect(ui->pushButton_addUWB, &QPushButton::clicked, - this, &Map::addRowUWB); - connect(ui->pushButton_updateLocationUWB, &QPushButton::clicked, - this, &Map::updateLocationUWB); -} - -void Map::createPlot() -{ - beacon1 = new QScatterSeries(); - beacon2 = new QScatterSeries(); - beacon3 = new QScatterSeries(); - - agent1Coords = new QScatterSeries(); - agent2Coords = new QScatterSeries(); - missionPlanning_goto_goal = new QScatterSeries(); - missionPlanning_goto_goal->setColor(QColor(255, 51, 153)); - - circle1 = new QLineSeries(); - circle1->setColor(QColor(0, 0, 255)); - circle2 = new QLineSeries(); - circle2->setColor(QColor(0, 255, 0)); - circle3 = new QLineSeries(); - circle3->setColor(QColor(255, 165, 0)); - missionPlanning_goto_goal_radius = new QLineSeries(); - missionPlanning_goto_goal_radius->setColor(QColor(255, 51, 153)); - missionPlanning_goto_traj = new QLineSeries(); - missionPlanning_goto_traj->setColor(QColor(255, 0, 0)); - - chart = new QChart(); - chart->addSeries(beacon1); - chart->addSeries(beacon2); - chart->addSeries(beacon3); - chart->addSeries(circle1); - chart->addSeries(circle2); - chart->addSeries(circle3); - chart->addSeries(missionPlanning_goto_goal_radius); - chart->addSeries(missionPlanning_goto_traj); - chart->addSeries(agent1Coords); - chart->addSeries(agent2Coords); - chart->addSeries(missionPlanning_goto_goal); - chart->createDefaultAxes(); - chart->axes(Qt::Vertical).first()->setRange(-50,100); - chart->axes(Qt::Vertical).first()->setTitleText("Y, см"); - chart->axes(Qt::Horizontal).first()->setRange(-50,150); - chart->axes(Qt::Horizontal).first()->setTitleText("X, см"); - chartView = new QChartView(chart); - - ui->verticalLayout_map->addWidget(chartView); - - connect(ui->pushButton_scaling, &QPushButton::toggled, - this, &Map::plotScaling); -} - -void Map::updateUi_map(DataUWB dataUWB) -{ - drawCurrentCoords(agent1Coords, missionPlanning_goto_traj, dataUWB.locationX, dataUWB.locationY); - - range[0] = dataUWB.distanceToBeacon[0]; - range[1] = dataUWB.distanceToBeacon[1]; - range[2] = dataUWB.distanceToBeacon[2]; - - drawCircle(circle1, beacon1, x[0], y[0], range[0], 1); - drawCircle(circle2, beacon2, x[1], y[1], range[1], 1); - drawCircle(circle3, beacon3, x[2], y[2], range[2], 1); -} - -void Map::updateUi_map2(DataUWB dataUWB) -{ - drawCurrentCoords(agent2Coords, missionPlanning_goto_traj, dataUWB.locationX, dataUWB.locationY); -} - -void Map::updateUi_missionPlanning_goto_goal(double x, double y, double r, int flag_clear) -{ -// drawCurrentCoords(missionPlanning_goto_goal, x, y); - drawCircle( missionPlanning_goto_goal_radius, missionPlanning_goto_goal, x, y, r, flag_clear); -} - -void Map::updateUi_missionPlanning_goto_goal_clear() -{ - missionPlanning_goto_goal->clear(); - missionPlanning_goto_goal_radius->clear(); -} - -void Map::addRowUWB() -{ - int countRows = ui->tableWidget_listUWB->rowCount(); - if (countRows == 2) - ui->pushButton_addUWB->setEnabled(false); - ui->tableWidget_listUWB->insertRow(countRows); - ui->tableWidget_listUWB->setItem(countRows, 0, new QTableWidgetItem(color.at(countRows))); - ui->tableWidget_listUWB->resizeColumnsToContents(); -} - -void Map::updateLocationUWB() -{ - int countRows = ui->tableWidget_listUWB->rowCount(); - for (int row = 0; row < countRows; row++) - { - QTableWidgetItem *item_color = ui->tableWidget_listUWB->item(row, 0); - QTableWidgetItem *item_x = ui->tableWidget_listUWB->item(row, 1); - QTableWidgetItem *item_y = ui->tableWidget_listUWB->item(row, 2); - if (item_x && item_y) { - x[row] = item_x->text().toInt(nullptr, 10); - y[row] = item_y->text().toInt(nullptr, 10); - db->inserIntoDeviceTable(item_color->text(), x[row], y[row]); - } - } - emit sendLocationUWB(&x[0],&y[0]); - drawCircle(circle1, beacon1, x[0], y[0], range[0], 1); - drawCircle(circle2, beacon2, x[1], y[1], range[1], 1); - drawCircle(circle3, beacon3, x[2], y[2], range[2], 1); -} - -void Map::plotScaling(bool state) -{ - if (state) - chartView->setRubberBand(QChartView::RectangleRubberBand); - else - chartView->setRubberBand(QChartView::NoRubberBand); - -} - -void Map::updateUi_missionPlanning_goto_traj_onoff() -{ - if (flag_traj) - flag_traj = 0; - else - flag_traj = 1; -} - -void Map::updateUi_missionPlanning_goto_traj_clear() -{ - missionPlanning_goto_traj->clear(); -} - -void Map::drawCircle(QLineSeries *circle, QScatterSeries *point, double x, double y, double R, int flag_clear) -{ - if (flag_clear) { - circle->clear(); - point->clear(); - } - -// circle = new QLineSeries(); -// circle->setColor(QColor(0, 0, 255)); -// chart->addSeries(circle); - - point->append(x,y); - - for(int i=0; i<=360; i++){ - double alpha = i*M_PI/180; - double plot_x = x+R*cos(alpha); - double plot_y = y+R*sin(alpha); - circle->append(plot_x,plot_y); - } -} - -void Map::drawCurrentCoords(QScatterSeries *agentCoords, QLineSeries *traj, double x, double y) -{ - agentCoords->clear(); - agentCoords->append(x,y); - if (flag_traj) - traj->append(x,y); -} - -Map::~Map() -{ - delete ui; -} diff --git a/UMAS_GUI-develop/map/map.h b/UMAS_GUI-develop/map/map.h deleted file mode 100755 index e750b5b..0000000 --- a/UMAS_GUI-develop/map/map.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef MAP_H -#define MAP_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "uv_state.h" -#include "database.h" - -namespace Ui { -class Map; -} -using namespace QtCharts; - -/*! - * \brief Map class класс отображения данных об UWB и агентов. - */ -class Map : public QWidget -{ - Q_OBJECT - -public: - explicit Map(QWidget *parent = nullptr); - ~Map(); - - /*! - * \brief drawCircle метод рисования расстояние от модуля до агента. - * \param circle окружность. - * \param R расстояние от модуля до агетна. - */ - void drawCircle(QLineSeries *circle, QScatterSeries *point, double x, double y, double R, int flag_clear); - /*! - * \brief drawCurrentCoords метод отображения агента. - * \param x координата агента по оси X. - * \param y координата агента по оси Y. - */ - void drawCurrentCoords(QScatterSeries *agentCoords, QLineSeries *traj, double x, double y); - -protected: - /*! - * \brief x координаты модулей по оси X. - */ - double x[3]; - /*! - * \brief y координаты модулей по оси Y. - */ - double y[3]; - /*! - * \brief range текущее расстояние от агетна до модуля. - */ - double range[3]; - - /*! - * \brief ui указатель на форму map.ui - */ - Ui::Map *ui; - - QChartView *chartView = nullptr; - QChart *chart = nullptr; - QScatterSeries *beacon1 = nullptr; - QScatterSeries *beacon2 = nullptr; - QScatterSeries *beacon3 = nullptr; - QScatterSeries *agent1Coords = nullptr; - QScatterSeries *agent2Coords = nullptr; - QScatterSeries *missionPlanning_goto_goal = nullptr; - QLineSeries *missionPlanning_goto_goal_radius = nullptr; - QLineSeries *missionPlanning_goto_traj = nullptr; - QLineSeries *circle1 = nullptr; - QLineSeries *circle2 = nullptr; - QLineSeries *circle3 = nullptr; - int flag_traj=0; - - QStringList color = { "Синий", "Зеленый", "Оранжевый" }; - -private: - DataBase *db; - - void createPlot(); - -public slots: - /*! - * \brief updateUi_map слот обновления данных о расположении UWB и агента. - * \param dataUWB структура с информацией об расположении агента. - */ - void updateUi_map(DataUWB dataUWB); - void updateUi_map2(DataUWB dataUWB); - void updateUi_missionPlanning_goto_goal(double x, double y, double r, int flag_clear); - void updateUi_missionPlanning_goto_goal_clear(); - - /*! - * \brief addRowUWB слот добавления строк и цветов модулей в таблицу. - */ - void addRowUWB(); - /*! - * \brief updateLocationUWB метод обновления по кнопке данных о UWB модулях. - */ - void updateLocationUWB(); - /*! - * \brief plotScaling слот переключения. масштабирования графика. - * \param state состояние нажатия кнопки. - */ - void plotScaling(bool state); - - void updateUi_missionPlanning_goto_traj_onoff(); - void updateUi_missionPlanning_goto_traj_clear(); - - -signals: - /*! - * \brief sendLocationUWB сигнал отправки расположения UWB модулей - * \param x координаты модулей по оси X. - * \param y координаты модулей по оси Y. - */ - void sendLocationUWB(double *x, double *y); -}; - -#endif // MAP_H diff --git a/UMAS_GUI-develop/map/map.ui b/UMAS_GUI-develop/map/map.ui deleted file mode 100755 index 7659d34..0000000 --- a/UMAS_GUI-develop/map/map.ui +++ /dev/null @@ -1,110 +0,0 @@ - - - Map - - - - 0 - 0 - 1149 - 775 - - - - Form - - - - - - - - - - - - - Расположение UWB - модулей - - - Qt::AlignCenter - - - - - - - - - - - - Добавить модуль - - - - - - - Обновить - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - Месторасположение - - - - - - - Масштабирование - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - diff --git a/UMAS_GUI-develop/remote_control/.vscode/tasks.json b/UMAS_GUI-develop/remote_control/.vscode/tasks.json deleted file mode 100644 index 08d9005..0000000 --- a/UMAS_GUI-develop/remote_control/.vscode/tasks.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "tasks": [ - { - "type": "cppbuild", - "label": "C/C++: gcc build active file", - "command": "/usr/bin/gcc", - "args": [ - "-fdiagnostics-color=always", - "-g", - "${file}", - "-o", - "${fileDirname}/${fileBasenameNoExtension}" - ], - "options": { - "cwd": "${fileDirname}" - }, - "problemMatcher": [ - "$gcc" - ], - "group": { - "kind": "build", - "isDefault": true - }, - "detail": "Task generated by Debugger." - } - ], - "version": "2.0.0" -} \ No newline at end of file diff --git a/UMAS_GUI-develop/remote_control/joy_stick.cpp b/UMAS_GUI-develop/remote_control/joy_stick.cpp deleted file mode 100755 index 446b444..0000000 --- a/UMAS_GUI-develop/remote_control/joy_stick.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "joy_stick.h" -#include -#include -#include -#include -#include "SFML/Window/Joystick.hpp" - -namespace { - double baseDepth = 0.0; // базовое значение глубины - bool fluctuationsActivated = false; -} - -JoyStick::JoyStick(QObject *parent) : RemoteControl() -{ - Q_UNUSED(parent); - - id = 0; - int periodUpdateMsec = 80; - int updperde = 150; - - updateTimer = new QTimer(this); - updateTimer2 = new QTimer(this); - connect(updateTimer, &QTimer::timeout, this, &JoyStick::updateImpact); - connect(updateTimer2, &QTimer::timeout, this, &JoyStick::Naebalovo); - updateTimer->start(periodUpdateMsec); - updateTimer2->start(updperde); - - // Назначение осей и кнопок - impactAxisMarch = sf::Joystick::Y; - impactAxisDepth = sf::Joystick::Z; - impactAxisRoll = sf::Joystick::PovX; - impactAxisPitch = sf::Joystick::PovY; - impactAxisYaw = sf::Joystick::R; - impactAxisLag = sf::Joystick::X; - impactButtonGripping = 0; - impactButtonRotman = 1; - falseDepthplus = 8; - falseDepthminus = 9; - offPower = 10; - - baseDepth = currentDepth; - - fluctuationTimer.start(); -} - -JoyStick::~JoyStick() -{ - // Освобождение ресурсов, если потребуется -} - -void JoyStick::Naebalovo() -{ - // При нажатии кнопок глубина изменяется, и базовое значение обновляется - if (sf::Joystick::isButtonPressed(id, falseDepthplus)) { - currentDepth += 0.1; - baseDepth = currentDepth; - fluctuationsActivated = true; - qDebug() << "Глубина:" << QString::number(currentDepth, 'f', 3); - } - if (sf::Joystick::isButtonPressed(id, falseDepthminus)) { - currentDepth -= 0.1; - baseDepth = currentDepth; - fluctuationsActivated = true; - qDebug() << "Глубина:" << QString::number(currentDepth, 'f', 3); - } -} - -void JoyStick::updateImpact() -{ - sf::Joystick::update(); - - if (!fluctuationsActivated) { - return; - } - - - double fluctuationValue = QRandomGenerator::global()->generateDouble() * 0.20 - 0.10; - currentDepth = baseDepth + fluctuationValue; - fluctuationTimer.restart(); - qDebug() << "Глубина:" << QString::number(currentDepth, 'f', 3); - - if (sf::Joystick::isConnected((id))) { - setOffPower(sf::Joystick::isButtonPressed(id, offPower)); - - } - -} diff --git a/UMAS_GUI-develop/remote_control/joy_stick.h b/UMAS_GUI-develop/remote_control/joy_stick.h deleted file mode 100755 index 7d1b0ec..0000000 --- a/UMAS_GUI-develop/remote_control/joy_stick.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef JOYSTICK_H -#define JOYSTICK_H - -#include -#include -#include - -#include "remote_control.h" -#include "SFML/Window.hpp" - - - -class JoyStick : public RemoteControl -{ - Q_OBJECT -public: - explicit JoyStick(QObject *parent = nullptr); // Добавлен explicit - ~JoyStick(); - -private: - double currentDepth = 0.00; - QElapsedTimer fluctuationTimer; - double fluctuationValue = 0.0; - - - -private slots: - void updateImpact(); - void Naebalovo(); -}; - -#endif // JOYSTICK_H diff --git a/UMAS_GUI-develop/remote_control/key_board.cpp b/UMAS_GUI-develop/remote_control/key_board.cpp deleted file mode 100755 index d36fa6e..0000000 --- a/UMAS_GUI-develop/remote_control/key_board.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "key_board.h" - -KeyBoard::KeyBoard(QObject *parent) -{ - -} - -KeyBoard::~KeyBoard() -{ -} - -void KeyBoard::keyPressEvent(QKeyEvent *event) -{ - ControlData control = getControlData(); - switch (event->key()) { - case Qt::Key_O: - setMarch(1); - break; - case Qt::Key_L: - setMarch(-1); - break; - case Qt::Key_W: - setPitch(1); - break; - case Qt::Key_S: - setPitch(-1); - break; - case Qt::Key_A: - setYaw(1); - break; - case Qt::Key_D: - setYaw(-1); - break; - case Qt::Key_C: - setDepth(0.5); - break; - case Qt::Key_V: - setDepth(-0.5); - break; - case Qt::Key_Q: - setRoll(1); - break; - case Qt::Key_E: - setRoll(-1); - break; - case Qt::Key_K: - setLag(1); - break; - case Qt::Key_Semicolon: - setLag(-1); - break; - } -} - -void KeyBoard::keyReleaseEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_O: - setMarch(0); - break; - case Qt::Key_L: - setMarch(0); - break; - case Qt::Key_W: - setPitch(0); - break; - case Qt::Key_S: - setPitch(0); - break; - case Qt::Key_A: - setYaw(0); - break; - case Qt::Key_D: - setYaw(0); - break; - case Qt::Key_C: - setDepth(0); - break; - case Qt::Key_V: - setDepth(0); - break; - case Qt::Key_Q: - setRoll(0); - break; - case Qt::Key_E: - setRoll(0); - break; - case Qt::Key_K: - setLag(0); - break; - case Qt::Key_Semicolon: - setLag(0); - break; - } -} diff --git a/UMAS_GUI-develop/remote_control/key_board.h b/UMAS_GUI-develop/remote_control/key_board.h deleted file mode 100755 index b879064..0000000 --- a/UMAS_GUI-develop/remote_control/key_board.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef KEYBOARD_H -#define KEYBOARD_H - -#include -#include - -#include "remote_control.h" - -class KeyBoard : public RemoteControl -{ -public: - explicit KeyBoard(QObject *parent = nullptr); - ~KeyBoard(); - - -public: - void keyPressEvent(QKeyEvent *event); - void keyReleaseEvent(QKeyEvent *event); - -private slots: - void updateImpact(); -}; - -#endif // KEYBOARD_H diff --git a/UMAS_GUI-develop/remote_control/remote_control.cpp b/UMAS_GUI-develop/remote_control/remote_control.cpp deleted file mode 100755 index 98b2824..0000000 --- a/UMAS_GUI-develop/remote_control/remote_control.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "remote_control.h" - -RemoteControl::RemoteControl() -{ - -} - - - -RemoteControl::~RemoteControl(){ -} - - diff --git a/UMAS_GUI-develop/remote_control/remote_control.h b/UMAS_GUI-develop/remote_control/remote_control.h deleted file mode 100755 index 53034c1..0000000 --- a/UMAS_GUI-develop/remote_control/remote_control.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef REMOTECONTROL_H -#define REMOTECONTROL_H - -#include -#include "i_control_data.h" -#include -#include - -#include "SFML/Window.hpp" -//#include "joy_stick.h" -//#include "key_board.h" - -class RemoteControl : public IControlData -{ - Q_OBJECT -public: - explicit RemoteControl(); - ~RemoteControl(); - - int id; - QTimer *updateTimer; - QTimer *updateTimer2; - -protected: - //оси - sf::Joystick::Axis impactAxisMarch; - sf::Joystick::Axis impactAxisDepth; - sf::Joystick::Axis impactAxisRoll; - sf::Joystick::Axis impactAxisPitch; - sf::Joystick::Axis impactAxisYaw; - sf::Joystick::Axis impactAxisLag; - //кнопки - int impactButtonGripping; - int impactButtonRotman; - int falseDepthplus; - int falseDepthminus; - int offPower; - - -}; - -#endif // REMOTECONTROL_H diff --git a/UMAS_GUI-develop/remote_control/test.cpp b/UMAS_GUI-develop/remote_control/test.cpp deleted file mode 100644 index 76bc8f9..0000000 --- a/UMAS_GUI-develop/remote_control/test.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "joy_stick.h" -#include - -JoyStick::JoyStick(QObject *parent) : QObject(parent) { - id = 0; // ID джойстика - int periodUpdateMsec = 20; // Интервал обновления (20 мс) - - updateTimer = new QTimer(this); - connect(updateTimer, &QTimer::timeout, this, &JoyStick::updateImpact); - updateTimer->start(periodUpdateMsec); -} - -void JoyStick::updateImpact() { - sf::Joystick::update(); // Обновление состояния джойстика - - // Проверка всех осей - for (int axis = 0; axis < sf::Joystick::AxisCount; ++axis) { - float value = sf::Joystick::getAxisPosition(id, static_cast(axis)); - qDebug() << "Axis" << axis << ":" << value; - } - - // Проверка всех кнопок - for (int btn = 0; btn < sf::Joystick::getButtonCount(id); ++btn) { - if (sf::Joystick::isButtonPressed(id, btn)) { - qDebug() << "Кнопка" << btn << "нажата!"; - } - } -} \ No newline at end of file diff --git a/UMAS_GUI-develop/ui_utils/dataIMU_magn.db b/UMAS_GUI-develop/ui_utils/dataIMU_magn.db deleted file mode 100755 index 6cc7723ecf3e70cd49c553264eeb3007658429a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24576 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 diff --git a/UMAS_GUI-develop/ui_utils/database.cpp b/UMAS_GUI-develop/ui_utils/database.cpp deleted file mode 100755 index 7260d0e..0000000 --- a/UMAS_GUI-develop/ui_utils/database.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "database.h" - -DataBase::DataBase(QString name, - QString tableName, - QString nameColumn1, QString nameColumn2, QString nameColumn3, - QObject *parent) : QObject(parent) -{ - nameDB = name; - tableNameDB = tableName; - nameColumn1DB = nameColumn1; - nameColumn2DB = nameColumn2; - nameColumn3DB = nameColumn3; -} - -DataBase::~DataBase() -{ -} - -/*! - * \brief DataBase::connectToDataBase Перед подключением к базе данных производим - * проверку на её существование.В зависимости от результата производим открытие - * базы данных или её восстановление. - */ -void DataBase::connectToDataBase() -{ - if(!QFile("./ui_utils/" + nameDB).exists()){ - qDebug() << "createDeviceTable" << this->restoreDataBase(); - } else { - this->openDataBase(); - } -} - -bool DataBase::restoreDataBase() -{ - if(this->openDataBase()){ - if(!this->createDeviceTable()){ - return false; - } else { - return true; - } - } else { - qDebug() << "Не удалось восстановить базу данных"; - return false; - } - return false; -} - -/*! - * \brief DataBase::openDataBase База данных открывается по заданному пути и - * имени базы данных, если она существует. - */ -bool DataBase::openDataBase() -{ - db = QSqlDatabase::addDatabase("QSQLITE"); - db.setDatabaseName("./ui_utils/" + nameDB); - if(db.open()){ - return true; - } else { - return false; - } -} - -void DataBase::closeDataBase() -{ - db.close(); -} - -/*! - * \brief DataBase::createDeviceTable В данном случае используется формирование - * сырого SQL-запроса с последующим его выполнением. - */ -bool DataBase::createDeviceTable() -{ - QSqlQuery query; - if(!query.exec( "CREATE TABLE " + tableNameDB + " (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - + nameColumn1DB + " STRING NOT NULL," - + nameColumn2DB + " FLOAT NOT NULL," - + nameColumn3DB + " FLOAT NOT NULL" - " )" - )){ - qDebug() << "DataBase: error of create " << tableNameDB; - qDebug() << query.lastError().text(); - return false; - } else { - return true; - } - return false; -} - -bool DataBase::inserIntoDeviceTable(QString str, float value1, float value2) -{ - QSqlQuery query; - - query.prepare("INSERT INTO " + tableNameDB + " ( " + nameColumn1DB + ", " - + nameColumn2DB + ", " + nameColumn3DB + " ) " - "VALUES (?, ?, ?)"); - - query.addBindValue(str); - query.addBindValue(value1); - query.addBindValue(value2); - - if(!query.exec()){ - qDebug() << "error insert into " << tableNameDB; - qDebug() << query.lastError().text(); - return false; - } else { - return true; - } - return false; -} - -void DataBase::createTable(QTableWidget* table) -{ - table->setColumnCount(3); // Указываем число колонок - table->setShowGrid(true); // Включаем сетку - // Разрешаем выделение только одного элемента - table->setSelectionMode(QAbstractItemView::SingleSelection); - // Разрешаем выделение построчно - table->setSelectionBehavior(QAbstractItemView::SelectRows); - // Устанавливаем заголовки колонок - table->setHorizontalHeaderLabels(QStringList() << nameColumn1DB - << nameColumn2DB - << nameColumn3DB - ); - // Обновляем ширину столбцов - table->resizeColumnsToContents(); -} diff --git a/UMAS_GUI-develop/ui_utils/database.h b/UMAS_GUI-develop/ui_utils/database.h deleted file mode 100755 index 536f4d3..0000000 --- a/UMAS_GUI-develop/ui_utils/database.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef DATABASE_H -#define DATABASE_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* Директивы имен таблицы, полей таблицы и базы данных */ - -#define DATABASE_NAME "dataIMU_magn.db" - -#define TABLENAME "IMUDATA_magn" -#define TIME "Time" -#define DATAIMU_MAGN_X "Magn_x" -#define DATAIMU_MAGN_Y "Magn_y" - -/*! - * \brief DataBase class вспомогательный класс для работы с таблицами и базами данных. - */ -class DataBase : public QObject -{ - Q_OBJECT -public: - /*! - * \brief DataBase конструктор класса, определяет структуру ДБ. - * \param name название файла ".db". - * \param tableName название таблицы. - * \param nameColumn1 название первой колонки. - * \param nameColumn2 название второй колонки. - * \param nameColumn3 название третей колонки. - */ - explicit DataBase(QString name, - QString tableName, - QString nameColumn1, QString nameColumn2, QString nameColumn3, - QObject *parent = 0); - ~DataBase(); - - /*! - * \brief connectToDataBase метод подключение к ДБ. - */ - void connectToDataBase(); - /*! - * \brief inserIntoDeviceTable метод заполнения ДБ - * \param str строка для первой колонки - * \param value1 значение для второй колонки. - * \param value2 значение для третей колонки. - * \return false в случае неудачи. - */ - bool inserIntoDeviceTable(QString str, float value1, float value2); - /*! - * \brief createTable метод созания таблицы в QTableWidget. - * \param table указатель на QTableWidget. - */ - void createTable(QTableWidget* table); - - -private: - /*! - * \brief db объект базы данных, с которым будет производиться работа - */ - QSqlDatabase db; - - QString nameDB; - QString tableNameDB; - QString nameColumn1DB; - QString nameColumn2DB; - QString nameColumn3DB; - -private: - /*! - * \brief openDataBase метод открытия ДБ. - * \return false в случае неудачи. - */ - bool openDataBase(); - /*! - * \brief restoreDataBase метод восстановления ДБ. - * \return false в случае неудачи. - */ - bool restoreDataBase(); - /*! - * \brief closeDataBase метод закрытия ДБ. - */ - void closeDataBase(); - /*! - * \brief createDeviceTable метод создания таблицы в ДБ. - * \return false в случае неудачи. - */ - bool createDeviceTable(); -}; - -#endif // DATABASE_H diff --git a/UMAS_GUI-develop/ui_utils/list_uwb.db b/UMAS_GUI-develop/ui_utils/list_uwb.db deleted file mode 100755 index 5e3910bc10cd49cb6d4e54d31c3c7967bcc56ff9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI&Piz!b9Ki9J-R{hr|GTB@IwGa!7`zGn=NMX8Oq5G@zv!y!imZFj@OFfiIk~GiuFx#(eGJDZ-<$!%|9RJ%k zFLh3=wb)r9CnPyO`ye(^Kok%KL;+Di6c7bO0Z~8{5Cud5QQ$u*FdR}6?d|e-y)-#f zIaHfrkHZs(Dz&F7b5qTS;hn`?*3VHt+gr%drgPJCrP)dcduQgkjI1V7Df#*M-)5mY zRjN-{=O)JX^samzTBWU=q3P)|&3k^XKUbu~#r$BlI8Fz0<1{XZBZ>&)0SfG7{p{(B+`)BZJV31}S&*n8HDmlx}*UmZTwDX#?;8YyX z>2|22*~|8K_NVqK`>1``F59E_4m)MHTEAPDtS_vy)*IH#R?XUN?Xosmt(Ii|Xntv) zGv78}F&E5|*=KGw*O?*X7vme_W8;kRy77#0z!)*M85;~s|5d-Ff2O~yzp1~dAJq5i zS$(74rv0h?pat5Jc0xO%y`ar&`?MadQ%jIP$WP=evPj+`uaY{MBm-nKNfK54S^ZZ1 zL_MhufD<3Gwm6w#N;w!yMJNp*JCJKlGqJSuHjRI~hB5jf7 z;KYSzgZF~-!P(%$;Qb3nf~ANOe=;Iv*wisL^by<7H-^J4(P~6mugSq%!6G|0CAVdEaoxEnX_f{i;l zV;gSV0UKL6qZ>E6U}FnsY{re-VWX2XHsMAGY_xO6ZMczvjWlQ6iW?hYBgGjTaN`!( zxS2E7;|7I|n>Zth7|CRO9bmMz#cpIq)6IVaj;w_dmq)J0kpzrf$03P0LkQs)1#8+E z!6sHM37jsetupUi(this); - - connect( - ui->pushButton_setupIMU_nextStep1, SIGNAL(clicked()), - this, SLOT(setupIMU_nextStep1())); -} - -SetupIMU::~SetupIMU() -{ - delete ui; -} - -void SetupIMU::setupIMU_nextStep1() -{ - hide(); - SetupIMU_start window_setupIMU_start; - window_setupIMU_start.setModal(true); - window_setupIMU_start.exec(); -} diff --git a/UMAS_GUI-develop/ui_utils/setup_imu.h b/UMAS_GUI-develop/ui_utils/setup_imu.h deleted file mode 100755 index 9eecdf0..0000000 --- a/UMAS_GUI-develop/ui_utils/setup_imu.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SETUP_IMU_H -#define SETUP_IMU_H - -#include -#include "setupimu_start.h" -#include "ui_setupimu_start.h" -#include "i_user_interface_data.h" - -namespace Ui { -class SetupIMU; -} - -/*! - * \brief SetupIMU class класс UI формы подготовки к настройке БСО. - */ -class SetupIMU : public QDialog -{ - Q_OBJECT - -public: - explicit SetupIMU(QWidget *parent = nullptr); - ~SetupIMU(); - -public slots: - /*! - * \brief setupIMU_nextStep1 слот открытия окна старта настройки БСО. - */ - void setupIMU_nextStep1(); - - -private: - /*! - * \brief ui окно этой формы. - */ - Ui::SetupIMU *ui; -}; - -#endif // SETUP_IMU_H diff --git a/UMAS_GUI-develop/ui_utils/setup_imu.ui b/UMAS_GUI-develop/ui_utils/setup_imu.ui deleted file mode 100755 index 3814438..0000000 --- a/UMAS_GUI-develop/ui_utils/setup_imu.ui +++ /dev/null @@ -1,67 +0,0 @@ - - - SetupIMU - - - true - - - - 0 - 0 - 400 - 300 - - - - Настройка БСО - - - - - - - - - 0 - 0 - - - - Переведите устройство в горизонтальное положение - - - true - - - - - - - - - - - - 0 - 0 - - - - Qt::LeftToRight - - - false - - - Следующий шаг - - - - - - - - - - diff --git a/UMAS_GUI-develop/ui_utils/setupimu_check.cpp b/UMAS_GUI-develop/ui_utils/setupimu_check.cpp deleted file mode 100755 index 8e40a57..0000000 --- a/UMAS_GUI-develop/ui_utils/setupimu_check.cpp +++ /dev/null @@ -1,238 +0,0 @@ -#include "setupimu_check.h" -#include "ui_setupimu_check.h" - - -SetupIMU_check::SetupIMU_check(QWidget *parent) : - QDialog(parent), - ui(new Ui::SetupIMU_check) -{ - ui->setupUi(this); - - ui->pushButton_setupIMU_check_stop->setEnabled(false); - ui->pushButton_setupIMU_check_pause->setEnabled(false); - ui->pushButton_setupIMU_check_reset->setEnabled(false); - - - db = new DataBase("dataIMU_magn.db", "IMUDATA_magn", "Time", "Magn_x", "Magn_y"); - db->connectToDataBase(); - db->createTable(ui->tableWidget); - - this->createPlot(); - - - connect( - ui->pushButton_setupIMU_check_start, SIGNAL(clicked()), - this, SLOT(startCheck())); - - connect( - ui->pushButton_setupIMU_check_reset, SIGNAL(clicked()), - this, SLOT(resetTable())); - - connect( - ui->pushButton_setupIMU_check_stop, SIGNAL(clicked()), - this, SLOT(stopCheck())); - -} - -SetupIMU_check::~SetupIMU_check() -{ - delete ui; -} - -void SetupIMU_check::startCheck() -{ - time = ui->spinBox_time->value(); - periodicity = ui->doubleSpinBox_periodicity->value(); - i = 0; - - - if (time && periodicity) - { - ui->pushButton_setupIMU_check_start->setEnabled(false); - ui->pushButton_setupIMU_check_stop->setEnabled(true); - ui->pushButton_setupIMU_check_pause->setEnabled(true); - - rowCount_beforeStart = ui->tableWidget->rowCount(); - - timer_updateUI_check = new QTimer(this); - connect( - timer_updateUI_check, SIGNAL(timeout()), - this, SLOT(updateUI_table())); - timer_updateUI_check->start(periodicity*1000); - - ui->label_setupIMU_check_timer->setNum(time); - - timer_setupIMU_check = new QTimer(this); - connect( - timer_setupIMU_check, SIGNAL(timeout()), - this, SLOT(timer_setupIMU_check_timeStart())); - timer_setupIMU_check->start(1000); - } - else - qInfo() << "Необходимо выставить длительность и периодичность записи"; -} - -void SetupIMU_check::timer_setupIMU_check_timeStart() -{ - ui->label_setupIMU_check_timer->setNum(--time); - if (time == 0) { - timer_setupIMU_check->stop(); - timer_updateUI_check->stop(); - ui->pushButton_setupIMU_check_reset->setEnabled(true); - ui->pushButton_setupIMU_check_start->setEnabled(true); - - ui->pushButton_setupIMU_check_pause->setEnabled(false); - ui->pushButton_setupIMU_check_stop->setEnabled(false); - - updateUI_setPlot(); - } -} - -void SetupIMU_check::updateUI_table() -{ - DataAH127C imuData = uv_interface.getImuData(); - float X_magn = imuData.X_magn; - float Y_magn = imuData.Y_magn; - - QString currentTime = QTime::currentTime().toString("HH:mm:ss"); - - db->inserIntoDeviceTable(currentTime, X_magn, Y_magn); - - QSqlQuery query("SELECT " - TABLENAME "." TIME ", " - TABLENAME "." DATAIMU_MAGN_X ", " - TABLENAME "." DATAIMU_MAGN_Y - " FROM " TABLENAME); - query.last(); - ui->tableWidget->insertRow(i + rowCount_beforeStart); - ui->tableWidget->setItem(i + rowCount_beforeStart, 0, new QTableWidgetItem(query.value(0).toString())); - ui->tableWidget->setItem(i + rowCount_beforeStart, 1, new QTableWidgetItem(query.value(1).toString())); - ui->tableWidget->setItem(i + rowCount_beforeStart, 2, new QTableWidgetItem(query.value(2).toString())); - i++; - - ui->tableWidget->resizeColumnsToContents(); -} - -void SetupIMU_check::resetTable() -{ - ui->pushButton_setupIMU_check_reset->setEnabled(false); - ui->pushButton_setupIMU_check_start->setEnabled(true); - - int rowCount = ui->tableWidget->rowCount(); - for (int r = rowCount; r >= 0; r--) - ui->tableWidget->removeRow(r); -} - -void SetupIMU_check::stopCheck() -{ - timer_setupIMU_check->stop(); - timer_updateUI_check->stop(); - ui->pushButton_setupIMU_check_reset->setEnabled(true); - ui->pushButton_setupIMU_check_start->setEnabled(true); - - ui->pushButton_setupIMU_check_pause->setEnabled(false); - ui->pushButton_setupIMU_check_stop->setEnabled(false); - - resetTable(); -} - -void SetupIMU_check::createPlot() -{ - // Построить ряд как источник данных диаграммы и добавить к нему 6 координатных точек - series = new QSplineSeries; - - // Построить график - chart = new QChart(); - chart->legend()->hide(); // скрыть легенду - chart->addSeries(series); // добавить серию на график - chart->setTitle("Построение магнитной характеристики"); // Устанавливаем заголовок графика - - QValueAxis *axisX = new QValueAxis(); - axisX->setTitleText("Magn x"); - axisX->setLabelFormat("%g"); - axisX->setTickCount(5); - chart->addAxis(axisX, Qt::AlignBottom); - series->attachAxis(axisX); - - QValueAxis *axisY = new QValueAxis(); - axisY->setTitleText("Magn y"); - axisY->setLabelFormat("%g"); - axisY->setTickCount(5); - chart->addAxis(axisY, Qt::AlignLeft); - series->attachAxis(axisY); - - // Создаем QChartView и устанавливаем сглаживание, заголовок, размер - chartView = new QChartView(chart); - - // Добавляем его в горизонтальный Layout - ui->verticalLayout_map->addWidget(chartView); - chartView->setRenderHint(QPainter::Antialiasing); -} - -void SetupIMU_check::updateUI_setPlot() -{ - ui->verticalLayout_map->removeWidget(chartView); - - series = new QSplineSeries; - - float magnX_max = 0; - float magnY_max = 0; - float magnX_min = 0; - float magnY_min = 0; - - for (int r = 0; r < ui->tableWidget->rowCount(); r++) - { - QString magn_x = ui->tableWidget->item(r,1)->text(); - QString magn_y = ui->tableWidget->item(r,2)->text(); - - if (magnX_max < magn_x.toFloat()) - magnX_max = magn_x.toFloat(); - if (magnY_max < magn_y.toFloat()) - magnY_max = magn_y.toFloat(); - if (magnX_min > magn_x.toFloat()) - magnX_min = magn_x.toFloat(); - if (magnY_min > magn_y.toFloat()) - magnY_min = magn_y.toFloat(); - - series->append(magn_x.toFloat() , magn_y.toFloat()); - } - - QString magn_x = ui->tableWidget->item(0,1)->text(); - QString magn_y = ui->tableWidget->item(0,2)->text(); - - series->append(magn_x.toFloat() , magn_y.toFloat()); - - float bb_x = (magnX_max-magnX_min) * 0.1; - float bb_y = (magnY_max-magnY_min) * 0.1; - - - // Построить график - chart = new QChart(); - chart->legend()->hide(); // скрыть легенду - chart->addSeries(series); // добавить серию на график - chart->setTitle("Построение магнитной характеристики"); // Устанавливаем заголовок графика - - QValueAxis *axisX = new QValueAxis(); - axisX->setTitleText("Magn x"); - axisX->setLabelFormat("%g"); - axisX->setTickCount(5); - axisX->setRange(magnX_min - bb_x , magnX_max + bb_x); - chart->addAxis(axisX, Qt::AlignBottom); - series->attachAxis(axisX); - - QValueAxis *axisY = new QValueAxis(); - axisY->setTitleText("Magn y"); - axisY->setLabelFormat("%g"); - axisY->setTickCount(5); - axisY->setRange(magnY_min - bb_y, magnY_max + bb_y); - chart->addAxis(axisY, Qt::AlignLeft); - series->attachAxis(axisY); - - // Создаем QChartView и устанавливаем сглаживание, заголовок, размер - chartView = new QChartView(chart); - - // Добавляем его в горизонтальный Layout - ui->verticalLayout_map->addWidget(chartView); - chartView->setRenderHint(QPainter::Antialiasing); - -} diff --git a/UMAS_GUI-develop/ui_utils/setupimu_check.h b/UMAS_GUI-develop/ui_utils/setupimu_check.h deleted file mode 100755 index 4dabfe6..0000000 --- a/UMAS_GUI-develop/ui_utils/setupimu_check.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef SETUPIMU_CHECK_H -#define SETUPIMU_CHECK_H - -#include -#include -#include -#include - - -#include - - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include "database.h" -#include "i_user_interface_data.h" - -namespace Ui { -class SetupIMU_check; -} -using namespace QtCharts; - -/*! - * \brief SetupIMU_check class класс проверки настройки БСО. - */ -class SetupIMU_check : public QDialog -{ - Q_OBJECT - -public: - explicit SetupIMU_check(QWidget *parent = nullptr); - ~SetupIMU_check(); - - -private slots: - /*! - * \brief startCheck слот старта проверки. - */ - void startCheck(); - /*! - * \brief timer_setupIMU_check_timeStart слот окончания записи данных и - * и последующего построения графиков - */ - void timer_setupIMU_check_timeStart(); - /*! - * \brief updateUI_table слот заполнения таблицы. - */ - void updateUI_table(); - /*! - * \brief resetTable слот очистки таблицы. - */ - void resetTable(); - /*! - * \brief stopCheck слот окончания проверки и стерания данных. - */ - void stopCheck(); - - -private: - /*! - * \brief ui указатель на форму проверки настройки БСО. - */ - Ui::SetupIMU_check *ui; - - /*! - * \brief timer_setupIMU_check таймер окончания записи данных и - * и последующего построения графиков - */ - QTimer *timer_setupIMU_check; - /*! - * \brief timer_updateUI_check таймер заполнения таблицы. - */ - QTimer *timer_updateUI_check; - - /*! - * \brief time длительность записи. - */ - float time; - /*! - * \brief periodicity периодичность записи данныз - */ - float periodicity; - /*! - * \brief количество строк в таблице. - */ - int i; - /*! - * \brief rowCount_beforeStart количество строк в таблице до начала записи. - */ - int rowCount_beforeStart; - - /*! - * \brief uv_interface получения данных - */ - IUserInterfaceData uv_interface; - - /*! - * \brief db база данных для хранения значений магнитометров. - */ - DataBase *db; - - QChart *chart; - QChartView *chartView; - QSplineSeries *series; - - /*! - * \brief createPlot метод построение графика. - */ - void createPlot(); - /*! - * \brief updateUI_setPlot метод повторного построение графика. - */ - void updateUI_setPlot(); -}; - -#endif // SETUPIMU_CHECK_H diff --git a/UMAS_GUI-develop/ui_utils/setupimu_check.ui b/UMAS_GUI-develop/ui_utils/setupimu_check.ui deleted file mode 100755 index 6ecb0a6..0000000 --- a/UMAS_GUI-develop/ui_utils/setupimu_check.ui +++ /dev/null @@ -1,196 +0,0 @@ - - - SetupIMU_check - - - - 0 - 0 - 920 - 613 - - - - Проверка настройки БСО - - - - - - - - - - Введите данные для -проверки настройки БСО - - - - - - - Qt::Horizontal - - - - - - - - - Длительность, с: - - - - - - - 5 - - - - - - - Периодичность записи, с: - - - - - - - 1.000000000000000 - - - - - - - - - Qt::Horizontal - - - - - - - Установите аппарат в -горизонтальное положение. - - - - - - - Qt::Horizontal - - - - - - - Начать запись - - - - - - - - - Приостановить - - - - - - - Завершить - - - - - - - - - Qt::Horizontal - - - - - - - Поворачивайте вокруг -вертикальной оси. - - - - - - - Qt::Horizontal - - - - - - - - - До окончания записи: - - - - - - - - 0 - 0 - - - - 0 - - - - - - - Qt::Horizontal - - - - - - - - - Qt::Horizontal - - - - - - - - - - Очистить значения - - - - - - - - - - - - - - - diff --git a/UMAS_GUI-develop/ui_utils/setupimu_start.cpp b/UMAS_GUI-develop/ui_utils/setupimu_start.cpp deleted file mode 100755 index b1c4014..0000000 --- a/UMAS_GUI-develop/ui_utils/setupimu_start.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include "setupimu_start.h" -#include "ui_setupimu_start.h" - -SetupIMU_start::SetupIMU_start(QWidget *parent) : - QDialog(parent), - ui(new Ui::SetupIMU_start) -{ - ui->setupUi(this); - ui->pushButton_setupIMU_end->setEnabled(false); - - - connect( - ui->pushButton_setupIMU_startTimer, SIGNAL(clicked()), - this, SLOT(pushButton_startTimer1())); - connect( - this, SIGNAL(on_t2()), - this, SLOT(pushButton_startTimer2())); - connect( - ui->pushButton_setupIMU_end, SIGNAL(clicked()), - this, SLOT(close())); -} - -SetupIMU_start::~SetupIMU_start() -{ - delete ui; -} - -void SetupIMU_start::pushButton_startTimer1() -{ - flagAH127C_pult.initCalibration = true; - uv_interface.setFlagAH127C_pult(flagAH127C_pult); - - timer_checkFlag = new QTimer(this); - connect( - timer_checkFlag, SIGNAL(timeout()), - this, SLOT(isCheckedFlagBort_start())); - timer_checkFlag->start(1000); -} - -void SetupIMU_start::isCheckedFlagBort_start() -{ - flagAH127C_bort = uv_interface.getFlagAH127C_bort(); - if(flagAH127C_bort.startCalibration) - { - timer_checkFlag->stop(); - flagAH127C_pult.initCalibration = false; - uv_interface.setFlagAH127C_pult(flagAH127C_pult); - - ui->pushButton_setupIMU_startTimer->setEnabled(false); - ui->SetupIMU_start_statusBar->setStyleSheet("color: rgb(0, 153, 76)"); - ui->SetupIMU_start_statusBar->setText("Равномерно поворачивайте аппарат вокруг вертикали 2 раза за 30 секунд"); - - updateTimerSec = new QTimer(this); - connect( - updateTimerSec, SIGNAL(timeout()), - this, SLOT(updateUi_sec_t1()) - ); - updateTimerSec->start(1000); - } - else - { - ui->SetupIMU_start_statusBar->setStyleSheet("color: rgb(255, 0, 0)"); - ui->SetupIMU_start_statusBar->setText("Ожидаение подтверждения настройки от БСО"); - } -} - -void SetupIMU_start::updateUi_sec_t1() -{ - ui->label_setupIMU_timer1->setText(QString::number(--sec)); - if (sec == 0) { - sec = 30; - updateTimerSec->stop(); - emit on_t2(); - } -} - -void SetupIMU_start::pushButton_startTimer2() -{ - ui->SetupIMU_start_statusBar->setStyleSheet("color: rgb(0, 153, 76)"); - ui->SetupIMU_start_statusBar->setText("Теперь вокруг оси вращения 2 раза за 30 секунд"); - - updateTimerSec = new QTimer(this); - connect( - updateTimerSec, SIGNAL(timeout()), - this, SLOT(updateUi_sec_t2()) - ); - updateTimerSec->start(1000); - -} - -void SetupIMU_start::updateUi_sec_t2() -{ - ui->label_setupIMU_timer2->setText(QString::number(--sec)); - if (sec == 0) - { - updateTimerSec->stop(); - flagAH127C_pult.saveCalibration = true; - uv_interface.setFlagAH127C_pult(flagAH127C_pult); - - timer_checkFlag = new QTimer(this); - connect( - timer_checkFlag, SIGNAL(timeout()), - this, SLOT(isCheckedFlagBort_end())); - timer_checkFlag->start(1000); - } -} - -void SetupIMU_start::isCheckedFlagBort_end() -{ - flagAH127C_bort = uv_interface.getFlagAH127C_bort(); - if(flagAH127C_bort.endCalibration) - { - timer_checkFlag->stop(); - flagAH127C_pult.saveCalibration = false; - uv_interface.setFlagAH127C_pult(flagAH127C_pult); - - ui->pushButton_setupIMU_end->setEnabled(true); - ui->SetupIMU_start_statusBar->setStyleSheet("color: rgb(0, 153, 76)"); - ui->SetupIMU_start_statusBar->setText("Данные сохранились, можно завершать настройку "); - } else { - ui->SetupIMU_start_statusBar->setStyleSheet("color: rgb(255, 0, 0)"); - ui->SetupIMU_start_statusBar->setText("Данные сохраняются"); - } -} - diff --git a/UMAS_GUI-develop/ui_utils/setupimu_start.h b/UMAS_GUI-develop/ui_utils/setupimu_start.h deleted file mode 100755 index 4c9858a..0000000 --- a/UMAS_GUI-develop/ui_utils/setupimu_start.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef SETUPIMU_START_H -#define SETUPIMU_START_H - -#include -#include -#include - -#include "i_user_interface_data.h" - -namespace Ui { -class SetupIMU_start; -} - -/*! - * \brief SetupIMU_start class класс настройки БСО. - */ -class SetupIMU_start : public QDialog -{ - Q_OBJECT - -public: - /*! - * \brief SetupIMU_start конструктор, в котором задаются начальные настройки - * интерфейса и подключаются слоты. - */ - explicit SetupIMU_start(QWidget *parent = nullptr); - ~SetupIMU_start(); - - -private slots: - /*! - * \brief pushButton_startTimer1 слот старта настройки и запуска таймера. - * Срабатывает по нажатию кнопки. - */ - void pushButton_startTimer1(); - /*! - * \brief pushButton_startTimer2 слот старта второго таймера. - */ - void pushButton_startTimer2(); - /*! - * \brief updateUi_sec_t1 слот отчета первого таймера. - */ - void updateUi_sec_t1(); - /*! - * \brief updateUi_sec_t2 слот отчета второго таймера и сохранение результатов. - */ - void updateUi_sec_t2(); - - /*! - * \brief isCheckedFlagBort_start слот проверки начала настройки от БСО. - */ - void isCheckedFlagBort_start(); - /*! - * \brief isCheckedFlagBort_end слот проверки сохранения данных настройки. - */ - void isCheckedFlagBort_end(); - -signals: - /*! - * \brief on_t2 сигнал запуска второго таймера. - */ - void on_t2(); - -private: - /*! - * \brief ui указатель на форму настройки БСО. - */ - Ui::SetupIMU_start *ui; - /*! - * \brief uv_interface интерфейс получения приходящих на аппарат данных - */ - IUserInterfaceData uv_interface; - /*! - * \brief flagAH127C_pult флаги старта и окончания настройки. - */ - FlagAH127C_pult flagAH127C_pult; - /*! - * \brief flagAH127C_bort флаги подтверждения старта и сохранения данных - * после окончания настройки. - */ - FlagAH127C_bort flagAH127C_bort; - - QTimer *updateTimerSec; - QTimer *timer_checkFlag; - - int sec = 30; - -}; - -#endif // SETUPIMU_START_H diff --git a/UMAS_GUI-develop/ui_utils/setupimu_start.ui b/UMAS_GUI-develop/ui_utils/setupimu_start.ui deleted file mode 100755 index ed48d64..0000000 --- a/UMAS_GUI-develop/ui_utils/setupimu_start.ui +++ /dev/null @@ -1,172 +0,0 @@ - - - SetupIMU_start - - - - 0 - 0 - 773 - 304 - - - - Инструкция настройки БСО - - - - - - - - image: url(:/img/setupIMU_for_agent.png); - - - - - - - - - - - - - - - - - 0 - 0 - - - - 1. Поверните аппарат вокруг - оси Z 2 раза за 30 с. - - - false - - - - - - - - 0 - 0 - - - - 2. Поверните аппарат вокруг -оси X 2 раза за 30 с. - - - false - - - - - - - - - - - - 0 - 0 - - - - Qt::LeftToRight - - - false - - - 30 - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - Qt::LeftToRight - - - false - - - 30 - - - Qt::AlignCenter - - - - - - - - - - 0 - 0 - - - - запустить -таймеры - - - - - - - - - - 0 - 0 - - - - Qt::LeftToRight - - - false - - - Завершить настройку - - - - - - - - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - diff --git a/UMAS_GUI-develop/uv/uv_state.cpp b/UMAS_GUI-develop/uv/uv_state.cpp deleted file mode 100755 index 93ea545..0000000 --- a/UMAS_GUI-develop/uv/uv_state.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "uv_state.h" - -UVState::UVState() -{ - modeAUV_selection = true; - cSMode = e_CSMode::MODE_MANUAL; - - controlContoursFlags.depth = 1; - controlContoursFlags.lag = 1; - controlContoursFlags.march = 1; - controlContoursFlags.pitch = 1; - controlContoursFlags.roll = 1; - controlContoursFlags.yaw = 1; - - pMode = power_Mode::MODE_2; - - - -} - -ControlData::ControlData() { - yaw = 0; - pitch = 0; - roll = 0; - march = 0; - depth = 0; - lag = 0; - offPower = 0; -} - -ControlContoursFlags::ControlContoursFlags() { - yaw = 1; - pitch = 1; - roll = 1; - march = 1; - depth = 1; - lag = 1; -} - -DataPressure::DataPressure() { //структура данных с датчика давления - temperature = 0; //Temperature returned in deg C. - depth = 0; //Depth returned in meters - pressure = 0; // Pressure returned in mbar or mbar*conversion rate. -} - -//DataUWB::DataUWB() { -// locationX = 0; -// locationY = 0; - -// for (int i = 0; i < 5; i++) -// distanceToBeacon [i] = 0; - -// for (int i = 0; i < 11; i++) -// distanceToAgent [i] = 0; -//} diff --git a/UMAS_GUI-develop/uv/uv_state.h b/UMAS_GUI-develop/uv/uv_state.h deleted file mode 100755 index 104dc6d..0000000 --- a/UMAS_GUI-develop/uv/uv_state.h +++ /dev/null @@ -1,279 +0,0 @@ -#ifndef UVSTATE_H -#define UVSTATE_H - -#include -#include - -/*! - * \brief e_CSMode enum класс режимов работы системы управления. - */ -enum class e_CSMode : quint8 { - MODE_MANUAL = 0, //! Ручной - MODE_AUTOMATED, //! Автоматизированный - MODE_AUTOMATIC, //! Автоматический - MODE_GROUP //! Групповой -}; - -/*! - * \brief e_StabilizationContours enum класс для работы с замыканием и - * размыканием контуров управления. - */ -enum class e_StabilizationContours : unsigned char { - CONTOUR_DEPTH = 0, - CONTOUR_MARCH, - CONTOUR_LAG, - CONTOUR_YAW, - CONTOUR_ROLL, - CONTOUR_PITCH -}; - -/*! - * \brief power_Mode enum класс режимов работы системы питания. - */ -enum class power_Mode : quint8 -{ //режим работы - MODE_2 = 0, //! Включены вычислитель, wifi, uwb - MODE_3, //! Включены вычислитель, wifi, uwb, гидроакустика - MODE_4, //! Включены вычислитель, wifi, uwb, гидроакустика, ВМА - MODE_5 //! Выключить вычислитель на 5 секунд и включить обратно -}; - -#pragma pack(push,1) - -/*! - * \brief The mission_Control enum - команды управления миссией - */ -enum class mission_Control : quint8 -{ - MODE_IDLE = 0, //!ожидание - MODE_START, //!отправка запроса на выполнение миссии - MODE_CANCEL, //!отмена выполнения миссии - MODE_STOP, //!пауза, остановить временно - MODE_COMPLETE //!завершить миссию -}; - -/*! - * \brief The mission_Status enum состояния миссий - */ -enum class mission_Status : quint8 -{ - MODE_IDLE = 0, //!ожидание - MODE_ERROR, //!ошибка инициализации миссии - MODE_RUNNING, //!миссия запущена и выполняется - MODE_STOPPED, //!миссия приостановлена, на паузе - MODE_PERFOMED, //!миссия завершена -}; - - -/*! - * \brief FlagAH127C_bort class структура, передаваемая на пульт. - * Используется для калибровки БСО. - */ -struct FlagAH127C_bort -{ - quint8 startCalibration = false; //! Флаг подтверждает старт калибровки. - quint8 endCalibration = false; //! Флаг подтверждает завершение калибровки. -}; - -/*! - * \brief The FlagAH127C_pult class структура, передаваемая на агента. - * Используется для калибровки БСО. - */ -struct FlagAH127C_pult -{ - quint8 initCalibration = false; //! Флаг запуска калибровки. - quint8 saveCalibration = false; //! Флаг сохранения калибровки. -}; - -/*! - * \brief ControlData class управляющие воздействия с пульта управления. - */ -struct ControlData { - ControlData(); - float yaw; - float pitch; - float roll; - float march; - float depth; - float lag; - quint8 gripping; - quint8 rotman; - quint8 offPower; -}; - -/*! - * \brief ControlVMA class управляющие воздействия на каждый ВМА. - */ -struct ControlVMA -{ - float VMA1 = 0; - float VMA2 = 0; - float VMA3 = 0; - float VMA4 = 0; - float VMA5 = 0; - float VMA6 = 0; -}; - -/*! - * \brief ControlContoursFlags class структура со значениями замкутости контуров - * (если 1, то замкнуты, 0 - разомкнуты). - */ -struct ControlContoursFlags { - ControlContoursFlags(); - quint8 yaw; - quint8 pitch; - quint8 roll; - quint8 march; - quint8 depth; - quint8 lag; -}; - -/*! - * \brief AUVCurrentData class структура, передаваемая на пульт. - * Имеет текущие параметры агента. - */ -struct AUVCurrentData -{ - quint8 modeReal; //! Текущий режим. - ControlContoursFlags controlReal; //! Текущее состояние контуров. - quint8 modeAUV_Real; //! Текущий выбор модель/реальный НПА. - ControlData ControlDataReal; //! Текущие курс, дифферент, крен. - ControlVMA signalVMA_real; //! Управление на ВМА. -}; - -struct Header { - int senderID; - int receiverID; - int msgSize; -}; - -/*! - * \brief DataAH127C class структура данных с датчика БСО. - * Курс измеряется в градусах +/- 180 и т.д. - */ -struct DataAH127C { - - float yaw; - float pitch; - float roll; - - float X_accel; - float Y_accel; - float Z_accel; - - float X_rate; - float Y_rate; - float Z_rate; - - float X_magn; - float Y_magn; - float Z_magn; - - float quat [4]; -}; - -/*! - * \brief DataPressure class структура данных с датчика давления - */ -struct DataPressure { - DataPressure(); - float temperature; //! Temperature returned in deg C. - float depth; //! Depth returned in meters - float pressure; //! Pressure returned in mbar or mbar*conversion rate. -}; - -/*! - * \brief DataUWB class структура данных с UWB модуля. - */ -struct DataUWB -{ - uint16_t error_code = 0; - uint16_t connection_field = 0; - float locationX = 0; //! Координата аппарата по оси X - float locationY = 0; //! Координата аппарата по оси Y - float distanceToBeacon[4]; //! Расстоние до i-го маяка - float distanceToAgent[10]; //! Расстояние до i-го агента -}; - -/*! - * \brief PultUWB class структура данных с выставленным положением маяков. - * Идет от пульта. - */ -struct PultUWB -{ - float beacon_x[3]; - float beacon_y[3]; -}; - -/*! - * \brief ToPult class структура данных, принимаемых на пульте. - */ -struct ToPult -{ - ToPult(int auvID=0) - { - header.senderID = auvID; - header.receiverID = 0; - header.msgSize = sizeof (ToPult); - } - Header header; - AUVCurrentData auvData; //! Данные о текущих параметрах - DataAH127C dataAH127C; //! Данные с БСО - DataPressure dataPressure; //! Данные с датчика давления - FlagAH127C_bort flagAH127C_bort; //! Флаги для настрой - uint checksum; -}; - -/*! - * \brief FromPult class структура данных, передаваемая из пульта на агент. - */ -struct FromPult -{ - ControlData controlData; //! Данные, которые идут с пульта при замыканиии контуров - e_CSMode cSMode; //! Режим работы - PultUWB pultUWB; //! Флаги для настрой - ControlContoursFlags controlContoursFlags; //! Флаги замыкания контуров (1 - замкнуты) - quint8 modeAUV_selection; //! Текущий выбор модель/реальный НПА - power_Mode pMode; //! Режим работы системы питания - FlagAH127C_pult flagAH127C_pult; - uint checksum; -}; - -#pragma pack (pop) - -/*! - * \brief UVState class класс всех возможных состояний при работе с ПА. - */ -class UVState : public QObject -{ - Q_OBJECT -public: - UVState(); - Header header; - DataAH127C imuData; - DataPressure dataPressure; - DataUWB dataUWB; - PultUWB pultUWB; - - AUVCurrentData auvData; - - FlagAH127C_bort flagAH127C_bort; - FlagAH127C_pult flagAH127C_pult; - - bool modeAUV_selection; - e_CSMode cSMode; - ControlContoursFlags controlContoursFlags; - ControlData control; - power_Mode pMode; - - quint8 ID_mission; - mission_Status missionStatus; - quint8 ID_mission_AUV; - mission_Control missionControl; - - int checksum_msg_gui_send; - int checksum_msg_agent_send; - int checksum_msg_gui_received; -}; - -#endif // UVSTATE_H From d3e3ce9df0708ff3697245ea9b04167a17e9b8ad Mon Sep 17 00:00:00 2001 From: iTassadar Date: Sun, 12 Oct 2025 11:44:50 +0300 Subject: [PATCH 2/3] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=B2=D0=B8=D0=B4=D0=B6=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 61 ++++++------ interface/i_user_interface_data.cpp | 2 +- mainwindow.cpp | 8 +- mainwindow.h | 11 +++ mainwindow.ui | 24 ++++- uv/uv_state.h | 5 + videowidget/main.cpp | 11 --- videowidget/mainwindow.cpp | 89 ----------------- videowidget/mainwindow.h | 34 ------- videowidget/mainwindow.ui | 55 ----------- videowidget/untitled.pro | 21 ---- videowidget/videowidget.cpp | 143 ++++++++++++++++++++++++++++ videowidget/videowidget.h | 38 ++++++++ videowidget/videowidget.ui | 42 ++++++++ 14 files changed, 299 insertions(+), 245 deletions(-) delete mode 100644 videowidget/main.cpp delete mode 100644 videowidget/mainwindow.cpp delete mode 100644 videowidget/mainwindow.h delete mode 100644 videowidget/mainwindow.ui delete mode 100644 videowidget/untitled.pro create mode 100644 videowidget/videowidget.cpp create mode 100644 videowidget/videowidget.h create mode 100644 videowidget/videowidget.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index 33bf6f1..e0ea6a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,17 +10,36 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Charts) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Network) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Sql) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS WebEngineWidgets) -find_package(Qt5 REQUIRED COMPONENTS Widgets Quick QuickControls2 Positioning Location) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS + Widgets + Charts + Core + Network + Sql + Gui + WebEngineWidgets + Positioning +) +find_package(Qt5 REQUIRED COMPONENTS Quick QuickControls2 Location) +find_package(X11 REQUIRED) + +# === GStreamer === +find_package(PkgConfig REQUIRED) +pkg_check_modules(GST REQUIRED + gstreamer-1.0 + gstreamer-video-1.0 + gstreamer-app-1.0 +) + +# === Python конфигурация === +find_package(Python3 REQUIRED COMPONENTS Interpreter Development) -find_package(Qt5 REQUIRED COMPONENTS Core Widgets Location) +# Добавляем пути к заголовочным файлам GStreamer +include_directories(${GST_INCLUDE_DIRS}) +include_directories(${Python3_INCLUDE_DIRS}) +# Пути к вашим собственным заголовочным файлам include_directories("${PROJECT_SOURCE_DIR}/compass") include_directories("${PROJECT_SOURCE_DIR}/remote_control") include_directories("${PROJECT_SOURCE_DIR}/uv") @@ -32,15 +51,9 @@ include_directories("${PROJECT_SOURCE_DIR}/missions") include_directories("${PROJECT_SOURCE_DIR}/tabs") include_directories("${PROJECT_SOURCE_DIR}/mods") include_directories("${PROJECT_SOURCE_DIR}/Diagnostic_bord_UI/Diagnostic_bord") +include_directories("${PROJECT_SOURCE_DIR}/videowidget") include_directories("${PROJECT_SOURCE_DIR}") -include_directories(${Python3_INCLUDE_DIRS}) - - -find_package(Python3 REQUIRED COMPONENTS Interpreter Development) -find_package(Qt5 REQUIRED COMPONENTS Widgets Quick QuickWidgets Positioning Location) - -include_directories(${Python3_INCLUDE_DIRS}) set(PROJECT_SOURCES main.cpp @@ -89,26 +102,21 @@ set(PROJECT_SOURCES Diagnostic_bord_UI/Diagnostic_bord/diagnostic_board.cpp Diagnostic_bord_UI/Diagnostic_bord/diagnostic_board.h Diagnostic_bord_UI/Diagnostic_bord/diagnostic_board.ui + videowidget/videowidget.cpp + videowidget/videowidget.h + videowidget/videowidget.ui ) - - if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) qt_add_executable(UMAS_GUI MANUAL_FINALIZATION ${PROJECT_SOURCES} ) -# Define target properties for Android with Qt 6 as: -# set_property(TARGET UMAS_GUI APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR -# ${CMAKE_CURRENT_SOURCE_DIR}/android) -# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation else() if(ANDROID) add_library(UMAS_GUI SHARED ${PROJECT_SOURCES} ) -# Define properties for Android with Qt 5 after find_package() calls as: -# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") else() add_executable(UMAS_GUI ${PROJECT_SOURCES} @@ -116,6 +124,7 @@ else() endif() endif() +# Подключаем все библиотеки в одном месте target_link_libraries(UMAS_GUI PRIVATE sfml-graphics sfml-window sfml-system Qt${QT_VERSION_MAJOR}::Widgets @@ -126,12 +135,10 @@ target_link_libraries(UMAS_GUI PRIVATE Qt${QT_VERSION_MAJOR}::WebEngineWidgets Qt${QT_VERSION_MAJOR}::Positioning Python3::Python + ${GST_LIBRARIES} # <-- КЛЮЧЕВОЕ ИЗМЕНЕНИЕ: подключаем GStreamer и все его зависимости + ${X11_LIBRARIES} ) - -target_link_libraries(UMAS_GUI PRIVATE Qt5::Core Qt5::Widgets Qt5::Location) - - set_target_properties(UMAS_GUI PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} diff --git a/interface/i_user_interface_data.cpp b/interface/i_user_interface_data.cpp index 1e83804..8e2ce9b 100644 --- a/interface/i_user_interface_data.cpp +++ b/interface/i_user_interface_data.cpp @@ -19,7 +19,7 @@ void IUserInterfaceData::setFlagAH127C_pult(FlagAH127C_pult flagAH127C_pult) void IUserInterfaceData::setPowerMode(power_Mode mode) { agent[getCurrentAgent()].pMode = mode; - displayText_toConsole("Включен " + QString::number(static_cast(mode) + 2) + " режим питания"); + //displayText_toConsole("Включен " + QString::number(static_cast(mode) + 2) + " режим питания"); } void IUserInterfaceData::setControlContoursFlags(e_StabilizationContours contour, bool value) { diff --git a/mainwindow.cpp b/mainwindow.cpp index 6de2047..92ec837 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -17,7 +17,6 @@ MainWindow::MainWindow(QWidget *parent) setUpdateUI(); } -// void MainWindow::setWidget() { @@ -31,6 +30,8 @@ void MainWindow::setWidget() ui->verticalLayout_modeAutomatic->addWidget(modeAutomatic); diagnostic_board = new Diagnostic_board(this); ui->horizontalLayout_diagnosticBoard->addWidget(diagnostic_board); + videowidget = new Videowidget(this); + ui->horizontalLayout_video->addWidget(videowidget); // setMission_map connect( @@ -341,7 +342,7 @@ void MainWindow::setConnection() QString ip_pult = ui->lineEdit_ip_pult->text(); QString ip_agent = ui->lineEdit_ip_agent->text(); communicationAgent1 = new Pult::PC_Protocol(QHostAddress(ip_pult), 13053, - QHostAddress(ip_agent), 13050, 10, 0); + QHostAddress(ip_agent), 13052, 10, 0); communicationAgent1->startExchange(); if (communicationAgent1->bindState()) { @@ -462,7 +463,8 @@ void MainWindow::setTab() ui->tabWidget->setTabText(2, "Контроль сообщений"); ui->tabWidget->setTabText(3, "Режимы питания"); ui->tabWidget->setTabText(4, "Карта ГИC"); - ui->tabWidget->setCurrentIndex(4); + //ui->tabWidget->setCurrentIndex(4); + ui->tabWidget->setTabText(5, "Видео"); //виджет с видео } diff --git a/mainwindow.h b/mainwindow.h index ed5f6e9..3f5e3bb 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -8,6 +8,11 @@ #include #include +#include +#include +#include + + #include "remote_control.h" #include "uv_state.h" #include "i_user_interface_data.h" @@ -23,6 +28,7 @@ #include "mode_automatic.h" #include "map_widget.h" #include "diagnostic_board.h" +#include "videowidget.h" QT_BEGIN_NAMESPACE @@ -100,6 +106,7 @@ class MainWindow : public QMainWindow ModeAutomatic *modeAutomatic; MapWidget *mapWidget; Diagnostic_board *diagnostic_board; + Videowidget *videowidget; @@ -173,6 +180,9 @@ private slots: void slot_addMarker_to_gui(double x, double y); + //void on_pushButton_Play_Pause_clicked(); + + signals: /*! @@ -236,5 +246,6 @@ private slots: */ RemoteControl pult; + }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index ec6b6dc..4621e1c 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -79,7 +79,7 @@ - 192.168.1.7 + 192.168.1.111 100 @@ -118,7 +118,7 @@ - 192.168.1.5 + 192.168.1.11 Qt::AlignCenter @@ -201,7 +201,7 @@ - 0 + 5 @@ -253,6 +253,22 @@ + + + Page + + + + + -1 + 29 + 1081 + 481 + + + + + @@ -582,7 +598,7 @@ 0 0 3840 - 22 + 24 diff --git a/uv/uv_state.h b/uv/uv_state.h index 0097aab..9e9ebc4 100644 --- a/uv/uv_state.h +++ b/uv/uv_state.h @@ -107,6 +107,11 @@ struct ControlData { float march; float depth; float lag; + quint8 gripping = 0; + quint8 opening = 0; + quint8 rotmanlf = 0; + quint8 rotmanrt = 0; + quint8 powoff = 0; }; /*! diff --git a/videowidget/main.cpp b/videowidget/main.cpp deleted file mode 100644 index fd3e533..0000000 --- a/videowidget/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "mainwindow.h" - -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - MainWindow w; - w.show(); - return a.exec(); -} diff --git a/videowidget/mainwindow.cpp b/videowidget/mainwindow.cpp deleted file mode 100644 index d1c484e..0000000 --- a/videowidget/mainwindow.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// mainwindow.cpp -#include "mainwindow.h" -#include "ui_mainwindow.h" -#include -#include - -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent), - ui(new Ui::MainWindow) -{ - ui->setupUi(this); - pipeline = nullptr; // Инициализируем пайплайн как неактивный - - // Инициализация GStreamer - gst_init(nullptr, nullptr); - - // Получаем "внутренний" идентификатор нашего виджета для видео - videoWindowId = ui->videoWidget->winId(); - - ui->pushButton_Play_Pause->setText("Начать прием"); -} - -MainWindow::~MainWindow() -{ - // Корректно останавливаем и освобождать ресурсы при закрытии - if (pipeline) { - gst_element_set_state(pipeline, GST_STATE_NULL); - gst_object_unref(pipeline); - pipeline = nullptr; - } - delete ui; -} - -void MainWindow::on_pushButton_Play_Pause_clicked() -{ - // Отправка видео с Raspberry Pi - QString command = "ssh -X agent1@192.168.1.11 " - "\"gst-launch-1.0 v4l2src device=/dev/video0 ! " - "image/jpeg,width=100,height=100,framerate=30/1 ! " - "jpegparse ! rtpjpegpay ! udpsink host=192.168.1.6 port=5000\""; - - QProcess *sshProcess = new QProcess(this); - sshProcess->start(command); - - if (!pipeline) { // Если пайплайн не запущен, запускаем его - qDebug() << "Starting pipeline..."; - - // Приём видео на ПК через xvimagesink - const char *pipeline_str = - "udpsrc port=5000 ! application/x-rtp,encoding-name=JPEG,payload=96 ! " - "rtpjpegdepay ! jpegdec ! videoconvert ! xvimagesink name=sink"; - - GError *error = nullptr; - pipeline = gst_parse_launch(pipeline_str, &error); - - if (error) { - qWarning() << "Failed to create pipeline:" << error->message; - g_error_free(error); - return; - } - - // Находим элемент sink и привязываем к нашему QWidget - GstElement *sink = gst_bin_get_by_name(GST_BIN(pipeline), "sink"); - if (!sink) { - qWarning() << "Could not find sink element"; - gst_object_unref(pipeline); - pipeline = nullptr; - return; - } - - if (GST_IS_VIDEO_OVERLAY(sink)) { - gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink), videoWindowId); - } else { - qWarning() << "Sink is not video overlay capable!"; - } - gst_object_unref(sink); - - // Запускаем пайплайн - gst_element_set_state(pipeline, GST_STATE_PLAYING); - ui->pushButton_Play_Pause->setText("Остановить прием"); - - } else { // Если пайплайн уже работает, останавливаем его - qDebug() << "Stopping pipeline..."; - gst_element_set_state(pipeline, GST_STATE_NULL); - gst_object_unref(pipeline); - pipeline = nullptr; - ui->pushButton_Play_Pause->setText("Начать прием"); - } -} diff --git a/videowidget/mainwindow.h b/videowidget/mainwindow.h deleted file mode 100644 index ab691dd..0000000 --- a/videowidget/mainwindow.h +++ /dev/null @@ -1,34 +0,0 @@ -// mainwindow.h -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include -#include -#include -#include -#include -#include -#include - - -QT_BEGIN_NAMESPACE -namespace Ui { class MainWindow; } -QT_END_NAMESPACE - -class MainWindow : public QMainWindow { - Q_OBJECT - -public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); - -private slots: - void on_pushButton_Play_Pause_clicked(); - -private: - Ui::MainWindow *ui; - GstElement *pipeline; - WId videoWindowId; -}; -#endif // MAINWINDOW_H diff --git a/videowidget/mainwindow.ui b/videowidget/mainwindow.ui deleted file mode 100644 index 7765042..0000000 --- a/videowidget/mainwindow.ui +++ /dev/null @@ -1,55 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 800 - 600 - - - - MainWindow - - - - - - 70 - 456 - 121 - 61 - - - - PushButton - - - - - - 50 - 30 - 721 - 391 - - - - - - - - 0 - 0 - 800 - 24 - - - - - - - - diff --git a/videowidget/untitled.pro b/videowidget/untitled.pro deleted file mode 100644 index f4290fa..0000000 --- a/videowidget/untitled.pro +++ /dev/null @@ -1,21 +0,0 @@ -QT += core gui multimedia multimediawidgets - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -CONFIG += link_pkgconfig -PKGCONFIG += gstreamer-1.0 gstreamer-video-1.0 - -SOURCES += \ - main.cpp \ - mainwindow.cpp - -HEADERS += \ - mainwindow.h - -FORMS += \ - mainwindow.ui - -# Default rules for deployment. -qnx: target.path = /tmp/$${TARGET}/bin -else: unix:!android: target.path = /opt/$${TARGET}/bin -!isEmpty(target.path): INSTALLS += target diff --git a/videowidget/videowidget.cpp b/videowidget/videowidget.cpp new file mode 100644 index 0000000..61f7248 --- /dev/null +++ b/videowidget/videowidget.cpp @@ -0,0 +1,143 @@ +#include "videowidget.h" +#include "ui_videowidget.h" + +#include +#include +#include #include +#include + + +Videowidget::Videowidget(QWidget *parent) + : QWidget(parent), + ui(new Ui::Videowidget), + pipeline(nullptr), + pendingStart(false) +{ + ui->setupUi(this); + + gst_init(nullptr, nullptr); + + qDebug() << "Platform:" << QGuiApplication::platformName(); + + connect(ui->pushButton_Play_Pause, &QPushButton::clicked, + this, &Videowidget::togglePipeline); + + // появление winId + ui->videoWidget->installEventFilter(this); + + ui->pushButton_Play_Pause->setText("Начать прием"); +} + +Videowidget::~Videowidget() +{ + if (pipeline) { + gst_element_set_state(pipeline, GST_STATE_NULL); + gst_object_unref(pipeline); + pipeline = nullptr; + } + delete ui; +} + +bool Videowidget::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == ui->videoWidget) { + // QEvent::WinIdChange сработает, когда Qt создаст/изменит winId + if (event->type() == QEvent::WinIdChange) { + qDebug() << "videoWidget WinIdChange event, winId() =" << ui->videoWidget->winId(); + if (pendingStart) { + // как только winId появился — запускаем пайплайн + pendingStart = false; + startPipelineNow(); + } + } + // также можно ловить Show если нужно: + if (event->type() == QEvent::Show) { + qDebug() << "videoWidget Show event, winId() =" << ui->videoWidget->winId(); + if (pendingStart) { + pendingStart = false; + startPipelineNow(); + } + } + } + return QWidget::eventFilter(watched, event); +} + +void Videowidget::togglePipeline() +{ + if (!pipeline) { + // Попробуем принудительно создать winId и windowHandle + ui->videoWidget->createWinId(); // запрос на создание native window + QWindow *w = ui->videoWidget->windowHandle(); + if (!w) { + // окна ещё нет — пометим и дождёмся события WinIdChange (eventFilter) + qDebug() << "No windowHandle yet — deferring pipeline start"; + pendingStart = true; + return; + } + + // если windowHandle уже есть — запускаем здесь + startPipelineNow(); + } else { + // Останов пайплайна + qDebug() << "Stopping pipeline..."; + gst_element_set_state(pipeline, GST_STATE_NULL); + gst_object_unref(pipeline); + pipeline = nullptr; + ui->pushButton_Play_Pause->setText("Начать прием"); + } +} + +void Videowidget::startPipelineNow() +{ + // Здесь гарантированно есть windowHandle / winId + QWindow *window = ui->videoWidget->windowHandle(); + if (!window) { + qWarning() << "startPipelineNow: still no windowHandle!"; + return; + } + + WId wid = window->winId(); + qDebug() << "startPipelineNow: using window id =" << wid; + + // Отправка (ssh) — если нужно + QString command = + "ssh -X agent1@192.168.1.11 " + "\"gst-launch-1.0 v4l2src device=/dev/video0 ! " + "image/jpeg,framerate=30/1 ! " + "jpegparse ! rtpjpegpay ! udpsink host=192.168.1.111 port=5000\""; + + QProcess *sshProcess = new QProcess(this); + sshProcess->start(command); + + // Создаём пайплайн + const char *pipeline_str = + "udpsrc port=5000 ! application/x-rtp,encoding-name=JPEG,payload=96 ! " + "rtpjpegdepay ! jpegdec ! videoconvert ! xvimagesink name=sink"; + + GError *error = nullptr; + pipeline = gst_parse_launch(pipeline_str, &error); + if (error) { + qWarning() << "Failed to create pipeline:" << error->message; + g_error_free(error); + pipeline = nullptr; + return; + } + + GstElement *sink = gst_bin_get_by_name(GST_BIN(pipeline), "sink"); + if (!sink) { + qWarning() << "Could not find sink element"; + gst_object_unref(pipeline); + pipeline = nullptr; + return; + } + + if (GST_IS_VIDEO_OVERLAY(sink)) { + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink), (guintptr)wid); + } else { + qWarning() << "Sink is not video overlay capable!"; + } + gst_object_unref(sink); + + gst_element_set_state(pipeline, GST_STATE_PLAYING); + ui->pushButton_Play_Pause->setText("Остановить прием"); +} diff --git a/videowidget/videowidget.h b/videowidget/videowidget.h new file mode 100644 index 0000000..7a3ed7e --- /dev/null +++ b/videowidget/videowidget.h @@ -0,0 +1,38 @@ +#ifndef VIDEOWIDGET_H +#define VIDEOWIDGET_H + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class Videowidget; } +QT_END_NAMESPACE + +class Videowidget : public QWidget +{ + Q_OBJECT + +public: + explicit Videowidget(QWidget *parent = nullptr); + ~Videowidget(); + +private slots: + void togglePipeline(); + +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + void startPipelineNow(); // реальное создание/запуск пайплайна + + Ui::Videowidget *ui; + GstElement *pipeline; + bool pendingStart; // ждем winId +}; + +#endif // VIDEOWIDGET_H diff --git a/videowidget/videowidget.ui b/videowidget/videowidget.ui new file mode 100644 index 0000000..3e9fb73 --- /dev/null +++ b/videowidget/videowidget.ui @@ -0,0 +1,42 @@ + + + Videowidget + + + + 0 + 0 + 948 + 596 + + + + Form + + + + + 30 + 20 + 701 + 561 + + + + + + + 740 + 20 + 201 + 571 + + + + PushButton + + + + + + From 551618f561c086b61e31dc365ee6fe69ed8920ba Mon Sep 17 00:00:00 2001 From: iTassadar Date: Fri, 24 Oct 2025 19:07:08 +0300 Subject: [PATCH 3/3] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=B8=D1=84=D1=8B=20=D0=B2=20useKeyBoard=20=D0=B8=20useJoyS?= =?UTF-8?q?tick?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mainwindow.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 92ec837..42c1c06 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -217,7 +217,23 @@ void MainWindow::setTimer_updateImpact(int periodUpdateMsec) void MainWindow::useKeyBoard() { - delete joyStick; + + if (joyStick != nullptr) { + qDebug() << "Deleting joyStick"; + delete joyStick; + joyStick = nullptr; + } + + if (keyBoard != nullptr) { + qDebug() << "Deleting existing keyBoard"; + delete keyBoard; + keyBoard = nullptr; + } + + qDebug() << "Creating new keyBoard"; + keyBoard = new KeyBoard(this); + displayText("Используемые клавиши..."); + keyBoard = new KeyBoard(this); displayText("Используемые клавиши(должна быть английская раскладка):\n" @@ -238,7 +254,23 @@ void MainWindow::useKeyBoard() void MainWindow::useJoyStick() { - delete keyBoard; + + if (joyStick != nullptr) { + qDebug() << "Deleting joyStick"; + delete joyStick; + joyStick = nullptr; + } + + if (keyBoard != nullptr) { + qDebug() << "Deleting existing keyBoard"; + delete keyBoard; + keyBoard = nullptr; + } + + qDebug() << "Creating new keyBoard"; + keyBoard = new KeyBoard(this); + displayText("Используемые клавиши..."); + joyStick = new JoyStick(this); }