Joystick.cc 21 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

#include "Joystick.h"
#include "QGC.h"
#include "AutoPilotPlugin.h"
#include "UAS.h"

#include <QSettings>

QGC_LOGGING_CATEGORY(JoystickLog, "JoystickLog")
19
QGC_LOGGING_CATEGORY(JoystickValuesLog, "JoystickValuesLog")
20 21

const char* Joystick::_settingsGroup =              "Joysticks";
22
const char* Joystick::_calibratedSettingsKey =      "Calibrated1"; // Increment number to force recalibration
Don Gagne's avatar
Don Gagne committed
23
const char* Joystick::_buttonActionSettingsKey =    "ButtonActionName%1";
24
const char* Joystick::_throttleModeSettingsKey =    "ThrottleMode";
25
const char* Joystick::_exponentialSettingsKey =     "Exponential";
26
const char* Joystick::_accumulatorSettingsKey =     "Accumulator";
Gregory Dymarek's avatar
Gregory Dymarek committed
27
const char* Joystick::_deadbandSettingsKey =        "Deadband";
28 29 30 31 32 33 34 35

const char* Joystick::_rgFunctionSettingsKey[Joystick::maxFunction] = {
    "RollAxis",
    "PitchAxis",
    "YawAxis",
    "ThrottleAxis"
};

36
Joystick::Joystick(const QString& name, int axisCount, int buttonCount, int hatCount, MultiVehicleManager* multiVehicleManager)
Gregory Dymarek's avatar
Gregory Dymarek committed
37
    : _exitThread(false)
38 39 40
    , _name(name)
    , _axisCount(axisCount)
    , _buttonCount(buttonCount)
41 42 43
    , _hatCount(hatCount)
    , _hatButtonCount(4*hatCount)
    , _totalButtonCount(_buttonCount+_hatButtonCount)
Don Gagne's avatar
Don Gagne committed
44
    , _calibrationMode(CalibrationModeOff)
45 46 47
    , _rgAxisValues(NULL)
    , _rgCalibration(NULL)
    , _rgButtonValues(NULL)
48 49
    , _lastButtonBits(0)
    , _throttleMode(ThrottleModeCenterZero)
50
    , _exponential(false)
51
    , _accumulator(false)
Gregory Dymarek's avatar
Gregory Dymarek committed
52
    , _deadband(false)
53 54
    , _activeVehicle(NULL)
    , _pollingStartedForCalibration(false)
55
    , _multiVehicleManager(multiVehicleManager)
56
{
57

58 59
    _rgAxisValues = new int[_axisCount];
    _rgCalibration = new Calibration_t[_axisCount];
60
    _rgButtonValues = new bool[_totalButtonCount];
61 62

    for (int i=0; i<_axisCount; i++) {
63 64
        _rgAxisValues[i] = 0;
    }
65
    for (int i=0; i<_totalButtonCount; i++) {
66 67
        _rgButtonValues[i] = false;
    }
68

69 70 71 72 73
    _loadSettings();
}

Joystick::~Joystick()
{
74 75 76
    delete _rgAxisValues;
    delete _rgCalibration;
    delete _rgButtonValues;
77 78 79 80 81
}

