kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			Rotator Controller: Add gamepad input controller support.
							rodzic
							
								
									fc923ebbed
								
							
						
					
					
						commit
						a1c1308580
					
				| 
						 | 
				
			
			@ -610,7 +610,9 @@ else()
 | 
			
		|||
                     MultimediaWidgets
 | 
			
		||||
                     Positioning
 | 
			
		||||
                     Charts
 | 
			
		||||
                     SerialPort)
 | 
			
		||||
                     SerialPort
 | 
			
		||||
                   OPTIONAL_COMPONENTS
 | 
			
		||||
                     Gamepad)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# for the server we don't need OpenGL/Qt Quick components
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,17 +38,27 @@ 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)
 | 
			
		||||
        set(gs232controller_HEADERS ${gs232controller_HEADERS} gamepadinputcontroller.h)
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
    set(TARGET_NAME featuregs232controllersrv)
 | 
			
		||||
    set(TARGET_LIB "")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,139 @@
 | 
			
		|||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// 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"
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GamepadInputController::axisRightXChanged(double value)
 | 
			
		||||
{
 | 
			
		||||
    m_rightX = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GamepadInputController::axisRightYChanged(double value)
 | 
			
		||||
{
 | 
			
		||||
    m_rightY = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GamepadInputController::axisLeftXChanged(double value)
 | 
			
		||||
{
 | 
			
		||||
    m_leftX = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GamepadInputController::axisLeftYChanged(double value)
 | 
			
		||||
{
 | 
			
		||||
    m_leftY = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QStringList GamepadInputController::getAllControllers()
 | 
			
		||||
{
 | 
			
		||||
    QStringList names;
 | 
			
		||||
    QGamepadManager *gamepadManager = QGamepadManager::instance();
 | 
			
		||||
 | 
			
		||||
    if (gamepadManager)
 | 
			
		||||
    {
 | 
			
		||||
        const QList<int> gamepads = gamepadManager->connectedGamepads();
 | 
			
		||||
        for (const auto gamepad : gamepads)
 | 
			
		||||
        {
 | 
			
		||||
            QString name;
 | 
			
		||||
            if (gamepadManager->gamepadName(gamepad).isEmpty()) {
 | 
			
		||||
                name = QString("Gamepad %1").arg(gamepad);
 | 
			
		||||
            } else {
 | 
			
		||||
                name = gamepadManager->gamepadName(gamepad);
 | 
			
		||||
            }
 | 
			
		||||
            qDebug() << "GamepadInputController::getAllControllers: Gamepad: " << gamepad << "name:" << gamepadManager->gamepadName(gamepad) << " connected " << gamepadManager->isGamepadConnected(gamepad);
 | 
			
		||||
            names.append(name);
 | 
			
		||||
        }
 | 
			
		||||
        if (gamepads.size() == 0) {
 | 
			
		||||
            qDebug() << "GamepadInputController::getAllControllers: No gamepads";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        qDebug() << "GamepadInputController::getAllControllers: No gamepad manager";
 | 
			
		||||
    }
 | 
			
		||||
    return names;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GamepadInputController* GamepadInputController::open(const QString& name)
 | 
			
		||||
{
 | 
			
		||||
    GamepadInputController *inputController = nullptr;
 | 
			
		||||
    QGamepadManager *gamepadManager = QGamepadManager::instance();
 | 
			
		||||
 | 
			
		||||
    if (gamepadManager)
 | 
			
		||||
    {
 | 
			
		||||
        const QList<int> gamepads = gamepadManager->connectedGamepads();
 | 
			
		||||
        for (const auto gamepad : gamepads)
 | 
			
		||||
        {
 | 
			
		||||
            QString gamepadName;
 | 
			
		||||
            if (gamepadManager->gamepadName(gamepad).isEmpty()) {
 | 
			
		||||
                gamepadName = QString("Gamepad %1").arg(gamepad);
 | 
			
		||||
            } else {
 | 
			
		||||
                gamepadName = gamepadManager->gamepadName(gamepad);
 | 
			
		||||
            }
 | 
			
		||||
            if (name == gamepadName)
 | 
			
		||||
            {
 | 
			
		||||
                inputController = new GamepadInputController(gamepad);
 | 
			
		||||
                if (inputController)
 | 
			
		||||
                {
 | 
			
		||||
                    qDebug() << "GamepadInputController::open: Opened gamepad " << name;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    qDebug() << "GamepadInputController::open: Failed to open gamepad: " << gamepad;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return inputController;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,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/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
    static QStringList getAllControllers();
 | 
			
		||||
    static GamepadInputController* open(const QString& name);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
 | 
			
		||||
    void axisRightXChanged(double value);
 | 
			
		||||
    void axisRightYChanged(double value);
 | 
			
		||||
    void axisLeftXChanged(double value);
 | 
			
		||||
    void axisLeftYChanged(double value);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    QGamepad m_gamepad;
 | 
			
		||||
    double m_rightX;
 | 
			
		||||
    double m_rightY;
 | 
			
		||||
    double m_leftX;
 | 
			
		||||
    double m_leftY;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // INCLUDE_FEATURE_GAMEPADINPUTCONTROLLER_H_
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -491,6 +491,8 @@ void GS232Controller::webapiFormatFeatureSettings(
 | 
			
		|||
    response.getGs232ControllerSettings()->setProtocol(settings.m_protocol);
 | 
			
		||||
    response.getGs232ControllerSettings()->setPrecision(settings.m_precision);
 | 
			
		||||
    response.getGs232ControllerSettings()->setCoordinates((int)settings.m_coordinates);
 | 
			
		||||
    response.getGs232ControllerSettings()->setInputController(new QString(settings.m_inputController));
 | 
			
		||||
    response.getGs232ControllerSettings()->setInputSensitivity(settings.m_inputSensitivity);
 | 
			
		||||
 | 
			
		||||
    if (response.getGs232ControllerSettings()->getTitle()) {
 | 
			
		||||
        *response.getGs232ControllerSettings()->getTitle() = settings.m_title;
 | 
			
		||||
| 
						 | 
				
			
			@ -585,6 +587,12 @@ void GS232Controller::webapiUpdateFeatureSettings(
 | 
			
		|||
    if (featureSettingsKeys.contains("coordinates")) {
 | 
			
		||||
        settings.m_coordinates = (GS232ControllerSettings::Coordinates)response.getGs232ControllerSettings()->getCoordinates();
 | 
			
		||||
    }
 | 
			
		||||
    if (featureSettingsKeys.contains("inputController")) {
 | 
			
		||||
        settings.m_inputController = *response.getGs232ControllerSettings()->getInputController();
 | 
			
		||||
    }
 | 
			
		||||
    if (featureSettingsKeys.contains("inputSensitivity")) {
 | 
			
		||||
        settings.m_inputSensitivity = response.getGs232ControllerSettings()->getInputSensitivity();
 | 
			
		||||
    }
 | 
			
		||||
    if (featureSettingsKeys.contains("title")) {
 | 
			
		||||
        settings.m_title = *response.getGs232ControllerSettings()->getTitle();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -676,6 +684,12 @@ void GS232Controller::webapiReverseSendSettings(const QList<QString>& featureSet
 | 
			
		|||
    if (featureSettingsKeys.contains("coordinates") || force) {
 | 
			
		||||
        swgGS232ControllerSettings->setCoordinates(settings.m_coordinates);
 | 
			
		||||
    }
 | 
			
		||||
    if (featureSettingsKeys.contains("inputController") || force) {
 | 
			
		||||
        swgGS232ControllerSettings->setInputController(new QString(settings.m_inputController));
 | 
			
		||||
    }
 | 
			
		||||
    if (featureSettingsKeys.contains("inputSensitivity") || force) {
 | 
			
		||||
        swgGS232ControllerSettings->setInputSensitivity(settings.m_inputSensitivity);
 | 
			
		||||
    }
 | 
			
		||||
    if (featureSettingsKeys.contains("title") || force) {
 | 
			
		||||
        swgGS232ControllerSettings->setTitle(new QString(settings.m_title));
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -216,7 +216,13 @@ GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featu
 | 
			
		|||
    m_doApplySettings(true),
 | 
			
		||||
    m_lastFeatureState(0),
 | 
			
		||||
    m_lastOnTarget(false),
 | 
			
		||||
    m_dfmStatusDialog()
 | 
			
		||||
    m_dfmStatusDialog(),
 | 
			
		||||
    m_inputController(nullptr),
 | 
			
		||||
    m_inputCoord1(0.0),
 | 
			
		||||
    m_inputCoord2(0.0),
 | 
			
		||||
    m_inputAzOffset(0.0),
 | 
			
		||||
    m_inputElOffset(0.0),
 | 
			
		||||
    m_inputUpdate(false)
 | 
			
		||||
{
 | 
			
		||||
    m_feature = feature;
 | 
			
		||||
    setAttribute(Qt::WA_DeleteOnClose, true);
 | 
			
		||||
| 
						 | 
				
			
			@ -246,6 +252,10 @@ GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featu
 | 
			
		|||
 | 
			
		||||
    m_settings.setRollupState(&m_rollupState);
 | 
			
		||||
 | 
			
		||||
    updateInputControllerList();
 | 
			
		||||
    connect(InputControllerManager::instance(), &InputControllerManager::controllersChanged, this, &GS232ControllerGUI::updateInputControllerList);
 | 
			
		||||
    connect(&m_inputTimer, &QTimer::timeout, this, &GS232ControllerGUI::checkInputController);
 | 
			
		||||
 | 
			
		||||
    displaySettings();
 | 
			
		||||
    applySettings(true);
 | 
			
		||||
    makeUIConnections();
 | 
			
		||||
| 
						 | 
				
			
			@ -256,6 +266,123 @@ 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GS232ControllerGUI::~GS232ControllerGUI()
 | 
			
		||||
{
 | 
			
		||||
    m_dfmStatusDialog.close();
 | 
			
		||||
| 
						 | 
				
			
			@ -302,6 +429,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 +673,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 +701,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 +947,8 @@ 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->dfmTrack, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmTrack_clicked);
 | 
			
		||||
    QObject::connect(ui->dfmLubePumps, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmLubePumps_clicked);
 | 
			
		||||
    QObject::connect(ui->dfmBrakes, &QToolButton::toggled, this, &GS232ControllerGUI::on_dfmBrakes_clicked);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@
 | 
			
		|||
 | 
			
		||||
#include "gs232controllersettings.h"
 | 
			
		||||
#include "dfmstatusdialog.h"
 | 
			
		||||
#include "inputcontroller.h"
 | 
			
		||||
 | 
			
		||||
class PluginAPI;
 | 
			
		||||
class FeatureUISet;
 | 
			
		||||
| 
						 | 
				
			
			@ -68,6 +69,14 @@ private:
 | 
			
		|||
 | 
			
		||||
    DFMStatusDialog m_dfmStatusDialog;
 | 
			
		||||
 | 
			
		||||
    InputController *m_inputController;
 | 
			
		||||
    QTimer m_inputTimer;
 | 
			
		||||
    double m_inputCoord1;
 | 
			
		||||
    double m_inputCoord2;
 | 
			
		||||
    double m_inputAzOffset;
 | 
			
		||||
    double m_inputElOffset;
 | 
			
		||||
    bool m_inputUpdate;
 | 
			
		||||
 | 
			
		||||
    explicit GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
 | 
			
		||||
    virtual ~GS232ControllerGUI();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +93,7 @@ private:
 | 
			
		|||
    void makeUIConnections();
 | 
			
		||||
    void azElToDisplay(float az, float el, float& coord1, float& coord2) const;
 | 
			
		||||
    void displayToAzEl(float coord1, float coord2);
 | 
			
		||||
    void updateInputController();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void onMenuDialogCalled(const QPoint &p);
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +125,10 @@ 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 updateInputControllerList();
 | 
			
		||||
    void checkInputController();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // INCLUDE_FEATURE_GS232CONTROLLERGUI_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -306,7 +306,7 @@
 | 
			
		|||
     <x>10</x>
 | 
			
		||||
     <y>140</y>
 | 
			
		||||
     <width>341</width>
 | 
			
		||||
     <height>191</height>
 | 
			
		||||
     <height>201</height>
 | 
			
		||||
    </rect>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="windowTitle">
 | 
			
		||||
| 
						 | 
				
			
			@ -330,6 +330,84 @@
 | 
			
		|||
    </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="8" column="1">
 | 
			
		||||
       <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 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 +415,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 +481,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 +491,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 +558,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 +623,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 +630,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 +696,52 @@
 | 
			
		|||
        </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>
 | 
			
		||||
     </layout>
 | 
			
		||||
    </item>
 | 
			
		||||
   </layout>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,6 +64,8 @@ void GS232ControllerSettings::resetToDefaults()
 | 
			
		|||
    m_connection = SERIAL;
 | 
			
		||||
    m_precision = 0;
 | 
			
		||||
    m_coordinates = AZ_EL;
 | 
			
		||||
    m_inputController = "None";
 | 
			
		||||
    m_inputSensitivity = 0.25;
 | 
			
		||||
    m_dfmTrackOn = false;
 | 
			
		||||
    m_dfmLubePumpsOn = false;
 | 
			
		||||
    m_dfmBrakesOn = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -119,6 +121,8 @@ QByteArray GS232ControllerSettings::serialize() const
 | 
			
		|||
    s.writeBool(32, m_dfmLubePumpsOn);
 | 
			
		||||
    s.writeBool(33, m_dfmBrakesOn);
 | 
			
		||||
    s.writeBool(34, m_dfmDrivesOn);
 | 
			
		||||
    s.writeString(35, m_inputController);
 | 
			
		||||
    s.writeFloat(36, m_inputSensitivity);
 | 
			
		||||
 | 
			
		||||
    return s.final();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -187,6 +191,8 @@ bool GS232ControllerSettings::deserialize(const QByteArray& data)
 | 
			
		|||
        d.readBool(32, &m_dfmLubePumpsOn);
 | 
			
		||||
        d.readBool(33, &m_dfmBrakesOn);
 | 
			
		||||
        d.readBool(34, &m_dfmDrivesOn);
 | 
			
		||||
        d.readString(35, &m_inputController, "None");
 | 
			
		||||
        d.readFloat(36, &m_inputSensitivity, 0.25);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -271,6 +277,12 @@ void GS232ControllerSettings::applySettings(const QStringList& settingsKeys, con
 | 
			
		|||
    if (settingsKeys.contains("coordinates")) {
 | 
			
		||||
        m_coordinates = settings.m_coordinates;
 | 
			
		||||
    }
 | 
			
		||||
    if (settingsKeys.contains("inputController")) {
 | 
			
		||||
        m_inputController = settings.m_inputController;
 | 
			
		||||
    }
 | 
			
		||||
    if (settingsKeys.contains("inputSensitivity")) {
 | 
			
		||||
        m_inputSensitivity = settings.m_inputSensitivity;
 | 
			
		||||
    }
 | 
			
		||||
    if (settingsKeys.contains("dfmTrackOn")) {
 | 
			
		||||
        m_dfmTrackOn = settings.m_dfmTrackOn;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -370,6 +382,12 @@ QString GS232ControllerSettings::getDebugString(const QStringList& settingsKeys,
 | 
			
		|||
    if (settingsKeys.contains("coordinates") || force) {
 | 
			
		||||
        ostr << " m_coordinates: " << m_precision;
 | 
			
		||||
    }
 | 
			
		||||
    if (settingsKeys.contains("inputController") || force) {
 | 
			
		||||
        ostr << " m_inputController: " << m_inputController.toStdString();
 | 
			
		||||
    }
 | 
			
		||||
    if (settingsKeys.contains("inputSensitivity") || force) {
 | 
			
		||||
        ostr << " m_inputSensitivity: " << m_inputSensitivity;
 | 
			
		||||
    }
 | 
			
		||||
    if (settingsKeys.contains("title") || force) {
 | 
			
		||||
        ostr << " m_title: " << m_title.toStdString();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -397,4 +415,3 @@ QString GS232ControllerSettings::getDebugString(const QStringList& settingsKeys,
 | 
			
		|||
 | 
			
		||||
    return QString(ostr.str().c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,6 +62,8 @@ struct GS232ControllerSettings
 | 
			
		|||
    enum Connection { SERIAL, TCP } m_connection;
 | 
			
		||||
    int m_precision;
 | 
			
		||||
    enum Coordinates { AZ_EL, X_Y_85, X_Y_30 } m_coordinates;
 | 
			
		||||
    QString m_inputController;
 | 
			
		||||
    float m_inputSensitivity;
 | 
			
		||||
 | 
			
		||||
    bool m_dfmTrackOn;
 | 
			
		||||
    bool m_dfmLubePumpsOn;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2023 Jon Beniston, M7RCE                                        //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
// (at your option) any later version.                                           //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifdef QT_GAMEPAD_FOUND
 | 
			
		||||
#include <QGamepadManager>
 | 
			
		||||
#include "gamepadinputcontroller.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "inputcontroller.h"
 | 
			
		||||
 | 
			
		||||
InputControllerManager* InputControllerManager::m_instance = nullptr;
 | 
			
		||||
 | 
			
		||||
QStringList InputControllerManager::getAllControllers()
 | 
			
		||||
{
 | 
			
		||||
#ifdef QT_GAMEPAD_FOUND
 | 
			
		||||
    return GamepadInputController::getAllControllers();
 | 
			
		||||
#else
 | 
			
		||||
    return {};
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
InputController* InputControllerManager::open(const QString& name)
 | 
			
		||||
{
 | 
			
		||||
#ifdef QT_GAMEPAD_FOUND
 | 
			
		||||
    return GamepadInputController::open(name);
 | 
			
		||||
#else
 | 
			
		||||
    return nullptr;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
InputControllerManager* InputControllerManager::instance()
 | 
			
		||||
{
 | 
			
		||||
    if (!m_instance) {
 | 
			
		||||
        m_instance = new InputControllerManager();
 | 
			
		||||
    }
 | 
			
		||||
    return m_instance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
InputControllerManager::InputControllerManager()
 | 
			
		||||
{
 | 
			
		||||
#ifdef QT_GAMEPAD_FOUND
 | 
			
		||||
    connect(QGamepadManager::instance(), &QGamepadManager::connectedGamepadsChanged, this, &InputControllerManager::connectedGamepadsChanged);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void InputControllerManager::connectedGamepadsChanged()
 | 
			
		||||
{
 | 
			
		||||
    emit controllersChanged();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// 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;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class InputControllerManager : public QObject {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static QStringList getAllControllers();
 | 
			
		||||
    static InputController* open(const QString& name);
 | 
			
		||||
    static InputControllerManager* instance();
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
 | 
			
		||||
    void controllersChanged();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void connectedGamepadsChanged();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    InputControllerManager();
 | 
			
		||||
 | 
			
		||||
    static InputControllerManager *m_instance;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // INCLUDE_FEATURE_INPUTCONTROLLER_H_
 | 
			
		||||
| 
						 | 
				
			
			@ -2,10 +2,10 @@
 | 
			
		|||
 | 
			
		||||
<h2>Introduction</h2>
 | 
			
		||||
 | 
			
		||||
The Rotator Controller feature plugin allows SDRangel to send commands to GS-232 and SPID rotators as well as hamlib's rotctld, via a serial or TCP connection. 
 | 
			
		||||
The Rotator Controller feature plugin allows SDRangel to send commands to GS-232 and SPID rotators as well as hamlib's rotctld, via a serial or TCP connection.
 | 
			
		||||
This allows SDRangel to point antennas mounted on a rotator to a specified azimuth and elevation.
 | 
			
		||||
 | 
			
		||||
Azimuth and elevation can be set manually by a user in the GUI, via the REST API, or via another plugin, such as the Map Feature, the ADS-B Demodulator, or the Star Tracker.
 | 
			
		||||
Azimuth and elevation can be set manually by a user in the GUI, via the REST API, via another plugin, such as the Map Feature, the ADS-B Demodulator, or the Star Tracker, or by controller/gamepads (such as an XBox Controller).
 | 
			
		||||
 | 
			
		||||
<h2>Interface</h2>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,20 @@ 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 (such as an XBox Wireless Controller) that can be used to specify target coordinates or azimuth and elevation offset.
 | 
			
		||||
 | 
			
		||||
When a controller 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.
 | 
			
		||||
 | 
			
		||||
<h3>23: Sensitivity</h3>
 | 
			
		||||
 | 
			
		||||
Specifies the sensitivity on the input controls (22). The higher the value, the faster coordinates will change for a given control stick movement.
 | 
			
		||||
 | 
			
		||||
<h2>Protocol Implementations</h2>
 | 
			
		||||
 | 
			
		||||
<h3>GS-232 Protocol Implementation Notes</h3>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,6 +58,13 @@ GS232ControllerSettings:
 | 
			
		|||
    coordinates:
 | 
			
		||||
      description: (0 Az/El, 1 X/Y 85, 2 X/Y 30)
 | 
			
		||||
      type: integer
 | 
			
		||||
    inputController:
 | 
			
		||||
      description: Name of input controller
 | 
			
		||||
      type: string
 | 
			
		||||
    inputSensitivity:
 | 
			
		||||
      description: Input controller sensitivity
 | 
			
		||||
      type: number
 | 
			
		||||
      format: float      
 | 
			
		||||
    title:
 | 
			
		||||
      type: string
 | 
			
		||||
    rgbColor:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,6 +64,10 @@ SWGGS232ControllerSettings::SWGGS232ControllerSettings() {
 | 
			
		|||
    m_precision_isSet = false;
 | 
			
		||||
    coordinates = 0;
 | 
			
		||||
    m_coordinates_isSet = false;
 | 
			
		||||
    input_controller = nullptr;
 | 
			
		||||
    m_input_controller_isSet = false;
 | 
			
		||||
    input_sensitivity = 0.0f;
 | 
			
		||||
    m_input_sensitivity_isSet = false;
 | 
			
		||||
    title = nullptr;
 | 
			
		||||
    m_title_isSet = false;
 | 
			
		||||
    rgb_color = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -124,6 +128,10 @@ SWGGS232ControllerSettings::init() {
 | 
			
		|||
    m_precision_isSet = false;
 | 
			
		||||
    coordinates = 0;
 | 
			
		||||
    m_coordinates_isSet = false;
 | 
			
		||||
    input_controller = new QString("");
 | 
			
		||||
    m_input_controller_isSet = false;
 | 
			
		||||
    input_sensitivity = 0.0f;
 | 
			
		||||
    m_input_sensitivity_isSet = false;
 | 
			
		||||
    title = new QString("");
 | 
			
		||||
    m_title_isSet = false;
 | 
			
		||||
    rgb_color = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -168,6 +176,10 @@ SWGGS232ControllerSettings::cleanup() {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if(input_controller != nullptr) { 
 | 
			
		||||
        delete input_controller;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(title != nullptr) { 
 | 
			
		||||
        delete title;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -231,6 +243,10 @@ SWGGS232ControllerSettings::fromJsonObject(QJsonObject &pJson) {
 | 
			
		|||
    
 | 
			
		||||
    ::SWGSDRangel::setValue(&coordinates, pJson["coordinates"], "qint32", "");
 | 
			
		||||
    
 | 
			
		||||
    ::SWGSDRangel::setValue(&input_controller, pJson["inputController"], "QString", "QString");
 | 
			
		||||
    
 | 
			
		||||
    ::SWGSDRangel::setValue(&input_sensitivity, pJson["inputSensitivity"], "float", "");
 | 
			
		||||
    
 | 
			
		||||
    ::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
 | 
			
		||||
    
 | 
			
		||||
    ::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
 | 
			
		||||
| 
						 | 
				
			
			@ -317,6 +333,12 @@ SWGGS232ControllerSettings::asJsonObject() {
 | 
			
		|||
    if(m_coordinates_isSet){
 | 
			
		||||
        obj->insert("coordinates", QJsonValue(coordinates));
 | 
			
		||||
    }
 | 
			
		||||
    if(input_controller != nullptr && *input_controller != QString("")){
 | 
			
		||||
        toJsonValue(QString("inputController"), input_controller, obj, QString("QString"));
 | 
			
		||||
    }
 | 
			
		||||
    if(m_input_sensitivity_isSet){
 | 
			
		||||
        obj->insert("inputSensitivity", QJsonValue(input_sensitivity));
 | 
			
		||||
    }
 | 
			
		||||
    if(title != nullptr && *title != QString("")){
 | 
			
		||||
        toJsonValue(QString("title"), title, obj, QString("QString"));
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -525,6 +547,26 @@ SWGGS232ControllerSettings::setCoordinates(qint32 coordinates) {
 | 
			
		|||
    this->m_coordinates_isSet = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString*
 | 
			
		||||
SWGGS232ControllerSettings::getInputController() {
 | 
			
		||||
    return input_controller;
 | 
			
		||||
}
 | 
			
		||||
void
 | 
			
		||||
SWGGS232ControllerSettings::setInputController(QString* input_controller) {
 | 
			
		||||
    this->input_controller = input_controller;
 | 
			
		||||
    this->m_input_controller_isSet = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float
 | 
			
		||||
SWGGS232ControllerSettings::getInputSensitivity() {
 | 
			
		||||
    return input_sensitivity;
 | 
			
		||||
}
 | 
			
		||||
void
 | 
			
		||||
SWGGS232ControllerSettings::setInputSensitivity(float input_sensitivity) {
 | 
			
		||||
    this->input_sensitivity = input_sensitivity;
 | 
			
		||||
    this->m_input_sensitivity_isSet = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString*
 | 
			
		||||
SWGGS232ControllerSettings::getTitle() {
 | 
			
		||||
    return title;
 | 
			
		||||
| 
						 | 
				
			
			@ -664,6 +706,12 @@ SWGGS232ControllerSettings::isSet(){
 | 
			
		|||
        if(m_coordinates_isSet){
 | 
			
		||||
            isObjectUpdated = true; break;
 | 
			
		||||
        }
 | 
			
		||||
        if(input_controller && *input_controller != QString("")){
 | 
			
		||||
            isObjectUpdated = true; break;
 | 
			
		||||
        }
 | 
			
		||||
        if(m_input_sensitivity_isSet){
 | 
			
		||||
            isObjectUpdated = true; break;
 | 
			
		||||
        }
 | 
			
		||||
        if(title && *title != QString("")){
 | 
			
		||||
            isObjectUpdated = true; break;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,6 +97,12 @@ public:
 | 
			
		|||
    qint32 getCoordinates();
 | 
			
		||||
    void setCoordinates(qint32 coordinates);
 | 
			
		||||
 | 
			
		||||
    QString* getInputController();
 | 
			
		||||
    void setInputController(QString* input_controller);
 | 
			
		||||
 | 
			
		||||
    float getInputSensitivity();
 | 
			
		||||
    void setInputSensitivity(float input_sensitivity);
 | 
			
		||||
 | 
			
		||||
    QString* getTitle();
 | 
			
		||||
    void setTitle(QString* title);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -179,6 +185,12 @@ private:
 | 
			
		|||
    qint32 coordinates;
 | 
			
		||||
    bool m_coordinates_isSet;
 | 
			
		||||
 | 
			
		||||
    QString* input_controller;
 | 
			
		||||
    bool m_input_controller_isSet;
 | 
			
		||||
 | 
			
		||||
    float input_sensitivity;
 | 
			
		||||
    bool m_input_sensitivity_isSet;
 | 
			
		||||
 | 
			
		||||
    QString* title;
 | 
			
		||||
    bool m_title_isSet;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue