Joystick.h 13.4 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 11 12 13 14 15 16 17 18

#ifndef Joystick_H
#define Joystick_H

#include <QObject>
#include <QThread>

#include "QGCLoggingCategory.h"
#include "Vehicle.h"
19
#include "MultiVehicleManager.h"
20 21

Q_DECLARE_LOGGING_CATEGORY(JoystickLog)
22
Q_DECLARE_LOGGING_CATEGORY(JoystickValuesLog)
23

Gus Grubba's avatar
Gus Grubba committed
24
//-- Action assigned to button
Gus Grubba's avatar
Gus Grubba committed
25
class AssignedButtonAction : public QObject {
Gus Grubba's avatar
Gus Grubba committed
26 27
    Q_OBJECT
public:
Gus Grubba's avatar
Gus Grubba committed
28
    AssignedButtonAction(QObject* parent, const QString name);
Gus Grubba's avatar
Gus Grubba committed
29 30
    QString action;
    QTime   buttonTime;
Gus Grubba's avatar
Gus Grubba committed
31
    bool    repeat = false;
Gus Grubba's avatar
Gus Grubba committed
32 33 34
};

//-- Assignable Button Action
Gus Grubba's avatar
Gus Grubba committed
35
class AssignableButtonAction : public QObject {
Gus Grubba's avatar
Gus Grubba committed
36 37
    Q_OBJECT
public:
Gus Grubba's avatar
Gus Grubba committed
38
    AssignableButtonAction(QObject* parent, QString action_, bool canRepeat_ = false);
Gus Grubba's avatar
Gus Grubba committed
39 40
    Q_PROPERTY(QString  action      READ action     CONSTANT)
    Q_PROPERTY(bool     canRepeat   READ canRepeat  CONSTANT)
Gus Grubba's avatar
Gus Grubba committed
41 42
    QString action      () { return _action; }
    bool    canRepeat   () { return _repeat; }
Gus Grubba's avatar
Gus Grubba committed
43 44 45 46 47
private:
    QString _action;
    bool    _repeat = false;
};

48 49 50 51
class Joystick : public QThread
{
    Q_OBJECT
public:
52 53
    Joystick(const QString& name, int axisCount, int buttonCount, int hatCount, MultiVehicleManager* multiVehicleManager);

54
    ~Joystick();
55

56
    typedef struct Calibration_t {
57 58 59
        int     min;
        int     max;
        int     center;
60
        int     deadband;
61
        bool    reversed;
62 63 64 65 66 67
        Calibration_t()
            : min(-32767)
            , max(32767)
            , center(0)
            , deadband(0)
            , reversed(false) {}
68
    } Calibration_t;
69

70 71 72 73 74
    typedef enum {
        rollFunction,
        pitchFunction,
        yawFunction,
        throttleFunction,
Gus Grubba's avatar
Gus Grubba committed
75 76
        gimbalPitchFunction,
        gimbalYawFunction,
77 78
        maxFunction
    } AxisFunction_t;
79

80 81 82 83 84
    typedef enum {
        ThrottleModeCenterZero,
        ThrottleModeDownZero,
        ThrottleModeMax
    } ThrottleMode_t;
85

Gus Grubba's avatar
Gus Grubba committed
86 87 88 89 90
    Q_PROPERTY(QString  name                    READ name                   CONSTANT)
    Q_PROPERTY(bool     calibrated              MEMBER _calibrated          NOTIFY calibratedChanged)
    Q_PROPERTY(int      totalButtonCount        READ totalButtonCount       CONSTANT)
    Q_PROPERTY(int      axisCount               READ axisCount              CONSTANT)
    Q_PROPERTY(bool     requiresCalibration     READ requiresCalibration    CONSTANT)
Gus Grubba's avatar
Gus Grubba committed
91

Gus Grubba's avatar
Gus Grubba committed
92 93
    //-- Actions assigned to buttons
    Q_PROPERTY(QStringList buttonActions        READ buttonActions          NOTIFY buttonActionsChanged)
Gus Grubba's avatar
Gus Grubba committed
94

Gus Grubba's avatar
Gus Grubba committed
95 96 97 98 99 100 101
    //-- Actions that can be assigned to buttons
    Q_PROPERTY(QmlObjectListModel* assignableActions    READ assignableActions          CONSTANT)
    Q_PROPERTY(QStringList assignableActionTitles       READ assignableActionTitles     CONSTANT)
    Q_PROPERTY(QString  disabledActionName              READ disabledActionName         CONSTANT)

