Joystick.h 13.2 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 216 217 218
    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               ();
    void setArmed                   (bool arm);
    void setVtolInFwdFlight         (bool set);
    void setFlightMode              (const QString& flightMode);
219

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

233
private:
Gus Grubba's avatar
Gus Grubba committed
234 235 236
    virtual bool _open      ()          = 0;
    virtual void _close     ()          = 0;
    virtual bool _update    ()          = 0;
237

Gus Grubba's avatar
Gus Grubba committed
238 239 240
    virtual bool _getButton (int i)      = 0;
    virtual int  _getAxis   (int i)      = 0;
    virtual bool _getHat    (int hat,int i) = 0;
241

242
    void _updateTXModeSettingsKey(Vehicle* activeVehicle);
243 244 245
    int _mapFunctionMode(int mode, int function);
    void _remapAxes(int currentMode, int newMode, int (&newMapping)[maxFunction]);

246
    // Override from QThread
Gus Grubba's avatar
Gus Grubba committed
247
    virtual void run();
248

249
protected:
250

Gus Grubba's avatar
Gus Grubba committed
251 252 253 254 255 256 257 258
    enum {
        BUTTON_UP,
        BUTTON_DOWN,
        BUTTON_REPEAT
    };

    uint8_t*_rgButtonValues         = nullptr;

Gus Grubba's avatar
Gus Grubba committed
259 260 261 262 263 264 265 266 267 268
    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
269 270
    float   _axisFrequency          = 25.0f;
    float   _buttonFrequency        = 5.0f;
Gus Grubba's avatar
Gus Grubba committed
271
    Vehicle* _activeVehicle         = nullptr;
Gus Grubba's avatar
Gus Grubba committed
272
    bool    _gimbalEnabled          = false;
Gus Grubba's avatar
Gus Grubba committed
273 274

    bool    _pollingStartedForCalibration = false;
275

276 277 278 279
    QString _name;
    bool    _calibrated;
    int     _axisCount;
    int     _buttonCount;
280 281 282
    int     _hatCount;
    int     _hatButtonCount;
    int     _totalButtonCount;
283

284
    static int          _transmitterMode;
Gus Grubba's avatar
Gus Grubba committed
285
    int                 _rgFunctionAxis[maxFunction] = {};
Gus Grubba's avatar
Gus Grubba committed
286
    QTime               _axisTime;
287

Gus Grubba's avatar
Gus Grubba committed
288 289 290 291
    QmlObjectListModel              _assignableButtonActions;
    QList<AssignedButtonAction*>    _buttonActionArray;
    QStringList                     _availableActionTitles;
    MultiVehicleManager*            _multiVehicleManager = nullptr;
292

293 294 295
private:
    static const char*  _rgFunctionSettingsKey[maxFunction];

296 297
    static const char* _settingsGroup;
    static const char* _calibratedSettingsKey;
Gus Grubba's avatar
Gus Grubba committed
298 299
    static const char* _buttonActionNameKey;
    static const char* _buttonActionRepeatKey;
300
    static const char* _throttleModeSettingsKey;
301
    static const char* _exponentialSettingsKey;
302
    static const char* _accumulatorSettingsKey;
Gregory Dymarek's avatar
Gregory Dymarek committed
303
    static const char* _deadbandSettingsKey;
304
    static const char* _circleCorrectionSettingsKey;
Gus Grubba's avatar
Gus Grubba committed
305 306
    static const char* _axisFrequencySettingsKey;
    static const char* _buttonFrequencySettingsKey;
307
    static const char* _txModeSettingsKey;
308 309 310 311 312
    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
313
    static const char* _gimbalSettingsKey;
314

Gus Grubba's avatar
Gus Grubba committed
315
    static const char* _buttonActionNone;
316 317
    static const char* _buttonActionArm;
    static const char* _buttonActionDisarm;
Gus Grubba's avatar
Gus Grubba committed
318
    static const char* _buttonActionToggleArm;
319 320
    static const char* _buttonActionVTOLFixedWing;
    static const char* _buttonActionVTOLMultiRotor;
Gus Grubba's avatar
Gus Grubba committed
321 322 323 324
    static const char* _buttonActionStepZoomIn;
    static const char* _buttonActionStepZoomOut;
    static const char* _buttonActionContinuousZoomIn;
    static const char* _buttonActionContinuousZoomOut;
325 326 327 328
    static const char* _buttonActionNextStream;
    static const char* _buttonActionPreviousStream;
    static const char* _buttonActionNextCamera;
    static const char* _buttonActionPreviousCamera;
Gus Grubba's avatar
Gus Grubba committed
329 330 331 332
    static const char* _buttonActionTriggerCamera;
    static const char* _buttonActionStartVideoRecord;
    static const char* _buttonActionStopVideoRecord;
    static const char* _buttonActionToggleVideoRecord;
Gus Grubba's avatar
Gus Grubba committed
333 334 335 336 337
    static const char* _buttonActionGimbalDown;
    static const char* _buttonActionGimbalUp;
    static const char* _buttonActionGimbalLeft;
    static const char* _buttonActionGimbalRight;
    static const char* _buttonActionGimbalCenter;
338

339 340
private slots:
    void _activeVehicleChanged(Vehicle* activeVehicle);
341
};
342

343
#endif