JoystickConfigController.h 12.7 KB
Newer Older
1 2 3 4 5 6 7 8 9
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

10
/// @file
11
///     @brief Joystick Config Qml Controller
12 13 14 15 16 17 18 19 20 21 22 23 24 25
///     @author Don Gagne <don@thegagnes.com

#ifndef JoystickConfigController_H
#define JoystickConfigController_H

#include <QTimer>

#include "FactPanelController.h"
#include "QGCLoggingCategory.h"
#include "Joystick.h"

Q_DECLARE_LOGGING_CATEGORY(JoystickConfigControllerLog)

class RadioConfigest;
26
class JoystickManager;
27 28 29 30 31 32 33 34 35

namespace Ui {
    class JoystickConfigController;
}

class JoystickConfigController : public FactPanelController
{
    Q_OBJECT
    
36
    //friend class RadioConfigTest; ///< This allows our unit test to access internal information needed.
37 38 39 40 41
    
public:
    JoystickConfigController(void);
    ~JoystickConfigController();
    
42 43
    Q_PROPERTY(QString statusText               READ statusText                 NOTIFY statusTextChanged)

Gus Grubba's avatar
Gus Grubba committed
44 45 46 47
    Q_PROPERTY(bool rollAxisMapped              READ rollAxisMapped             NOTIFY rollAxisMappedChanged)
    Q_PROPERTY(bool pitchAxisMapped             READ pitchAxisMapped            NOTIFY pitchAxisMappedChanged)
    Q_PROPERTY(bool yawAxisMapped               READ yawAxisMapped              NOTIFY yawAxisMappedChanged)
    Q_PROPERTY(bool throttleAxisMapped          READ throttleAxisMapped         NOTIFY throttleAxisMappedChanged)
Gregory Dymarek's avatar
Gregory Dymarek committed
48

Gus Grubba's avatar
Gus Grubba committed
49 50 51
    Q_PROPERTY(bool hasGimbalPitch              READ hasGimbalPitch             NOTIFY hasGimbalPitchChanged)
    Q_PROPERTY(bool hasGimbalYaw                READ hasGimbalYaw               NOTIFY hasGimbalYawChanged)

Gus Grubba's avatar
Gus Grubba committed
52 53 54 55 56 57 58 59 60 61 62 63
    Q_PROPERTY(bool gimbalPitchAxisMapped       READ gimbalPitchAxisMapped      NOTIFY gimbalPitchAxisMappedChanged)
    Q_PROPERTY(bool gimbalYawAxisMapped         READ gimbalYawAxisMapped        NOTIFY gimbalYawAxisMappedChanged)

    Q_PROPERTY(int  rollAxisReversed            READ rollAxisReversed           NOTIFY rollAxisReversedChanged)
    Q_PROPERTY(int  pitchAxisReversed           READ pitchAxisReversed          NOTIFY pitchAxisReversedChanged)
    Q_PROPERTY(int  yawAxisReversed             READ yawAxisReversed            NOTIFY yawAxisReversedChanged)
    Q_PROPERTY(int  throttleAxisReversed        READ throttleAxisReversed       NOTIFY throttleAxisReversedChanged)

    Q_PROPERTY(int  gimbalPitchAxisReversed     READ gimbalPitchAxisReversed    NOTIFY gimbalPitchAxisReversedChanged)
    Q_PROPERTY(int  gimbalYawAxisReversed       READ gimbalYawAxisReversed      NOTIFY gimbalYawAxisReversedChanged)

    Q_PROPERTY(bool deadbandToggle              READ getDeadbandToggle          WRITE setDeadbandToggle    NOTIFY deadbandToggled)
64

65 66
    Q_PROPERTY(int  transmitterMode             READ transmitterMode            WRITE setTransmitterMode NOTIFY transmitterModeChanged)
    Q_PROPERTY(bool calibrating                 READ calibrating                NOTIFY calibratingChanged)
Gus Grubba's avatar
Gus Grubba committed
67 68
    Q_PROPERTY(bool nextEnabled                 READ nextEnabled                NOTIFY nextEnabledChanged)
    Q_PROPERTY(bool skipEnabled                 READ skipEnabled                NOTIFY skipEnabledChanged)
69 70 71 72