    Q_PROPERTY(bool     gimbalEnabled           READ gimbalEnabled          WRITE setGimbalEnabled      NOTIFY gimbalEnabledChanged)
    Q_PROPERTY(int      throttleMode            READ throttleMode           WRITE setThrottleMode       NOTIFY throttleModeChanged)
Gus Grubba's avatar
Gus Grubba committed
102 103
    Q_PROPERTY(float    axisFrequency           READ axisFrequency          WRITE setAxisFrequency      NOTIFY axisFrequencyChanged)
    Q_PROPERTY(float    buttonFrequency         READ buttonFrequency        WRITE setButtonFrequency    NOTIFY buttonFrequencyChanged)
Gus Grubba's avatar
Gus Grubba committed
104 105 106 107 108 109
    Q_PROPERTY(bool     negativeThrust          READ negativeThrust         WRITE setNegativeThrust     NOTIFY negativeThrustChanged)
    Q_PROPERTY(float    exponential             READ exponential            WRITE setExponential        NOTIFY exponentialChanged)
    Q_PROPERTY(bool     accumulator             READ accumulator            WRITE setAccumulator        NOTIFY accumulatorChanged)
    Q_PROPERTY(bool     circleCorrection        READ circleCorrection       WRITE setCircleCorrection   NOTIFY circleCorrectionChanged)

    Q_INVOKABLE void    setButtonRepeat     (int button, bool repeat);
Gus Grubba's avatar
Gus Grubba committed
110
    Q_INVOKABLE bool    getButtonRepeat     (int button);
Gus Grubba's avatar
Gus Grubba committed
111 112
    Q_INVOKABLE void    setButtonAction     (int button, const QString& action);
    Q_INVOKABLE QString getButtonAction     (int button);
113

114 115
    // Property accessors

Gus Grubba's avatar
Gus Grubba committed
116 117 118 119
    QString     name                () { return _name; }
    int         totalButtonCount    () { return _totalButtonCount; }
    int         axisCount           () { return _axisCount; }
    bool        gimbalEnabled       () { return _gimbalEnabled; }
Gus Grubba's avatar
Gus Grubba committed
120 121 122 123 124
    QStringList buttonActions       ();

    QmlObjectListModel* assignableActions   () { return &_assignableButtonActions; }
    QStringList assignableActionTitles      () { return _availableActionTitles; }
    QString     disabledActionName          () { return _buttonActionNone; }
Gus Grubba's avatar
Gus Grubba committed
125 126

    void setGimbalEnabled           (bool set);
127

128
    /// Start the polling thread which will in turn emit joystick signals
129
    void startPolling(Vehicle* vehicle);
130
    void stopPolling(void);
131

132 133
    void setCalibration(int axis, Calibration_t& calibration);
    Calibration_t getCalibration(int axis);
134

135 136
    void setFunctionAxis(AxisFunction_t function, int axis);
    int getFunctionAxis(AxisFunction_t function);
137 138


139
/*
Jacob Walser's avatar
Jacob Walser committed
140
    // Joystick index used by sdl library
Patrick José Pereira's avatar
Patrick José Pereira committed
141
    // Settable because sdl library remaps indices after certain events
Jacob Walser's avatar
Jacob Walser committed
142 143
    virtual int index(void) = 0;
    virtual void setIndex(int index) = 0;
144
*/
145 146
	virtual bool requiresCalibration(void) { return true; }

Gus Grubba's avatar
Gus Grubba committed
147 148
    int   throttleMode      ();
    void  setThrottleMode   (int mode);
149

Gus Grubba's avatar
Gus Grubba committed
150 151
    bool  negativeThrust    ();
    void  setNegativeThrust (bool allowNegative);
152

Gus Grubba's avatar
Gus Grubba committed
153
    float exponential       ();
Gus Grubba's avatar
Gus Grubba committed
154
    void  setExponential    (float expo);
155

Gus Grubba's avatar
Gus Grubba committed
156 157
    bool  accumulator       ();
    void  setAccumulator    (bool accu);
158

Gus Grubba's avatar
Gus Grubba committed
159 160
    bool  deadband          ();
    void  setDeadband       (bool accu);
Gregory Dymarek's avatar
Gregory Dymarek committed
161

Gus Grubba's avatar
Gus Grubba committed
162 163
    bool  circleCorrection  ();
    void  setCircleCorrection(bool circleCorrection);
164

Gus Grubba's avatar
Gus Grubba committed
165 166
    void  setTXMode         (int mode);
    int   getTXMode         () { return _transmitterMode; }
167

Don Gagne's avatar
Don Gagne committed
168
    /// Set the current calibration mode
Gus Grubba's avatar
Gus Grubba committed
169
    void  setCalibrationMode (bool calibrating);
170

Gus Grubba's avatar
Gus Grubba committed
171 172 173 174 175
    float axisFrequency     () { return _axisFrequency; }
    void  setAxisFrequency  (float val);

