Rotator Controller: Add additional gamepad calibration and functionality

pull/1761/head
Jon Beniston 2023-08-05 12:33:01 +01:00
rodzic 83834674c0
commit 2d7c572040
22 zmienionych plików z 1063 dodań i 204 usunięć

Wyświetl plik

@ -45,6 +45,7 @@ if(NOT SERVER_MODE)
gs232controllergui.h gs232controllergui.h
dfmstatusdialog.h dfmstatusdialog.h
inputcontroller.h inputcontroller.h
inputcontrollersettings.h
) )
set(TARGET_NAME featuregs232controller) set(TARGET_NAME featuregs232controller)

Wyświetl plik

@ -19,17 +19,32 @@
#include <QGamepad> #include <QGamepad>
#include "gamepadconfigurationdialog.h" #include "gamepadconfigurationdialog.h"
#include "inputcontrollersettings.h"
GamepadConfigurationDialog::GamepadConfigurationDialog(QGamepad *gamepad, QWidget* parent) : GamepadConfigurationDialog::GamepadConfigurationDialog(QGamepad *gamepad, InputControllerSettings *settings, bool supportsConfiguraiton, QWidget* parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::GamepadConfigurationDialog), ui(new Ui::GamepadConfigurationDialog),
m_gamepad(gamepad) m_gamepad(gamepad),
m_settings(settings)
{ {
ui->setupUi(this); ui->setupUi(this);
connect(m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadConfigurationDialog::axisRightXChanged); connect(m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadConfigurationDialog::axisRightXChanged);
connect(m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadConfigurationDialog::axisRightYChanged); connect(m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadConfigurationDialog::axisRightYChanged);
connect(m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadConfigurationDialog::axisLeftXChanged); connect(m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadConfigurationDialog::axisLeftXChanged);
connect(m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadConfigurationDialog::axisLeftYChanged); connect(m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadConfigurationDialog::axisLeftYChanged);
ui->deadzone0->setValue(settings->m_deadzone[0]);
ui->deadzone1->setValue(settings->m_deadzone[1]);
ui->deadzone2->setValue(settings->m_deadzone[2]);
ui->deadzone3->setValue(settings->m_deadzone[3]);
ui->lowSensitivity->blockSignals(true);
ui->lowSensitivity->setRange(0.01, 100);
ui->lowSensitivity->blockSignals(false);
ui->lowSensitivity->setValue((double)settings->m_lowSensitivity);
ui->highSensitivity->blockSignals(true);
ui->highSensitivity->setRange(0.01, 100);
ui->highSensitivity->blockSignals(false);
ui->highSensitivity->setValue((double)settings->m_highSensitivity);
ui->configurationGroup->setEnabled(supportsConfiguraiton);
} }
GamepadConfigurationDialog::~GamepadConfigurationDialog() GamepadConfigurationDialog::~GamepadConfigurationDialog()
@ -42,6 +57,11 @@ void GamepadConfigurationDialog::accept()
QDialog::accept(); QDialog::accept();
} }
void GamepadConfigurationDialog::on_configReset_clicked()
{
QGamepadManager::instance()->resetConfiguration(m_gamepad->deviceId());
}
void GamepadConfigurationDialog::on_config0_clicked() void GamepadConfigurationDialog::on_config0_clicked()
{ {
ui->config0->setText("Configuring"); ui->config0->setText("Configuring");
@ -121,3 +141,52 @@ void GamepadConfigurationDialog::axisLeftYChanged(double value)
ui->config2->setEnabled(true); ui->config2->setEnabled(true);
ui->config3->setEnabled(true); ui->config3->setEnabled(true);
} }
// Convert double to string and remove trailing zeros
static QString toSimpleFloat(double v, int prec)
{
QString s = QString::number(v, 'f', prec);
while (s.back() == '0') {
s.chop(1);
}
if (s.back() == '.') {
s.chop(1);
}
return s;
}
void GamepadConfigurationDialog::on_lowSensitivity_logValueChanged(double value)
{
m_settings->m_lowSensitivity = value;
ui->lowSensitivityText->setText(QString("%1%").arg(toSimpleFloat(m_settings->m_lowSensitivity, 4)));
}
void GamepadConfigurationDialog::on_highSensitivity_logValueChanged(double value)
{
m_settings->m_highSensitivity = value;
ui->highSensitivityText->setText(QString("%1%").arg(toSimpleFloat(m_settings->m_highSensitivity, 4)));
}
void GamepadConfigurationDialog::on_deadzone0_valueChanged(int value)
{
m_settings->m_deadzone[0] = value;
ui->deadzone0Text->setText(QString("%1%").arg(m_settings->m_deadzone[0]));
}
void GamepadConfigurationDialog::on_deadzone1_valueChanged(int value)
{
m_settings->m_deadzone[1] = value;
ui->deadzone1Text->setText(QString("%1%").arg(m_settings->m_deadzone[1]));
}
void GamepadConfigurationDialog::on_deadzone2_valueChanged(int value)
{
m_settings->m_deadzone[2] = value;
ui->deadzone2Text->setText(QString("%1%").arg(m_settings->m_deadzone[2]));
}
void GamepadConfigurationDialog::on_deadzone3_valueChanged(int value)
{
m_settings->m_deadzone[3] = value;
ui->deadzone3Text->setText(QString("%1%").arg(m_settings->m_deadzone[3]));
}

Wyświetl plik

@ -21,16 +21,18 @@
#include "ui_gamepadconfigurationdialog.h" #include "ui_gamepadconfigurationdialog.h"
class QGamepad; class QGamepad;
struct InputControllerSettings;
class GamepadConfigurationDialog : public QDialog { class GamepadConfigurationDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit GamepadConfigurationDialog(QGamepad *gamepad, QWidget* parent = 0); explicit GamepadConfigurationDialog(QGamepad *gamepad, InputControllerSettings *settings, bool supportsConfiguraiton, QWidget* parent = 0);
~GamepadConfigurationDialog(); ~GamepadConfigurationDialog();
private slots: private slots:
void accept(); void accept();
void on_configReset_clicked();
void on_config0_clicked(); void on_config0_clicked();
void on_config1_clicked(); void on_config1_clicked();
void on_config2_clicked(); void on_config2_clicked();
@ -39,10 +41,17 @@ private slots:
void axisRightYChanged(double value); void axisRightYChanged(double value);
void axisLeftXChanged(double value); void axisLeftXChanged(double value);
void axisLeftYChanged(double value); void axisLeftYChanged(double value);
void on_lowSensitivity_logValueChanged(double value);
void on_highSensitivity_logValueChanged(double value);
void on_deadzone0_valueChanged(int value);
void on_deadzone1_valueChanged(int value);
void on_deadzone2_valueChanged(int value);
void on_deadzone3_valueChanged(int value);
private: private:
Ui::GamepadConfigurationDialog* ui; Ui::GamepadConfigurationDialog* ui;
QGamepad *m_gamepad; QGamepad *m_gamepad;
InputControllerSettings *m_settings;
}; };
#endif // INCLUDE_GAMEPADCONFIGURATIONDIALOG_H #endif // INCLUDE_GAMEPADCONFIGURATIONDIALOG_H

Wyświetl plik

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>380</width> <width>383</width>
<height>309</height> <height>568</height>
</rect> </rect>
</property> </property>
<property name="font"> <property name="font">
@ -21,10 +21,37 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="configurationGroup">
<property name="title">
<string>Configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="1" column="2"> <item row="8" column="1">
<widget class="QLabel" name="value0"> <widget class="QPushButton" name="configReset">
<property name="toolTip">
<string>Reset configuration</string>
</property>
<property name="text">
<string>Reset</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="4" column="0">
<widget class="QLabel" name="config3Label">
<property name="text">
<string>Elevation Offset Axis</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="value2">
<property name="text"> <property name="text">
<string>0</string> <string>0</string>
</property> </property>
@ -37,48 +64,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="2" column="0">
<widget class="QLabel" name="config1Label"> <widget class="QLabel" name="config1Label">
<property name="text"> <property name="text">
@ -86,40 +71,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="0" column="0" colspan="2">
<widget class="QLabel" name="instructions"> <widget class="QLabel" name="instructions">
<property name="minimumSize"> <property name="minimumSize">
@ -136,9 +87,264 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QPushButton" name="config0">
<property name="text">
<string>Configure</string>
</property>
</widget>
</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="8" 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="2" column="1">
<widget class="QPushButton" name="config1">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="value0">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<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="2" column="2">
<widget class="QLabel" name="value1">
<property name="text">
<string>0</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>
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="deadzonesGroup">
<property name="title">
<string>Deadzones</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="deadzone0Label">
<property name="text">
<string>Target Azimuth/X Axis</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="deadzone0">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="deadzone0Text">
<property name="minimumSize">
<size>
<width>35</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0%</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="deadzone1Label">
<property name="text">
<string>Target Elevation/Y Axis</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="deadzone1">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="deadzone1Text">
<property name="text">
<string>0%</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="deadzone2Label">
<property name="text">
<string>Azimuth Offset Axis</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="deadzone2">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="deadzone2Text">
<property name="text">
<string>0%</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="deadzone3Label">
<property name="text">
<string>Elevation Offset Axis</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSlider" name="deadzone3">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="deadzone3Text">
<property name="text">
<string>0%</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="responseGroup">
<property name="title">
<string>Sensitivity</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1">
<widget class="LogLabelSlider" name="lowSensitivity"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="highSensitivityText">
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lowSensitivityLabel">
<property name="minimumSize">
<size>
<width>65</width>
<height>0</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Low</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="lowSensitivityText">
<property name="minimumSize">
<size>
<width>65</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="highSensitivityLabel">
<property name="text">
<string>High</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="LogLabelSlider" name="highSensitivity"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true"/>
</item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
@ -151,6 +357,13 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>LogLabelSlider</class>
<extends>QSlider</extends>
<header>gui/loglabelslider.h</header>
</customwidget>
</customwidgets>
<tabstops> <tabstops>
<tabstop>config0</tabstop> <tabstop>config0</tabstop>
<tabstop>config1</tabstop> <tabstop>config1</tabstop>
@ -166,8 +379,8 @@
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>248</x> <x>257</x>
<y>254</y> <y>519</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>157</x> <x>157</x>
@ -182,8 +395,8 @@
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>316</x> <x>325</x>
<y>260</y> <y>519</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>286</x> <x>286</x>

Wyświetl plik