    Q_PROPERTY(QList<qreal> stickPositions      READ stickPositions             NOTIFY stickPositionsChanged)
    Q_PROPERTY(QList<qreal> gimbalPositions     READ gimbalPositions            NOTIFY gimbalPositionsChanged)

Gus Grubba's avatar
Gus Grubba committed
73 74 75 76 77
    Q_INVOKABLE void cancelButtonClicked    ();
    Q_INVOKABLE void skipButtonClicked      ();
    Q_INVOKABLE void nextButtonClicked      ();
    Q_INVOKABLE void start                  ();
    Q_INVOKABLE void setDeadbandValue       (int axis, int value);
Gregory Dymarek's avatar
Gregory Dymarek committed
78

79 80
    QString statusText                      () { return _statusText; }

Gus Grubba's avatar
Gus Grubba committed
81 82 83 84 85 86
    bool rollAxisMapped                     () { return _rgFunctionAxisMapping[Joystick::rollFunction]          != _axisNoAxis; }
    bool pitchAxisMapped                    () { return _rgFunctionAxisMapping[Joystick::pitchFunction]         != _axisNoAxis; }
    bool yawAxisMapped                      () { return _rgFunctionAxisMapping[Joystick::yawFunction]           != _axisNoAxis; }
    bool throttleAxisMapped                 () { return _rgFunctionAxisMapping[Joystick::throttleFunction]      != _axisNoAxis; }
    bool gimbalPitchAxisMapped              () { return _rgFunctionAxisMapping[Joystick::gimbalPitchFunction]   != _axisNoAxis; }
    bool gimbalYawAxisMapped                () { return _rgFunctionAxisMapping[Joystick::gimbalYawFunction]     != _axisNoAxis; }
87

Gus Grubba's avatar
Gus Grubba committed
88 89 90 91 92 93
    bool rollAxisReversed                   ();
    bool pitchAxisReversed                  ();
    bool yawAxisReversed                    ();
    bool throttleAxisReversed               ();
    bool gimbalPitchAxisReversed            ();
    bool gimbalYawAxisReversed              ();
94

Gus Grubba's avatar
Gus Grubba committed
95 96
    bool hasGimbalPitch                     () { return _axisCount > 4; }
    bool hasGimbalYaw                       () { return _axisCount > 5; }
97

Gus Grubba's avatar
Gus Grubba committed
98 99
    bool getDeadbandToggle                  ();
    void setDeadbandToggle                  (bool);
100

Gus Grubba's avatar
Gus Grubba committed
101 102 103 104 105 106
    int  axisCount                          () { return _axisCount; }

    int  transmitterMode                    () { return _transmitterMode; }
    void setTransmitterMode                 (int mode);

    bool calibrating                        () { return _currentStep != -1; }
Gus Grubba's avatar
Gus Grubba committed
107 108
    bool nextEnabled                        ();
    bool skipEnabled                        ();
109 110 111 112 113 114 115 116 117 118 119

    QList<qreal> stickPositions             () { return _currentStickPositions; }
    QList<qreal> gimbalPositions            () { return _currentGimbalPositions; }