    float buttonFrequency   () { return _buttonFrequency; }
    void  setButtonFrequency(float val);
176

177 178
signals:
    // The raw signals are only meant for use by calibration
Gus Grubba's avatar
Gus Grubba committed
179 180 181 182 183 184 185 186 187 188
    void rawAxisValueChanged        (int index, int value);
    void rawButtonPressedChanged    (int index, int pressed);
    void calibratedChanged          (bool calibrated);
    void buttonActionsChanged       ();
    void throttleModeChanged        (int mode);
    void negativeThrustChanged      (bool allowNegative);
    void exponentialChanged         (float exponential);
    void accumulatorChanged         (bool accumulator);
    void enabledChanged             (bool enabled);
    void circleCorrectionChanged    (bool circleCorrection);
189

190
    /// Signal containing new joystick information
Gus Grubba's avatar
Gus Grubba committed
191 192 193 194
    ///     @param roll         Range is -1:1, negative meaning roll left, positive meaning roll right
    ///     @param pitch        Range i -1:1, negative meaning pitch down, positive meaning pitch up
    ///     @param yaw          Range is -1:1, negative meaning yaw left, positive meaning yaw right
    ///     @param throttle     Range is 0:1, 0 meaning no throttle, 1 meaning full throttle
195
    ///     @param mode     See Vehicle::JoystickMode_t enum
Gus Grubba's avatar
Gus Grubba committed
196 197 198 199 200 201
    void manualControl              (float roll, float pitch, float yaw, float throttle, quint16 buttons, int joystickMmode);
    void manualControlGimbal        (float gimbalPitch, float gimbalYaw);

    void buttonActionTriggered      (int action);

    void gimbalEnabledChanged       ();
Gus Grubba's avatar
Gus Grubba committed
202 203
    void axisFrequencyChanged       ();
    void buttonFrequencyChanged     ();
Gus Grubba's avatar
Gus Grubba committed
204 205 206 207 208 209 210 211 212 213 214 215
    void startContinuousZoom        (int direction);
    void stopContinuousZoom         ();
    void stepZoom                   (int direction);
    void stepCamera                 (int direction);
    void stepStream                 (int direction);
    void triggerCamera              ();
    void startVideoRecord           ();
    void stopVideoRecord            ();
    void toggleVideoRecord          ();
    void gimbalPitchStep            (int direction);
    void gimbalYawStep              (int direction);
    void centerGimbal               ();
216
    void gimbalControlValue         (double pitch, double yaw);
Gus Grubba's avatar
Gus Grubba committed
217 218 219
    void setArmed                   (bool arm);
    void setVtolInFwdFlight         (bool set);
    void setFlightMode              (const QString& flightMode);
220

221
protected:
Gus Grubba's avatar
Gus Grubba committed
222 223
    void    _setDefaultCalibration  ();
    void    _saveSettings           ();
Gus Grubba's avatar
Gus Grubba committed
224
    void    _saveButtonSettings     ();
Gus Grubba's avatar
Gus Grubba committed
225 226
    void    _loadSettings           ();
    float   _adjustRange            (int value, Calibration_t calibration, bool withDeadbands);
Gus Grubba's avatar
Gus Grubba committed
227 228
    void    _executeButtonAction    (const QString& action);
    int     _findAssignableButtonAction(const QString& action);
Gus Grubba's avatar
Gus Grubba committed
229 230
    bool    _validAxis              (int axis);
    bool    _validButton            (int button);
Gus Grubba's avatar
Gus Grubba committed
231 232
    void    _handleAxis             ();
    void    _handleButtons          ();
233

234 235 236 237 238
    void    _pitchStep              (int direction);
    void    _yawStep                (int direction);
    double  _localYaw       = 0.0;
    double  _localPitch     = 0.0;

239
private:
Gus Grubba's avatar
Gus Grubba committed
240 241 242
    virtual bool _open      ()          = 0;
    virtual void _close     ()          = 0;
    virtual bool _update    ()          = 0;
243

Gus Grubba's avatar
Gus Grubba committed
244 245 246
    virtual bool _getButton (int i)      = 0;
    virtual int  _getAxis   (int i)      = 0;
    virtual bool _getHat    (int hat,int i) = 0;
247

248
    void _updateTXModeSettingsKey(Vehicle* activeVehicle);
249 250 251
    int _mapFunctionMode(int mode, int function);
    void _remapAxes(int currentMode, int newMode, int (&newMapping)[maxFunction]);

252
    // Override from QThread
Gus Grubba's avatar
Gus Grubba committed
253
    virtual void run();
254

255
protected:
256

Gus Grubba's avatar
Gus Grubba committed
257 258 259 260 261 262 263 264
    enum {
        BUTTON_UP,
        BUTTON_DOWN,
        BUTTON_REPEAT
    };