@ -26,12 +26,25 @@ GamepadInputController::GamepadInputController(int deviceId) :
m_rightX(0.0), m_rightX(0.0),
m_rightY(0.0), m_rightY(0.0),
m_leftX(0.0), m_leftX(0.0),
m_leftY(0.0) m_leftY(0.0),
m_configurationDialog(nullptr)
{ {
connect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged); connect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged);
connect(&m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadInputController::axisRightYChanged); connect(&m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadInputController::axisRightYChanged);
connect(&m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadInputController::axisLeftXChanged); connect(&m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadInputController::axisLeftXChanged);
connect(&m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadInputController::axisLeftYChanged); connect(&m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadInputController::axisLeftYChanged);
connect(&m_gamepad, &QGamepad::buttonAChanged, this, &GamepadInputController::buttonAChanged);
connect(&m_gamepad, &QGamepad::buttonBChanged, this, &GamepadInputController::buttonBChanged);
connect(&m_gamepad, &QGamepad::buttonXChanged, this, &GamepadInputController::buttonXChanged);
connect(&m_gamepad, &QGamepad::buttonYChanged, this, &GamepadInputController::buttonYChanged);
connect(&m_gamepad, &QGamepad::buttonUpChanged, this, &GamepadInputController::buttonUpChanged);
connect(&m_gamepad, &QGamepad::buttonDownChanged, this, &GamepadInputController::buttonDownChanged);
connect(&m_gamepad, &QGamepad::buttonLeftChanged, this, &GamepadInputController::buttonLeftChanged);
connect(&m_gamepad, &QGamepad::buttonRightChanged, this, &GamepadInputController::buttonRightChanged);
connect(&m_gamepad, &QGamepad::buttonR1Changed, this, &GamepadInputController::buttonR1Changed);
connect(&m_gamepad, &QGamepad::buttonL1Changed, this, &GamepadInputController::buttonL1Changed);
connect(&m_gamepad, &QGamepad::buttonR3Changed, this, &GamepadInputController::buttonR3Changed);
connect(&m_gamepad, &QGamepad::buttonL3Changed, this, &GamepadInputController::buttonL3Changed);
} }
double GamepadInputController::getAxisValue(int axis) double GamepadInputController::getAxisValue(int axis)
@ -65,20 +78,27 @@ bool GamepadInputController::supportsConfiguration() const
#endif #endif
} }
void GamepadInputController::configure() void GamepadInputController::configure(InputControllerSettings *settings)
{ {
disconnect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged); if (!m_configurationDialog)
disconnect(&m_gamepad, &QGamepad::axisRightYChanged, this, &GamepadInputController::axisRightYChanged); {
disconnect(&m_gamepad, &QGamepad::axisLeftXChanged, this, &GamepadInputController::axisLeftXChanged); m_configurationDialog = new GamepadConfigurationDialog(&m_gamepad, settings, supportsConfiguration());
disconnect(&m_gamepad, &QGamepad::axisLeftYChanged, this, &GamepadInputController::axisLeftYChanged); connect(m_configurationDialog, &QDialog::finished, this, &GamepadInputController::configurationDialogClosed);
m_configurationDialog->setAttribute(Qt::WA_DeleteOnClose, true);
m_configurationDialog->setModal(false);
m_configurationDialog->show();
}
else
{
m_configurationDialog->raise();
m_configurationDialog->activateWindow();
}
}
GamepadConfigurationDialog dialog(&m_gamepad); void GamepadInputController::configurationDialogClosed()
dialog.exec(); {
m_configurationDialog = false;
connect(&m_gamepad, &QGamepad::axisRightXChanged, this, &GamepadInputController::axisRightXChanged); emit configurationComplete();
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) void GamepadInputController::axisRightXChanged(double value)
@ -101,6 +121,66 @@ void GamepadInputController::axisLeftYChanged(double value)
m_leftY = value; m_leftY = value;
} }
void GamepadInputController::buttonAChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_RIGHT_BOTTOM, !value);
}
void GamepadInputController::buttonBChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_RIGHT_RIGHT, !value);
}
void GamepadInputController::buttonXChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_RIGHT_LEFT, !value);
}
void GamepadInputController::buttonYChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_RIGHT_TOP, !value);
}
void GamepadInputController::buttonUpChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_LEFT_UP, !value);
}
void GamepadInputController::buttonDownChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_LEFT_DOWN, !value);
}
void GamepadInputController::buttonLeftChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_LEFT_LEFT, !value);
}
void GamepadInputController::buttonRightChanged(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_LEFT_RIGHT, !value);
}
void GamepadInputController::buttonL1Changed(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_L1, !value);
}
void GamepadInputController::buttonR1Changed(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_R1, !value);
}
void GamepadInputController::buttonL3Changed(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_L3, !value);
}
void GamepadInputController::buttonR3Changed(bool value)
{
emit buttonChanged(INPUTCONTROLLER_BUTTON_R3, !value);
}
QStringList GamepadInputController::getAllControllers() QStringList GamepadInputController::getAllControllers()
{ {
QStringList names; QStringList names;

Wyświetl plik

@ -22,6 +22,8 @@
#include <QGamepad> #include <QGamepad>
class GamepadConfigurationDialog;
class GamepadInputController : public InputController { class GamepadInputController : public InputController {
public: public:
@ -30,17 +32,30 @@ public:
double getAxisValue(int axis) override; double getAxisValue(int axis) override;
int getNumberOfAxes() const override; int getNumberOfAxes() const override;
bool supportsConfiguration() const override; bool supportsConfiguration() const override;
void configure() override; void configure(InputControllerSettings *settings) override;
static QStringList getAllControllers(); static QStringList getAllControllers();
static GamepadInputController* open(const QString& name); static GamepadInputController* open(const QString& name);
private slots: private slots:
void configurationDialogClosed();
void axisRightXChanged(double value); void axisRightXChanged(double value);
void axisRightYChanged(double value); void axisRightYChanged(double value);
void axisLeftXChanged(double value); void axisLeftXChanged(double value);
void axisLeftYChanged(double value); void axisLeftYChanged(double value);
void buttonAChanged(bool value);
void buttonBChanged(bool value);
void buttonXChanged(bool value);
void buttonYChanged(bool value);
void buttonUpChanged(bool value);
void buttonDownChanged(bool value);
void buttonLeftChanged(bool value);
void buttonRightChanged(bool value);
void buttonL1Changed(bool value);
void buttonR1Changed(bool value);
void buttonL3Changed(bool value);
void buttonR3Changed(bool value);
private: private:
@ -49,6 +64,8 @@ private:
double m_rightY; double m_rightY;
double m_leftX; double m_leftX;
double m_leftY; double m_leftY;
GamepadConfigurationDialog *m_configurationDialog;
}; };
#endif // INCLUDE_FEATURE_GAMEPADINPUTCONTROLLER_H_ #endif // INCLUDE_FEATURE_GAMEPADINPUTCONTROLLER_H_

Wyświetl plik

@ -492,7 +492,7 @@ void GS232Controller::webapiFormatFeatureSettings(
response.getGs232ControllerSettings()->setPrecision(settings.m_precision); response.getGs232ControllerSettings()->setPrecision(settings.m_precision);
response.getGs232ControllerSettings()->setCoordinates((int)settings.m_coordinates); response.getGs232ControllerSettings()->setCoordinates((int)settings.m_coordinates);
response.getGs232ControllerSettings()->setInputController(new QString(settings.m_inputController)); response.getGs232ControllerSettings()->setInputController(new QString(settings.m_inputController));
response.getGs232ControllerSettings()->setInputSensitivity(settings.m_inputSensitivity); response.getGs232ControllerSettings()->setInputSensitivity(settings.m_inputControllerSettings.m_lowSensitivity);
if (response.getGs232ControllerSettings()->getTitle()) { if (response.getGs232ControllerSettings()->getTitle()) {
*response.getGs232ControllerSettings()->getTitle() = settings.m_title; *response.getGs232ControllerSettings()->getTitle() = settings.m_title;
@ -591,7 +591,7 @@ void GS232Controller::webapiUpdateFeatureSettings(
settings.m_inputController = *response.getGs232ControllerSettings()->getInputController(); settings.m_inputController = *response.getGs232ControllerSettings()->getInputController();
} }
if (featureSettingsKeys.contains("inputSensitivity")) { if (featureSettingsKeys.contains("inputSensitivity")) {
settings.m_inputSensitivity = response.getGs232ControllerSettings()->getInputSensitivity(); settings.m_inputControllerSettings.m_lowSensitivity = response.getGs232ControllerSettings()->getInputSensitivity();
} }
if (featureSettingsKeys.contains("title")) { if (featureSettingsKeys.contains("title")) {
settings.m_title = *response.getGs232ControllerSettings()->getTitle(); settings.m_title = *response.getGs232ControllerSettings()->getTitle();
@ -688,7 +688,7 @@ void GS232Controller::webapiReverseSendSettings(const QList<QString>& featureSet
swgGS232ControllerSettings->setInputController(new QString(settings.m_inputController)); swgGS232ControllerSettings->setInputController(new QString(settings.m_inputController));
} }
if (featureSettingsKeys.contains("inputSensitivity") || force) { if (featureSettingsKeys.contains("inputSensitivity") || force) {
swgGS232ControllerSettings->setInputSensitivity(settings.m_inputSensitivity); swgGS232ControllerSettings->setInputSensitivity(settings.m_inputControllerSettings.m_lowSensitivity);
} }
if (featureSettingsKeys.contains("title") || force) { if (featureSettingsKeys.contains("title") || force) {
swgGS232ControllerSettings->setTitle(new QString(settings.m_title)); swgGS232ControllerSettings->setTitle(new QString(settings.m_title));

Wyświetl plik

@ -252,7 +252,8 @@ GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featu
m_settings.setRollupState(&m_rollupState); m_settings.setRollupState(&m_rollupState);
ui->inputConfigure->setVisible(false); //ui->inputConfigure->setVisible(false);
ui->inputConfigure->setEnabled(false);
updateInputControllerList(); updateInputControllerList();
connect(InputControllerManager::instance(), &InputControllerManager::controllersChanged, this, &GS232ControllerGUI::updateInputControllerList); connect(InputControllerManager::instance(), &InputControllerManager::controllersChanged, this, &GS232ControllerGUI::updateInputControllerList);
connect(&m_inputTimer, &QTimer::timeout, this, &GS232ControllerGUI::checkInputController); connect(&m_inputTimer, &QTimer::timeout, this, &GS232ControllerGUI::checkInputController);
@ -293,6 +294,8 @@ void GS232ControllerGUI::updateInputController()
m_inputController = InputControllerManager::open(m_settings.m_inputController); m_inputController = InputControllerManager::open(m_settings.m_inputController);
if (m_inputController) if (m_inputController)
{ {
connect(m_inputController, &InputController::buttonChanged, this, &GS232ControllerGUI::buttonChanged);
connect(m_inputController, &InputController::configurationComplete, this, &GS232ControllerGUI::inputConfigurationComplete);
m_inputTimer.start(20); m_inputTimer.start(20);
enabled = true; enabled = true;
} }
@ -301,12 +304,32 @@ void GS232ControllerGUI::updateInputController()
{ {
m_inputTimer.stop(); m_inputTimer.stop();
} }
ui->inputSensitivityLabel->setEnabled(enabled);
ui->inputSensitivity->setEnabled(enabled);
ui->inputSensitivityText->setEnabled(enabled);
ui->inputConfigure->setEnabled(enabled); ui->inputConfigure->setEnabled(enabled);
ui->inputConfigure->setVisible(enabled && m_inputController->supportsConfiguration()); }
void GS232ControllerGUI::buttonChanged(int button, bool released)
{
if (!released)
{
switch (button)
{
case INPUTCONTROLLER_BUTTON_RIGHT_TOP:
ui->startStop->doToggle(!ui->startStop->isChecked());
break;
case INPUTCONTROLLER_BUTTON_RIGHT_BOTTOM:
ui->track->click();
break;
case INPUTCONTROLLER_BUTTON_RIGHT_RIGHT:
ui->enableTargetControl->click();
break;
case INPUTCONTROLLER_BUTTON_RIGHT_LEFT:
ui->enableOffsetControl->click();
break;
case INPUTCONTROLLER_BUTTON_R1:
ui->highSensitivity->click();
break;
}
}
} }
void GS232ControllerGUI::checkInputController() void GS232ControllerGUI::checkInputController()
@ -319,8 +342,11 @@ void GS232ControllerGUI::checkInputController()
if (!m_settings.m_track) if (!m_settings.m_track)
{ {
m_inputCoord1 += m_settings.m_inputSensitivity * m_inputController->getAxisValue(0); if (m_settings.m_targetControlEnabled)
m_inputCoord2 += m_settings.m_inputSensitivity * -m_inputController->getAxisValue(1); {
m_inputCoord1 += m_extraSensitivity * m_inputController->getAxisCalibratedValue(0, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
m_inputCoord2 += m_extraSensitivity * -m_inputController->getAxisCalibratedValue(1, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
}
if (m_settings.m_coordinates == GS232ControllerSettings::AZ_EL) if (m_settings.m_coordinates == GS232ControllerSettings::AZ_EL)
{ {
@ -340,13 +366,19 @@ void GS232ControllerGUI::checkInputController()
if ((m_inputController->getNumberOfAxes() < 4) && m_settings.m_track) if ((m_inputController->getNumberOfAxes() < 4) && m_settings.m_track)
{ {
m_inputAzOffset += m_settings.m_inputSensitivity * m_inputController->getAxisValue(0); if (m_settings.m_offsetControlEnabled)
m_inputElOffset += m_settings.m_inputSensitivity * -m_inputController->getAxisValue(1); {
m_inputAzOffset += m_extraSensitivity * m_inputController->getAxisCalibratedValue(0, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
m_inputElOffset += m_extraSensitivity * -m_inputController->getAxisCalibratedValue(1, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
}
} }
else if (m_inputController->getNumberOfAxes() >= 4) else if (m_inputController->getNumberOfAxes() >= 4)
{ {
m_inputAzOffset += m_settings.m_inputSensitivity * m_inputController->getAxisValue(2); if (m_settings.m_offsetControlEnabled)
m_inputElOffset += m_settings.m_inputSensitivity * -m_inputController->getAxisValue(3); {
m_inputAzOffset += m_extraSensitivity * m_inputController->getAxisCalibratedValue(2, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
m_inputElOffset += m_extraSensitivity * -m_inputController->getAxisCalibratedValue(3, &m_settings.m_inputControllerSettings, m_settings.m_highSensitivity);
}
} }
m_inputAzOffset = std::max(m_inputAzOffset, -360.0); m_inputAzOffset = std::max(m_inputAzOffset, -360.0);
m_inputAzOffset = std::min(m_inputAzOffset, 360.0); m_inputAzOffset = std::min(m_inputAzOffset, 360.0);
@ -374,25 +406,47 @@ void GS232ControllerGUI::on_inputController_currentIndexChanged(int index)
if (index >= 0) if (index >= 0)
{ {
m_settings.m_inputController = ui->inputController->currentText(); m_settings.m_inputController = ui->inputController->currentText();
m_settingsKeys.append("inputController");
applySettings(); applySettings();
updateInputController(); 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() void GS232ControllerGUI::on_inputConfigure_clicked()
{ {
if (m_inputController) { if (m_inputController) {
m_inputController->configure(); m_inputController->configure(&m_settings.m_inputControllerSettings);
} }
} }
void GS232ControllerGUI::on_highSensitivity_clicked(bool checked)
{
m_settings.m_highSensitivity = checked;
ui->highSensitivity->setText(checked ? "H" : "L");
m_settingsKeys.append("highSensitivity");
applySettings();
}
void GS232ControllerGUI::on_enableTargetControl_clicked(bool checked)
{
m_settings.m_targetControlEnabled = checked;
m_settingsKeys.append("targetControlEnabled");
applySettings();
}
void GS232ControllerGUI::on_enableOffsetControl_clicked(bool checked)
{
m_settings.m_offsetControlEnabled = checked;
m_settingsKeys.append("offsetControlEnabled");
applySettings();
}
void GS232ControllerGUI::inputConfigurationComplete()
{
m_settingsKeys.append("inputControllerSettings");
applySettings();
}
GS232ControllerGUI::~GS232ControllerGUI() GS232ControllerGUI::~GS232ControllerGUI()
{ {
m_dfmStatusDialog.close(); m_dfmStatusDialog.close();
@ -440,8 +494,9 @@ void GS232ControllerGUI::displaySettings()
ui->elevationMax->setValue(m_settings.m_elevationMax); ui->elevationMax->setValue(m_settings.m_elevationMax);
ui->tolerance->setValue(m_settings.m_tolerance); ui->tolerance->setValue(m_settings.m_tolerance);
ui->inputController->setCurrentText(m_settings.m_inputController); ui->inputController->setCurrentText(m_settings.m_inputController);
ui->inputSensitivity->setValue((int) (m_settings.m_inputSensitivity * 1000.0)); ui->highSensitivity->setChecked(m_settings.m_highSensitivity);
ui->inputSensitivityText->setText(QString("%1%").arg(m_settings.m_inputSensitivity * 100.0)); ui->enableTargetControl->setChecked(m_settings.m_targetControlEnabled);
ui->enableOffsetControl->setChecked(m_settings.m_offsetControlEnabled);
ui->dfmTrack->setChecked(m_settings.m_dfmTrackOn); ui->dfmTrack->setChecked(m_settings.m_dfmTrackOn);
ui->dfmLubePumps->setChecked(m_settings.m_dfmLubePumpsOn); ui->dfmLubePumps->setChecked(m_settings.m_dfmLubePumpsOn);
ui->dfmBrakes->setChecked(m_settings.m_dfmBrakesOn); ui->dfmBrakes->setChecked(m_settings.m_dfmBrakesOn);
@ -960,8 +1015,10 @@ void GS232ControllerGUI::makeUIConnections()
QObject::connect(ui->precision, qOverload<int>(&QSpinBox::valueChanged), this, &GS232ControllerGUI::on_precision_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->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->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->inputConfigure, &QToolButton::clicked, this, &GS232ControllerGUI::on_inputConfigure_clicked);
QObject::connect(ui->highSensitivity, &QToolButton::clicked, this, &GS232ControllerGUI::on_highSensitivity_clicked);
QObject::connect(ui->enableTargetControl, &QToolButton::clicked, this, &GS232ControllerGUI::on_enableTargetControl_clicked);
QObject::connect(ui->enableOffsetControl, &QToolButton::clicked, this, &GS232ControllerGUI::on_enableOffsetControl_clicked);
QObject::connect(ui->dfmTrack, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmTrack_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->dfmLubePumps, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmLubePumps_clicked);
QObject::connect(ui->dfmBrakes, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmBrakes_clicked); QObject::connect(ui->dfmBrakes, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmBrakes_clicked);

Wyświetl plik

@ -76,6 +76,7 @@ private:
double m_inputAzOffset; double m_inputAzOffset;
double m_inputElOffset; double m_inputElOffset;
bool m_inputUpdate; bool m_inputUpdate;
static const int m_extraSensitivity = 4.0f; // Otherwise 100% isn't quite fast enough
explicit GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr); explicit GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
virtual ~GS232ControllerGUI(); virtual ~GS232ControllerGUI();
@ -126,10 +127,14 @@ private slots:
void on_dfmShowStatus_clicked(); void on_dfmShowStatus_clicked();
void updateStatus(); void updateStatus();
void on_inputController_currentIndexChanged(int index); void on_inputController_currentIndexChanged(int index);
void on_inputSensitivty_valueChanged(int value);
void on_inputConfigure_clicked(); void on_inputConfigure_clicked();
void on_highSensitivity_clicked(bool checked);
void on_enableTargetControl_clicked(bool checked);
void on_enableOffsetControl_clicked(bool checked);
void updateInputControllerList(); void updateInputControllerList();
void checkInputController(); void checkInputController();
void buttonChanged(int button, bool released);
void inputConfigurationComplete();
}; };
#endif // INCLUDE_FEATURE_GS232CONTROLLERGUI_H_ #endif // INCLUDE_FEATURE_GS232CONTROLLERGUI_H_

Wyświetl plik

@ -382,16 +382,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="5" column="2">
<widget class="QLabel" name="elevationMaxLabel"> <widget class="QLabel" name="elevationMaxLabel">
<property name="text"> <property name="text">
@ -667,64 +657,13 @@
</item> </item>
<item row="8" column="3"> <item row="8" column="3">
<layout class="QHBoxLayout" name="horizontalLayout"> <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> <item>
<widget class="QToolButton" name="inputConfigure"> <widget class="QToolButton" name="inputConfigure">
<property name="toolTip"> <property name="toolTip">
<string>Configure input</string> <string>Configure input</string>
</property> </property>
<property name="text"> <property name="text">
<string>C</string> <string>Config...</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -762,6 +701,70 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1" colspan="2">
<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="highSensitivity">
<property name="toolTip">
<string>Input controller sensitvitiy (High / low)</string>
</property>
<property name="text">
<string>H</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="enableOffsetControl">
<property name="toolTip">
<string>Enable offset control</string>
</property>
<property name="text">
<string>O</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="enableTargetControl">
<property name="toolTip">
<string>Enable target control</string>
</property>
<property name="text">
<string>T</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@ -800,6 +803,17 @@
<tabstop>elevationMin</tabstop> <tabstop>elevationMin</tabstop>
<tabstop>elevationMax</tabstop> <tabstop>elevationMax</tabstop>
<tabstop>tolerance</tabstop> <tabstop>tolerance</tabstop>
<tabstop>precision</tabstop>
<tabstop>coordinates</tabstop>
<tabstop>inputController</tabstop>
<tabstop>highSensitivity</tabstop>
<tabstop>enableTargetControl</tabstop>
<tabstop>inputConfigure</tabstop>
<tabstop>dfmTrack</tabstop>
<tabstop>dfmLubePumps</tabstop>
<tabstop>dfmBrakes</tabstop>
<tabstop>dfmDrives</tabstop>
<tabstop>dfmShowStatus</tabstop>
</tabstops> </tabstops>
<resources> <resources>
<include location="../../../sdrgui/resources/res.qrc"/> <include location="../../../sdrgui/resources/res.qrc"/>

Wyświetl plik

@ -30,7 +30,7 @@
const PluginDescriptor GS232ControllerPlugin::m_pluginDescriptor = { const PluginDescriptor GS232ControllerPlugin::m_pluginDescriptor = {
GS232Controller::m_featureId, GS232Controller::m_featureId,
QStringLiteral("Rotator Controller"), QStringLiteral("Rotator Controller"),
QStringLiteral("7.15.2"), QStringLiteral("7.15.3"),
QStringLiteral("(c) Jon Beniston, M7RCE"), QStringLiteral("(c) Jon Beniston, M7RCE"),
QStringLiteral("https://github.com/f4exb/sdrangel"), QStringLiteral("https://github.com/f4exb/sdrangel"),
true, true,

Wyświetl plik

@ -22,6 +22,7 @@
#include "settings/serializable.h" #include "settings/serializable.h"
#include "gs232controllersettings.h" #include "gs232controllersettings.h"
#include "inputcontrollersettings.h"
const QStringList GS232ControllerSettings::m_pipeTypes = { const QStringList GS232ControllerSettings::m_pipeTypes = {
QStringLiteral("ADSBDemod"), QStringLiteral("ADSBDemod"),
@ -65,7 +66,14 @@ void GS232ControllerSettings::resetToDefaults()
m_precision = 0; m_precision = 0;
m_coordinates = AZ_EL; m_coordinates = AZ_EL;
m_inputController = "None"; m_inputController = "None";
m_inputSensitivity = 0.25; m_targetControlEnabled = true;
m_offsetControlEnabled = true;
m_highSensitivity = true;
m_inputControllerSettings.m_lowSensitivity = 5.0f;
m_inputControllerSettings.m_highSensitivity = 50.0f;
for (int i = 0; i < INPUTCONTROLLER_MAX_AXES; i++) {
m_inputControllerSettings.m_deadzone[i] = 10.0f;
}
m_dfmTrackOn = false; m_dfmTrackOn = false;
m_dfmLubePumpsOn = false; m_dfmLubePumpsOn = false;
m_dfmBrakesOn = false; m_dfmBrakesOn = false;
@ -122,7 +130,15 @@ QByteArray GS232ControllerSettings::serialize() const
s.writeBool(33, m_dfmBrakesOn); s.writeBool(33, m_dfmBrakesOn);
s.writeBool(34, m_dfmDrivesOn); s.writeBool(34, m_dfmDrivesOn);
s.writeString(35, m_inputController); s.writeString(35, m_inputController);
s.writeFloat(36, m_inputSensitivity); s.writeBool(37, m_targetControlEnabled);
s.writeBool(38, m_offsetControlEnabled);
s.writeBool(39, m_highSensitivity);
s.writeFloat(50, m_inputControllerSettings.m_lowSensitivity);
s.writeFloat(51, m_inputControllerSettings.m_highSensitivity);
for (int i = 0; i < INPUTCONTROLLER_MAX_AXES; i++) {
s.writeFloat(60+i, m_inputControllerSettings.m_deadzone[i]);
}
return s.final(); return s.final();
} }
@ -192,7 +208,15 @@ bool GS232ControllerSettings::deserialize(const QByteArray& data)
d.readBool(33, &m_dfmBrakesOn); d.readBool(33, &m_dfmBrakesOn);
d.readBool(34, &m_dfmDrivesOn); d.readBool(34, &m_dfmDrivesOn);
d.readString(35, &m_inputController, "None"); d.readString(35, &m_inputController, "None");
d.readFloat(36, &m_inputSensitivity, 0.25); d.readBool(37, &m_targetControlEnabled, true);
d.readBool(38, &m_offsetControlEnabled, true);
d.readBool(39, &m_highSensitivity, true);
d.readFloat(50, &m_inputControllerSettings.m_lowSensitivity, 5.0f);
d.readFloat(51, &m_inputControllerSettings.m_highSensitivity, 50.0f);
for (int i = 0; i < INPUTCONTROLLER_MAX_AXES; i++) {
d.readFloat(60+i, &m_inputControllerSettings.m_deadzone[i], 10.0f);
}
return true; return true;
} }
@ -280,8 +304,17 @@ void GS232ControllerSettings::applySettings(const QStringList& settingsKeys, con
if (settingsKeys.contains("inputController")) { if (settingsKeys.contains("inputController")) {
m_inputController = settings.m_inputController; m_inputController = settings.m_inputController;
} }
if (settingsKeys.contains("inputSensitivity")) { if (settingsKeys.contains("inputControllerSettings")) {
m_inputSensitivity = settings.m_inputSensitivity; m_inputControllerSettings = settings.m_inputControllerSettings;
}
if (settingsKeys.contains("targetControlEnabled")) {
m_targetControlEnabled = settings.m_targetControlEnabled;
}
if (settingsKeys.contains("offsetControlEnabled")) {
m_offsetControlEnabled = settings.m_offsetControlEnabled;
}
if (settingsKeys.contains("highSensitivity")) {
m_highSensitivity = settings.m_highSensitivity;
} }
if (settingsKeys.contains("dfmTrackOn")) { if (settingsKeys.contains("dfmTrackOn")) {
m_dfmTrackOn = settings.m_dfmTrackOn; m_dfmTrackOn = settings.m_dfmTrackOn;
@ -385,8 +418,21 @@ QString GS232ControllerSettings::getDebugString(const QStringList& settingsKeys,
if (settingsKeys.contains("inputController") || force) { if (settingsKeys.contains("inputController") || force) {
ostr << " m_inputController: " << m_inputController.toStdString(); ostr << " m_inputController: " << m_inputController.toStdString();
} }
if (settingsKeys.contains("inputSensitivity") || force) { if (settingsKeys.contains("inputControllerSettings") || force) {
ostr << " m_inputSensitivity: " << m_inputSensitivity; ostr << " m_inputControllerSettings.m_lowSensitivity: " << m_inputControllerSettings.m_lowSensitivity;
ostr << " m_inputControllerSettings.m_highSensitivity: " << m_inputControllerSettings.m_highSensitivity;
for (int i = 0; i < INPUTCONTROLLER_MAX_AXES; i++) {
ostr << " m_inputControllerSettings.m_deadzone: " << m_inputControllerSettings.m_deadzone[i];
}
}
if (settingsKeys.contains("targetControlEnabled") || force) {
ostr << " m_targetControlEnabled: " << m_targetControlEnabled;
}
if (settingsKeys.contains("offsetControlEnabled") || force) {
ostr << " m_offsetControlEnabled: " << m_offsetControlEnabled;
}
if (settingsKeys.contains("highSensitivity") || force) {
ostr << " m_highSensitivity: " << m_highSensitivity;
} }
if (settingsKeys.contains("title") || force) { if (settingsKeys.contains("title") || force) {
ostr << " m_title: " << m_title.toStdString(); ostr << " m_title: " << m_title.toStdString();

Wyświetl plik

@ -23,6 +23,7 @@
#include <QString> #include <QString>
#include "util/message.h" #include "util/message.h"
#include "inputcontrollersettings.h"
class Serializable; class Serializable;
@ -63,7 +64,10 @@ struct GS232ControllerSettings
int m_precision; int m_precision;
enum Coordinates { AZ_EL, X_Y_85, X_Y_30 } m_coordinates; enum Coordinates { AZ_EL, X_Y_85, X_Y_30 } m_coordinates;
QString m_inputController; QString m_inputController;
float m_inputSensitivity; InputControllerSettings m_inputControllerSettings;
bool m_targetControlEnabled;
bool m_offsetControlEnabled;
bool m_highSensitivity;
bool m_dfmTrackOn; bool m_dfmTrackOn;
bool m_dfmLubePumpsOn; bool m_dfmLubePumpsOn;

Wyświetl plik

@ -22,6 +22,23 @@
#include "inputcontroller.h" #include "inputcontroller.h"
double InputController::getAxisCalibratedValue(int axis, InputControllerSettings *settings, bool highSensitvity)
{
double value = getAxisValue(axis);
double absValue = abs(value);
double l = settings->m_deadzone[axis] / 100.0;
if (absValue < l) {
// Set to 0 if in deadzone
value = 0.0;
} else {
// Rescale to [0,1] if outside of deadzone
absValue = (absValue - l) / (1.0 - l);
// Negate if original value was negative
value = (value < 0.0) ? -absValue : absValue;
}
return value * (highSensitvity ? settings->m_highSensitivity : settings->m_lowSensitivity) / 100.0;
}
InputControllerManager* InputControllerManager::m_instance = nullptr; InputControllerManager* InputControllerManager::m_instance = nullptr;
QStringList InputControllerManager::getAllControllers() QStringList InputControllerManager::getAllControllers()

Wyświetl plik

@ -20,6 +20,23 @@
#include <QObject> #include <QObject>
#include "inputcontrollersettings.h"
#define INPUTCONTROLLER_BUTTON_RIGHT_TOP 0 // Y / triangle
#define INPUTCONTROLLER_BUTTON_RIGHT_BOTTOM 1 // A / X
#define INPUTCONTROLLER_BUTTON_RIGHT_LEFT 2 // X / Square
#define INPUTCONTROLLER_BUTTON_RIGHT_RIGHT 3 // B / Circle
#define INPUTCONTROLLER_BUTTON_LEFT_UP 4 // D-Pad
#define INPUTCONTROLLER_BUTTON_LEFT_DOWN 5
#define INPUTCONTROLLER_BUTTON_LEFT_LEFT 6
#define INPUTCONTROLLER_BUTTON_LEFT_RIGHT 7
#define INPUTCONTROLLER_BUTTON_R1 8 // On top of controller
#define INPUTCONTROLLER_BUTTON_L1 9
#define INPUTCONTROLLER_BUTTON_R3 10 // Sticks pushed
#define INPUTCONTROLLER_BUTTON_L3 11
class InputController : public QObject { class InputController : public QObject {
Q_OBJECT Q_OBJECT
public: public:
@ -28,9 +45,15 @@ public:
// axis 0-3. 0=Az/X, 1=El/Y, 2=Az Offset, 3=El Offset // 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] // value returned should be current axis position in range [-1,1]
virtual double getAxisValue(int axis) = 0; virtual double getAxisValue(int axis) = 0;
// Gets axis value applying deadzone and sensitivity
double getAxisCalibratedValue(int axis, InputControllerSettings *settings, bool highSensitivity);
virtual int getNumberOfAxes() const = 0; virtual int getNumberOfAxes() const = 0;
virtual bool supportsConfiguration() const { return false; } virtual bool supportsConfiguration() const { return false; }
virtual void configure() {}; virtual void configure(InputControllerSettings *settings) {};
signals:
void buttonChanged(int button, bool released);
void configurationComplete();
}; };

Wyświetl plik

@ -0,0 +1,29 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_INPUTCONTROLLERSETTINGS_H_
#define INCLUDE_FEATURE_INPUTCONTROLLERSETTINGS_H_
#define INPUTCONTROLLER_MAX_AXES 4
struct InputControllerSettings {
float m_lowSensitivity;
float m_highSensitivity;
float m_deadzone[INPUTCONTROLLER_MAX_AXES];
};
#endif // INCLUDE_FEATURE_INPUTCONTROLLERSETTINGS_H_

Wyświetl plik

@ -115,14 +115,52 @@ When a gamepad with 2 sticks (4 axes) such as the XBox Wireless Controller is us
while the left stick is for controlling azimuth and elevation offset. 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. If a controller only has 2 axes, target coordinates will be controlled when not tracking (6) and offset will be controlled when tracking.
Buttons on a controller are assigned to the following functions:
| Button | XBox Controller | Function |
|---------|------------------|------------------------------------------|
| 0 | Y | Start/stop plugin |
| 1 | A | Enable/disabling tracking |
| 3 | B | Enable/disable target control |
| 2 | X | Enable/disable offset control |
| 8 | R1 | Switch between low and high sensitivity |
The [Qt Gamepad](https://doc.qt.io/qt-5/qtgamepad-index.html) library is used to implement gamepad support. 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). 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. If using a joystick which only has 2 axes, whether it corresponds to the left or right stick can be configured by pressing the 'Config...' 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. 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> <h3>23: High or Low 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. Specifies High (H) or Low (L) Sensitivity mode. This is how fast coordinates will change for a given control stick movement.
High Sensitivity is used for coarse target/offset adjustment, whereas Low sensitivity is used for fine target/offset adjustment.
The sensitivity in each mode can be set in the Input Configuration Dialog (22).
<h3>24: (T) Enable Target Control</h3>
When checked, the target coordinates can be set with the input controller. When unchecked, the axes controlling the target will be ignored.
<h3>25: (O) Enable Offset Control</h3>
When checked, the offset coordinates can be set with the input controller. When unchecked, the axes controlling the offset will be ignored.
<h3>26: Input Control Configuration</h3>
Pressing the Config... button will display the Input Configuration Dialog:
<h4>1: Configuration</h4>
The Configure buttons allow setting which axis is assigned to target or offset control. To assign an axis, press the corresponding Configure button, then move the controller axis.
<h4>2: Deadzones</h3>
Deadzones can be set individually for each for the 4 axes. A deadzone specifies the amount a controller axis can be moved without a response.
This can be used to prevent very small movements around the center position on a stick from adjusting the target, or eliminate target adjustments
when a stick is centered, but is reporting a non-zero position on the axis.
<h4>3: Sensitivity</h3>
Specifies the sensitivity of the input in Low and High Sensitivity mode (23). The higher the value, the faster coordinates will change for a given control stick movement.
<h2>Protocol Implementations</h2> <h2>Protocol Implementations</h2>

Wyświetl plik

@ -62,6 +62,8 @@ set(sdrgui_SOURCES
gui/indicator.cpp gui/indicator.cpp
gui/levelmeter.cpp gui/levelmeter.cpp
gui/loggingdialog.cpp gui/loggingdialog.cpp
gui/logslider.cpp
gui/loglabelslider.cpp
gui/mypositiondialog.cpp gui/mypositiondialog.cpp
gui/pluginsdialog.cpp gui/pluginsdialog.cpp
gui/presetitem.cpp gui/presetitem.cpp
@ -176,6 +178,8 @@ set(sdrgui_HEADERS
gui/indicator.h gui/indicator.h
gui/levelmeter.h gui/levelmeter.h
gui/loggingdialog.h gui/loggingdialog.h
gui/logslider.h
gui/loglabelslider.h
gui/mypositiondialog.h gui/mypositiondialog.h
gui/physicalunit.h gui/physicalunit.h
gui/pluginsdialog.h gui/pluginsdialog.h

Wyświetl plik

@ -0,0 +1,70 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 "loglabelslider.h"
LogLabelSlider::LogLabelSlider(QWidget *parent) :
QWidget(parent)
{
m_vLayout = new QVBoxLayout(this);
m_hLayout = new QHBoxLayout();
m_slider = new LogSlider();
connect(m_slider, &LogSlider::logValueChanged, this, &LogLabelSlider::handleLogValueChanged);
m_vLayout->addLayout(m_hLayout);
m_vLayout->addWidget(m_slider);
}
void LogLabelSlider::setRange(double min, double max)
{
m_slider->setRange(min, max);
double start = floor(log10(min));
double stop = ceil(log10(max));
double steps = stop - start;
qDeleteAll(m_labels);
m_labels.clear();
double v = pow(10.0, start);
for (int i = 0; i <= steps; i++)
{
QString t = QString("%1").arg(v);
QLabel *label = new QLabel(t);
if (i == 0) {
label->setAlignment(Qt::AlignLeft);
} else if (i == steps) {
label->setAlignment(Qt::AlignRight);
} else {
label->setAlignment(Qt::AlignCenter);
}
m_labels.append(label);
m_hLayout->addWidget(label);
v *= 10.0;
}
}
void LogLabelSlider::handleLogValueChanged(double value)
{
emit logValueChanged(value);
}

Wyświetl plik

@ -0,0 +1,56 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 SDRGUI_GUI_LOGLABELSLIDER_H
#define SDRGUI_GUI_LOGLABELSLIDER_H
#include <QSlider>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "logslider.h"
#include "export.h"
// Logarithmic Slider with labels above
class SDRGUI_API LogLabelSlider : public QWidget {
Q_OBJECT
public:
explicit LogLabelSlider(QWidget *parent = nullptr);
void setRange(double min, double max);
void setValue(double value) { m_slider->setValue(value); }
signals:
void logValueChanged(double value);
private slots:
void handleLogValueChanged(double value);
private:
QList<QLabel *> m_labels;
LogSlider *m_slider;
QVBoxLayout *m_vLayout;
QHBoxLayout *m_hLayout;
};
#endif // SDRGUI_GUI_LOGLABELSLIDER_H

Wyświetl plik

@ -0,0 +1,53 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 <QFontMetrics>
#include <QPainter>
#include <QDebug>
#include "logslider.h"
LogSlider::LogSlider(QWidget *parent) :
QSlider(Qt::Horizontal, parent)
{
setRange(0, 1000);
connect(this, &QSlider::valueChanged, this, &LogSlider::handleValueChanged);
setPageStep(1);
setTickPosition(QSlider::TicksAbove);
setTickInterval(m_stepsPerPower);
}
void LogSlider::setRange(double min, double max)
{
m_start = floor(log10(min));
m_stop = ceil(log10(max));
m_steps = m_stop - m_start;
setMinimum(0);
setMaximum(m_steps * m_stepsPerPower);
}
void LogSlider::handleValueChanged(int value)
{
double v = pow(10.0, value/(double)m_stepsPerPower + m_start);
emit logValueChanged(v);
}
void LogSlider::setValue(double value)
{
int v = (int)((log10(value) - m_start) * 100);
QSlider::setValue(v);
}

Wyświetl plik

@ -0,0 +1,54 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 SDRGUI_GUI_LOGSLIDER_H
#define SDRGUI_GUI_LOGSLIDER_H
#include <QSlider>
#include "export.h"
// Logarithmic Slider (hozizontal only)
class SDRGUI_API LogSlider : public QSlider {
Q_OBJECT
public:
explicit LogSlider(QWidget *parent = nullptr);
void setRange(double min, double max);
void setValue(double value);
signals:
void logValueChanged(double value);
private slots:
void handleValueChanged(int value);
private:
double m_start;
double m_stop;
double m_steps;
static const int m_stepsPerPower = 100;
};
#endif // SDRGUI_GUI_LOGSLIDER_H