void Joystick::_loadSettings(void)
{
    QSettings   settings;
82

83 84
    settings.beginGroup(_settingsGroup);
    settings.beginGroup(_name);
85

86 87
    bool badSettings = false;
    bool convertOk;
88

89
    qCDebug(JoystickLog) << "_loadSettings " << _name;
90

91
    _calibrated = settings.value(_calibratedSettingsKey, false).toBool();
92
    _exponential = settings.value(_exponentialSettingsKey, false).toBool();
93
    _accumulator = settings.value(_accumulatorSettingsKey, false).toBool();
Gregory Dymarek's avatar
Gregory Dymarek committed
94
    _deadband = settings.value(_deadbandSettingsKey, false).toBool();
95

96 97
    _throttleMode = (ThrottleMode_t)settings.value(_throttleModeSettingsKey, ThrottleModeCenterZero).toInt(&convertOk);
    badSettings |= !convertOk;
98

99
    qCDebug(JoystickLog) << "_loadSettings calibrated:throttlemode:exponential:deadband:badsettings" << _calibrated << _throttleMode << _exponential << _deadband << badSettings;
100

101 102 103 104
    QString minTpl  ("Axis%1Min");
    QString maxTpl  ("Axis%1Max");
    QString trimTpl ("Axis%1Trim");
    QString revTpl  ("Axis%1Rev");
105
    QString deadbndTpl  ("Axis%1Deadbnd");
106

107
    for (int axis=0; axis<_axisCount; axis++) {
108
        Calibration_t* calibration = &_rgCalibration[axis];
109

110 111
        calibration->center = settings.value(trimTpl.arg(axis), 0).toInt(&convertOk);
        badSettings |= !convertOk;
112

113 114
        calibration->min = settings.value(minTpl.arg(axis), -32768).toInt(&convertOk);
        badSettings |= !convertOk;
115

116
        calibration->max = settings.value(maxTpl.arg(axis), 32767).toInt(&convertOk);
117
        badSettings |= !convertOk;
118

119 120 121
        calibration->deadband = settings.value(deadbndTpl.arg(axis), 0).toInt(&convertOk);
        badSettings |= !convertOk;

122
        calibration->reversed = settings.value(revTpl.arg(axis), false).toBool();
123

124

125
        qCDebug(JoystickLog) << "_loadSettings axis:min:max:trim:reversed:deadband:badsettings" << axis << calibration->min << calibration->max << calibration->center << calibration->reversed << calibration->deadband << badSettings;
126
    }
127

128 129
    for (int function=0; function<maxFunction; function++) {
        int functionAxis;
130

131 132
        functionAxis = settings.value(_rgFunctionSettingsKey[function], -1).toInt(&convertOk);
        badSettings |= !convertOk || (functionAxis == -1);
133

134
        _rgFunctionAxis[function] = functionAxis;
135

136 137
        qCDebug(JoystickLog) << "_loadSettings function:axis:badsettings" << function << functionAxis << badSettings;
    }
138

Don Gagne's avatar
Don Gagne committed
139
    for (int button=0; button<_totalButtonCount; button++) {
140
        _rgButtonActions << settings.value(QString(_buttonActionSettingsKey).arg(button), QString()).toString();
Don Gagne's avatar
Don Gagne committed
141
        qCDebug(JoystickLog) << "_loadSettings button:action" << button << _rgButtonActions[button];
142
    }
143

144 145 146 147 148 149 150 151 152
    if (badSettings) {
        _calibrated = false;
        settings.setValue(_calibratedSettingsKey, false);
    }
}

void Joystick::_saveSettings(void)
{
    QSettings settings;
153

154 155
    settings.beginGroup(_settingsGroup);
    settings.beginGroup(_name);
156

157
    settings.setValue(_calibratedSettingsKey, _calibrated);
158
    settings.setValue(_exponentialSettingsKey, _exponential);
159
    settings.setValue(_accumulatorSettingsKey, _accumulator);
Gregory Dymarek's avatar
Gregory Dymarek committed
160
    settings.setValue(_deadbandSettingsKey, _deadband);
161
    settings.setValue(_throttleModeSettingsKey, _throttleMode);
162

163
    qCDebug(JoystickLog) << "_saveSettings calibrated:throttlemode:deadband" << _calibrated << _throttleMode << _deadband;
164 165 166 167 168

    QString minTpl  ("Axis%1Min");
    QString maxTpl  ("Axis%1Max");
    QString trimTpl ("Axis%1Trim");
    QString revTpl  ("Axis%1Rev");
169
    QString deadbndTpl  ("Axis%1Deadbnd");
170

171
    for (int axis=0; axis<_axisCount; axis++) {
172
        Calibration_t* calibration = &_rgCalibration[axis];
173

174 175 176 177
        settings.setValue(trimTpl.arg(axis), calibration->center);
        settings.setValue(minTpl.arg(axis), calibration->min);
        settings.setValue(maxTpl.arg(axis), calibration->max);
        settings.setValue(revTpl.arg(axis), calibration->reversed);
178
        settings.setValue(deadbndTpl.arg(axis), calibration->deadband);
179

180
        qCDebug(JoystickLog) << "_saveSettings name:axis:min:max:trim:reversed:deadband"
181 182 183 184 185
                                << _name
                                << axis
                                << calibration->min
                                << calibration->max
                                << calibration->center
186 187
                                << calibration->reversed
                                << calibration->deadband;
188
    }
189

190 191 192 193
    for (int function=0; function<maxFunction; function++) {
        settings.setValue(_rgFunctionSettingsKey[function], _rgFunctionAxis[function]);
        qCDebug(JoystickLog) << "_saveSettings name:function:axis" << _name << function << _rgFunctionSettingsKey[function];
    }
194

Don Gagne's avatar
Don Gagne committed
195
    for (int button=0; button<_totalButtonCount; button++) {
196 197 198 199 200 201
        settings.setValue(QString(_buttonActionSettingsKey).arg(button), _rgButtonActions[button]);
        qCDebug(JoystickLog) << "_saveSettings button:action" << button << _rgButtonActions[button];
    }
}

/// Adjust the raw axis value to the -1:1 range given calibration information
202
float Joystick::_adjustRange(int value, Calibration_t calibration, bool withDeadbands)
203 204 205 206
{
    float valueNormalized;
    float axisLength;
    float axisBasis;
207

208 209 210 211 212 213 214 215 216
    if (value > calibration.center) {
        axisBasis = 1.0f;
        valueNormalized = value - calibration.center;
        axisLength =  calibration.max - calibration.center;
    } else {
        axisBasis = -1.0f;
        valueNormalized = calibration.center - value;
        axisLength =  calibration.center - calibration.min;
    }
217

218
    if (withDeadbands) {
Gregory Dymarek's avatar
Gregory Dymarek committed
219 220
        if (valueNormalized>calibration.deadband) valueNormalized-=calibration.deadband;
        else if (valueNormalized<-calibration.deadband) valueNormalized+=calibration.deadband;
221 222 223
        else valueNormalized = 0.f;
    }

224
    float axisPercent = valueNormalized / axisLength;
225

226
    float correctedValue = axisBasis * axisPercent;
227

228 229 230
    if (calibration.reversed) {
        correctedValue *= -1.0f;
    }
231

232
#if 0
233
    qCDebug(JoystickLog) << "_adjustRange corrected:value:min:max:center:reversed:deadband:basis:normalized:length"
234 235 236 237 238
                            << correctedValue
                            << value
                            << calibration.min
                            << calibration.max
                            << calibration.center
239
                            << calibration.reversed
240
                            << calibration.deadband
241 242 243 244 245
                            << axisBasis
                            << valueNormalized
                            << axisLength;
#endif

246
    return std::max(-1.0f, std::min(correctedValue, 1.0f));
247 248 249 250 251
}


void Joystick::run(void)
{
Gregory Dymarek's avatar
Gregory Dymarek committed
252
    _open();
253

254
    while (!_exitThread) {
Gregory Dymarek's avatar
Gregory Dymarek committed
255
    _update();
256 257 258

        // Update axes
        for (int axisIndex=0; axisIndex<_axisCount; axisIndex++) {
Gregory Dymarek's avatar
Gregory Dymarek committed
259
            int newAxisValue = _getAxis(axisIndex);
260 261 262 263
            // Calibration code requires signal to be emitted even if value hasn't changed
            _rgAxisValues[axisIndex] = newAxisValue;
            emit rawAxisValueChanged(axisIndex, newAxisValue);
        }
264

265 266
        // Update buttons
        for (int buttonIndex=0; buttonIndex<_buttonCount; buttonIndex++) {
Gregory Dymarek's avatar
Gregory Dymarek committed
267
            bool newButtonValue = _getButton(buttonIndex);
268 269 270 271 272
            if (newButtonValue != _rgButtonValues[buttonIndex]) {
                _rgButtonValues[buttonIndex] = newButtonValue;
                emit rawButtonPressedChanged(buttonIndex, newButtonValue);
            }
        }
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287

        // Update hat - append hat buttons to the end of the normal button list
        int numHatButtons = 4;
        for (int hatIndex=0; hatIndex<_hatCount; hatIndex++) {
            for (int hatButtonIndex=0; hatButtonIndex<numHatButtons; hatButtonIndex++) {
                // Create new index value that includes the normal button list
                int rgButtonValueIndex = hatIndex*numHatButtons + hatButtonIndex + _buttonCount;
                // Get hat value from joystick
                bool newButtonValue = _getHat(hatIndex,hatButtonIndex);
                if (newButtonValue != _rgButtonValues[rgButtonValueIndex]) {
                    _rgButtonValues[rgButtonValueIndex] = newButtonValue;
                    emit rawButtonPressedChanged(rgButtonValueIndex, newButtonValue);
                }
            }
        }
288

Don Gagne's avatar
Don Gagne committed
289
        if (_calibrationMode != CalibrationModeCalibrating) {
290
            int     axis = _rgFunctionAxis[rollFunction];
291
            float   roll = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis], _deadband);
292

293
                    axis = _rgFunctionAxis[pitchFunction];
294
            float   pitch = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis], _deadband);
295

296
                    axis = _rgFunctionAxis[yawFunction];
297
            float   yaw = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis],_deadband);
298

299
                    axis = _rgFunctionAxis[throttleFunction];
300
            float   throttle = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis], _throttleMode==ThrottleModeDownZero?false:_deadband);
301

302 303 304 305 306 307 308 309 310
            if ( _accumulator ) {
                static float throttle_accu = 0.f;

                throttle_accu += throttle*(40/1000.f); //for throttle to change from min to max it will take 1000ms (40ms is a loop time)

                throttle_accu = std::max(static_cast<float>(-1.f), std::min(throttle_accu, static_cast<float>(1.f)));
                throttle = throttle_accu;
            }

311 312 313 314 315
            float roll_limited = std::max(static_cast<float>(-M_PI_4), std::min(roll, static_cast<float>(M_PI_4)));
            float pitch_limited = std::max(static_cast<float>(-M_PI_4), std::min(pitch, static_cast<float>(M_PI_4)));
            float yaw_limited = std::max(static_cast<float>(-M_PI_4), std::min(yaw, static_cast<float>(M_PI_4)));
            float throttle_limited = std::max(static_cast<float>(-M_PI_4), std::min(throttle, static_cast<float>(M_PI_4)));

316
            // Map from unit circle to linear range and limit
317 318 319 320
            roll =      std::max(-1.0f, std::min(tanf(asinf(roll_limited)), 1.0f));
            pitch =     std::max(-1.0f, std::min(tanf(asinf(pitch_limited)), 1.0f));
            yaw =       std::max(-1.0f, std::min(tanf(asinf(yaw_limited)), 1.0f));
            throttle =  std::max(-1.0f, std::min(tanf(asinf(throttle_limited)), 1.0f));
321
            
322 323 324 325 326 327 328 329 330 331 332
            if ( _exponential ) {
                // Exponential (0% to -50% range like most RC radios)
                // 0 for no exponential
                // -0.5 for strong exponential
                float expo = -0.35f;

                // Calculate new RPY with exponential applied
                roll =      -expo*powf(roll,3) + (1+expo)*roll;
                pitch =     -expo*powf(pitch,3) + (1+expo)*pitch;
                yaw =       -expo*powf(yaw,3) + (1+expo)*yaw;
            }
333

334
            // Adjust throttle to 0:1 range
335
            if (_throttleMode == ThrottleModeCenterZero && _activeVehicle->supportsThrottleModeCenterZero()) {
336
                throttle = std::max(0.0f, throttle);
337
            } else {
338 339
                throttle = (throttle + 1.0f) / 2.0f;
            }
340

341
            // Set up button pressed information
342

343
            // We only send the buttons the firmwware has reserved
344
            int reservedButtonCount = _activeVehicle->manualControlReservedButtonCount();
345
            if (reservedButtonCount == -1) {
346
                reservedButtonCount = _totalButtonCount;
347
            }
348

349 350
            quint16 newButtonBits = 0;      // New set of button which are down
            quint16 buttonPressedBits = 0;  // Buttons pressed for manualControl signal
351

352
            for (int buttonIndex=0; buttonIndex<_totalButtonCount; buttonIndex++) {
353
                quint16 buttonBit = 1 << buttonIndex;
354

355 356
                if (!_rgButtonValues[buttonIndex]) {
                    // Button up, just record it
357 358 359
                    newButtonBits |= buttonBit;
                } else {
                    if (_lastButtonBits & buttonBit) {
360
                        // Button was up last time through, but is now down which indicates a button press
361
                        qCDebug(JoystickLog) << "button triggered" << buttonIndex;
362

363 364
                        if (buttonIndex >= reservedButtonCount) {
                            // Button is above firmware reserved set
Don Gagne's avatar
Don Gagne committed
365 366 367
                            QString buttonAction =_rgButtonActions[buttonIndex];
                            if (!buttonAction.isEmpty()) {
                                _buttonAction(buttonAction);
368 369 370
                            }
                        }
                    }
371 372

                    // Mark the button as pressed as long as its pressed
373
                    buttonPressedBits |= buttonBit;
374 375
                }
            }
376

377
            _lastButtonBits = newButtonBits;
378

379
            qCDebug(JoystickValuesLog) << "name:roll:pitch:yaw:throttle" << name() << roll << -pitch << yaw << throttle;