    uint8_t*_rgButtonValues         = nullptr;

Gus Grubba's avatar
Gus Grubba committed
265 266 267 268 269 270 271 272 273 274
    bool    _exitThread             = false;    ///< true: signal thread to exit
    bool    _calibrationMode        = false;
    int*    _rgAxisValues           = nullptr;
    Calibration_t* _rgCalibration   = nullptr;
    ThrottleMode_t _throttleMode    = ThrottleModeDownZero;
    bool    _negativeThrust         = false;
    float   _exponential            = 0;
    bool    _accumulator            = false;
    bool    _deadband               = false;
    bool    _circleCorrection       = true;
Gus Grubba's avatar
Gus Grubba committed
275 276
    float   _axisFrequency          = 25.0f;
    float   _buttonFrequency        = 5.0f;
Gus Grubba's avatar
Gus Grubba committed
277
    Vehicle* _activeVehicle         = nullptr;
Gus Grubba's avatar
Gus Grubba committed
278
    bool    _gimbalEnabled          = false;
Gus Grubba's avatar
Gus Grubba committed
279 280

    bool    _pollingStartedForCalibration = false;
281

282 283 284 285
    QString _name;
    bool    _calibrated;
    int     _axisCount;
    int     _buttonCount;
286 287 288
    int     _hatCount;
    int     _hatButtonCount;
    int     _totalButtonCount;
289

290
    static int          _transmitterMode;
Gus Grubba's avatar
Gus Grubba committed
291
    int                 _rgFunctionAxis[maxFunction] = {};
Gus Grubba's avatar
Gus Grubba committed
292
    QTime               _axisTime;
293

Gus Grubba's avatar
Gus Grubba committed
294 295 296 297
    QmlObjectListModel              _assignableButtonActions;
    QList<AssignedButtonAction*>    _buttonActionArray;
    QStringList                     _availableActionTitles;
    MultiVehicleManager*            _multiVehicleManager = nullptr;
298

299

300 301 302
private:
    static const char*  _rgFunctionSettingsKey[maxFunction];

303 304
    static const char* _settingsGroup;
    static const char* _calibratedSettingsKey;
Gus Grubba's avatar
Gus Grubba committed
305 306
    static const char* _buttonActionNameKey;
    static const char* _buttonActionRepeatKey;
307
    static const char* _throttleModeSettingsKey;
308
    static const char* _exponentialSettingsKey;
309
    static const char* _accumulatorSettingsKey;
Gregory Dymarek's avatar
Gregory Dymarek committed
310
    static const char* _deadbandSettingsKey;
311
    static const char* _circleCorrectionSettingsKey;
Gus Grubba's avatar
Gus Grubba committed
312 313
    static const char* _axisFrequencySettingsKey;
    static const char* _buttonFrequencySettingsKey;
314
    static const char* _txModeSettingsKey;
315 316 317 318 319
    static const char* _fixedWingTXModeSettingsKey;
    static const char* _multiRotorTXModeSettingsKey;
    static const char* _roverTXModeSettingsKey;
    static const char* _vtolTXModeSettingsKey;
    static const char* _submarineTXModeSettingsKey;
Gus Grubba's avatar
Gus Grubba committed
320
    static const char* _gimbalSettingsKey;
321

Gus Grubba's avatar
Gus Grubba committed
322
    static const char* _buttonActionNone;
323 324
    static const char* _buttonActionArm;
    static const char* _buttonActionDisarm;
Gus Grubba's avatar
Gus Grubba committed
325
    static const char* _buttonActionToggleArm;
326 327
    static const char* _buttonActionVTOLFixedWing;
    static const char* _buttonActionVTOLMultiRotor;
Gus Grubba's avatar
Gus Grubba committed
328 329 330 331
    static const char* _buttonActionStepZoomIn;
    static const char* _buttonActionStepZoomOut;
    static const char* _buttonActionContinuousZoomIn;
    static const char* _buttonActionContinuousZoomOut;
332 333 334 335
    static const char* _buttonActionNextStream;
    static const char* _buttonActionPreviousStream;
    static const char* _buttonActionNextCamera;
    static const char* _buttonActionPreviousCamera;
Gus Grubba's avatar
Gus Grubba committed
336 337 338 339
    static const char* _buttonActionTriggerCamera;
    static const char* _buttonActionStartVideoRecord;
    static const char* _buttonActionStopVideoRecord;
    static const char* _buttonActionToggleVideoRecord;
Gus Grubba's avatar
Gus Grubba committed
340 341 342 343 344
    static const char* _buttonActionGimbalDown;
    static const char* _buttonActionGimbalUp;
    static const char* _buttonActionGimbalLeft;
    static const char* _buttonActionGimbalRight;
    static const char* _buttonActionGimbalCenter;
345

346 347
private slots:
    void _activeVehicleChanged(Vehicle* activeVehicle);
348
};
349

350
#endif