PX4RCCalibrationTest.cc 24.7 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
/*=====================================================================
 
 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/>.
 
 ======================================================================*/

#include "PX4RCCalibrationTest.h"
#include "UASManager.h"
#include "MockQGCUASParamManager.h"

/// @file
Don Gagne's avatar
Don Gagne committed
29
///     @brief QPX4RCCalibration Widget unit test
30 31 32
///
///     @author Don Gagne <don@thegagnes.com>

Don Gagne's avatar
Don Gagne committed
33 34
UT_REGISTER_TEST(PX4RCCalibrationTest)

35 36 37 38 39 40
// This will check for the wizard buttons being enabled of disabled according to the mask you pass in.
// We use a macro instead of a method so that we get better line number reporting on failure.
#define CHK_BUTTONS(mask) \
{ \
    if (_nextButton->isEnabled() != !!((mask) & nextButtonMask) || \
        _skipButton->isEnabled() != !!((mask) & skipButtonMask) || \
Don Gagne's avatar
Don Gagne committed
41
        _cancelButton->isEnabled() != !!((mask) & cancelButtonMask) ) { \
42 43 44 45 46 47 48 49 50 51 52
        qDebug() << _statusLabel->text(); \
    } \
    QCOMPARE(_nextButton->isEnabled(), !!((mask) & nextButtonMask)); \
    QCOMPARE(_skipButton->isEnabled(), !!((mask) & skipButtonMask)); \
    QCOMPARE(_cancelButton->isEnabled(), !!((mask) & cancelButtonMask)); \
}

// This allows you to write unit tests which will click the Cancel button the first time through, followed
// by the Next button on the second iteration.
#define NEXT_OR_CANCEL(cancelNum) \
{ \
Don Gagne's avatar
Don Gagne committed
53
    if (mode == testModeStandalone && tryCancel ## cancelNum) { \
54 55 56 57 58 59 60 61 62
        QTest::mouseClick(_cancelButton, Qt::LeftButton); \
        QCOMPARE(_calWidget->_rcCalState, PX4RCCalibration::rcCalStateChannelWait); \
        tryCancel ## cancelNum = false; \
        goto StartOver; \
    } else { \
        QTest::mouseClick(_nextButton, Qt::LeftButton); \
    } \
}

Don Gagne's avatar
Don Gagne committed
63 64
const int PX4RCCalibrationTest::_stickSettleWait = PX4RCCalibration::_stickDetectSettleMSecs * 1.5;

Don Gagne's avatar
Don Gagne committed
65 66
const int PX4RCCalibrationTest::_testMinValue = PX4RCCalibration::_rcCalPWMDefaultMinValue + 10;
const int PX4RCCalibrationTest::_testMaxValue = PX4RCCalibration::_rcCalPWMDefaultMaxValue - 10;
Don Gagne's avatar
Don Gagne committed
67
const int PX4RCCalibrationTest::_testCenterValue = PX4RCCalibrationTest::_testMinValue + ((PX4RCCalibrationTest::_testMaxValue - PX4RCCalibrationTest::_testMinValue) / 2);
Don Gagne's avatar
Don Gagne committed
68

69 70
/// @brief Maps from function index to channel index. -1 signals no mapping. Channel indices are offset 1 from function index
/// to catch bugs where function index is incorrectly used as channel index.
Don Gagne's avatar
Don Gagne committed
71
const int PX4RCCalibrationTest::_rgFunctionChannelMap[PX4RCCalibration::rcCalFunctionMax]= { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
72

Don Gagne's avatar
Don Gagne committed
73 74
const struct PX4RCCalibrationTest::ChannelSettings PX4RCCalibrationTest::_rgChannelSettings[PX4RCCalibrationTest::_availableChannels] = {
	// Function										Min                 Max                 #  Reversed
75 76
	
	// Channel 0 : Not mapped to function, Simulate invalid Min/Max
Don Gagne's avatar
Don Gagne committed
77
	{ PX4RCCalibration::rcCalFunctionMax,			_testCenterValue,	_testCenterValue,   0, false },
78
	
Don Gagne's avatar
Don Gagne committed
79 80 81 82 83 84 85 86 87 88 89 90
    // Channels 1-11 are mapped to all available modes
    { PX4RCCalibration::rcCalFunctionRoll,			_testMinValue,      _testMaxValue,      0, true },
    { PX4RCCalibration::rcCalFunctionPitch,			_testMinValue,      _testMaxValue,      0, false },
    { PX4RCCalibration::rcCalFunctionYaw,			_testMinValue,      _testMaxValue,      0, true },
    { PX4RCCalibration::rcCalFunctionThrottle,		_testMinValue,      _testMaxValue,      0,  false },
    { PX4RCCalibration::rcCalFunctionModeSwitch,	_testMinValue,      _testMaxValue,      0, false },
    { PX4RCCalibration::rcCalFunctionPosCtlSwitch,	_testMinValue,      _testMaxValue,      0, false },
    { PX4RCCalibration::rcCalFunctionLoiterSwitch,	_testMinValue,      _testMaxValue,      0, false },
    { PX4RCCalibration::rcCalFunctionReturnSwitch,	_testMinValue,      _testMaxValue,      0, false },
    { PX4RCCalibration::rcCalFunctionFlaps,			_testMinValue,      _testMaxValue,      0, false },
    { PX4RCCalibration::rcCalFunctionAux1,			_testMinValue,      _testMaxValue,      0, false },
    { PX4RCCalibration::rcCalFunctionAux2,			_testMinValue,      _testMaxValue,      0, false },
91 92
	
    // Channel 12 : Not mapped to function, Simulate invalid Min, valid Max
Don Gagne's avatar
Don Gagne committed
93
    { PX4RCCalibration::rcCalFunctionMax,			_testCenterValue,	_testMaxValue,      0,  false },
94 95
    
	// Channel 13 : Not mapped to function, Simulate valid Min, invalid Max
Don Gagne's avatar
Don Gagne committed
96
	{ PX4RCCalibration::rcCalFunctionMax,           _testMinValue,      _testCenterValue,   0,	false },
97 98
	
    // Channels 14-17: Not mapped to function, Simulate invalid Min/Max, since available channel Min/Max is still shown
Don Gagne's avatar
Don Gagne committed
99 100 101 102
    { PX4RCCalibration::rcCalFunctionMax,			_testCenterValue,   _testCenterValue,   0,	false },
    { PX4RCCalibration::rcCalFunctionMax,			_testCenterValue,   _testCenterValue,   0,	false },
	{ PX4RCCalibration::rcCalFunctionMax,			_testCenterValue,   _testCenterValue,   0,	false },
	{ PX4RCCalibration::rcCalFunctionMax,			_testCenterValue,   _testCenterValue,   0,	false },
Don Gagne's avatar
Don Gagne committed
103 104
};

Don Gagne's avatar
Don Gagne committed
105 106
const struct PX4RCCalibrationTest::ChannelSettings PX4RCCalibrationTest::_rgChannelSettingsValidate[PX4RCCalibration::_chanMax] = {
    // Function										Min Value									Max Value									Trim Value										Reversed
107 108
	
	// Channel 0 is not mapped and should be defaulted
Don Gagne's avatar
Don Gagne committed
109
	{ PX4RCCalibration::rcCalFunctionMax,			PX4RCCalibration::_rcCalPWMDefaultMinValue,	PX4RCCalibration::_rcCalPWMDefaultMaxValue,	PX4RCCalibration::_rcCalPWMCenterPoint,         false },
110
	
Don Gagne's avatar
Don Gagne committed
111 112 113 114 115 116 117 118 119 120 121 122
	// Channels 1-11 are mapped to all available modes
	{ PX4RCCalibration::rcCalFunctionRoll,			_testMinValue,		_testMaxValue,        _testCenterValue, true },
    { PX4RCCalibration::rcCalFunctionPitch,			_testMinValue,		_testMaxValue,        _testCenterValue, false },
    { PX4RCCalibration::rcCalFunctionYaw,			_testMinValue,		_testMaxValue,        _testCenterValue, true },
    { PX4RCCalibration::rcCalFunctionThrottle,		_testMinValue,		_testMaxValue,        _testMinValue,    false },
    { PX4RCCalibration::rcCalFunctionModeSwitch,	_testMinValue,		_testMaxValue,        _testCenterValue, false },
    { PX4RCCalibration::rcCalFunctionPosCtlSwitch,	_testMinValue,		_testMaxValue,        _testCenterValue, false },
    { PX4RCCalibration::rcCalFunctionLoiterSwitch,	_testMinValue,		_testMaxValue,        _testCenterValue, false },
    { PX4RCCalibration::rcCalFunctionReturnSwitch,	_testMinValue,		_testMaxValue,        _testCenterValue, false },
    { PX4RCCalibration::rcCalFunctionFlaps,			_testMinValue,		_testMaxValue,        _testCenterValue, false },
    { PX4RCCalibration::rcCalFunctionAux1,			_testMinValue,		_testMaxValue,        _testCenterValue, false },
    { PX4RCCalibration::rcCalFunctionAux2,			_testMinValue,		_testMaxValue,        _testCenterValue, false },
123
	
Don Gagne's avatar
Don Gagne committed
124 125 126 127 128 129 130
	// Channels 12-17 are not mapped and should be set to defaults
	{ PX4RCCalibration::rcCalFunctionMax,			PX4RCCalibration::_rcCalPWMDefaultMinValue,	PX4RCCalibration::_rcCalPWMDefaultMaxValue,	PX4RCCalibration::_rcCalPWMCenterPoint,         false },
	{ PX4RCCalibration::rcCalFunctionMax,			PX4RCCalibration::_rcCalPWMDefaultMinValue,	PX4RCCalibration::_rcCalPWMDefaultMaxValue,	PX4RCCalibration::_rcCalPWMCenterPoint,         false },
	{ PX4RCCalibration::rcCalFunctionMax,			PX4RCCalibration::_rcCalPWMDefaultMinValue,	PX4RCCalibration::_rcCalPWMDefaultMaxValue,	PX4RCCalibration::_rcCalPWMCenterPoint,         false },
	{ PX4RCCalibration::rcCalFunctionMax,			PX4RCCalibration::_rcCalPWMDefaultMinValue,	PX4RCCalibration::_rcCalPWMDefaultMaxValue,	PX4RCCalibration::_rcCalPWMCenterPoint,         false },
	{ PX4RCCalibration::rcCalFunctionMax,			PX4RCCalibration::_rcCalPWMDefaultMinValue,	PX4RCCalibration::_rcCalPWMDefaultMaxValue,	PX4RCCalibration::_rcCalPWMCenterPoint,         false },
	{ PX4RCCalibration::rcCalFunctionMax,			PX4RCCalibration::_rcCalPWMDefaultMinValue,	PX4RCCalibration::_rcCalPWMDefaultMaxValue,	PX4RCCalibration::_rcCalPWMCenterPoint,         false },
Don Gagne's avatar
Don Gagne committed
131 132
};

133 134 135 136
PX4RCCalibrationTest::PX4RCCalibrationTest(void) :
    _mockUASManager(NULL),
    _calWidget(NULL)
{
Don Gagne's avatar
Don Gagne committed
137 138 139 140 141
}

/// @brief Called one time before any test cases are run.
void PX4RCCalibrationTest::initTestCase(void)
{
Don Gagne's avatar
Don Gagne committed
142 143
    UnitTest::initTestCase();
    
144 145 146 147
	// Validate that our function to channel mapping is still correct.
	for (int function=0; function<PX4RCCalibration::rcCalFunctionMax; function++) {
		int chanIndex = _rgFunctionChannelMap[function];
		if (chanIndex != -1) {
Don Gagne's avatar
Don Gagne committed
148 149
			Q_ASSERT(_rgChannelSettings[chanIndex].function == function);
			Q_ASSERT(_rgChannelSettingsValidate[chanIndex].function == function);
150 151
		}
	}
152 153 154 155
}

void PX4RCCalibrationTest::init(void)
{
Don Gagne's avatar
Don Gagne committed
156 157
    UnitTest::init();
    
158 159 160 161 162 163 164 165 166 167 168
    _mockUASManager = new MockUASManager();
    Q_ASSERT(_mockUASManager);
    
    UASManager::setMockUASManager(_mockUASManager);
    
    _mockUAS = new MockUAS();
    Q_CHECK_PTR(_mockUAS);
    
    // This will instatiate the widget with no active UAS set
    _calWidget = new PX4RCCalibration();
    Q_CHECK_PTR(_calWidget);
Don Gagne's avatar
Don Gagne committed
169 170
    _calWidget->_setUnitTestMode();
    _calWidget->setVisible(true);
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    
    _mockUASManager->setMockActiveUAS(_mockUAS);

    // Get pointers to the push buttons
    _cancelButton = _calWidget->findChild<QPushButton*>("rcCalCancel");
    _nextButton = _calWidget->findChild<QPushButton*>("rcCalNext");
    _skipButton = _calWidget->findChild<QPushButton*>("rcCalSkip");
    
    Q_ASSERT(_cancelButton);
    Q_ASSERT(_nextButton);
    Q_ASSERT(_skipButton);
    
    _statusLabel = _calWidget->findChild<QLabel*>("rcCalStatus");
    Q_ASSERT(_statusLabel);
 
    for (size_t i=0; i<PX4RCCalibration::_chanMax; i++) {
Don Gagne's avatar
Don Gagne committed
187 188 189
        QString radioWidgetName("channel%1Value");

        RCValueWidget* radioWidget = _calWidget->findChild<RCValueWidget*>(radioWidgetName.arg(i+1));
190 191
        Q_ASSERT(radioWidget);
        
Don Gagne's avatar
Don Gagne committed
192
        _rgValueWidget[i] = radioWidget;
193
    }
Don Gagne's avatar
Don Gagne committed
194 195 196 197 198 199 200
    
    _rgSignals[0] = SIGNAL(nextButtonMessageBoxDisplayed());
    _multiSpyNextButtonMessageBox = new MultiSignalSpy();
    Q_CHECK_PTR(_multiSpyNextButtonMessageBox);
    QCOMPARE(_multiSpyNextButtonMessageBox->init(_calWidget, _rgSignals, 1), true);
    
    QCOMPARE(_calWidget->_currentStep, -1);
201 202 203 204
}

void PX4RCCalibrationTest::cleanup(void)
{
Don Gagne's avatar
Don Gagne committed
205 206
    UnitTest::cleanup();
    
Don Gagne's avatar
Don Gagne committed
207 208 209
    Q_ASSERT(_calWidget);
    delete _calWidget;
    
210 211 212 213
    Q_ASSERT(_mockUAS);
    delete _mockUAS;
    
    UASManager::setMockUASManager(NULL);
Don Gagne's avatar
Don Gagne committed
214
    
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
    Q_ASSERT(_mockUASManager);
    delete _mockUASManager;
    
}

/// @brief Tests for correct behavior when active UAS is set into widget.
void PX4RCCalibrationTest::_setUAS_test(void)
{
    // Widget is initialized with UAS, so it should be enabled
    QCOMPARE(_calWidget->isEnabled(), true);

    // Take away the UAS and widget should disable
    _mockUASManager->setMockActiveUAS(NULL);
    QCOMPARE(_calWidget->isEnabled(), false);
}

Don Gagne's avatar
Don Gagne committed
231
/// @brief Test for correct behavior in determining minimum numbers of channels for flight.
232 233 234
void PX4RCCalibrationTest::_minRCChannels_test(void)
{
    // Next button won't be enabled until we see the minimum number of channels.
235 236
    for (int chan=0; chan<PX4RCCalibration::_chanMinimum; chan++) {
        _mockUAS->emitRemoteControlChannelRawChanged(chan, (float)PX4RCCalibration::_rcCalPWMCenterPoint);
Don Gagne's avatar
Don Gagne committed
237 238
        
        // We use _chanCount internally so we should validate it
239
        QCOMPARE(_calWidget->_chanCount, chan+1);
Don Gagne's avatar
Don Gagne committed
240 241
        
        // Validate Next button state
Don Gagne's avatar
Don Gagne committed
242 243
        QTest::mouseClick(_nextButton, Qt::LeftButton);
        bool signalFound = _multiSpyNextButtonMessageBox->waitForSignalByIndex(0, 200);
244
        if (chan == PX4RCCalibration::_chanMinimum - 1) {
Don Gagne's avatar
Don Gagne committed
245 246 247
            // Last channel should trigger Calibration available
            QCOMPARE(signalFound, false);
            QCOMPARE(_calWidget->_currentStep, 0);
248
        } else {
Don Gagne's avatar
Don Gagne committed
249 250 251
            // Still less than the minimum channels. Next button should show message box. Calibration should not start.
            QCOMPARE(signalFound, true);
            QCOMPARE(_calWidget->_currentStep, -1);
252
        }
Don Gagne's avatar
Don Gagne committed
253
        _multiSpyNextButtonMessageBox->clearAllSignals();
Don Gagne's avatar
Don Gagne committed
254

255 256 257
        // The following test code no longer works since view update doesn't happens until parameters are received.
        // Leaving code here because RC Cal could be restructured to handle this case at some point.
#if 0
Don Gagne's avatar
Don Gagne committed
258
        // Only available channels should have visible widget. A ui update cycle needs to have passed so we wait a little.
Don Gagne's avatar
Don Gagne committed
259 260
        QTest::qWait(PX4RCCalibration::_updateInterval * 2);
        for (int chanWidget=0; chanWidget<PX4RCCalibration::_chanMax; chanWidget++) {
Don Gagne's avatar
Don Gagne committed
261 262
            //qDebug() << _rgValueWidget[chanWidget]->objectName() << chanWidget << chan;
            QCOMPARE(_rgValueWidget[chanWidget]->isVisible(), !!(chanWidget <= chan));
Don Gagne's avatar
Don Gagne committed
263
        }
264
#endif
265 266 267
    }
}

Don Gagne's avatar
Don Gagne committed
268
void PX4RCCalibrationTest::_beginCalibration(void)
269 270 271
{
    CHK_BUTTONS(nextButtonMask | cancelButtonMask);

Don Gagne's avatar
Don Gagne committed
272 273 274 275
    // We should already have enough channels to proceed with calibration. Click next to start the process.
    
    QTest::mouseClick(_nextButton, Qt::LeftButton);
    QCOMPARE(_calWidget->_currentStep, 1);
276 277 278
    CHK_BUTTONS(cancelButtonMask);
}

Don Gagne's avatar
Don Gagne committed
279
void PX4RCCalibrationTest::_stickMoveWaitForSettle(int channel, int value)
280
{
Don Gagne's avatar
Don Gagne committed
281 282 283 284 285 286 287 288 289 290 291 292 293
    //qDebug() << "_stickMoveWaitForSettle channel:value" << channel << value;

    // Move the stick, this will initialized the settle checker
    _mockUAS->emitRemoteControlChannelRawChanged(channel, value);
    
    // Emit the signal again to start the settle timer
    _mockUAS->emitRemoteControlChannelRawChanged(channel, value);
    
    // Wait long enough for the settle timer to expire
    QTest::qWait(PX4RCCalibration::_stickDetectSettleMSecs * 1.5);
    
    // Emit the signal again so that we detect stick settle
    _mockUAS->emitRemoteControlChannelRawChanged(channel, value);
294 295
}

Don Gagne's avatar
Don Gagne committed
296
void PX4RCCalibrationTest::_stickMoveAutoStep(const char* functionStr, enum PX4RCCalibration::rcCalFunctions function, enum PX4RCCalibrationTest::MoveToDirection direction, bool identifyStep)
297
{
Don Gagne's avatar
Don Gagne committed
298 299
    Q_UNUSED(functionStr);
    //qDebug() << "_stickMoveAutoStep function:direction:reversed:identifyStep" << functionStr << function << direction << identifyStep;
300
    
Don Gagne's avatar
Don Gagne committed
301 302 303 304 305 306
    CHK_BUTTONS(cancelButtonMask);
    
    int channel = _rgFunctionChannelMap[function];
    int saveStep = _calWidget->_currentStep;
    
    bool reversed = _rgChannelSettings[channel].reversed;
307
    
Don Gagne's avatar
Don Gagne committed
308 309
    if (!identifyStep && direction != moveToCenter) {
        // We have already identified the function channel mapping. Move other channels around to make sure there is no impact.
310
        
Don Gagne's avatar
Don Gagne committed
311 312 313
        int otherChannel = channel + 1;
        if (otherChannel >= PX4RCCalibration::_chanMax) {
            otherChannel = 0;
Don Gagne's avatar
Don Gagne committed
314 315
        }
        
Don Gagne's avatar
Don Gagne committed
316 317 318
        _stickMoveWaitForSettle(otherChannel, _testMinValue);
        QCOMPARE(_calWidget->_currentStep, saveStep);
        CHK_BUTTONS(cancelButtonMask);
319
        
Don Gagne's avatar
Don Gagne committed
320 321 322
        _stickMoveWaitForSettle(otherChannel, PX4RCCalibration::_rcCalPWMCenterPoint);
        QCOMPARE(_calWidget->_currentStep, saveStep);
        CHK_BUTTONS(cancelButtonMask);
323 324
    }
    
Don Gagne's avatar
Don Gagne committed
325 326 327 328 329 330 331 332 333 334 335
    // Move channel to specified position to trigger next step
    
    int value;
    if (direction == moveToMin) {
        value = reversed ? _testMaxValue : _testMinValue;
    } else if (direction == moveToMax) {
        value = reversed ? _testMinValue : _testMaxValue;
    } else if (direction == moveToCenter) {
        value = PX4RCCalibration::_rcCalPWMCenterPoint;
    } else {
        Q_ASSERT(false);
336
    }
Don Gagne's avatar
Don Gagne committed
337 338 339
    
    _stickMoveWaitForSettle(channel, value);
    QCOMPARE(_calWidget->_currentStep, saveStep + 1);
340 341
}

Don Gagne's avatar
Don Gagne committed
342
void PX4RCCalibrationTest::_switchMinMaxStep(void)
343
{
Don Gagne's avatar
Don Gagne committed
344
    CHK_BUTTONS(nextButtonMask | cancelButtonMask);
Don Gagne's avatar
Don Gagne committed
345 346 347 348
    
    // Try setting a min/max value that is below the threshold to make sure min/max doesn't go valid
    _mockUAS->emitRemoteControlChannelRawChanged(0, (float)(PX4RCCalibration::_rcCalPWMValidMinValue + 1));
    _mockUAS->emitRemoteControlChannelRawChanged(0, (float)(PX4RCCalibration::_rcCalPWMValidMaxValue - 1));
Don Gagne's avatar
Don Gagne committed
349 350 351 352
    QCOMPARE(_rgValueWidget[0]->isMinValid(), false);
    QCOMPARE(_rgValueWidget[0]->isMaxValid(), false);
    
    // Send min/max values switch channels
353
    for (int chan=0; chan<_availableChannels; chan++) {
Don Gagne's avatar
Don Gagne committed
354 355 356
        //qDebug() << chan << _rgChannelSettingsPreValidate[chan].rcMin << _rgChannelSettingsPreValidate[chan].rcMax;
        _mockUAS->emitRemoteControlChannelRawChanged(chan, _rgChannelSettings[chan].rcMin);
        _mockUAS->emitRemoteControlChannelRawChanged(chan, _rgChannelSettings[chan].rcMax);
357
    }
Don Gagne's avatar
Don Gagne committed
358
    
Don Gagne's avatar
Don Gagne committed
359
    _channelHomePosition();
360

Don Gagne's avatar
Don Gagne committed
361 362 363
    int saveStep = _calWidget->_currentStep;
    QTest::mouseClick(_nextButton, Qt::LeftButton);
    QCOMPARE(_calWidget->_currentStep, saveStep + 1);
364 365
}

Don Gagne's avatar
Don Gagne committed
366
void PX4RCCalibrationTest::_flapsDetectStep(void)
367
{
Don Gagne's avatar
Don Gagne committed
368
    int channel = _rgFunctionChannelMap[PX4RCCalibration::rcCalFunctionFlaps];
369
    
Don Gagne's avatar
Don Gagne committed
370
    //qDebug() << "_flapsDetectStep channel" << channel;
371
    
Don Gagne's avatar
Don Gagne committed
372 373
    // Test code can't handle reversed flaps channel
    Q_ASSERT(!_rgChannelSettings[channel].reversed);
374
    
Don Gagne's avatar
Don Gagne committed
375 376 377
    CHK_BUTTONS(nextButtonMask | cancelButtonMask | skipButtonMask);
    
    int saveStep = _calWidget->_currentStep;
378

Don Gagne's avatar
Don Gagne committed
379 380 381
    // Wiggle channel to identify
    _stickMoveWaitForSettle(channel, _testMaxValue);
    _stickMoveWaitForSettle(channel, _testMinValue);
382
    
Don Gagne's avatar
Don Gagne committed
383 384
    // Leave channel on full flaps down
    _stickMoveWaitForSettle(channel, _testMaxValue);
385
    
Don Gagne's avatar
Don Gagne committed
386 387 388 389 390
    // User has to hit next at this step
    QCOMPARE(_calWidget->_currentStep, saveStep);
    CHK_BUTTONS(nextButtonMask | cancelButtonMask | skipButtonMask);
    QTest::mouseClick(_nextButton, Qt::LeftButton);
    QCOMPARE(_calWidget->_currentStep, saveStep + 1);
391 392
}

Don Gagne's avatar
Don Gagne committed
393
void PX4RCCalibrationTest::_switchSelectAutoStep(const char* functionStr, PX4RCCalibration::rcCalFunctions function)
394
{
Don Gagne's avatar
Don Gagne committed
395 396
    Q_UNUSED(functionStr);
    //qDebug() << "_switchSelectAutoStep" << functionStr << "function:" << function;
397
    
Don Gagne's avatar
Don Gagne committed
398 399 400
    int buttonMask = cancelButtonMask;
    if (function != PX4RCCalibration::rcCalFunctionModeSwitch) {
        buttonMask |= skipButtonMask;
Don Gagne's avatar
Don Gagne committed
401 402
    }
    
Don Gagne's avatar
Don Gagne committed
403
    CHK_BUTTONS(buttonMask);
Don Gagne's avatar
Don Gagne committed
404
    
Don Gagne's avatar
Don Gagne committed
405
    int saveStep = _calWidget->_currentStep;
406
    
Don Gagne's avatar
Don Gagne committed
407 408 409 410 411 412
    // Wiggle stick for channel
    int channel = _rgFunctionChannelMap[function];
    _mockUAS->emitRemoteControlChannelRawChanged(channel, _testMinValue);
    _mockUAS->emitRemoteControlChannelRawChanged(channel, _testMaxValue);
    
    QCOMPARE(_calWidget->_currentStep, saveStep + 1);
413 414
}

Don Gagne's avatar
Don Gagne committed
415
void PX4RCCalibrationTest::_fullCalibration_test(void)
416
{
Don Gagne's avatar
Don Gagne committed
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
    
    _channelHomePosition();
    QTest::mouseClick(_nextButton, Qt::LeftButton);    
    _beginCalibration();
    _stickMoveAutoStep("Throttle", PX4RCCalibration::rcCalFunctionThrottle, moveToMax, true /* identify step */);
    _stickMoveAutoStep("Throttle", PX4RCCalibration::rcCalFunctionThrottle, moveToMin, false /* not identify step */);
    _stickMoveAutoStep("Yaw", PX4RCCalibration::rcCalFunctionYaw, moveToMax, true /* identify step */);
    _stickMoveAutoStep("Yaw", PX4RCCalibration::rcCalFunctionYaw, moveToMin, false /* not identify step */);
    _stickMoveAutoStep("Roll", PX4RCCalibration::rcCalFunctionRoll, moveToMax, true /* identify step */);
    _stickMoveAutoStep("Roll", PX4RCCalibration::rcCalFunctionRoll, moveToMin, false /* not identify step */);
    _stickMoveAutoStep("Pitch", PX4RCCalibration::rcCalFunctionPitch, moveToMax, true /* identify step */);
    _stickMoveAutoStep("Pitch", PX4RCCalibration::rcCalFunctionPitch, moveToMin, false /* not identify step */);
    _stickMoveAutoStep("Pitch", PX4RCCalibration::rcCalFunctionPitch, moveToCenter, false /* not identify step */);
    _switchMinMaxStep();
    _flapsDetectStep();
    _stickMoveAutoStep("Flaps", PX4RCCalibration::rcCalFunctionFlaps, moveToMin, false /* not identify step */);
    _switchSelectAutoStep("Mode", PX4RCCalibration::rcCalFunctionModeSwitch);
    _switchSelectAutoStep("PostCtl", PX4RCCalibration::rcCalFunctionPosCtlSwitch);
    _switchSelectAutoStep("Loiter", PX4RCCalibration::rcCalFunctionLoiterSwitch);
    _switchSelectAutoStep("Return", PX4RCCalibration::rcCalFunctionReturnSwitch);
    _switchSelectAutoStep("Aux1", PX4RCCalibration::rcCalFunctionAux1);
    _switchSelectAutoStep("Aux2", PX4RCCalibration::rcCalFunctionAux2);
439 440 441

    // One more click and the parameters should get saved
    QTest::mouseClick(_nextButton, Qt::LeftButton);
Don Gagne's avatar
Don Gagne committed
442
    _validateParameters();
443 444
}

Don Gagne's avatar
Don Gagne committed
445 446
/// @brief Sets rc input to Throttle down home position. Centers all other channels.
void PX4RCCalibrationTest::_channelHomePosition(void)
447
{
Don Gagne's avatar
Don Gagne committed
448
    // Initialize available channels to center point.
Don Gagne's avatar
Don Gagne committed
449
    for (int i=0; i<_availableChannels; i++) {
450 451
        _mockUAS->emitRemoteControlChannelRawChanged(i, (float)PX4RCCalibration::_rcCalPWMCenterPoint);
    }
Don Gagne's avatar
Don Gagne committed
452 453 454
    
    // Throttle to low position (throttle is not reversed)/
    _mockUAS->emitRemoteControlChannelRawChanged(_rgFunctionChannelMap[PX4RCCalibration::rcCalFunctionThrottle], _testMinValue);
455 456
}

Don Gagne's avatar
Don Gagne committed
457
void PX4RCCalibrationTest::_validateParameters(void)
458 459 460 461 462 463 464 465 466
{
    MockQGCUASParamManager* paramMgr = _mockUAS->getMockQGCUASParamManager();
    MockQGCUASParamManager::ParamMap_t mapParamsSet = paramMgr->getMockSetParameters();

    QString minTpl("RC%1_MIN");
    QString maxTpl("RC%1_MAX");
    QString trimTpl("RC%1_TRIM");
    QString revTpl("RC%1_REV");
    
Don Gagne's avatar
Don Gagne committed
467 468 469 470 471 472 473 474 475 476 477 478 479 480
    // Check mapping for all fuctions
    for (int chanFunction=0; chanFunction<PX4RCCalibration::rcCalFunctionMax; chanFunction++) {
        int chanIndex = _rgFunctionChannelMap[chanFunction];
        
        int expectedParameterValue;
        if (chanIndex == -1) {
            expectedParameterValue = 0;  // 0 signals no mapping
        } else {
            expectedParameterValue = chanIndex + 1; // 1-based parameter value
        }
        
        QCOMPARE(mapParamsSet.contains(PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName), true);
        QCOMPARE(mapParamsSet[PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName].toInt(), expectedParameterValue);
    }
Don Gagne's avatar
Don Gagne committed
481 482 483 484 485 486 487

    // Validate the channel settings. Note the channels are 1-based in parameter names.
    for (int chan = 0; chan<PX4RCCalibration::_chanMax; chan++) {
        int oneBasedChannel = chan + 1;
        bool convertOk;
        
        // Required channels have min/max set on them. Remaining channels are left to default.
Don Gagne's avatar
Don Gagne committed
488 489 490 491 492 493 494 495 496
		int rcMinExpected = _rgChannelSettingsValidate[chan].rcMin;
		int rcMaxExpected = _rgChannelSettingsValidate[chan].rcMax;
		int rcTrimExpected = _rgChannelSettingsValidate[chan].rcTrim;
        bool rcReversedExpected = _rgChannelSettingsValidate[chan].reversed;

        QCOMPARE(mapParamsSet.contains(minTpl.arg(oneBasedChannel)), true);
        QCOMPARE(mapParamsSet.contains(maxTpl.arg(oneBasedChannel)), true);
        QCOMPARE(mapParamsSet.contains(trimTpl.arg(oneBasedChannel)), true);
        QCOMPARE(mapParamsSet.contains(revTpl.arg(oneBasedChannel)), true);
Don Gagne's avatar
Don Gagne committed
497
        
Don Gagne's avatar
Don Gagne committed
498 499 500 501 502 503 504 505 506 507 508 509
        int rcMinActual = mapParamsSet[minTpl.arg(oneBasedChannel)].toInt(&convertOk);
        QCOMPARE(convertOk, true);
        int rcMaxActual = mapParamsSet[maxTpl.arg(oneBasedChannel)].toInt(&convertOk);
        QCOMPARE(convertOk, true);
        int rcTrimActual = mapParamsSet[trimTpl.arg(oneBasedChannel)].toInt(&convertOk);
        QCOMPARE(convertOk, true);
        float rcReversedFloat = mapParamsSet[revTpl.arg(oneBasedChannel)].toFloat(&convertOk);
        QCOMPARE(convertOk, true);
        bool rcReversedActual = (rcReversedFloat == -1.0f);
        
        //qDebug() << "_validateParemeters expected channel:min:max:trim:rev" << chan << rcMinExpected << rcMaxExpected << rcTrimExpected << rcReversedExpected;
        //qDebug() << "_validateParemeters actual channel:min:max:trim:rev" << chan << rcMinActual << rcMaxActual << rcTrimActual << rcReversedActual;
510

Don Gagne's avatar
Don Gagne committed
511 512 513 514
        QCOMPARE(rcMinExpected, rcMinActual);
        QCOMPARE(rcMaxExpected, rcMaxActual);
        QCOMPARE(rcTrimExpected, rcTrimActual);
        QCOMPARE(rcReversedExpected, rcReversedActual);
515 516
    }
    
Don Gagne's avatar
Don Gagne committed
517 518 519
    // Check mapping for all fuctions
    for (int chanFunction=0; chanFunction<PX4RCCalibration::rcCalFunctionMax; chanFunction++) {
        QCOMPARE(mapParamsSet.contains(PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName), true);
520

Don Gagne's avatar
Don Gagne committed
521 522 523 524 525
        int expectedValue;
        if (_rgFunctionChannelMap[chanFunction] == -1) {
            expectedValue = 0;  // 0 signals no mapping
        } else {
            expectedValue = _rgFunctionChannelMap[chanFunction] + 1; // 1-based
526
        }
Don Gagne's avatar
Don Gagne committed
527 528
        // qDebug() << chanFunction << expectedValue << mapParamsSet[PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName].toInt();
        QCOMPARE(mapParamsSet[PX4RCCalibration::_rgFunctionInfo[chanFunction].parameterName].toInt(), expectedValue);
529
    }
Don Gagne's avatar
Don Gagne committed
530
}