Merge pull request #1668 from srcejon/rotator_gamepad

Rotator controller: Add gamepad/joystick control
pull/1670/head
Edouard Griffiths 2023-04-24 16:41:30 +02:00 zatwierdzone przez GitHub
commit 0f583806ad
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
21 zmienionych plików z 1316 dodań i 214 usunięć

Wyświetl plik

@ -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 \

Wyświetl plik

@ -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()

6
debian/control vendored
Wyświetl plik

@ -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

Wyświetl plik

@ -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()

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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>

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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_

Wyświetl plik

@ -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));
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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_

Wyświetl plik

@ -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>

Wyświetl plik

@ -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());
}

Wyświetl plik

@ -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;

Wyświetl plik

@ -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();
}

Wyświetl plik

@ -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_

Wyświetl plik

@ -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>

Wyświetl plik

@ -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:

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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;