WimaController.cc 6.48 KB
Newer Older
Valentin Platzgummer's avatar
Valentin Platzgummer committed
1
#include "WimaController.h"
2

Valentin Platzgummer's avatar
Valentin Platzgummer committed
3
#include "utilities.h"
4

5 6 7 8
#include "MissionController.h"
#include "MissionSettingsItem.h"
#include "PlanMasterController.h"
#include "QGCApplication.h"
9
#include "QGCLoggingCategory.h"
10
#include "SettingsManager.h"
11 12
#include "SimpleMissionItem.h"

13 14
#include "WimaBridge.h"
#include "WimaPlanData.h"
15 16
#include "WimaSettings.h"

17
#include "Snake/QNemoHeartbeat.h"
18
#include "Snake/QNemoProgress.h"
19
#include "Snake/SnakeTile.h"
20

21
#include "QVector3D"
22
#include <QScopedPointer>
23

24
#define CLIPPER_SCALE 1000000
25
#include "clipper/clipper.hpp"
26

27 28
#include <memory>

29 30
QGC_LOGGING_CATEGORY(WimaControllerLog, "WimaControllerLog")

Valentin Platzgummer's avatar
Valentin Platzgummer committed
31 32 33 34 35
template <typename T>
constexpr typename std::underlying_type<T>::type integral(T value) {
  return static_cast<typename std::underlying_type<T>::type>(value);
}

36 37 38 39 40 41 42 43
#define EVENT_TIMER_INTERVAL 50        // ms

const char *WimaController::areaItemsName = "AreaItems";
const char *WimaController::missionItemsName = "MissionItems";
const char *WimaController::settingsGroup = "WimaController";
const char *WimaController::enableWimaControllerName = "EnableWimaController";
const char *WimaController::flightSpeedName = "FlightSpeed";
const char *WimaController::altitudeName = "Altitude";
Valentin Platzgummer's avatar
Valentin Platzgummer committed
44

45
WimaController::WimaController(QObject *parent)
46
    : QObject(parent), _joinedArea(), _measurementArea(), _serviceArea(),
47
      _corridor(), _planDataValid(false),
48 49
      _areaInterface(&_measurementArea, &_serviceArea, &_corridor,
                     &_joinedArea),
50
      _WMSettings(), _emptyWM(_WMSettings, _areaInterface),
51
      _rtlWM(_WMSettings, _areaInterface),
52
      _currentWM(&_emptyWM), _WMList{&_emptyWM, &_rtlWM},
53 54 55
      _metaDataMap(FactMetaData::createMapFromJsonFile(
          QStringLiteral(":/json/WimaController.SettingsGroup.json"), this)),
      _enableWimaController(settingsGroup,
56
                            _metaDataMap[enableWimaControllerName]){
57 58 59 60 61
  // PlanData and Progress.
  connect(WimaBridge::instance(), &WimaBridge::planDataChanged, this,
          &WimaController::planDataChangedHandler);
  connect(WimaBridge::instance(), &WimaBridge::progressChanged, this,
          &WimaController::progressChangedHandler);
62 63
}

64
PlanMasterController *WimaController::masterController() {
65
  return _masterController;
66 67 68
}

MissionController *WimaController::missionController() {
69
  return _missionController;
70 71
}

72
QmlObjectListModel *WimaController::visualItems() { return &_areas; }
73 74

QmlObjectListModel *WimaController::missionItems() {
75
  return const_cast<QmlObjectListModel *>(&_currentWM->currentMissionItems());
76 77
}

78
QVariantList WimaController::waypointPath() {
79
  return const_cast<QVariantList &>(_currentWM->currentWaypointsVariant());
80 81
}

82
Fact *WimaController::enableWimaController() { return &_enableWimaController; }
83

84
Fact *WimaController::flightSpeed() { return &_flightSpeed; }
85

86
Fact *WimaController::altitude() { return &_altitude; }
87

88 89 90 91
void WimaController::setMasterController(PlanMasterController *masterC) {
  _masterController = masterC;
  _WMSettings.setMasterController(masterC);
  emit masterControllerChanged();
92 93
}

94 95 96 97
void WimaController::setMissionController(MissionController *missionC) {
  _missionController = missionC;
  _WMSettings.setMissionController(missionC);
  emit missionControllerChanged();
98 99
}

