Joystick.h 5.31 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
/*=====================================================================
 
 QGroundControl Open Source Ground Control Station
 
 (c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 
 This file is part of the QGROUNDCONTROL project
 
 QGROUNDCONTROL 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, either version 3 of the License, or
 (at your option) any later version.
 
 QGROUNDCONTROL 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 for more details.
 
 You should have received a copy of the GNU General Public License
 along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
 
 ======================================================================*/

#ifndef Joystick_H
#define Joystick_H

#include <QObject>
#include <QThread>

#include "QGCLoggingCategory.h"
#include "Vehicle.h"

Q_DECLARE_LOGGING_CATEGORY(JoystickLog)

class Joystick : public QThread
{
    Q_OBJECT
    
public:
    Joystick(const QString& name, int axisCount, int buttonCount, int sdlIndex);
    ~Joystick();
    
    typedef struct {
        int     min;
        int     max;
        int     center;
        bool    reversed;
    } Calibration_t;
    
    typedef enum {
        rollFunction,
        pitchFunction,
        yawFunction,
        throttleFunction,
        maxFunction
    } AxisFunction_t;
    
    typedef enum {
        ThrottleModeCenterZero,
        ThrottleModeDownZero,
        ThrottleModeMax
    } ThrottleMode_t;
    
    Q_PROPERTY(QString name READ name CONSTANT)
    
    Q_PROPERTY(bool calibrated MEMBER _calibrated NOTIFY calibratedChanged)
    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
    
    Q_PROPERTY(int buttonCount MEMBER _buttonCount CONSTANT)
    Q_PROPERTY(int axisCount MEMBER _axisCount CONSTANT)
    
    Q_PROPERTY(QStringList actions READ actions CONSTANT)
    
    Q_PROPERTY(QVariantList buttonActions READ buttonActions NOTIFY buttonActionsChanged)
    Q_INVOKABLE void setButtonAction(int button, int action);
    Q_INVOKABLE int getButtonAction(int button);
    
    Q_PROPERTY(int throttleMode READ throttleMode WRITE setThrottleMode NOTIFY throttleModeChanged)
    
    /// Start the polling thread which will in turn emit joystick signals
    void startPolling(void);
    void stopPolling(void);
    
    void setCalibration(int axis, Calibration_t& calibration);
    Calibration_t getCalibration(int axis);
    
    void setFunctionAxis(AxisFunction_t function, int axis);
    int getFunctionAxis(AxisFunction_t function);
    
    QStringList actions(void);
    QVariantList buttonActions(void);
    
    QString name(void) { return _name; }
    
    int throttleMode(void);
    void setThrottleMode(int mode);
    
    bool enabled(void);
    void setEnabled(bool enabled);
    
    bool calibrating(void) { return _calibrating; }
    void setCalibrating(bool calibrating) { _calibrating = calibrating; }
    
signals:
    void calibratedChanged(bool calibrated);
    
    // The raw signals are only meant for use by calibration
    void rawAxisValueChanged(int index, int value);
    void rawButtonPressedChanged(int index, int pressed);
    
    void buttonActionsChanged(QVariantList actions);
    
    void throttleModeChanged(int mode);
    
    void enabledChanged(bool enabled);
    
    /// Signal containing new joystick information
    ///     @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
    ///     @param mode     See Vehicle::JoystickMode_t enum
    void manualControl(float roll, float pitch, float yaw, float throttle, quint16 buttons, int joystickMmode);
    
    void buttonActionTriggered(int action);
    
private:
    void _saveSettings(void);
    void _loadSettings(void);
    float _adjustRange(int value, Calibration_t calibration);
    
    // Override from QThread
    virtual void run(void);

private:
    int     _sdlIndex;      ///< Index for SDL_JoystickOpen
    
    bool    _exitThread;    ///< true: signal thread to exit
    
    QString _name;
    bool    _enabled;
    bool    _calibrated;
    bool    _calibrating;
    int     _axisCount;
    int     _buttonCount;
    
    static const int    _cAxes = 4;
    int                 _rgAxisValues[_cAxes];
    Calibration_t       _rgCalibration[_cAxes];
    int                 _rgFunctionAxis[maxFunction];
    static const char*  _rgFunctionSettingsKey[maxFunction];
    
    static const int    _cButtons = 12;
    int                 _rgButtonValues[_cButtons];
    int                 _rgButtonActions[_cButtons];
    quint16             _lastButtonBits;
    
    ThrottleMode_t      _throttleMode;
    
    static const char* _settingsGroup;
    static const char* _calibratedSettingsKey;
    static const char* _buttonActionSettingsKey;
    static const char* _throttleModeSettingsKey;
    static const char* _enabledSettingsKey;
};
    
#endif