kopia lustrzana https://github.com/f4exb/sdrangel
Merge pull request #1668 from srcejon/rotator_gamepad
Rotator controller: Add gamepad/joystick controlpull/1670/head
commit
0f583806ad
|
@ -84,7 +84,7 @@ for:
|
|||
qml-module-qtlocation qml-module-qtpositioning qml-module-qtquick-window2 qml-module-qtquick-dialogs \
|
||||
qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtgraphicaleffects \
|
||||
libqt5serialport5-dev qtdeclarative5-dev qtpositioning5-dev qtlocation5-dev \
|
||||
libqt5charts5-dev libqt5texttospeech5-dev libfaad-dev zlib1g-dev \
|
||||
libqt5charts5-dev libqt5texttospeech5-dev libqt5gamepad5-dev libfaad-dev zlib1g-dev \
|
||||
libusb-1.0-0-dev libhidapi-dev libboost-all-dev libasound2-dev libopencv-dev libopencv-imgcodecs-dev \
|
||||
libxml2-dev bison flex ffmpeg libpostproc-dev libavcodec-dev libavformat-dev \
|
||||
libopus-dev libcodec2-dev libairspy-dev libhackrf-dev \
|
||||
|
|
|
@ -635,7 +635,9 @@ if (BUILD_GUI)
|
|||
Location
|
||||
TextToSpeech
|
||||
Svg
|
||||
AndroidExtras)
|
||||
AndroidExtras
|
||||
OPTIONAL_COMPONENTS
|
||||
Gamepad)
|
||||
endif()
|
||||
else()
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
@ -662,7 +664,8 @@ if (BUILD_GUI)
|
|||
OPTIONAL_COMPONENTS
|
||||
WebEngine
|
||||
WebEngineCore
|
||||
WebEngineWidgets)
|
||||
WebEngineWidgets
|
||||
Gamepad)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -16,6 +16,7 @@ Build-Depends: debhelper (>= 9),
|
|||
libqt5websockets5-dev,
|
||||
libqt5quick5,
|
||||
libqt5texttospeech5-dev,
|
||||
libqt5gamepad5-dev,
|
||||
qml-module-qtlocation,
|
||||
qml-module-qtpositioning,
|
||||
qml-module-qtquick-window2,
|
||||
|
@ -61,6 +62,7 @@ Depends: ${shlibs:Depends},
|
|||
libasound2,
|
||||
libgl1-mesa-glx,
|
||||
libqt5multimedia5-plugins,
|
||||
libqt5gamepad5,
|
||||
qtspeech5-speechd-plugin,
|
||||
pulseaudio,
|
||||
ffmpeg,
|
||||
|
@ -80,8 +82,8 @@ Description: SDR/Analyzer/Generator front-end for various hardware
|
|||
Based on Qt5 framework and OpenGL for the spectrum and scope rendering.
|
||||
Builds on Linux, Windows and Mac O/S
|
||||
Reception modes supported:
|
||||
Analog: AM, ATV, NFM, WFM, SSB, broadcast FM, APT
|
||||
Digital: D-Star, Yaesu SF, DMR, dPMR, FreeDV, DAB, DVB-S, LoRa, ADS-B, Packet (AX.25/APRS), AIS
|
||||
Analog: AM, ATV, NFM, WFM, SSB, broadcast FM, APT, ILS, VOR
|
||||
Digital: D-Star, Yaesu SF, DMR, dPMR, FreeDV, M17, DAB, DVB-S, LoRa, ADS-B, Packet (AX.25/APRS), AIS, FT8, Navtex, Radiosonde, RTTY, Pager
|
||||
Analyzer: Generic channel
|
||||
Transmission modes supported:
|
||||
Analog: AM, ATV, NFM, SSB, WFM
|
||||
|
|
|
@ -38,17 +38,34 @@ if(NOT SERVER_MODE)
|
|||
gs232controllergui.ui
|
||||
dfmstatusdialog.cpp
|
||||
dfmstatusdialog.ui
|
||||
inputcontroller.cpp
|
||||
)
|
||||
set(gs232controller_HEADERS
|
||||
${gs232controller_HEADERS}
|
||||
gs232controllergui.h
|
||||
dfmstatusdialog.h
|
||||
inputcontroller.h
|
||||
)
|
||||
|
||||
set(TARGET_NAME featuregs232controller)
|
||||
set(TARGET_LIB Qt::Widgets)
|
||||
set(TARGET_LIB_GUI "sdrgui")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
|
||||
|
||||
if(Qt${QT_DEFAULT_MAJOR_VERSION}Gamepad_FOUND)
|
||||
add_compile_definitions(QT_GAMEPAD_FOUND)
|
||||
set(TARGET_LIB ${TARGET_LIB} Qt::Gamepad)
|
||||
set(gs232controller_SOURCES
|
||||
${gs232controller_SOURCES}
|
||||
gamepadinputcontroller.cpp
|
||||
gamepadconfigurationdialog.cpp
|
||||
gamepadconfigurationdialog.ui)
|
||||
set(gs232controller_HEADERS
|
||||
${gs232controller_HEADERS}
|
||||
gamepadinputcontroller.h
|
||||
gamepadconfiguration.h)
|
||||
endif()
|
||||
|
||||
else()
|
||||
set(TARGET_NAME featuregs232controllersrv)
|
||||
set(TARGET_LIB "")
|
||||
|
@ -71,7 +88,7 @@ target_link_libraries(${TARGET_NAME}
|
|||
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
||||
|
||||
if(WIN32)
|
||||
# Run deployqt for serial libraries
|
||||
# Run deployqt for serial & gamepad libraries
|
||||
include(DeployQt)
|
||||
windeployqt(${TARGET_NAME} ${SDRANGEL_BINARY_BIN_DIR} ${PROJECT_SOURCE_DIR}/../../../sdrgui/resources)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QGamepadManager>
|
||||
#include <QGamepad>
|
||||
|
||||
#include "gamepadconfigurationdialog.h"
|
||||
|
||||
GamepadConfigurationDialog::GamepadConfigurationDialog(QGamepad *gamepad, QWidget* parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::GamepadConfigurationDialog),
|
||||
m_gamepad(gamepad)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
connect(m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadConfigurationDialog::axisRightXChanged);
|
||||
connect(m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadConfigurationDialog::axisRightYChanged);
|
||||
connect(m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadConfigurationDialog::axisLeftXChanged);
|
||||
connect(m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadConfigurationDialog::axisLeftYChanged);
|
||||
}
|
||||
|
||||
GamepadConfigurationDialog::~GamepadConfigurationDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void GamepadConfigurationDialog::accept()
|
||||
{
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void GamepadConfigurationDialog::on_config0_clicked()
|
||||
{
|
||||
ui->config0->setText("Configuring");
|
||||
ui->config0->setEnabled(false);
|
||||
ui->config1->setEnabled(false);
|
||||
ui->config2->setEnabled(false);
|
||||
ui->config3->setEnabled(false);
|
||||
QGamepadManager::instance()->configureAxis(m_gamepad->deviceId(), QGamepadManager ::AxisRightX);
|
||||
}
|
||||
|
||||
void GamepadConfigurationDialog::on_config1_clicked()
|
||||
{
|
||||
ui->config1->setText("Configuring");
|
||||
ui->config0->setEnabled(false);
|
||||
ui->config1->setEnabled(false);
|
||||
ui->config2->setEnabled(false);
|
||||
ui->config3->setEnabled(false);
|
||||
QGamepadManager::instance()->configureAxis(m_gamepad->deviceId(), QGamepadManager ::AxisRightY);
|
||||
}
|
||||
|
||||
void GamepadConfigurationDialog::on_config2_clicked()
|
||||
{
|
||||
ui->config2->setText("Configuring");
|
||||
ui->config0->setEnabled(false);
|
||||
ui->config1->setEnabled(false);
|
||||
ui->config2->setEnabled(false);
|
||||
ui->config3->setEnabled(false);
|
||||
QGamepadManager::instance()->configureAxis(m_gamepad->deviceId(), QGamepadManager ::AxisLeftX);
|
||||
}
|
||||
|
||||
void GamepadConfigurationDialog::on_config3_clicked()
|
||||
{
|
||||
ui->config3->setText("Configuring");
|
||||
ui->config0->setEnabled(false);
|
||||
ui->config1->setEnabled(false);
|
||||
ui->config2->setEnabled(false);
|
||||
ui->config3->setEnabled(false);
|
||||
QGamepadManager::instance()->configureAxis(m_gamepad->deviceId(), QGamepadManager ::AxisLeftY);
|
||||
}
|
||||
|
||||
void GamepadConfigurationDialog::axisRightXChanged(double value)
|
||||
{
|
||||
ui->value0->setText(QString::number(value));
|
||||
ui->config0->setText("Configure");
|
||||
ui->config0->setEnabled(true);
|
||||
ui->config1->setEnabled(true);
|
||||
ui->config2->setEnabled(true);
|
||||
ui->config3->setEnabled(true);
|
||||
}
|
||||
|
||||
void GamepadConfigurationDialog::axisRightYChanged(double value)
|
||||
{
|
||||
ui->value1->setText(QString::number(value));
|
||||
ui->config1->setText("Configure");
|
||||
ui->config0->setEnabled(true);
|
||||
ui->config1->setEnabled(true);
|
||||
ui->config2->setEnabled(true);
|
||||
ui->config3->setEnabled(true);
|
||||
}
|
||||
|
||||
void GamepadConfigurationDialog::axisLeftXChanged(double value)
|
||||
{
|
||||
ui->value2->setText(QString::number(value));
|
||||
ui->config2->setText("Configure");
|
||||
ui->config0->setEnabled(true);
|
||||
ui->config1->setEnabled(true);
|
||||
ui->config2->setEnabled(true);
|
||||
ui->config3->setEnabled(true);
|
||||
}
|
||||
|
||||
void GamepadConfigurationDialog::axisLeftYChanged(double value)
|
||||
{
|
||||
ui->value3->setText(QString::number(value));
|
||||
ui->config3->setText("Configure");
|
||||
ui->config0->setEnabled(true);
|
||||
ui->config1->setEnabled(true);
|
||||
ui->config2->setEnabled(true);
|
||||
ui->config3->setEnabled(true);
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_GAMEPADCONFIGURATIONDIALOG_H
|
||||
#define INCLUDE_GAMEPADCONFIGURATIONDIALOG_H
|
||||
|
||||
#include "ui_gamepadconfigurationdialog.h"
|
||||
|
||||
class QGamepad;
|
||||
|
||||
class GamepadConfigurationDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GamepadConfigurationDialog(QGamepad *gamepad, QWidget* parent = 0);
|
||||
~GamepadConfigurationDialog();
|
||||
|
||||
private slots:
|
||||
void accept();
|
||||
void on_config0_clicked();
|
||||
void on_config1_clicked();
|
||||
void on_config2_clicked();
|
||||
void on_config3_clicked();
|
||||
void axisRightXChanged(double value);
|
||||
void axisRightYChanged(double value);
|
||||
void axisLeftXChanged(double value);
|
||||
void axisLeftYChanged(double value);
|
||||
|
||||
private:
|
||||
Ui::GamepadConfigurationDialog* ui;
|
||||
QGamepad *m_gamepad;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_GAMEPADCONFIGURATIONDIALOG_H
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GamepadConfigurationDialog</class>
|
||||
<widget class="QDialog" name="GamepadConfigurationDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>380</width>
|
||||
<height>309</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Sans</family>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Gamepad Configuration</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="value0">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="config3">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="value1">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="config1">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="config3Label">
|
||||
<property name="text">
|
||||
<string>Elevation Offset Axis</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="value3">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="config2">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="config2Label">
|
||||
<property name="text">
|
||||
<string>Azimuth Offset Axis</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="config1Label">
|
||||
<property name="text">
|
||||
<string>Target Elevation/Y Axis</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="config0Label">
|
||||
<property name="text">
|
||||
<string>Target Aziumth/X Axis</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="value2">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="config0">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="instructions">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>To configure a controller axis:
|
||||
|
||||
- press the Configure button,
|
||||
- move the controller axis you want for that function.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>config0</tabstop>
|
||||
<tabstop>config1</tabstop>
|
||||
<tabstop>config2</tabstop>
|
||||
<tabstop>config3</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>GamepadConfigurationDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>GamepadConfigurationDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -0,0 +1,166 @@
|
|||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QDebug>
|
||||
#include <QGamepadManager>
|
||||
|
||||
#include "gamepadinputcontroller.h"
|
||||
#include "gamepadconfigurationdialog.h"
|
||||
|
||||
GamepadInputController::GamepadInputController(int deviceId) :
|
||||
m_gamepad(deviceId),
|
||||
m_rightX(0.0),
|
||||
m_rightY(0.0),
|
||||
m_leftX(0.0),
|
||||
m_leftY(0.0)
|
||||
{
|
||||
connect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged);
|
||||
connect(&m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadInputController::axisRightYChanged);
|
||||
connect(&m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadInputController::axisLeftXChanged);
|
||||
connect(&m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadInputController::axisLeftYChanged);
|
||||
}
|
||||
|
||||
double GamepadInputController::getAxisValue(int axis)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case 0:
|
||||
return m_rightX;
|
||||
case 1:
|
||||
return m_rightY;
|
||||
case 2:
|
||||
return m_leftX;
|
||||
case 3:
|
||||
return m_leftY;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int GamepadInputController::getNumberOfAxes() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool GamepadInputController::supportsConfiguration() const
|
||||
{
|
||||
// Should only return true on Linux evdev or Android
|
||||
#if defined(LINUX) || defined(ANDROID)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GamepadInputController::configure()
|
||||
{
|
||||
disconnect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged);
|
||||
disconnect(&m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadInputController::axisRightYChanged);
|
||||
disconnect(&m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadInputController::axisLeftXChanged);
|
||||
disconnect(&m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadInputController::axisLeftYChanged);
|
||||
|
||||
GamepadConfigurationDialog dialog(&m_gamepad);
|
||||
dialog.exec();
|
||||
|
||||
connect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged);
|
||||
connect(&m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadInputController::axisRightYChanged);
|
||||
connect(&m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadInputController::axisLeftXChanged);
|
||||
connect(&m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadInputController::axisLeftYChanged);
|
||||
}
|
||||
|
||||
void GamepadInputController::axisRightXChanged(double value)
|
||||
{
|
||||
m_rightX = value;
|
||||
}
|
||||
|
||||
void GamepadInputController::axisRightYChanged(double value)
|
||||
{
|
||||
m_rightY = value;
|
||||
}
|
||||
|
||||
void GamepadInputController::axisLeftXChanged(double value)
|
||||
{
|
||||
m_leftX = value;
|
||||
}
|
||||
|
||||
void GamepadInputController::axisLeftYChanged(double value)
|
||||
{
|
||||
m_leftY = value;
|
||||
}
|
||||
|
||||
QStringList GamepadInputController::getAllControllers()
|
||||
{
|
||||
QStringList names;
|
||||
QGamepadManager *gamepadManager = QGamepadManager::instance();
|
||||
|
||||
if (gamepadManager)
|
||||
{
|
||||
const QList<int> gamepads = gamepadManager->connectedGamepads();
|
||||
for (const auto gamepad : gamepads)
|
||||
{
|
||||
QString name;
|
||||
if (gamepadManager->gamepadName(gamepad).isEmpty()) {
|
||||
name = QString("Gamepad %1").arg(gamepad);
|
||||
} else {
|
||||
name = gamepadManager->gamepadName(gamepad);
|
||||
}
|
||||
qDebug() << "GamepadInputController::getAllControllers: Gamepad: " << gamepad << "name:" << gamepadManager->gamepadName(gamepad) << " connected " << gamepadManager->isGamepadConnected(gamepad);
|
||||
names.append(name);
|
||||
}
|
||||
if (gamepads.size() == 0) {
|
||||
qDebug() << "GamepadInputController::getAllControllers: No gamepads";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "GamepadInputController::getAllControllers: No gamepad manager";
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
GamepadInputController* GamepadInputController::open(const QString& name)
|
||||
{
|
||||
GamepadInputController *inputController = nullptr;
|
||||
QGamepadManager *gamepadManager = QGamepadManager::instance();
|
||||
|
||||
if (gamepadManager)
|
||||
{
|
||||
const QList<int> gamepads = gamepadManager->connectedGamepads();
|
||||
for (const auto gamepad : gamepads)
|
||||
{
|
||||
QString gamepadName;
|
||||
if (gamepadManager->gamepadName(gamepad).isEmpty()) {
|
||||
gamepadName = QString("Gamepad %1").arg(gamepad);
|
||||
} else {
|
||||
gamepadName = gamepadManager->gamepadName(gamepad);
|
||||
}
|
||||
if (name == gamepadName)
|
||||
{
|
||||
inputController = new GamepadInputController(gamepad);
|
||||
if (inputController)
|
||||
{
|
||||
qDebug() << "GamepadInputController::open: Opened gamepad " << name;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "GamepadInputController::open: Failed to open gamepad: " << gamepad;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inputController;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_FEATURE_GAMEPADINPUTCONTROLLER_H_
|
||||
#define INCLUDE_FEATURE_GAMEPADINPUTCONTROLLER_H_
|
||||
|
||||
#include "inputcontroller.h"
|
||||
|
||||
#include <QGamepad>
|
||||
|
||||
class GamepadInputController : public InputController {
|
||||
|
||||
public:
|
||||
|
||||
GamepadInputController(int deviceId);
|
||||
double getAxisValue(int axis) override;
|
||||
int getNumberOfAxes() const override;
|
||||
bool supportsConfiguration() const override;
|
||||
void configure() override;
|
||||
|
||||
static QStringList getAllControllers();
|
||||
static GamepadInputController* open(const QString& name);
|
||||
|
||||
private slots:
|
||||
|
||||
void axisRightXChanged(double value);
|
||||
void axisRightYChanged(double value);
|
||||
void axisLeftXChanged(double value);
|
||||
void axisLeftYChanged(double value);
|
||||
|
||||
private:
|
||||
|
||||
QGamepad m_gamepad;
|
||||
double m_rightX;
|
||||
double m_rightY;
|
||||
double m_leftX;
|
||||
double m_leftY;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_FEATURE_GAMEPADINPUTCONTROLLER_H_
|
||||
|
|
@ -491,6 +491,8 @@ void GS232Controller::webapiFormatFeatureSettings(
|
|||
response.getGs232ControllerSettings()->setProtocol(settings.m_protocol);
|
||||
response.getGs232ControllerSettings()->setPrecision(settings.m_precision);
|
||||
response.getGs232ControllerSettings()->setCoordinates((int)settings.m_coordinates);
|
||||
response.getGs232ControllerSettings()->setInputController(new QString(settings.m_inputController));
|
||||
response.getGs232ControllerSettings()->setInputSensitivity(settings.m_inputSensitivity);
|
||||
|
||||
if (response.getGs232ControllerSettings()->getTitle()) {
|
||||
*response.getGs232ControllerSettings()->getTitle() = settings.m_title;
|
||||
|
@ -585,6 +587,12 @@ void GS232Controller::webapiUpdateFeatureSettings(
|
|||
if (featureSettingsKeys.contains("coordinates")) {
|
||||
settings.m_coordinates = (GS232ControllerSettings::Coordinates)response.getGs232ControllerSettings()->getCoordinates();
|
||||
}
|
||||
if (featureSettingsKeys.contains("inputController")) {
|
||||
settings.m_inputController = *response.getGs232ControllerSettings()->getInputController();
|
||||
}
|
||||
if (featureSettingsKeys.contains("inputSensitivity")) {
|
||||
settings.m_inputSensitivity = response.getGs232ControllerSettings()->getInputSensitivity();
|
||||
}
|
||||
if (featureSettingsKeys.contains("title")) {
|
||||
settings.m_title = *response.getGs232ControllerSettings()->getTitle();
|
||||
}
|
||||
|
@ -676,6 +684,12 @@ void GS232Controller::webapiReverseSendSettings(const QList<QString>& featureSet
|
|||
if (featureSettingsKeys.contains("coordinates") || force) {
|
||||
swgGS232ControllerSettings->setCoordinates(settings.m_coordinates);
|
||||
}
|
||||
if (featureSettingsKeys.contains("inputController") || force) {
|
||||
swgGS232ControllerSettings->setInputController(new QString(settings.m_inputController));
|
||||
}
|
||||
if (featureSettingsKeys.contains("inputSensitivity") || force) {
|
||||
swgGS232ControllerSettings->setInputSensitivity(settings.m_inputSensitivity);
|
||||
}
|
||||
if (featureSettingsKeys.contains("title") || force) {
|
||||
swgGS232ControllerSettings->setTitle(new QString(settings.m_title));
|
||||
}
|
||||
|
|
|
@ -216,7 +216,13 @@ GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featu
|
|||
m_doApplySettings(true),
|
||||
m_lastFeatureState(0),
|
||||
m_lastOnTarget(false),
|
||||
m_dfmStatusDialog()
|
||||
m_dfmStatusDialog(),
|
||||
m_inputController(nullptr),
|
||||
m_inputCoord1(0.0),
|
||||
m_inputCoord2(0.0),
|
||||
m_inputAzOffset(0.0),
|
||||
m_inputElOffset(0.0),
|
||||
m_inputUpdate(false)
|
||||
{
|
||||
m_feature = feature;
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
|
@ -246,6 +252,11 @@ GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featu
|
|||
|
||||
m_settings.setRollupState(&m_rollupState);
|
||||
|
||||
ui->inputConfigure->setVisible(false);
|
||||
updateInputControllerList();
|
||||
connect(InputControllerManager::instance(), &InputControllerManager::controllersChanged, this, &GS232ControllerGUI::updateInputControllerList);
|
||||
connect(&m_inputTimer, &QTimer::timeout, this, &GS232ControllerGUI::checkInputController);
|
||||
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
makeUIConnections();
|
||||
|
@ -256,6 +267,132 @@ GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featu
|
|||
new DialogPositioner(&m_dfmStatusDialog, true);
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::updateInputControllerList()
|
||||
{
|
||||
ui->inputController->blockSignals(true);
|
||||
ui->inputController->clear();
|
||||
ui->inputController->addItem("None");
|
||||
|
||||
QStringList controllers = InputControllerManager::getAllControllers();
|
||||
for (const auto& controller : controllers) {
|
||||
ui->inputController->addItem(controller);
|
||||
}
|
||||
ui->inputController->blockSignals(false);
|
||||
int index = ui->inputController->findText(m_settings.m_inputController);
|
||||
ui->inputController->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::updateInputController()
|
||||
{
|
||||
delete m_inputController;
|
||||
m_inputController = nullptr;
|
||||
|
||||
bool enabled = false;
|
||||
if (m_settings.m_inputController != "None")
|
||||
{
|
||||
m_inputController = InputControllerManager::open(m_settings.m_inputController);
|
||||
if (m_inputController)
|
||||
{
|
||||
m_inputTimer.start(20);
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_inputTimer.stop();
|
||||
}
|
||||
|
||||
ui->inputSensitivityLabel->setEnabled(enabled);
|
||||
ui->inputSensitivity->setEnabled(enabled);
|
||||
ui->inputSensitivityText->setEnabled(enabled);
|
||||
ui->inputConfigure->setEnabled(enabled);
|
||||
ui->inputConfigure->setVisible(enabled && m_inputController->supportsConfiguration());
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::checkInputController()
|
||||
{
|
||||
if (m_inputController)
|
||||
{
|
||||
// If our input device has two sticks (four axes), we use one for target and one for offset
|
||||
// If only one stick (two axes), it's used both for target when not tracking and offset, when tracking
|
||||
// Use separate variables rather than values in UI, to allow for higher precision
|
||||
|
||||
if (!m_settings.m_track)
|
||||
{
|
||||
m_inputCoord1 += m_settings.m_inputSensitivity * m_inputController->getAxisValue(0);
|
||||
m_inputCoord2 += m_settings.m_inputSensitivity * -m_inputController->getAxisValue(1);
|
||||
|
||||
if (m_settings.m_coordinates == GS232ControllerSettings::AZ_EL)
|
||||
{
|
||||
m_inputCoord1 = std::max(m_inputCoord1, (double) m_settings.m_azimuthMin);
|
||||
m_inputCoord1 = std::min(m_inputCoord1, (double) m_settings.m_azimuthMax);
|
||||
m_inputCoord2 = std::max(m_inputCoord2, (double) m_settings.m_elevationMin);
|
||||
m_inputCoord2 = std::min(m_inputCoord2, (double) m_settings.m_elevationMax);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_inputCoord1 = std::max(m_inputCoord1, -90.0);
|
||||
m_inputCoord1 = std::min(m_inputCoord1, 90.0);
|
||||
m_inputCoord2 = std::max(m_inputCoord2, -90.0);
|
||||
m_inputCoord2 = std::min(m_inputCoord2, 90.0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_inputController->getNumberOfAxes() < 4) && m_settings.m_track)
|
||||
{
|
||||
m_inputAzOffset += m_settings.m_inputSensitivity * m_inputController->getAxisValue(0);
|
||||
m_inputElOffset += m_settings.m_inputSensitivity * -m_inputController->getAxisValue(1);
|
||||
}
|
||||
else if (m_inputController->getNumberOfAxes() >= 4)
|
||||
{
|
||||
m_inputAzOffset += m_settings.m_inputSensitivity * m_inputController->getAxisValue(2);
|
||||
m_inputElOffset += m_settings.m_inputSensitivity * -m_inputController->getAxisValue(3);
|
||||
}
|
||||
m_inputAzOffset = std::max(m_inputAzOffset, -360.0);
|
||||
m_inputAzOffset = std::min(m_inputAzOffset, 360.0);
|
||||
m_inputElOffset = std::max(m_inputElOffset, -180.0);
|
||||
m_inputElOffset = std::min(m_inputElOffset, 180.0);
|
||||
|
||||
m_inputUpdate = true;
|
||||
if (!m_settings.m_track)
|
||||
{
|
||||
ui->coord1->setValue(m_inputCoord1);
|
||||
ui->coord2->setValue(m_inputCoord2);
|
||||
}
|
||||
if (((m_inputController->getNumberOfAxes() < 4) && m_settings.m_track) || (m_inputController->getNumberOfAxes() >= 4))
|
||||
{
|
||||
ui->azimuthOffset->setValue(m_inputAzOffset);
|
||||
ui->elevationOffset->setValue(m_inputElOffset);
|
||||
}
|
||||
m_inputUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_inputController_currentIndexChanged(int index)
|
||||
{
|
||||
// Don't update settings if set to -1
|
||||
if (index >= 0)
|
||||
{
|
||||
m_settings.m_inputController = ui->inputController->currentText();
|
||||
applySettings();
|
||||
updateInputController();
|
||||
}
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_inputSensitivty_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_inputSensitivity = value / 1000.0;
|
||||
ui->inputSensitivityText->setText(QString("%1%").arg(m_settings.m_inputSensitivity * 100.0));
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_inputConfigure_clicked()
|
||||
{
|
||||
if (m_inputController) {
|
||||
m_inputController->configure();
|
||||
}
|
||||
}
|
||||
|
||||
GS232ControllerGUI::~GS232ControllerGUI()
|
||||
{
|
||||
m_dfmStatusDialog.close();
|
||||
|
@ -302,6 +439,9 @@ void GS232ControllerGUI::displaySettings()
|
|||
ui->elevationMin->setValue(m_settings.m_elevationMin);
|
||||
ui->elevationMax->setValue(m_settings.m_elevationMax);
|
||||
ui->tolerance->setValue(m_settings.m_tolerance);
|
||||
ui->inputController->setCurrentText(m_settings.m_inputController);
|
||||
ui->inputSensitivity->setValue((int) (m_settings.m_inputSensitivity * 1000.0));
|
||||
ui->inputSensitivityText->setText(QString("%1%").arg(m_settings.m_inputSensitivity * 100.0));
|
||||
ui->dfmTrack->setChecked(m_settings.m_dfmTrackOn);
|
||||
ui->dfmLubePumps->setChecked(m_settings.m_dfmLubePumpsOn);
|
||||
ui->dfmBrakes->setChecked(m_settings.m_dfmBrakesOn);
|
||||
|
@ -543,18 +683,27 @@ void GS232ControllerGUI::on_port_valueChanged(int value)
|
|||
|
||||
void GS232ControllerGUI::on_coord1_valueChanged(double value)
|
||||
{
|
||||
if (!m_inputUpdate) {
|
||||
m_inputCoord1 = value;
|
||||
}
|
||||
displayToAzEl(value, ui->coord2->value());
|
||||
ui->targetName->setText("");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_coord2_valueChanged(double value)
|
||||
{
|
||||
if (!m_inputUpdate) {
|
||||
m_inputCoord2 = value;
|
||||
}
|
||||
displayToAzEl(ui->coord1->value(), value);
|
||||
ui->targetName->setText("");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_azimuthOffset_valueChanged(int value)
|
||||
{
|
||||
if (!m_inputUpdate) {
|
||||
m_inputAzOffset = value;
|
||||
}
|
||||
m_settings.m_azimuthOffset = value;
|
||||
m_settingsKeys.append("azimuthOffset");
|
||||
applySettings();
|
||||
|
@ -562,6 +711,9 @@ void GS232ControllerGUI::on_azimuthOffset_valueChanged(int value)
|
|||
|
||||
void GS232ControllerGUI::on_elevationOffset_valueChanged(int value)
|
||||
{
|
||||
if (!m_inputUpdate) {
|
||||
m_inputElOffset = value;
|
||||
}
|
||||
m_settings.m_elevationOffset = value;
|
||||
m_settingsKeys.append("elevationOffset");
|
||||
applySettings();
|
||||
|
@ -805,6 +957,9 @@ void GS232ControllerGUI::makeUIConnections()
|
|||
QObject::connect(ui->tolerance, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &GS232ControllerGUI::on_tolerance_valueChanged);
|
||||
QObject::connect(ui->precision, qOverload<int>(&QSpinBox::valueChanged), this, &GS232ControllerGUI::on_precision_valueChanged);
|
||||
QObject::connect(ui->coordinates, qOverload<int>(&QComboBox::currentIndexChanged), this, &GS232ControllerGUI::on_coordinates_currentIndexChanged);
|
||||
QObject::connect(ui->inputController, qOverload<int>(&QComboBox::currentIndexChanged), this, &GS232ControllerGUI::on_inputController_currentIndexChanged);
|
||||
QObject::connect(ui->inputSensitivity, qOverload<int>(&QSlider::valueChanged), this, &GS232ControllerGUI::on_inputSensitivty_valueChanged);
|
||||
QObject::connect(ui->inputConfigure, &QToolButton::clicked, this, &GS232ControllerGUI::on_inputConfigure_clicked);
|
||||
QObject::connect(ui->dfmTrack, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmTrack_clicked);
|
||||
QObject::connect(ui->dfmLubePumps, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmLubePumps_clicked);
|
||||
QObject::connect(ui->dfmBrakes, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmBrakes_clicked);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "gs232controllersettings.h"
|
||||
#include "dfmstatusdialog.h"
|
||||
#include "inputcontroller.h"
|
||||
|
||||
class PluginAPI;
|
||||
class FeatureUISet;
|
||||
|
@ -68,6 +69,14 @@ private:
|
|||
|
||||
DFMStatusDialog m_dfmStatusDialog;
|
||||
|
||||
InputController *m_inputController;
|
||||
QTimer m_inputTimer;
|
||||
double m_inputCoord1;
|
||||
double m_inputCoord2;
|
||||
double m_inputAzOffset;
|
||||
double m_inputElOffset;
|
||||
bool m_inputUpdate;
|
||||
|
||||
explicit GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
|
||||
virtual ~GS232ControllerGUI();
|
||||
|
||||
|
@ -84,6 +93,7 @@ private:
|
|||
void makeUIConnections();
|
||||
void azElToDisplay(float az, float el, float& coord1, float& coord2) const;
|
||||
void displayToAzEl(float coord1, float coord2);
|
||||
void updateInputController();
|
||||
|
||||
private slots:
|
||||
void onMenuDialogCalled(const QPoint &p);
|
||||
|
@ -115,6 +125,11 @@ private slots:
|
|||
void on_dfmDrives_clicked(bool checked=false);
|
||||
void on_dfmShowStatus_clicked();
|
||||
void updateStatus();
|
||||
void on_inputController_currentIndexChanged(int index);
|
||||
void on_inputSensitivty_valueChanged(int value);
|
||||
void on_inputConfigure_clicked();
|
||||
void updateInputControllerList();
|
||||
void checkInputController();
|
||||
};
|
||||
|
||||
#endif // INCLUDE_FEATURE_GS232CONTROLLERGUI_H_
|
||||
|
|
|
@ -306,7 +306,7 @@
|
|||
<x>10</x>
|
||||
<y>140</y>
|
||||
<width>341</width>
|
||||
<height>191</height>
|
||||
<height>201</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -330,6 +330,72 @@
|
|||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="settingsGridLayout">
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="baudRateLabel">
|
||||
<property name="text">
|
||||
<string>Baud rate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="azimuthMin">
|
||||
<property name="maximum">
|
||||
<number>450</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="elevationOffsetLabel">
|
||||
<property name="text">
|
||||
<string>Elevation offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="azimuthMaxLabel">
|
||||
<property name="text">
|
||||
<string>Azimuth max</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Coordinates</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="azimuthMinLabel">
|
||||
<property name="text">
|
||||
<string>Azimuth min</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QSpinBox" name="elevationMax">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="inputSensitivityLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sensitivity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="elevationMaxLabel">
|
||||
<property name="text">
|
||||
<string>Elevation max</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="azimuthOffsetLabel">
|
||||
<property name="text">
|
||||
|
@ -337,6 +403,56 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QSpinBox" name="elevationOffset">
|
||||
<property name="toolTip">
|
||||
<string>Specify an offset angle in degrees that will be added to the target elevation to correct for misalignment</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-180</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="protocol">
|
||||
<property name="toolTip">
|
||||
<string>Command protocol</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>GS-232</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>SPID</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>rotctld</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>DFM</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="portLabel">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3">
|
||||
<widget class="QSpinBox" name="precision">
|
||||
<property name="enabled">
|
||||
|
@ -353,64 +469,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="host">
|
||||
<property name="toolTip">
|
||||
<string>Hostname / IP address of computer to connect to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QSpinBox" name="azimuthMax">
|
||||
<property name="maximum">
|
||||
<number>450</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="toleranceLabel">
|
||||
<property name="text">
|
||||
<string>Tolerance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="serialPort">
|
||||
<property name="toolTip">
|
||||
<string>Name of serial port to use to connect to the rotator</string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="azimuthOffset">
|
||||
<property name="toolTip">
|
||||
<string>Specify an offset angel in degrees that will be added to the target azimuth to correct for misalignment</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-360</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>360</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="azimuthMaxLabel">
|
||||
<property name="text">
|
||||
<string>Azimuth max</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="connectionLabel">
|
||||
<property name="text">
|
||||
<string>Connection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QSpinBox" name="port">
|
||||
<property name="toolTip">
|
||||
|
@ -421,110 +479,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="baudRateLabel">
|
||||
<property name="text">
|
||||
<string>Baud rate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="connection">
|
||||
<property name="toolTip">
|
||||
<string>The type of connection to use to the rotator</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Serial</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TCP</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="serialPortLabel">
|
||||
<property name="text">
|
||||
<string>Serial Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QDoubleSpinBox" name="tolerance">
|
||||
<property name="toolTip">
|
||||
<string>Tolerance in degrees</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="azimuthMin">
|
||||
<item row="4" column="3">
|
||||
<widget class="QSpinBox" name="azimuthMax">
|
||||
<property name="maximum">
|
||||
<number>450</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="hostLabel">
|
||||
<property name="text">
|
||||
<string>Host</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="portLabel">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="elevationMaxLabel">
|
||||
<property name="text">
|
||||
<string>Elevation max</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="elevationMinLabel">
|
||||
<property name="text">
|
||||
<string>Elevation min</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QSpinBox" name="elevationMax">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="azimuthMinLabel">
|
||||
<property name="text">
|
||||
<string>Azimuth min</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="elevationOffsetLabel">
|
||||
<property name="text">
|
||||
<string>Elevation offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="elevationMin">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QComboBox" name="baudRate">
|
||||
<property name="toolTip">
|
||||
|
@ -585,6 +546,61 @@
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="connectionLabel">
|
||||
<property name="text">
|
||||
<string>Connection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="connection">
|
||||
<property name="toolTip">
|
||||
<string>The type of connection to use to the rotator</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Serial</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TCP</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="serialPort">
|
||||
<property name="toolTip">
|
||||
<string>Name of serial port to use to connect to the rotator</string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="hostLabel">
|
||||
<property name="text">
|
||||
<string>Host</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="elevationMin">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="host">
|
||||
<property name="toolTip">
|
||||
<string>Hostname / IP address of computer to connect to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLabel" name="precisionLabel">
|
||||
<property name="enabled">
|
||||
|
@ -595,49 +611,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="protocol">
|
||||
<property name="toolTip">
|
||||
<string>Command protocol</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>GS-232</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>SPID</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>rotctld</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>DFM</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QSpinBox" name="elevationOffset">
|
||||
<property name="toolTip">
|
||||
<string>Specify an offset angle in degrees that will be added to the target elevation to correct for misalignment</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-180</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="protocolLabel">
|
||||
<property name="text">
|
||||
|
@ -645,6 +618,50 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="elevationMinLabel">
|
||||
<property name="text">
|
||||
<string>Elevation min</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="azimuthOffset">
|
||||
<property name="toolTip">
|
||||
<string>Specify an offset angel in degrees that will be added to the target azimuth to correct for misalignment</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-360</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>360</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QDoubleSpinBox" name="tolerance">
|
||||
<property name="toolTip">
|
||||
<string>Tolerance in degrees</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="serialPortLabel">
|
||||
<property name="text">
|
||||
<string>Serial Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="toleranceLabel">
|
||||
<property name="text">
|
||||
<string>Tolerance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QComboBox" name="coordinates">
|
||||
<property name="toolTip">
|
||||
|
@ -667,13 +684,78 @@
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="inputControllerLabel">
|
||||
<property name="text">
|
||||
<string>Coordinates</string>
|
||||
<string>Input Control</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSlider" name="inputSensitivity">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Input controller sensitivity</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2000</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="inputSensitivityText">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>100%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QComboBox" name="inputController">
|
||||
<property name="toolTip">
|
||||
<string>Gamepad / joystick to use</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="inputConfigure">
|
||||
<property name="toolTip">
|
||||
<string>Configure input</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>C</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -64,6 +64,8 @@ void GS232ControllerSettings::resetToDefaults()
|
|||
m_connection = SERIAL;
|
||||
m_precision = 0;
|
||||
m_coordinates = AZ_EL;
|
||||
m_inputController = "None";
|
||||
m_inputSensitivity = 0.25;
|
||||
m_dfmTrackOn = false;
|
||||
m_dfmLubePumpsOn = false;
|
||||
m_dfmBrakesOn = false;
|
||||
|
@ -119,6 +121,8 @@ QByteArray GS232ControllerSettings::serialize() const
|
|||
s.writeBool(32, m_dfmLubePumpsOn);
|
||||
s.writeBool(33, m_dfmBrakesOn);
|
||||
s.writeBool(34, m_dfmDrivesOn);
|
||||
s.writeString(35, m_inputController);
|
||||
s.writeFloat(36, m_inputSensitivity);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
|
@ -187,6 +191,8 @@ bool GS232ControllerSettings::deserialize(const QByteArray& data)
|
|||
d.readBool(32, &m_dfmLubePumpsOn);
|
||||
d.readBool(33, &m_dfmBrakesOn);
|
||||
d.readBool(34, &m_dfmDrivesOn);
|
||||
d.readString(35, &m_inputController, "None");
|
||||
d.readFloat(36, &m_inputSensitivity, 0.25);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -271,6 +277,12 @@ void GS232ControllerSettings::applySettings(const QStringList& settingsKeys, con
|
|||
if (settingsKeys.contains("coordinates")) {
|
||||
m_coordinates = settings.m_coordinates;
|
||||
}
|
||||
if (settingsKeys.contains("inputController")) {
|
||||
m_inputController = settings.m_inputController;
|
||||
}
|
||||
if (settingsKeys.contains("inputSensitivity")) {
|
||||
m_inputSensitivity = settings.m_inputSensitivity;
|
||||
}
|
||||
if (settingsKeys.contains("dfmTrackOn")) {
|
||||
m_dfmTrackOn = settings.m_dfmTrackOn;
|
||||
}
|
||||
|
@ -370,6 +382,12 @@ QString GS232ControllerSettings::getDebugString(const QStringList& settingsKeys,
|
|||
if (settingsKeys.contains("coordinates") || force) {
|
||||
ostr << " m_coordinates: " << m_precision;
|
||||
}
|
||||
if (settingsKeys.contains("inputController") || force) {
|
||||
ostr << " m_inputController: " << m_inputController.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("inputSensitivity") || force) {
|
||||
ostr << " m_inputSensitivity: " << m_inputSensitivity;
|
||||
}
|
||||
if (settingsKeys.contains("title") || force) {
|
||||
ostr << " m_title: " << m_title.toStdString();
|
||||
}
|
||||
|
@ -397,4 +415,3 @@ QString GS232ControllerSettings::getDebugString(const QStringList& settingsKeys,
|
|||
|
||||
return QString(ostr.str().c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ struct GS232ControllerSettings
|
|||
enum Connection { SERIAL, TCP } m_connection;
|
||||
int m_precision;
|
||||
enum Coordinates { AZ_EL, X_Y_85, X_Y_30 } m_coordinates;
|
||||
QString m_inputController;
|
||||
float m_inputSensitivity;
|
||||
|
||||
bool m_dfmTrackOn;
|
||||
bool m_dfmLubePumpsOn;
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef QT_GAMEPAD_FOUND
|
||||
#include <QGamepadManager>
|
||||
#include "gamepadinputcontroller.h"
|
||||
#endif
|
||||
|
||||
#include "inputcontroller.h"
|
||||
|
||||
InputControllerManager* InputControllerManager::m_instance = nullptr;
|
||||
|
||||
QStringList InputControllerManager::getAllControllers()
|
||||
{
|
||||
#ifdef QT_GAMEPAD_FOUND
|
||||
return GamepadInputController::getAllControllers();
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
InputController* InputControllerManager::open(const QString& name)
|
||||
{
|
||||
#ifdef QT_GAMEPAD_FOUND
|
||||
return GamepadInputController::open(name);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
InputControllerManager* InputControllerManager::instance()
|
||||
{
|
||||
if (!m_instance) {
|
||||
m_instance = new InputControllerManager();
|
||||
}
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
InputControllerManager::InputControllerManager()
|
||||
{
|
||||
#ifdef QT_GAMEPAD_FOUND
|
||||
connect(QGamepadManager::instance(), &QGamepadManager::connectedGamepadsChanged, this, &InputControllerManager::connectedGamepadsChanged);
|
||||
#endif
|
||||
}
|
||||
|
||||
void InputControllerManager::connectedGamepadsChanged()
|
||||
{
|
||||
emit controllersChanged();
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_FEATURE_INPUTCONTROLLER_H_
|
||||
#define INCLUDE_FEATURE_INPUTCONTROLLER_H_
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class InputController : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
// Called every ~50ms
|
||||
// axis 0-3. 0=Az/X, 1=El/Y, 2=Az Offset, 3=El Offset
|
||||
// value returned should be current axis position in range [-1,1]
|
||||
virtual double getAxisValue(int axis) = 0;
|
||||
virtual int getNumberOfAxes() const = 0;
|
||||
virtual bool supportsConfiguration() const { return false; }
|
||||
virtual void configure() {};
|
||||
|
||||
};
|
||||
|
||||
class InputControllerManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
static QStringList getAllControllers();
|
||||
static InputController* open(const QString& name);
|
||||
static InputControllerManager* instance();
|
||||
|
||||
signals:
|
||||
|
||||
void controllersChanged();
|
||||
|
||||
private slots:
|
||||
void connectedGamepadsChanged();
|
||||
|
||||
private:
|
||||
InputControllerManager();
|
||||
|
||||
static InputControllerManager *m_instance;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // INCLUDE_FEATURE_INPUTCONTROLLER_H_
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
The Rotator Controller feature plugin allows SDRangel to send commands to GS-232 and SPID rotators as well as hamlib's rotctld, via a serial or TCP connection.
|
||||
The Rotator Controller feature plugin allows SDRangel to send commands to GS-232 and SPID rotators as well as hamlib's rotctld, via a serial or TCP connection.
|
||||
This allows SDRangel to point antennas mounted on a rotator to a specified azimuth and elevation.
|
||||
|
||||
Azimuth and elevation can be set manually by a user in the GUI, via the REST API, or via another plugin, such as the Map Feature, the ADS-B Demodulator, or the Star Tracker.
|
||||
Azimuth and elevation can be set manually by a user in the GUI, via the REST API, via another plugin, such as the Map Feature, the ADS-B Demodulator, or the Star Tracker, or by controller/gamepads (such as an XBox Wireless Controller).
|
||||
|
||||
<h2>Interface</h2>
|
||||
|
||||
|
@ -107,6 +107,23 @@ Specifies the coordinate system used by the GUI for entry and display of the pos
|
|||
|
||||
Equations for translating between these coordinate systems can be found [here](https://ntrs.nasa.gov/citations/19670030005).
|
||||
|
||||
<h3>22: Input Control</h3>
|
||||
|
||||
Specifies a controller/gamepad that can be used to specify target coordinates or azimuth and elevation offset.
|
||||
|
||||
When a gamepad with 2 sticks (4 axes) such as the XBox Wireless Controller is used, the right stick is used for controlling target coordinates,
|
||||
while the left stick is for controlling azimuth and elevation offset.
|
||||
If a controller only has 2 axes, target coordinates will be controlled when not tracking (6) and offset will be controlled when tracking.
|
||||
|
||||
The [Qt Gamepad](https://doc.qt.io/qt-5/qtgamepad-index.html) library is used to implement gamepad support.
|
||||
On Linux, using Qt Gamepad with the evdev backend, all joysticks & gamepads appear as though they have 4 axes (a limitation of Qt Gamepad).
|
||||
If using a joystick which only has 2 axes, whether it corresponds to the left or right stick can be configured by pressing the 'C' button.
|
||||
On Linux, the [xone driver](https://github.com/medusalix/xone) has support for the Xbox Wireless Controller, that isn't supported by the older xpad driver that is included with Ubuntu.
|
||||
|
||||
<h3>23: Sensitivity</h3>
|
||||
|
||||
Specifies the sensitivity on the input controls (22). The higher the value, the faster coordinates will change for a given control stick movement.
|
||||
|
||||
<h2>Protocol Implementations</h2>
|
||||
|
||||
<h3>GS-232 Protocol Implementation Notes</h3>
|
||||
|
|
|
@ -58,6 +58,13 @@ GS232ControllerSettings:
|
|||
coordinates:
|
||||
description: (0 Az/El, 1 X/Y 85, 2 X/Y 30)
|
||||
type: integer
|
||||
inputController:
|
||||
description: Name of input controller
|
||||
type: string
|
||||
inputSensitivity:
|
||||
description: Input controller sensitivity
|
||||
type: number
|
||||
format: float
|
||||
title:
|
||||
type: string
|
||||
rgbColor:
|
||||
|
|
|
@ -64,6 +64,10 @@ SWGGS232ControllerSettings::SWGGS232ControllerSettings() {
|
|||
m_precision_isSet = false;
|
||||
coordinates = 0;
|
||||
m_coordinates_isSet = false;
|
||||
input_controller = nullptr;
|
||||
m_input_controller_isSet = false;
|
||||
input_sensitivity = 0.0f;
|
||||
m_input_sensitivity_isSet = false;
|
||||
title = nullptr;
|
||||
m_title_isSet = false;
|
||||
rgb_color = 0;
|
||||
|
@ -124,6 +128,10 @@ SWGGS232ControllerSettings::init() {
|
|||
m_precision_isSet = false;
|
||||
coordinates = 0;
|
||||
m_coordinates_isSet = false;
|
||||
input_controller = new QString("");
|
||||
m_input_controller_isSet = false;
|
||||
input_sensitivity = 0.0f;
|
||||
m_input_sensitivity_isSet = false;
|
||||
title = new QString("");
|
||||
m_title_isSet = false;
|
||||
rgb_color = 0;
|
||||
|
@ -168,6 +176,10 @@ SWGGS232ControllerSettings::cleanup() {
|
|||
|
||||
|
||||
|
||||
if(input_controller != nullptr) {
|
||||
delete input_controller;
|
||||
}
|
||||
|
||||
if(title != nullptr) {
|
||||
delete title;
|
||||
}
|
||||
|
@ -231,6 +243,10 @@ SWGGS232ControllerSettings::fromJsonObject(QJsonObject &pJson) {
|
|||
|
||||
::SWGSDRangel::setValue(&coordinates, pJson["coordinates"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&input_controller, pJson["inputController"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&input_sensitivity, pJson["inputSensitivity"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
|
||||
|
@ -317,6 +333,12 @@ SWGGS232ControllerSettings::asJsonObject() {
|
|||
if(m_coordinates_isSet){
|
||||
obj->insert("coordinates", QJsonValue(coordinates));
|
||||
}
|
||||
if(input_controller != nullptr && *input_controller != QString("")){
|
||||
toJsonValue(QString("inputController"), input_controller, obj, QString("QString"));
|
||||
}
|
||||
if(m_input_sensitivity_isSet){
|
||||
obj->insert("inputSensitivity", QJsonValue(input_sensitivity));
|
||||
}
|
||||
if(title != nullptr && *title != QString("")){
|
||||
toJsonValue(QString("title"), title, obj, QString("QString"));
|
||||
}
|
||||
|
@ -525,6 +547,26 @@ SWGGS232ControllerSettings::setCoordinates(qint32 coordinates) {
|
|||
this->m_coordinates_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGGS232ControllerSettings::getInputController() {
|
||||
return input_controller;
|
||||
}
|
||||
void
|
||||
SWGGS232ControllerSettings::setInputController(QString* input_controller) {
|
||||
this->input_controller = input_controller;
|
||||
this->m_input_controller_isSet = true;
|
||||
}
|
||||
|
||||
float
|
||||
SWGGS232ControllerSettings::getInputSensitivity() {
|
||||
return input_sensitivity;
|
||||
}
|
||||
void
|
||||
SWGGS232ControllerSettings::setInputSensitivity(float input_sensitivity) {
|
||||
this->input_sensitivity = input_sensitivity;
|
||||
this->m_input_sensitivity_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGGS232ControllerSettings::getTitle() {
|
||||
return title;
|
||||
|
@ -664,6 +706,12 @@ SWGGS232ControllerSettings::isSet(){
|
|||
if(m_coordinates_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(input_controller && *input_controller != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_input_sensitivity_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(title && *title != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
|
|
@ -97,6 +97,12 @@ public:
|
|||
qint32 getCoordinates();
|
||||
void setCoordinates(qint32 coordinates);
|
||||
|
||||
QString* getInputController();
|
||||
void setInputController(QString* input_controller);
|
||||
|
||||
float getInputSensitivity();
|
||||
void setInputSensitivity(float input_sensitivity);
|
||||
|
||||
QString* getTitle();
|
||||
void setTitle(QString* title);
|
||||
|
||||
|
@ -179,6 +185,12 @@ private:
|
|||
qint32 coordinates;
|
||||
bool m_coordinates_isSet;
|
||||
|
||||
QString* input_controller;
|
||||
bool m_input_controller_isSet;
|
||||
|
||||
float input_sensitivity;
|
||||
bool m_input_sensitivity_isSet;
|
||||
|
||||
QString* title;
|
||||
bool m_title_isSet;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue