CorridorScanComplexItemTest.cc 9.21 KB
Newer Older
1 2
/****************************************************************************
 *
Gus Grubba's avatar
Gus Grubba committed
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8 9 10 11 12 13 14
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "CorridorScanComplexItemTest.h"
#include "QGCApplication.h"

CorridorScanComplexItemTest::CorridorScanComplexItemTest(void)
{
15 16 17
    _polyLineVertices.append(QGeoCoordinate(47.633550640000003, -122.08982199));
    _polyLineVertices.append(_polyLineVertices[0].atDistanceAndAzimuth(_corridorLineSegmentDistance, 0));
    _polyLineVertices.append(_polyLineVertices[1].atDistanceAndAzimuth(_corridorLineSegmentDistance, 20));
18 19 20 21
}

void CorridorScanComplexItemTest::init(void)
{
22
    TransectStyleComplexItemTestBase::init();
23

24
    _corridorItem = new CorridorScanComplexItem(_masterController, false /* flyView */, QString() /* kmlFile */, this /* parent */);
25 26 27 28 29 30 31 32 33
    _corridorItem->corridorPolyline()->appendVertices(_polyLineVertices);

    // Setup for expected transect count
    _corridorItem->corridorWidth()->setRawValue(_corridorWidth);
    _corridorItem->cameraCalc()->adjustedFootprintSide()->setRawValue((_corridorWidth * 0.5) + 1.0);
    _corridorItem->cameraCalc()->adjustedFootprintFrontal()->setRawValue(_corridorLineSegmentDistance * 0.25);

    int expectedTransectCount = _expectedTransectCount;
    QCOMPARE(_corridorItem->_transectCount(), expectedTransectCount);
34 35 36 37 38 39

    // vehicleSpeed need for terrain calcs
    MissionController::MissionFlightStatus_t missionFlightStatus;
    missionFlightStatus.vehicleSpeed = 5;
    _corridorItem->setMissionFlightStatus(missionFlightStatus);

40 41 42 43 44
    _corridorItem->setDirty(false);

    _rgCorridorPolygonSignals[corridorPolygonPathChangedIndex] = SIGNAL(pathChanged());

    _multiSpyCorridorPolygon = new MultiSignalSpy();
45
    QCOMPARE(_multiSpyCorridorPolygon->init(_corridorItem->surveyAreaPolygon(), _rgCorridorPolygonSignals, _cCorridorPolygonSignals), true);
46 47 48 49 50
}

void CorridorScanComplexItemTest::cleanup(void)
{
    delete _corridorItem;
51
    TransectStyleComplexItemTestBase::cleanup();
52 53 54 55
}

void CorridorScanComplexItemTest::_testDirty(void)
{
56 57 58
    Fact* fact = _corridorItem->corridorWidth();
    fact->setRawValue(fact->rawValue().toDouble() + 1);
    QVERIFY(_corridorItem->dirty());
59 60
    _corridorItem->setDirty(false);

61
    changeFactValue(_corridorItem->cameraCalc()->distanceToSurface());
62 63 64
    QVERIFY(_corridorItem->dirty());
    _corridorItem->setDirty(false);

65 66 67 68 69
    QGeoCoordinate coord = _corridorItem->corridorPolyline()->vertexCoordinate(0);
    coord.setLatitude(coord.latitude() + 1);
    _corridorItem->corridorPolyline()->adjustVertex(1, coord);
    QVERIFY(_corridorItem->dirty());
    _corridorItem->setDirty(false);
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
}

void CorridorScanComplexItemTest::_testCameraTrigger(void)
{
#if 0
    QCOMPARE(_corridorItem->property("cameraTrigger").toBool(), true);

    // Set up a grid

    for (int i=0; i<3; i++) {
        _mapPolyline->appendVertex(_linePoints[i]);
    }

    _corridorItem->setDirty(false);
    _multiSpy->clearAllSignals();

    int lastSeq = _corridorItem->lastSequenceNumber();
    QVERIFY(lastSeq > 0);

    // Turning off camera triggering should remove two camera trigger mission items, this should trigger:
    //      lastSequenceNumberChanged
    //      dirtyChanged

    _corridorItem->setProperty("cameraTrigger", false);
    QVERIFY(_multiSpy->checkOnlySignalByMask(lastSequenceNumberChangedMask | dirtyChangedMask | cameraTriggerChangedMask));
    QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq - 2);

    _corridorItem->setDirty(false);
    _multiSpy->clearAllSignals();

    // Turn on camera triggering and make sure things go back to previous count

    _corridorItem->setProperty("cameraTrigger", true);
    QVERIFY(_multiSpy->checkOnlySignalByMask(lastSequenceNumberChangedMask | dirtyChangedMask | cameraTriggerChangedMask));
    QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq);
#endif
}

#if 0
void CorridorScanComplexItemTest::_testEntryLocation(void)
{
    _setPolygon();

    for (double gridAngle=-360.0; gridAngle<=360.0; gridAngle++) {
        _corridorItem->gridAngle()->setRawValue(gridAngle);

        QList<QGeoCoordinate> rgSeenEntryCoords;
        QList<int> rgEntryLocation;
118 119 120 121
        rgEntryLocation << SurveyComplexItem::EntryLocationTopLeft
                        << SurveyComplexItem::EntryLocationTopRight
                        << SurveyComplexItem::EntryLocationBottomLeft
                        << SurveyComplexItem::EntryLocationBottomRight;
122 123 124 125 126 127 128 129 130 131 132 133 134 135

        // Validate that each entry location is unique
        for (int i=0; i<rgEntryLocation.count(); i++) {
            int entryLocation = rgEntryLocation[i];

            _corridorItem->gridEntryLocation()->setRawValue(entryLocation);
            QVERIFY(!rgSeenEntryCoords.contains(_corridorItem->coordinate()));
            rgSeenEntryCoords << _corridorItem->coordinate();
        }
        rgSeenEntryCoords.clear();
    }
}
#endif