    struct stateStickPositions {
        qreal   leftX;
        qreal   leftY;
        qreal   rightX;
        qreal   rightY;
    };

120
signals:
Gus Grubba's avatar
Gus Grubba committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    void axisValueChanged                   (int axis, int value);
    void axisDeadbandChanged                (int axis, int value);
    void rollAxisMappedChanged              (bool mapped);
    void pitchAxisMappedChanged             (bool mapped);
    void yawAxisMappedChanged               (bool mapped);
    void throttleAxisMappedChanged          (bool mapped);
    void gimbalPitchAxisMappedChanged       (bool mapped);
    void gimbalYawAxisMappedChanged         (bool mapped);
    void rollAxisReversedChanged            (bool reversed);
    void pitchAxisReversedChanged           (bool reversed);
    void yawAxisReversedChanged             (bool reversed);
    void throttleAxisReversedChanged        (bool reversed);
    void gimbalPitchAxisReversedChanged     (bool reversed);
    void gimbalYawAxisReversedChanged       (bool reversed);
    void deadbandToggled                    (bool value);
    void transmitterModeChanged             (int mode);
    void calibratingChanged                 ();
Gus Grubba's avatar
Gus Grubba committed
138 139
    void nextEnabledChanged                 ();
    void skipEnabledChanged                 ();
140 141
    void stickPositionsChanged              ();
    void gimbalPositionsChanged             ();
Gus Grubba's avatar
Gus Grubba committed
142 143
    void hasGimbalPitchChanged              ();
    void hasGimbalYawChanged                ();
144 145
    void statusTextChanged                  ();

146
    // @brief Signalled when in unit test mode and a message box should be displayed by the next button
Gus Grubba's avatar
Gus Grubba committed
147
    void nextButtonMessageBoxDisplayed      ();
148 149

private slots:
150
    void _activeJoystickChanged(Joystick* joystick);
151
    void _axisValueChanged(int axis, int value);
Gregory Dymarek's avatar
Gregory Dymarek committed
152
    void _axisDeadbandChanged(int axis, int value);
153 154 155 156 157 158 159 160 161 162 163 164 165
   
private:
    /// @brief The states of the calibration state machine.
    enum calStates {
        calStateAxisWait,
        calStateBegin,
        calStateIdentify,
        calStateMinMax,
        calStateCenterThrottle,
        calStateDetectInversion,
        calStateTrims,
        calStateSave
    };
166

167 168 169 170 171
    typedef void (JoystickConfigController::*inputFn)(Joystick::AxisFunction_t function, int axis, int value);
    typedef void (JoystickConfigController::*buttonFn)(void);
    struct stateMachineEntry {
        Joystick::AxisFunction_t    function;
        const char*                 instructions;
172 173
        stateStickPositions         stickPositions;
        stateStickPositions         gimbalPositions;
174 175 176
        inputFn                     rcInputFn;
        buttonFn                    nextFn;
        buttonFn                    skipFn;
Gus Grubba's avatar
Gus Grubba committed
177
        int                         channelID;
178 179 180 181 182 183 184 185 186
    };
    
    /// @brief A set of information associated with a radio axis.
    struct AxisInfo {
        Joystick::AxisFunction_t    function;   ///< Function mapped to this axis, Joystick::maxFunction for none
        bool                        reversed;   ///< true: axis is reverse, false: not reversed
        int                         axisMin;    ///< Minimum axis value
        int                         axisMax;    ///< Maximum axis value
        int                         axisTrim;   ///< Trim position
187
        int                         deadband;   ///< Deadband
188 189
    };
    
Gus Grubba's avatar
Gus Grubba committed
190
    Joystick* _activeJoystick = nullptr;
191
    
Gus Grubba's avatar
Gus Grubba committed
192 193
    int _transmitterMode    = 2;
    int _currentStep        = -1;  ///< Current step of state machine
194 195 196
    