100
bool WimaController::upload() {
101 102 103 104 105 106 107 108 109 110 111
  auto &items = _currentWM->currentMissionItems();
  if (_masterController && _masterController->managerVehicle() &&
      items.count() > 0) {
    if (!_joinedArea.containsCoordinate(
            _masterController->managerVehicle()->coordinate())) {
      emit forceUploadConfirm();
      return false;
    } else {
      return forceUpload();
    }
  } else {
112 113
    return false;
  }
114 115
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
116 117
bool WimaController::_calcShortestPath(const QGeoCoordinate &start,
                                       const QGeoCoordinate &destination,
118 119 120 121 122 123 124 125 126
                                       QVector<QGeoCoordinate> &path) {
  using namespace GeoUtilities;
  using namespace PolygonCalculus;
  QPolygonF polygon2D;
  toCartesianList(_joinedArea.coordinateList(), /*origin*/ start, polygon2D);
  QPointF start2D(0, 0);
  QPointF end2D;
  toCartesian(destination, start, end2D);
  QVector<QPointF> path2D;
127

128 129 130
  bool retVal =
      PolygonCalculus::shortestPath(polygon2D, start2D, end2D, path2D);
  toGeoList(path2D, /*origin*/ start, path);
131

132 133
  return retVal;
}
134

135 136
void WimaController::planDataChangedHandler() {

137 138
  // reset visual items
  _areas.clear();
139 140 141 142
  _measurementArea = WimaMeasurementAreaData();
  _serviceArea = WimaServiceAreaData();
  _corridor = WimaCorridorData();
  _joinedArea = WimaJoinedAreaData();
143
  _planDataValid = false;
144

145 146 147
  emit visualItemsChanged();
  emit missionItemsChanged();
  emit waypointPathChanged();
148

149
  // Extract areas.
150
  auto planData = WimaBridge::instance()->planData();
151

152 153 154 155
  // Measurement Area.
  if (planData.measurementArea().coordinateList().size() >= 3) {
    _measurementArea = planData.measurementArea();
    _areas.append(&_measurementArea);
156

157 158 159 160
    // Service Area.
    if (planData.serviceArea().coordinateList().size() >= 3) {
      _serviceArea = planData.serviceArea();
      _areas.append(&_serviceArea);
161

162 163 164
      _WMSettings.setHomePosition(
          QGeoCoordinate(_serviceArea.depot().latitude(),
                         _serviceArea.depot().longitude(), 0));
165

166 167 168 169
      // Joined Area.
      if (planData.joinedArea().coordinateList().size() >= 3) {
        _joinedArea = planData.joinedArea();
        _areas.append(&_joinedArea);
170

171
        _planDataValid = true;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
172

173 174 175 176 177
        // Corridor.
        if (planData.corridor().coordinateList().size() >= 3) {
          _corridor = planData.corridor();
        }
      }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
178
    }
179
  }
180

181 182 183 184 185 186 187 188
  if (_planDataValid) {
    emit visualItemsChanged();
  } else {
    _areas.clear();
    _measurementArea = WimaMeasurementAreaData();
    _serviceArea = WimaServiceAreaData();
    _corridor = WimaCorridorData();
    _joinedArea = WimaJoinedAreaData();
189
  }
190 191 192 193
}

void WimaController::progressChangedHandler() {
  _measurementArea.setProgress(WimaBridge::instance()->progress());
194
}
195

196
WimaController *WimaController::thisPointer() { return this; }
197

198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
void WimaController::_updateflightSpeed() {
  bool value;
  _WMSettings.setFlightSpeed(_flightSpeed.rawValue().toDouble(&value));
  Q_ASSERT(value);
  (void)value;

  if (!_currentWM->update()) {
    Q_ASSERT(false);
  }

  emit missionItemsChanged();
  emit waypointPathChanged();
}

void WimaController::_updateAltitude() {
  bool value;
  _WMSettings.setAltitude(_altitude.rawValue().toDouble(&value));
  Q_ASSERT(value);
  (void)value;

  if (!_currentWM->update()) {
    Q_ASSERT(false);
  }

  emit missionItemsChanged();
  emit waypointPathChanged();
}