380

381
            emit manualControl(roll, -pitch, yaw, throttle, buttonPressedBits, _activeVehicle->joystickMode());
382
        }
383

384 385 386
        // Sleep, update rate of joystick is approx. 25 Hz (1000 ms / 25 = 40 ms)
        QGC::SLEEP::msleep(40);
    }
387

Gregory Dymarek's avatar
Gregory Dymarek committed
388
    _close();
389 390
}

391
void Joystick::startPolling(Vehicle* vehicle)
392
{
393 394 395 396 397 398
    if (vehicle) {

        // If a vehicle is connected, disconnect it
        if (_activeVehicle) {
            UAS* uas = _activeVehicle->uas();
            disconnect(this, &Joystick::manualControl, uas, &UAS::setExternalControlSetpoint);
399
        }
400 401

        // Always set up the new vehicle
402
        _activeVehicle = vehicle;
403

404 405 406 407 408
        // If joystick is not calibrated, disable it
        if ( !_calibrated ) {
            vehicle->setJoystickEnabled(false);
        }

409 410 411 412 413 414 415 416 417 418 419 420 421
        // Only connect the new vehicle if it wants joystick data
        if (vehicle->joystickEnabled()) {
            _pollingStartedForCalibration = false;

            UAS* uas = _activeVehicle->uas();
            connect(this, &Joystick::manualControl, uas, &UAS::setExternalControlSetpoint);
            // FIXME: ****
            //connect(this, &Joystick::buttonActionTriggered, uas, &UAS::triggerAction);
        }
    }


    if (!isRunning()) {
422 423
        _exitThread = false;
        start();
424 425 426 427 428
    }
}

void Joystick::stopPolling(void)
{
429
    if (isRunning()) {
430 431 432 433 434 435

        if (_activeVehicle && _activeVehicle->joystickEnabled()) {
            UAS* uas = _activeVehicle->uas();

            disconnect(this, &Joystick::manualControl,          uas, &UAS::setExternalControlSetpoint);
        }
Don Gagne's avatar
Don Gagne committed
436 437
        // FIXME: ****
        //disconnect(this, &Joystick::buttonActionTriggered,  uas, &UAS::triggerAction);
438

439 440
        _exitThread = true;
        }
441 442 443 444
}

void Joystick::setCalibration(int axis, Calibration_t& calibration)
{
445
    if (!_validAxis(axis)) {
446 447 448
        qCWarning(JoystickLog) << "Invalid axis index" << axis;
        return;
    }
449

450 451 452 453 454 455 456 457
    _calibrated = true;
    _rgCalibration[axis] = calibration;
    _saveSettings();
    emit calibratedChanged(_calibrated);
}

Joystick::Calibration_t Joystick::getCalibration(int axis)
{
458
    if (!_validAxis(axis)) {
459 460
        qCWarning(JoystickLog) << "Invalid axis index" << axis;
    }
461

462 463 464 465 466
    return _rgCalibration[axis];
}

void Joystick::setFunctionAxis(AxisFunction_t function, int axis)
{
467
    if (!_validAxis(axis)) {
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
        qCWarning(JoystickLog) << "Invalid axis index" << axis;
        return;
    }

    _calibrated = true;
    _rgFunctionAxis[function] = axis;
    _saveSettings();
    emit calibratedChanged(_calibrated);
}

int Joystick::getFunctionAxis(AxisFunction_t function)
{
    if (function < 0 || function >= maxFunction) {
        qCWarning(JoystickLog) << "Invalid function" << function;
    }

    return _rgFunctionAxis[function];
}

QStringList Joystick::actions(void)
{
    QStringList list;
Don Gagne's avatar
Don Gagne committed
490 491

    list << "Arm" << "Disarm";
492 493 494 495

    if (_activeVehicle) {
        list << _activeVehicle->flightModes();
    }
496

497 498 499
    return list;
}

Don Gagne's avatar
Don Gagne committed
500
void Joystick::setButtonAction(int button, const QString& action)
501
{
502
    if (!_validButton(button)) {
503 504 505
        qCWarning(JoystickLog) << "Invalid button index" << button;
        return;
    }
506

Don Gagne's avatar
Don Gagne committed
507
    qDebug() << "setButtonAction" << action;
508

509 510 511 512 513
    _rgButtonActions[button] = action;
    _saveSettings();
    emit buttonActionsChanged(buttonActions());
}

