WimaController.cc 9.75 KB
Newer Older
1 2
#include "WimaController.h"

3 4
const char* WimaController::wimaFileExtension = "wima";

5 6 7 8
WimaController::WimaController(QObject *parent) :
    QObject             (parent)
  ,_planView            (true)
  ,_visualItems         (new QmlObjectListModel(parent))
9
  ,_currentPolygonIndex (-1)
10 11 12 13
{
    connect(this, &WimaController::currentPolygonIndexChanged, this, &WimaController::recalcPolygonInteractivity);
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
14 15 16 17 18 19 20 21 22 23
QStringList WimaController::loadNameFilters() const
{
    QStringList filters;

    filters << tr("Supported types (*.%1)").arg(wimaFileExtension) <<
               tr("All Files (*.*)");
    return filters;

}

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
void WimaController::setMasterController(PlanMasterController *masterC)
{
    _masterController = masterC;
    emit masterControllerChanged();
}

void WimaController::setMissionController(MissionController *missionC)
{
    _missionController = missionC;
    emit missionControllerChanged();
}

void WimaController::setCurrentPolygonIndex(int index)
{
    if(index >= 0 && index < _visualItems->count() && index != _currentPolygonIndex){
        _currentPolygonIndex = index;

        emit currentPolygonIndexChanged(index);
    }
}

void WimaController::removeArea(int index)
{
    if(index >= 0 && index < _visualItems->count()){
        _visualItems->removeAt(index);

        emit visualItemsChanged();

52 53 54 55 56 57 58
        if (_visualItems->count() == 0) {
            // this branch is reached if all items are removed
            // to guarentee proper behavior, _currentPolygonIndex must be set to a invalid value, as on constructor init.
            _currentPolygonIndex = -1;
            return;
        }

59 60 61 62 63 64 65 66 67 68 69
        if(_currentPolygonIndex >= _visualItems->count()){
            setCurrentPolygonIndex(_visualItems->count() - 1);
        }else{
            recalcPolygonInteractivity(_currentPolygonIndex);
        }
    }else{
        qWarning("Index out of bounds!");
    }

}

70 71 72 73 74 75 76 77 78
void WimaController::addGOperationArea()
{
    WimaGOperationArea* newPoly = new WimaGOperationArea(this);
    _visualItems->append(newPoly);
    int newIndex = _visualItems->count()-1;
    setCurrentPolygonIndex(newIndex);
    emit visualItemsChanged();
}

79 80 81 82
void WimaController::addServiceArea()
{
    WimaServiceArea* newPoly = new WimaServiceArea(this);
    _visualItems->append(newPoly);
83 84
    int newIndex = _visualItems->count()-1;
    setCurrentPolygonIndex(newIndex);
85 86 87
    emit visualItemsChanged();
}

88
void WimaController::addVehicleCorridor()
89
{
90 91 92 93 94
    WimaVCorridor* corridor = new WimaVCorridor(this);
    _visualItems->append(corridor);
    int newIndex = _visualItems->count()-1;
    setCurrentPolygonIndex(newIndex);
    emit visualItemsChanged();
95 96
}

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
void WimaController::startMission()
{

}

void WimaController::abortMission()
{

}

void WimaController::pauseMission()
{

}

void WimaController::resumeMission()
{

}

117 118
bool WimaController::updateMission()
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
119
    #define debug 0
120
    // pick first WimaGOperationArea
121 122 123 124 125 126 127 128
    WimaGOperationArea* opArea = nullptr;
    for (int i = 0; i < _visualItems->count(); i++) {
        WimaGOperationArea* currentArea = qobject_cast<WimaGOperationArea*>(_visualItems->get(i));
        if (currentArea != nullptr){
            opArea = currentArea;
            break;
        }
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
129 130
    if (opArea == nullptr)
        return false;
131

132
    // pick first WimaServiceArea
133 134 135 136 137 138 139 140
    WimaServiceArea* serArea = nullptr;
    for (int i = 0; i < _visualItems->count(); i++) {
        WimaServiceArea* currentArea = qobject_cast<WimaServiceArea*>(_visualItems->get(i));
        if (currentArea != nullptr){
            serArea = currentArea;
            break;
        }
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
141 142
    if ( serArea == nullptr )
        return false;
143

144 145 146 147 148 149 150
    // pick first WimaVCorridor
    WimaVCorridor* corridor = nullptr;
    for (int i = 0; i < _visualItems->count(); i++) {
        WimaVCorridor* currentArea = qobject_cast<WimaVCorridor*>(_visualItems->get(i));
        if (currentArea != nullptr){
            corridor = currentArea;
            break;
151 152
        }
    }
153
    // join service area and op area
Valentin Platzgummer's avatar
Valentin Platzgummer committed
154
    WimaArea joinedArea;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
155
    if (corridor != nullptr) {
156 157
        WimaArea::join(*corridor, *serArea, joinedArea);
        joinedArea.join(*opArea);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
158
    } else {
Valentin Platzgummer's avatar
Valentin Platzgummer committed
159
        WimaArea::join(*serArea, *opArea, joinedArea);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
160 161
    }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
162 163 164 165
    #if debug
        WimaArea* joinedAreaPt = new WimaArea(joinedArea, this);
        _visualItems->append(joinedAreaPt);
    #endif
166

Valentin Platzgummer's avatar
Valentin Platzgummer committed
167 168


169 170 171 172 173 174 175 176 177 178
    // reset visual items
    _missionController->removeAll();
    QmlObjectListModel* missionItems = _missionController->visualItems();
    // set home position to serArea center
    MissionSettingsItem* settingsItem= qobject_cast<MissionSettingsItem*>(missionItems->get(0));
    if (settingsItem == nullptr){
        qWarning("WimaController::updateMission(): settingsItem == nullptr");
        return false;
    }
    settingsItem->setCoordinate(serArea->center());
Valentin Platzgummer's avatar
Valentin Platzgummer committed
179 180 181 182 183

    // create take off position item
    int index = 1;
    _missionController->insertSimpleMissionItem(serArea->center(), index++);

184
    // create survey item, will be extened with more mission types in the future
Valentin Platzgummer's avatar
Valentin Platzgummer committed
185
    _missionController->insertComplexMissionItem(_missionController->surveyComplexItemName(), opArea->center(), index++);
186 187 188
    SurveyComplexItem* survey = qobject_cast<SurveyComplexItem*>(missionItems->get(missionItems->count()-1));
    if (survey == nullptr){
        qWarning("WimaController::updateMission(): survey == nullptr");
189
        return false;
190 191 192 193
    } else {
        survey->surveyAreaPolygon()->clear();
        survey->surveyAreaPolygon()->appendVertices(opArea->coordinateList());
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
194 195 196 197 198

    // calculate path from take off to opArea
    QGeoCoordinate start = serArea->center();
    QGeoCoordinate end = survey->visualTransectPoints().first().value<QGeoCoordinate>();
    QList<QGeoCoordinate> path;
199
    WimaArea::dijkstraPath(start, end, joinedArea, path);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
200 201 202 203 204 205 206 207 208
    for (int i = 1; i < path.count()-1; i++) {
        _missionController->insertSimpleMissionItem(path.value(i), i+1);
        index++;
    }

    // calculate return path
    start   = survey->visualTransectPoints().last().value<QGeoCoordinate>();
    end     = serArea->center();
    path.clear();
209
    WimaArea::dijkstraPath(start, end, joinedArea, path);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
210 211 212 213
    for (int i = 1; i < path.count()-1; i++) {
        _missionController->insertSimpleMissionItem(path.value(i), index++);
    }

214
    // create land position item
Valentin Platzgummer's avatar
Valentin Platzgummer committed
215
    _missionController->insertSimpleMissionItem(serArea->center(), index++);
216 217 218 219 220 221 222 223 224 225
    SimpleMissionItem* landItem = qobject_cast<SimpleMissionItem*>(missionItems->get(missionItems->count()-1));
    if (landItem == nullptr){
        qWarning("WimaController::updateMission(): landItem == nullptr");
        return false;
    } else {
        Vehicle* controllerVehicle = _masterController->controllerVehicle();
        MAV_CMD landCmd = controllerVehicle->vtol() ? MAV_CMD_NAV_VTOL_LAND : MAV_CMD_NAV_LAND;
        if (controllerVehicle->firmwarePlugin()->supportedMissionCommands().contains(landCmd)) {
            landItem->setCommand(landCmd);
        }
226
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
227

Valentin Platzgummer's avatar
Valentin Platzgummer committed
228 229
    saveToFile("TestFile");

230
    return true;
231 232
}

233
void WimaController::saveToCurrent()
234 235 236 237
{

}

238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
void WimaController::saveToFile(const QString& filename)
{
    if (filename.isEmpty()) {
        return;
    }

    QString planFilename = filename;
    if (!QFileInfo(filename).fileName().contains(".")) {
        planFilename += QString(".%1").arg(wimaFileExtension);
    }

    QFile file(planFilename);

    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qgcApp()->showMessage(tr("Plan save error %1 : %2").arg(filename).arg(file.errorString()));
        _currentFile.clear();
        emit currentFileChanged();
    } else {
        QJsonDocument saveDoc = saveToJson();
        file.write(saveDoc.toJson());
        if(_currentFile != planFilename) {
            _currentFile = planFilename;
            emit currentFileChanged();
        }
    }
}

void WimaController::loadFromFile()
266 267 268 269 270
{

}

void WimaController::recalcVehicleCorridor()
271 272 273
{

}
274 275 276 277 278 279 280 281 282 283 284 285 286

void WimaController::recalcVehicleMeasurementAreas()
{

}

void WimaController::recalcAll()
{

}

void WimaController::recalcPolygonInteractivity(int index)
{
287 288 289 290 291
    if (index >= 0 && index < _visualItems->count()) {
        resetAllInteractive();
        WimaArea* interactivePoly = qobject_cast<WimaArea*>(_visualItems->get(index));
        interactivePoly->setInteractive(true);
    }
292 293
}

294
void WimaController::resetAllInteractive()
295 296
{
    int itemCount = _visualItems->count();
297 298 299 300 301
    if (itemCount > 0){
        for (int i = 0; i < itemCount; i++) {
            WimaArea* iteratorPoly = qobject_cast<WimaArea*>(_visualItems->get(i));
            iteratorPoly->setInteractive(false);
        }
302 303 304
    }
}

305 306 307 308 309
void WimaController::setInteractive()
{
    recalcPolygonInteractivity(_currentPolygonIndex);
}

310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
QJsonDocument WimaController::saveToJson()
{
    QJsonArray jsonArray;

    for (int i = 0; i < _visualItems->count(); i++) {
        QJsonObject json;

        WimaArea* area = qobject_cast<WimaArea*>(_visualItems->get(i));

        if (area == nullptr) {
            qWarning("WimaController::saveToJson(): Internal error, area == nullptr!");
            return QJsonDocument();
        }

        WimaGOperationArea* opArea =  qobject_cast<WimaGOperationArea*>(area);
        if (opArea != nullptr) {
            opArea->saveToJson(json);
            jsonArray.append(json);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
328
            continue;
329 330 331 332 333 334
        }

        WimaServiceArea* serArea =  qobject_cast<WimaServiceArea*>(area);
        if (serArea != nullptr) {
            serArea->saveToJson(json);
            jsonArray.append(json);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
335
            continue;
336 337 338 339 340 341
        }

        WimaVCorridor* corridor =  qobject_cast<WimaVCorridor*>(area);
        if (corridor != nullptr) {
            corridor->saveToJson(json);
            jsonArray.append(json);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
342
            continue;
343 344 345 346 347 348 349 350 351 352 353
        }

        // if non of the obove branches was trigger, type must be WimaArea
        area->saveToJson(json);
        jsonArray.append(json);
    }


    return QJsonDocument(jsonArray);
}

354 355