    const struct stateMachineEntry* _getStateMachineEntry(int step);
    
Gus Grubba's avatar
Gus Grubba committed
197 198
    void _advanceState          ();
    void _setupCurrentState     ();
199
    
Gus Grubba's avatar
Gus Grubba committed
200
    bool _validAxis             (int axis);
201

202 203 204 205 206
    void _inputCenterWaitBegin  (Joystick::AxisFunction_t function, int axis, int value);
    void _inputStickDetect      (Joystick::AxisFunction_t function, int axis, int value);
    void _inputStickMin         (Joystick::AxisFunction_t function, int axis, int value);
    void _inputCenterWait       (Joystick::AxisFunction_t function, int axis, int value);
    
Gus Grubba's avatar
Gus Grubba committed
207
    void _switchDetect          (Joystick::AxisFunction_t function, int axis, int value, bool moveToNextStep);
208
    
Gus Grubba's avatar
Gus Grubba committed
209 210 211
    void _saveFlapsDown         ();
    void _skipFlaps             ();
    void _saveAllTrims          ();
212
    
Gus Grubba's avatar
Gus Grubba committed
213
    bool _stickSettleComplete   (int axis, int value);
214
    
Gus Grubba's avatar
Gus Grubba committed
215 216 217 218
    void _validateCalibration   ();
    void _writeCalibration      ();
    void _resetInternalCalibrationValues();
    void _setInternalCalibrationValuesFromSettings();
219
    
Gus Grubba's avatar
Gus Grubba committed
220 221
    void _startCalibration      ();
    void _stopCalibration       ();
222

Gus Grubba's avatar
Gus Grubba committed
223
    void _calSaveCurrentValues  ();
224
    
225
    void _setStickPositions     ();
226
    
Gus Grubba's avatar
Gus Grubba committed
227
    void _signalAllAttitudeValueChanges();
228 229

    void _setStatusText         (const QString& text);
230
    
231 232 233 234 235 236 237 238 239 240 241 242 243
    stateStickPositions _sticksCentered;
    stateStickPositions _sticksThrottleUp;
    stateStickPositions _sticksThrottleDown;
    stateStickPositions _sticksYawLeft;
    stateStickPositions _sticksYawRight;
    stateStickPositions _sticksRollLeft;
    stateStickPositions _sticksRollRight;
    stateStickPositions _sticksPitchUp;
    stateStickPositions _sticksPitchDown;

    QList<qreal> _currentStickPositions;
    QList<qreal> _currentGimbalPositions;

244 245
    int _rgFunctionAxisMapping[Joystick::maxFunction]; ///< Maps from joystick function to axis index. _axisMax indicates axis not set for this function.

Gus Grubba's avatar
Gus Grubba committed
246 247 248 249 250 251 252 253
    static const int _attitudeControls  = 5;
    
    int                 _axisCount      = 0;        ///< Number of actual joystick axes available
    static const int    _axisNoAxis     = -1;       ///< Signals no axis set
    static const int    _axisMinimum    = 4;        ///< Minimum numner of joystick axes required to run PX4
    struct AxisInfo*    _rgAxisInfo     = nullptr;  ///< Information associated with each axis
    int*                _axisValueSave  = nullptr;  ///< Saved values prior to detecting axis movement
    int*                _axisRawValue   = nullptr;  ///< Current set of raw axis values
254

Gus Grubba's avatar
Gus Grubba committed
255 256 257 258 259 260
    enum calStates _calState = calStateAxisWait;    ///< Current calibration state

    int     _calStateCurrentAxis;                   ///< Current axis being worked on in calStateIdentify and calStateDetectInversion
    bool    _calStateAxisComplete;                  ///< Work associated with current axis is complete
    int     _calStateIdentifyOldMapping;            ///< Previous mapping for axis being currently identified
    int     _calStateReverseOldMapping;             ///< Previous mapping for axis being currently used to detect inversion
261 262 263 264 265 266 267 268 269
    
    static const int _calCenterPoint;
    static const int _calValidMinValue;
    static const int _calValidMaxValue;
    static const int _calDefaultMinValue;
    static const int _calDefaultMaxValue;
    static const int _calRoughCenterDelta;
    static const int _calMoveDelta;
    static const int _calSettleDelta;
270
    static const int _calMinDelta;    
271 272 273 274 275 276
    
    int     _stickDetectAxis;
    int     _stickDetectInitialValue;
    int     _stickDetectValue;
    bool    _stickDetectSettleStarted;
    QTime   _stickDetectSettleElapsed;
Gus Grubba's avatar
Gus Grubba committed
277

Gus Grubba's avatar
Gus Grubba committed
278
    static const int _stickDetectSettleMSecs;
279

Gus Grubba's avatar
Gus Grubba committed
280
    QString             _statusText;
281
    JoystickManager*    _joystickManager;
282 283 284
};

#endif // JoystickConfigController_H