Don Gagne's avatar
Don Gagne committed
514
QString Joystick::getButtonAction(int button)
515
{
516
    if (!_validButton(button)) {
517 518
        qCWarning(JoystickLog) << "Invalid button index" << button;
    }
519

520 521 522 523 524 525
    return _rgButtonActions[button];
}

QVariantList Joystick::buttonActions(void)
{
    QVariantList list;
526

Don Gagne's avatar
Don Gagne committed
527
    for (int button=0; button<_totalButtonCount; button++) {
528 529
        list += QVariant::fromValue(_rgButtonActions[button]);
    }
530

531 532 533 534 535 536 537 538 539 540 541 542 543 544
    return list;
}

int Joystick::throttleMode(void)
{
    return _throttleMode;
}

void Joystick::setThrottleMode(int mode)
{
    if (mode < 0 || mode >= ThrottleModeMax) {
        qCWarning(JoystickLog) << "Invalid throttle mode" << mode;
        return;
    }
545

546
    _throttleMode = (ThrottleMode_t)mode;
547 548 549 550 551

    if (_throttleMode == ThrottleModeDownZero) {
        setAccumulator(false);
    }

552 553 554 555
    _saveSettings();
    emit throttleModeChanged(_throttleMode);
}

556 557 558 559 560 561 562 563 564 565 566 567 568
bool Joystick::exponential(void)
{
    return _exponential;
}

void Joystick::setExponential(bool expo)
{
    _exponential = expo;

    _saveSettings();
    emit exponentialChanged(_exponential);
}

569 570 571 572 573 574 575 576 577 578 579 580 581
bool Joystick::accumulator(void)
{
    return _accumulator;
}

void Joystick::setAccumulator(bool accu)
{
    _accumulator = accu;

    _saveSettings();
    emit accumulatorChanged(_accumulator);
}

Gregory Dymarek's avatar
Gregory Dymarek committed
582 583 584 585 586 587 588 589 590 591 592 593
bool Joystick::deadband(void)
{
    return _deadband;
}

void Joystick::setDeadband(bool deadband)
{
    _deadband = deadband;

    _saveSettings();
}

Don Gagne's avatar
Don Gagne committed
594
void Joystick::startCalibrationMode(CalibrationMode_t mode)
595
{
Don Gagne's avatar
Don Gagne committed
596 597 598 599
    if (mode == CalibrationModeOff) {
        qWarning() << "Incorrect mode CalibrationModeOff";
        return;
    }
600

Don Gagne's avatar
Don Gagne committed
601
    _calibrationMode = mode;
602

603 604
    if (!isRunning()) {
        _pollingStartedForCalibration = true;
605
        startPolling(_multiVehicleManager->activeVehicle());
606
    }
607 608
}

Don Gagne's avatar
Don Gagne committed
609
void Joystick::stopCalibrationMode(CalibrationMode_t mode)
610
{
Don Gagne's avatar
Don Gagne committed
611 612 613 614
    if (mode == CalibrationModeOff) {
        qWarning() << "Incorrect mode: CalibrationModeOff";
        return;
    }
615

Don Gagne's avatar
Don Gagne committed
616 617 618 619
    if (mode == CalibrationModeCalibrating) {
        _calibrationMode = CalibrationModeMonitor;
    } else {
        _calibrationMode = CalibrationModeOff;
620 621 622
        if (_pollingStartedForCalibration) {
            stopPolling();
        }
623 624
    }
}
625

Don Gagne's avatar
Don Gagne committed
626 627
void Joystick::_buttonAction(const QString& action)
{
628 629 630 631
    if (!_activeVehicle || !_activeVehicle->joystickEnabled()) {
        return;
    }

Don Gagne's avatar
Don Gagne committed
632 633 634 635
    if (action == "Arm") {
        _activeVehicle->setArmed(true);
    } else if (action == "Disarm") {
        _activeVehicle->setArmed(false);
636 637
    } else if (_activeVehicle->flightModes().contains(action)) {
        _activeVehicle->setFlightMode(action);
Don Gagne's avatar
Don Gagne committed
638 639 640 641 642
    } else {
        qCDebug(JoystickLog) << "_buttonAction unknown action:" << action;
    }
}

643 644 645 646 647 648 649
bool Joystick::_validAxis(int axis)
{
    return axis >= 0 && axis < _axisCount;
}

bool Joystick::_validButton(int button)
{
650
    return button >= 0 && button < _totalButtonCount;
651 652
}