136 137 138 139
void CorridorScanComplexItemTest::_waitForReadyForSave(void)
{
    int loops = 0;
    while (loops++ < 8) {
DonLakeFlyer's avatar
DonLakeFlyer committed
140
        if (_corridorItem->readyForSaveState() == CorridorScanComplexItem::ReadyForSave) {
141 142 143 144 145 146 147
            return;
        }
        QTest::qWait(500);
    }
    QVERIFY(false);
}

148 149
void CorridorScanComplexItemTest::_testItemCount(void)
{
150 151 152 153 154 155 156 157 158 159 160 161
    typedef struct {
        bool triggerInTurnAround;
        bool hasTurnaround;
    } TestCase_t;

    static const TestCase_t rgTestCases[] = {
        { false,    false },
        { false,    false },
        { false,    true },
        { false,    true },
    };

162
    QList<MissionItem*> items;
163 164 165 166 167 168 169 170 171
    for (const TestCase_t& testCase : rgTestCases) {
        qDebug() << "triggerInTurnAround:hasTurnaround" << testCase.triggerInTurnAround << testCase.hasTurnaround;
        _corridorItem->cameraTriggerInTurnAround()->setRawValue(testCase.triggerInTurnAround);
        _corridorItem->turnAroundDistance()->setRawValue(testCase.hasTurnaround ? 50 : 0);
        _corridorItem->appendMissionItems(items, this);
        QCOMPARE(items.count() - 1, _corridorItem->lastSequenceNumber());
        items.clear();
    }
}
172

173 174 175 176 177
void CorridorScanComplexItemTest::_testPathChanges(void)
{
     QGeoCoordinate vertex = _corridorItem->corridorPolyline()->vertexCoordinate(1);
     vertex.setLatitude(vertex.latitude() + 0.01);
     _corridorItem->corridorPolyline()->adjustVertex(1, vertex);
178

179 180
     QVERIFY(_multiSpyCorridorPolygon->checkSignalsByMask(corridorPolygonPathChangedMask));
}
181

182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
QList<MAV_CMD> CorridorScanComplexItemTest::_createExpectedCommands(bool hasTurnaround, bool useConditionGate)
{
    static const QList<MAV_CMD> singleFullTransect = {
        MAV_CMD_NAV_WAYPOINT,           // Turnaround
        MAV_CMD_CONDITION_GATE,         // Survey area entry edge
        MAV_CMD_DO_SET_CAM_TRIGG_DIST,
        MAV_CMD_NAV_WAYPOINT,           // Polyline turn
        MAV_CMD_CONDITION_GATE,         // Survey area exit edge
        MAV_CMD_DO_SET_CAM_TRIGG_DIST,
        MAV_CMD_NAV_WAYPOINT,           // Turnaround
    };

    QList<MAV_CMD> singleTransect = singleFullTransect;
    QList<MAV_CMD> expectedCommands;

    if (!useConditionGate) {
        for (MAV_CMD& cmd : singleTransect) {
            cmd = cmd == MAV_CMD_CONDITION_GATE ? MAV_CMD_NAV_WAYPOINT : cmd;
        }
    }
202

203 204 205 206
    if (!hasTurnaround) {
        singleTransect.takeFirst();
        singleTransect.takeLast();
    }
207

208 209 210
    for (int i=0; i<_expectedTransectCount; i++) {
        expectedCommands.append(singleTransect);
    }
211

212 213
    return expectedCommands;
}
214 215 216



217 218 219 220 221 222 223 224 225
void CorridorScanComplexItemTest::_testItemGenerationWorker(bool imagesInTurnaround, bool hasTurnaround, bool useConditionGate, const QList<MAV_CMD>& expectedCommands)
{
    qDebug() << QStringLiteral("_testItemGenerationWorker imagesInTuraround:%1 turnaround:%2 gate:%3").arg(imagesInTurnaround).arg(hasTurnaround).arg(useConditionGate);

    _corridorItem->turnAroundDistance()->setRawValue(hasTurnaround ? 50 : 0);
    _corridorItem->cameraTriggerInTurnAround()->setRawValue(imagesInTurnaround);
    _planViewSettings->useConditionGate()->setRawValue(useConditionGate);

    QList<MissionItem*> items;
226
    _corridorItem->appendMissionItems(items, this);
227 228 229 230 231 232 233 234
    //_printItemCommands(items);
    QCOMPARE(items.count(), expectedCommands.count());
    for (int i=0; i<expectedCommands.count(); i++) {
        int actualCommand = items[i]->command();
        int expectedCommand = expectedCommands[i];
        //qDebug() << "Index" << i;
        QCOMPARE(actualCommand, expectedCommand);
    }
235 236
}

237
void CorridorScanComplexItemTest::_testItemGeneration(void)
238
{
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
    // Test all the combinations of: cameraTriggerInTurnAround: false, hasTurnAround: *, useConditionGate: *

    typedef struct {
        bool        hasTurnaround;
        bool        useConditionGate;
    } TestCase_t;

    static const TestCase_t rgTestCases[] = {
        { false,    false },
        { false,    true },
        { true,     false },
        { true,     true },
    };

    for (const TestCase_t& testCase : rgTestCases) {
        _testItemGenerationWorker(false /* imagesInTurnaround */, testCase.hasTurnaround, testCase.useConditionGate, _createExpectedCommands(testCase.hasTurnaround, testCase.useConditionGate));
    }
256
}
257