Commit 2ae959bc authored by GigAnon's avatar GigAnon

- Updated Majiks

parent 6667a020
......@@ -10,7 +10,7 @@
*.autosave
bin/
simulation/qtcreator-files/paprikaSimulateur-build*/
*.pro.user
*.pro.user*
remote/build-*/
remote/doc/
remote/Majiks/majiks.pro.user
#include "magiks.h"
#ifdef BLUETOOTH_USING_WINSOCK
#include "bluetoothproxy/bluetoothproxywinsock.h"
#include "bluetoothproxy/bluetoothproxywinsock.h"
#else
#include "bluetoothproxy/bluetoothproxyqt5.h"
#include "bluetoothproxy/bluetoothproxyqt5.h"
#endif
#include "serialproxy/serialproxy.h"
......@@ -12,7 +12,10 @@
#include <QVBoxLayout>
#include "subwindows/bluetoothmanagementwidget.h"
#include "subwindows/serialportmanagementwidget.h"
#ifdef SERIAL_ENABLED
#include "subwindows/serialportmanagementwidget.h"
#endif
#include "subwindows/odometrywindow.h"
#include "subwindows/asservwindow.h"
......@@ -33,8 +36,12 @@ Magiks::Magiks(QWidget *parent): QWidget(parent)
setWindowTitle(tr("Magiks - Robot remote"));
#ifndef BLUETOOTH_SERVER_MODE
#ifdef SERIAL_ENABLED
bool bluetoothMode = (QMessageBox::question(this, tr("Mode"), tr("Do you want to use Majiks in Bluetooth mode?"))
== QMessageBox::Yes);
#else
bool bluetoothMode = true;
#endif
if(bluetoothMode)
{
......@@ -46,13 +53,21 @@ Magiks::Magiks(QWidget *parent): QWidget(parent)
}
else
{
#ifdef SERIAL_ENABLED
m_serialProxy = new SerialProxy(9600, this);
#else
m_serialProxy = nullptr;
#endif
}
#ifdef SERIAL_ENABLED
if(bluetoothMode)
#endif
m_serialManagement = new BluetoothManagementWidget(bluetoothMode?static_cast<BluetoothProxy*>(m_serialProxy):nullptr);
#ifdef SERIAL_ENABLED
else
m_serialManagement = new SerialPortManagementWidget(bluetoothMode?nullptr:static_cast<SerialProxy*>(m_serialProxy));
#endif
m_odometry = new OdometryWindow(m_serialProxy);
m_asserv = new AsservWindow(m_serialProxy);
......@@ -77,30 +92,30 @@ Magiks::Magiks(QWidget *parent): QWidget(parent)
connect(m_packetProcessor, &PacketProcessor::robotPositionReceived, m_table, &TableWidget::setRobotPosition);
connect(m_packetProcessor, &PacketProcessor::robotAngleReceived, m_table, &TableWidget::setRobotAngle);
connect(m_serialProxy, &AbstractSerialProxy::connected, this, &Magiks::connected);
connect(m_serialProxy, &AbstractSerialProxy::disconnected, this, &Magiks::disconnected);
connect(m_serialProxy, &AbstractSerialProxy::dataReceived, m_packetProcessor, &PacketProcessor::processData);
connect(m_serialProxy, &AbstractSerialProxy::disconnected, m_plots, &PlotWidget::clear);
connect(m_odometry, &OdometryWindow::reseted, m_plots, &PlotWidget::clear);
connect(m_serialProxy, &AbstractSerialProxy::connected, this, [&]() { m_logger->log("Connected"); } );
connect(m_serialProxy, &AbstractSerialProxy::disconnected, this, [&]() { m_logger->log("Disconnected"); });
connect(m_serialProxy, &AbstractSerialProxy::dataReceived, m_packetProcessor, &PacketProcessor::processData);
connect(m_serialProxy, &AbstractSerialProxy::disconnected, m_plots, &PlotWidget::clear);
connect(m_remoteSettings, &MovementSettingsWidget::stepsUpdated, m_remote, &RemoteWidget::setSteps);
connect(m_odometry, &OdometryWindow::reseted, m_plots, &PlotWidget::clear);
connect(m_remoteSettings, &MovementSettingsWidget::stepsUpdated, m_remote, &RemoteWidget::setSteps);
connect(m_remoteSettings, &MovementSettingsWidget::tableOrientationChanged, m_table, &TableWidget::setTableOrientation);
m_remoteControlTab = new QTabWidget();
m_remoteControlTab->addTab(m_table, tr("Absolu"));
m_remoteControlTab->addTab(m_remote, tr("Relatif"));
m_remoteControlTab->addTab(m_remoteSettings,tr("Paramètres"));
m_remoteControlTab->addTab(m_table, tr("Absolute"));
m_remoteControlTab->addTab(m_remote, tr("Relative"));
m_remoteControlTab->addTab(m_remoteSettings,tr("Settings"));
m_robotSettingsTab = new QTabWidget();
m_robotSettingsTab->addTab(m_odometry, tr("Odometrie"));
m_robotSettingsTab->addTab(m_asserv, tr("Asservissement"));
m_robotSettingsTab->addTab(m_odometry, tr("Odometry"));
m_robotSettingsTab->addTab(m_asserv, tr("Control"));
m_robotSettingsTab->addTab(m_watches, tr("Watches"));
m_tabs = new QTabWidget(this);
m_tabs->addTab(m_serialManagement, tr("Connexion"));
m_tabs->addTab(m_robotSettingsTab, tr("Réglages"));
m_tabs->addTab(m_remoteControlTab, tr("Déplacements"));
m_tabs->addTab(m_plots, tr("Graphes"));
m_tabs->addTab(m_serialManagement, tr("Connection"));
m_tabs->addTab(m_robotSettingsTab, tr("Robot settings"));
m_tabs->addTab(m_remoteControlTab, tr("Movements"));
m_tabs->addTab(m_plots, tr("Graphs"));
m_tabs->addTab(m_logger, tr("Logs"));
QVBoxLayout* layout = new QVBoxLayout(this);
......@@ -110,13 +125,3 @@ Magiks::Magiks(QWidget *parent): QWidget(parent)
BluetoothTestServer* server = new BluetoothTestServer(this);
#endif
}
void Magiks::disconnected()
{
m_logger->log("Disconnected");
}
void Magiks::connected()
{
m_logger->log("Connected");
}
......@@ -19,17 +19,23 @@ class MovementSettingsWidget;
class QTabWidget;
/**
* @brief The application's main class.
*
* This class represents the main window. It builds everything else, connects signals to slots, and manages the tabs.
*/
class Magiks: public QWidget
{
Q_OBJECT
public:
/**
* @brief Constructor
* @param parent
*/
explicit Magiks(QWidget *parent = nullptr);
private:
void connected();
void disconnected();
AbstractSerialProxy* m_serialProxy;
PacketProcessor* m_packetProcessor;
......
QT += core gui widgets
QT += bluetooth serialport
TARGET = majiks
TEMPLATE = app
QT += core gui widgets
QT += bluetooth
CONFIG += console c++11 warn_on
# By default, QtSerialPort is not compiled with Qt for Android.
# Since direct serial communications are only usefull for desktops anyway, it's easier to disable it entierely.
!android:CONFIG += serial
# Disabled because of an obnoxious bug in GCC (struct A = {0} triggers the warning even though it's legal)
win32-g++:QMAKE_CXXFLAGS += -Wno-missing-field-initializers
TARGET = majiks
TEMPLATE = app
#NB: you HAVE to set QWT_ROOT as an env variable yourself
# The config when serial coms are enabled
serial {
QT += serialport
DEFINES += SERIAL_ENABLED
SOURCES += serialproxy/serialproxy.cpp \
subwindows/serialportmanagementwidget.cpp
HEADERS += serialproxy/serialproxy.h \
subwindows/serialportmanagementwidget.h
}
# Check if QWT_ROOT is defined as an environment variable
_QWT_ROOT = $$(QWT_ROOT)
isEmpty(_QWT_ROOT) {
error("Please set QWT_ROOT as an environment variable.")
}
# NB: you HAVE to set QWT_ROOT as an env variable yourself
# (it points to the folder where you compiled Qwt)
# We are not using the 'module' install because it is broken on several platforms
# qwt.prf should setup everything nicely...
include ( $(QWT_ROOT)/features/qwt.prf )
LIBS += -lqwt
#Qwt is VERY finicky when it comes to Android...
# Qwt is VERY finicky when it comes to Android...
# There has to be a better way to include Qt5PrintSupport.so and Qt5OpenGL.so by default directly from Qt, but I couldn't find it.
android:ANDROID_EXTRA_LIBS += $$(QWT_ROOT)/lib/libqwt.so $$(QWT_ROOT)/lib/libQt5PrintSupport.so $$(QWT_ROOT)/lib/libQt5OpenGL.so
# qwt.prf is broken for Android (the config is confused by the X-compil and uses Unix settings instead of the host's...)
android:INCLUDEPATH += $$(QWT_ROOT)/include
android:QMAKE_LIBDIR += $$(QWT_ROOT)/lib
# For KrabiPacket
INCLUDEPATH += ../../stm32/include/hardware
win32:HEADERS += bluetoothproxy/bluetoothproxywinsock.h
win32:SOURCES += bluetoothproxy/bluetoothproxywinsock.cpp
win32:DEFINES += BLUETOOTH_USING_WINSOCK
win32:LIBS += -lws2_32
DEFINES += BLUETOOTH
# Winsock config
win32 {
HEADERS += bluetoothproxy/bluetoothproxywinsock.h
SOURCES += bluetoothproxy/bluetoothproxywinsock.cpp
DEFINES += BLUETOOTH_USING_WINSOCK
LIBS += -lws2_32
}
# Sources files used by every config
# (note: used by both QtCreator for the project view AND by the linker - don't forget to call qmake when changing those)
SOURCES += main.cpp \
magiks.cpp \
../../stm32/src/hardware/krabipacket.cpp \
......@@ -47,14 +73,13 @@ SOURCES += main.cpp \
packetprocessor.cpp \
timemaster.cpp \
bluetoothtestserver.cpp \
subwindows/movementsettingswidget.cpp \
serialproxy/abstractserialproxy.cpp \
serialproxy/serialproxy.cpp \
subwindows/serialmanagementwidget.cpp \
subwindows/serialportmanagementwidget.cpp
subwindows/movementsettingswidget.cpp \
serialproxy/abstractserialproxy.cpp \
subwindows/serialmanagementwidget.cpp
# Headers files used by every config
# (note: only useful for the project view in QtCreator)
HEADERS += magiks.h \
../../stm32/include/hardware/krabipacket.h \
bluetoothproxy/bluetoothproxy.h \
......@@ -70,17 +95,14 @@ HEADERS += magiks.h \
packetprocessor.h \
timemaster.h \
bluetoothtestserver.h \
subwindows/movementsettingswidget.h \
serialproxy/abstractserialproxy.h \
serialproxy/serialproxy.h \
subwindows/serialmanagementwidget.h \
subwindows/serialportmanagementwidget.h
subwindows/movementsettingswidget.h \
serialproxy/abstractserialproxy.h \
subwindows/serialmanagementwidget.h
FORMS += \
subwindows/asservwindow.ui \
subwindows/debugwindow.ui \
subwindows/odometrywindow.ui \
subwindows/watchwindow.ui
......
This diff is collapsed.
......@@ -10,10 +10,10 @@ SerialProxy::SerialProxy(qint32 baudrate, QObject *parent): AbstractSerialProxy(
m_serialPort = new QSerialPort(this);
connect(m_serialPort, &QSerialPort::readyRead, this, &SerialProxy::readData);
setBaudrate(baudrate);
}
#ifdef SERIAL_ENABLED
bool SerialProxy::setBaudrate(qint32 baudrate)
{
return !m_serialPort->setBaudRate(baudrate);
......@@ -92,3 +92,5 @@ void SerialProxy::sendData(KrabiPacket& data)
m_serialPort->write(binData);
}
#endif
......@@ -5,24 +5,66 @@
class QSerialPort;
/**
* @brief This class provides an implementation of AbstractSerialProxy as a physical serial connection (COM)
*
* This class provides an implementation of AbstractSerialProxy as a physical serial connection (COM).
* Since it uses QtSerial, it should work with most plateforms.
* Note Qt is not always compiled with QtSerial enabled (it isn't on Android). You can disable serial support entierely through majiks.pro.
*/
class SerialProxy : public AbstractSerialProxy
{
public:
/**
* @brief Constructor
* @param baudrate The baudrate to use. It is preferable (but not mandatory) to use constants from QSerialPort::BaudRate.
* @param parent The parent object
*/
SerialProxy(qint32 baudrate = 9600, QObject* parent = nullptr);
virtual void sendData(KrabiPacket& data);
/**
* @brief It is preferable (but not mandatory) to use constants from QSerialPort::BaudRate.
* @param baudrate
* @return True if an error happened (i.e. invalid baudrate), false otherwise.
*/
bool setBaudrate(qint32 baudrate);
/**
* @brief Return the baudrate
* @return
*/
qint32 getBaudrate() const;
/**
* @brief Returns the port name as a QString
* @return The port name or an empty QString
*/
QString getPortName() const;
bool open(QString port);
/**
* @brief Open the serial port. Any previous connection is dropped.
* @param The port name to use. If empty, uses any available port.
* @return True on error, false otherwise
* @see close isOpen
*/
bool open(QString port = QString());
/**
* @brief Close the current connection.
* @see isOpen open
*/
void close();
/**
* @return True if a valid connection to a serial port exists, false otherwise.
* @see open close
*/
bool isOpen() const;
protected:
/**
* @brief Handles the incomming data
*/
void readData();
private:
......
......@@ -19,9 +19,6 @@ BluetoothManagementWidget::BluetoothManagementWidget(BluetoothProxy* bluetoothPr
m_bluetoothAvLabel = new QLabel(this);
m_connectionLabel = new QLabel(this);
//Debug
m_sendButton = new QPushButton(tr("Send"), this);
m_scanButton = new QPushButton(tr("Scan"), this);
m_connectButton = new QPushButton(this);
m_checkBluetoothButton = new QPushButton(tr("Check Bluetooth"), this);
......@@ -55,7 +52,6 @@ BluetoothManagementWidget::BluetoothManagementWidget(BluetoothProxy* bluetoothPr
layout->addLayout(btCxLay);
layout->addWidget(m_scanButton);
layout->addWidget(m_detectedDevices);
layout->addWidget(m_sendButton);
connect(m_connectButton, &QPushButton::clicked, this, &BluetoothManagementWidget::on_connectButton_clicked);
connect(m_checkBluetoothButton, &QPushButton::clicked, this, &BluetoothManagementWidget::checkBluetoothAvailability);
......@@ -70,8 +66,6 @@ BluetoothManagementWidget::BluetoothManagementWidget(BluetoothProxy* bluetoothPr
connect(m_UUIDInput, &QLineEdit::textChanged, this, &BluetoothManagementWidget::changeUUID);
//Debug
connect(m_sendButton, &QPushButton::clicked, this, &BluetoothManagementWidget::sendTest);
//m_UUIDInput->setText("B62C4E8D-62CC-404B-BBBF-BF3E3BBB1374");
m_UUIDInput->setText("00001101-0000-1000-8000-00805F9B34FB");
......@@ -128,7 +122,6 @@ void BluetoothManagementWidget::checkBluetoothAvailability()
btAv = m_bluetoothProxy->isBluetoothAvailable();
m_scanButton->setEnabled(btAv);
m_sendButton->setEnabled(btAv);
m_detectedDevices->setEnabled(btAv);
m_connectButton->setEnabled(btAv);
m_UUIDInput->setEnabled(btAv);
......@@ -181,16 +174,3 @@ QString BluetoothManagementWidget::getSelectedAddress() const
return m_detectedDevices->item(row, 1)->data(BluetoothManagementWidget::ADDRESS_DATA_INDEX).toString();
}
//Debug
void BluetoothManagementWidget::sendTest()
{
if(!m_bluetoothProxy)
return;
KrabiPacket packet(KrabiPacket::LOG_DEBUG);
packet.addString("test");
m_bluetoothProxy->sendData(packet);
}
......@@ -18,9 +18,6 @@ class BluetoothManagementWidget: public SerialManagementWidget
QString getSelectedAddress() const;
private:
//Debug
void sendTest();
QPushButton* m_sendButton;
void checkBluetoothAvailability();
void checkConnectionStatus();
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DebugWindow</class>
<widget class="QMainWindow" name="DebugWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="infoField">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menuPerspective">
<property name="title">
<string>Perspectives</string>
</property>
<addaction name="actionSimulateur"/>
<addaction name="actionOdom_trie"/>
<addaction name="actionAsservissement"/>
</widget>
<widget class="QMenu" name="menuViews">
<property name="title">
<string>Views</string>
</property>
<addaction name="actionBluetooth"/>
<addaction name="actionBluetooth_Interface"/>
<addaction name="actionOdometrie"/>
<addaction name="actionAsserv_Window"/>
<addaction name="actionSharps"/>
<addaction name="actionWatches"/>
</widget>
<widget class="QMenu" name="menuSettings">
<property name="title">
<string>Settings</string>
</property>
<addaction name="actionDisplay_route"/>
<addaction name="actionDisplay_strategy"/>
<addaction name="actionHide_table"/>
<addaction name="actionReset_objects"/>
<addaction name="actionRemove_objects"/>
<addaction name="actionRemote_Mod"/>
</widget>
<addaction name="menuSettings"/>
<addaction name="menuPerspective"/>
<addaction name="menuViews"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionSimulateur">
<property name="text">
<string>Simulateur</string>
</property>
</action>
<action name="actionOdom_trie">
<property name="text">
<string>Odometrie</string>
</property>
</action>
<action name="actionAsservissement">
<property name="text">
<string>Asservissement</string>
</property>
</action>
<action name="actionDisplay_route">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="text">
<string>Display route</string>
</property>
</action>
<action name="actionHide_table">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Hide table</string>
</property>
</action>
<action name="actionReset_objects">
<property name="text">
<string>Reset objects</string>
</property>
</action>
<action name="actionRemove_objects">
<property name="text">
<string>Remove objects</string>
</property>
</action>
<action name="actionDisplay_strategy">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>Display strategy</string>
</property>
</action>
<action name="actionRemote_Mod">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Remote Mod</string>
</property>
</action>
<action name="actionBluetooth">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Bluetooth Scanner</string>
</property>
</action>
<action name="actionBluetooth_Interface">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Bluetooth Interface</string>
</property>
</action>
<action name="actionOdometrie">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Odometrie</string>
</property>
</action>
<action name="actionAsserv_Window">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Asserv</string>
</property>
</action>
<action name="actionSharps">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Sharps</string>
</property>
</action>
<action name="actionWatches">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Watches</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>
......@@ -6,14 +6,29 @@
class QTextEdit;
/**
* @brief A simple widget to display logs.
*/
class LoggerWidget : public QWidget
{
Q_OBJECT
Q_OBJECT
public:
/**
* @brief Constructor
* @param parent The parent widget
*/
explicit LoggerWidget(QWidget *parent = nullptr);
/**
* @brief Add a line to the log
* @param text The text to add
* @param isDebug If set, this line will be displayed as 'debug'
*/
void log(const QString& text, bool isDebug = false);
/**
* @return The entierety of the logs
*/
QString getLogs() const;
private:
......
......@@ -3,12 +3,15 @@
#include <QGroupBox>
#include <QDoubleSpinBox>
#include <QLabel>
#include <QCheckBox>
#include <QBoxLayout>
#include <QGridLayout>
MovementSettingsWidget::MovementSettingsWidget(QWidget *parent) : QWidget(parent)
{
m_stepsGB = new QGroupBox(tr("Pas de déplacement"), this);
QVBoxLayout* layout = new QVBoxLayout(this);
m_stepsGB = new QGroupBox(tr("Movement steps"), this);
m_angularStepSB = new QDoubleSpinBox(this);
m_angularStepSB->setSuffix(tr(" °"));
......@@ -25,8 +28,6 @@ MovementSettingsWidget::MovementSettingsWidget(QWidget *parent) : QWidget(parent
connect(m_angularStepSB, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &MovementSettingsWidget::on_stepsUpdated);
connect(m_linearStepSB, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &MovementSettingsWidget::on_stepsUpdated);
QVBoxLayout* layout = new QVBoxLayout(this);
QGridLayout* stepsLayout = new QGridLayout(m_stepsGB);
stepsLayout->addWidget(new QLabel(tr("Distance")), 1, 1);
stepsLayout->addWidget(new QLabel(tr("Angle")), 1, 2);
......@@ -34,9 +35,26 @@ MovementSettingsWidget::MovementSettingsWidget(QWidget *parent) : QWidget(parent
stepsLayout->addWidget(m_angularStepSB, 2, 2);
layout->addWidget(m_stepsGB);
m_tableGB = new QGroupBox(tr("Table settings"), this);
m_tableOrientationCB = new QCheckBox(tr("Swap table axes"), this);
connect(m_tableOrientationCB, &QCheckBox::toggled, this, &MovementSettingsWidget::changeTableOrientation);
QGridLayout* tableSettingsLayout = new QGridLayout(m_tableGB);
tableSettingsLayout->addWidget(m_tableOrientationCB, 1, 1);
layout->addWidget(m_tableGB);
layout->addStretch();
}
void MovementSettingsWidget::changeTableOrientation(bool rotated)
{
emit tableOrientationChanged(rotated);
}
void MovementSettingsWidget::on_stepsUpdated(double)
{
......
......@@ -5,6 +5,7 @@
class QDoubleSpinBox;
class QGroupBox;
class QCheckBox;
class MovementSettingsWidget: public QWidget
{
......@@ -16,12 +17,19 @@ class MovementSettingsWidget: public QWidget
void stepsUpdated(float linearStep, float angularStep);
void tableOrientationChanged(bool rotated);
private:
void on_stepsUpdated(double);
void changeTableOrientation(bool rotated);
QGroupBox* m_stepsGB;
QDoubleSpinBox* m_angularStepSB;
QDoubleSpinBox* m_linearStepSB;