StateMachine.cpp 10.6 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
#include "StateMachine.h"

#include "QGCLoggingCategory.h"

#include <QDebug>

const QLoggingCategory &WimaPlanerLog();

namespace wima_planer_detail {

template <typename T>
constexpr typename std::underlying_type<T>::type integral(T value) {
  return static_cast<typename std::underlying_type<T>::type>(value);
}

StateMachine::StateMachine(QObject *parent)
    : QObject(parent), _state(STATE::NEEDS_INIT) {}

STATE StateMachine::state() { return this->_state; }

void StateMachine::updateState(EVENT e) {
  qCDebug(WimaPlanerLog) << "StateMachine::updateState(): event:" << e;
  switch (this->_state) {
  case STATE::NEEDS_INIT:
    switch (e) {
    case EVENT::INIT_DONE:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
29 30
    case EVENT::M_AREA_NOT_READY:
    case EVENT::M_AREA_READY:
31 32 33 34 35 36 37 38
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
39
    case EVENT::MISSION_ITEMS_DESTROYED:
40 41
    case EVENT::SURVEY_UPDATE_TRIGGERED:
    case EVENT::SURVEY_UPDATED:
42
    case EVENT::PATH_CHANGED:
43 44 45 46 47
    case EVENT::PATH_UPDATED:
      break;
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
48 49 50 51 52 53
    }
    break; // STATE::NEEDS_INIT
  case STATE::WAITING_FOR_TILE_UPDATE:
    switch (e) {
    case EVENT::INIT_DONE:
    case EVENT::M_AREA_NOT_READY:
54
      break;
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    case EVENT::M_AREA_READY:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
    case EVENT::MISSION_ITEMS_DESTROYED:
    case EVENT::SURVEY_UPDATE_TRIGGERED:
    case EVENT::SURVEY_UPDATED:
    case EVENT::PATH_CHANGED:
    case EVENT::PATH_UPDATED:
      break;
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
75 76 77 78 79
    }
    break; // STATE::NEEDS_INIT
  case STATE::NEEDS_J_AREA_UPDATE:
    switch (e) {
    case EVENT::INIT_DONE:
80 81 82 83 84
      break;
    case EVENT::M_AREA_NOT_READY:
      setState(STATE::WAITING_FOR_TILE_UPDATE);
      break;
    case EVENT::M_AREA_READY:
85 86 87 88 89 90 91 92 93 94
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
      break;
    case EVENT::J_AREA_UPDATED:
      setState(STATE::NEEDS_SURVEY_UPDATE);
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
95
    case EVENT::MISSION_ITEMS_DESTROYED:
96 97
    case EVENT::SURVEY_UPDATE_TRIGGERED:
    case EVENT::SURVEY_UPDATED:
98
    case EVENT::PATH_CHANGED:
99 100 101 102 103 104 105 106 107 108
    case EVENT::PATH_UPDATED:
      break;
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
    }
    break; // STATE::NEEDS_J_AREA_UPDATE
  case STATE::NEEDS_SURVEY_UPDATE:
    switch (e) {
    case EVENT::INIT_DONE:
109 110 111 112
    case EVENT::M_AREA_NOT_READY:
      setState(STATE::WAITING_FOR_TILE_UPDATE);
      break;
    case EVENT::M_AREA_READY:
113 114 115 116 117 118 119 120 121 122
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
123
    case EVENT::MISSION_ITEMS_DESTROYED:
124 125 126 127 128
      break;
    case EVENT::SURVEY_UPDATE_TRIGGERED:
      setState(STATE::WAITING_FOR_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATED:
129
    case EVENT::PATH_CHANGED:
130 131 132 133 134 135 136 137 138 139
    case EVENT::PATH_UPDATED:
      break;
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
    }
    break; // STATE::NEEDS_SURVEY_UPDATE
  case STATE::WAITING_FOR_SURVEY_UPDATE:
    switch (e) {
    case EVENT::INIT_DONE:
140 141 142 143
    case EVENT::M_AREA_NOT_READY:
      setState(STATE::WAITING_FOR_TILE_UPDATE);
      break;
    case EVENT::M_AREA_READY:
144 145 146 147 148 149 150 151 152 153
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
154
    case EVENT::MISSION_ITEMS_DESTROYED:
155 156 157 158 159 160
      setState(STATE::NEEDS_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATE_TRIGGERED:
      break;
    case EVENT::SURVEY_UPDATED:
      setState(STATE::NEEDS_PATH_UPDATE);
161
    case EVENT::PATH_CHANGED:
162 163 164 165 166 167 168 169 170 171
    case EVENT::PATH_UPDATED:
      break;
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
    }
    break; // STATE::WAYTING_FOR_SURVEY_UPDATE
  case STATE::NEEDS_PATH_UPDATE:
    switch (e) {
    case EVENT::INIT_DONE:
172 173 174 175
    case EVENT::M_AREA_NOT_READY:
      setState(STATE::WAITING_FOR_TILE_UPDATE);
      break;
    case EVENT::M_AREA_READY:
176 177 178 179 180 181 182 183 184 185
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
186
    case EVENT::MISSION_ITEMS_DESTROYED:
187 188 189 190 191 192
      setState(STATE::NEEDS_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATE_TRIGGERED:
      setState(STATE::WAITING_FOR_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATED:
193
    case EVENT::PATH_CHANGED:
194 195 196 197 198 199 200 201 202 203 204 205
      break;
    case EVENT::PATH_UPDATED:
      setState(STATE::UP_TO_DATE);
      break;
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
    }
    break; // STATE::NEEDS_PATH_UPDATE
  case STATE::UP_TO_DATE:
    switch (e) {
    case EVENT::INIT_DONE:
206 207 208 209
    case EVENT::M_AREA_NOT_READY:
      setState(STATE::WAITING_FOR_TILE_UPDATE);
      break;
    case EVENT::M_AREA_READY:
210 211 212 213 214 215 216 217 218 219
    case EVENT::M_AREA_PATH_CHANGED:
    case EVENT::S_AREA_PATH_CHANGED:
    case EVENT::CORRIDOR_PATH_CHANGED:
      setState(STATE::NEEDS_J_AREA_UPDATE);
      break;
    case EVENT::M_AREA_TILES_CHANGED:
    case EVENT::M_AREA_PROGRESS_CHANGED:
    case EVENT::J_AREA_UPDATED:
    case EVENT::DEPOT_CHANGED:
    case EVENT::SURVEY_DESTROYED:
220
    case EVENT::MISSION_ITEMS_DESTROYED:
221 222 223 224 225 226
      setState(STATE::NEEDS_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATE_TRIGGERED:
      setState(STATE::WAITING_FOR_SURVEY_UPDATE);
      break;
    case EVENT::SURVEY_UPDATED:
227
    case EVENT::PATH_CHANGED:
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
      setState(STATE::NEEDS_PATH_UPDATE);
      break;
    case EVENT::PATH_UPDATED:
      break;
      qCCritical(WimaPlanerLog)
          << "StateMachine::updateState: Unknown event: " << e;
      Q_ASSERT(false);
    }
    break; // STATE::UP_TO_DATE
    qCCritical(WimaPlanerLog)
        << "StateMachine::updateState: Unknown state: " << this->_state;
    Q_ASSERT(false);
  }
}

243 244 245
bool StateMachine::upToDate() { return upToDate(this->_state); }

bool StateMachine::surveyReady() { return surveyReady(this->_state); }
246 247 248 249 250 251

void StateMachine::setState(STATE s) {
  if (this->_state != s) {
    auto oldState = this->_state;
    this->_state = s;
    emit stateChanged();
252
    if (upToDate(oldState) != upToDate(s)) {
253 254
      emit upToDateChanged();
    }
255
    if (surveyReady(oldState) != surveyReady(s)) {
256
      emit surveyReadyChanged();
257
    }
258 259 260 261 262
    qCDebug(WimaPlanerLog) << "StateMachine::setState():" << oldState << "->"
                           << s;
  }
}

263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
bool StateMachine::surveyReady(STATE s) {
  // Using a switch to enable compiler checking of used states.
  bool value = false;
  switch (s) {
  case STATE::NEEDS_INIT:
  case STATE::WAITING_FOR_TILE_UPDATE:
  case STATE::NEEDS_J_AREA_UPDATE:
  case STATE::NEEDS_SURVEY_UPDATE:
  case STATE::WAITING_FOR_SURVEY_UPDATE:
    break;
  case STATE::NEEDS_PATH_UPDATE:
  case STATE::UP_TO_DATE:
    value = true;
    break;
  }
  return value;
}

bool StateMachine::upToDate(STATE s) {
  // Using a switch to enable compiler checking of used states.
  bool value = false;
284
  switch (s) {
285 286 287 288 289 290 291 292 293 294 295 296 297
  case STATE::NEEDS_INIT:
  case STATE::WAITING_FOR_TILE_UPDATE:
  case STATE::NEEDS_J_AREA_UPDATE:
  case STATE::NEEDS_SURVEY_UPDATE:
  case STATE::WAITING_FOR_SURVEY_UPDATE:
  case STATE::NEEDS_PATH_UPDATE:
    break;
  case STATE::UP_TO_DATE:
    value = true;
    break;
  }
  return value;
}
298

299 300
QDebug &operator<<(QDebug &ds, STATE s) {
  switch (s) {
301 302 303
  case STATE::NEEDS_INIT:
    ds << "NEEDS_INIT";
    break;
304 305 306
  case STATE::WAITING_FOR_TILE_UPDATE:
    ds << "WAITING_FOR_TILE_UPDATE";
    break;
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
  case STATE::NEEDS_J_AREA_UPDATE:
    ds << "NEEDS_J_AREA_UPDATE";
    break;
  case STATE::NEEDS_SURVEY_UPDATE:
    ds << "NEEDS_SURVEY_UPDATE";
    break;
  case STATE::WAITING_FOR_SURVEY_UPDATE:
    ds << "WAITING_FOR_SURVEY_UPDATE";
    break;
  case STATE::NEEDS_PATH_UPDATE:
    ds << "NEEDS_PATH_UPDATE";
    break;
  case STATE::UP_TO_DATE:
    ds << "UP_TO_DATE";
    break;
  }
  return ds;
}

QDebug &operator<<(QDebug &ds, EVENT s) {
  switch (s) {
  case EVENT::INIT_DONE:
    ds << "INIT_DONE";
    break;
331 332 333 334 335 336
  case EVENT::M_AREA_NOT_READY:
    ds << "M_AREA_NOT_READY";
    break;
  case EVENT::M_AREA_READY:
    ds << "M_AREA_READY";
    break;
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
  case EVENT::M_AREA_PATH_CHANGED:
    ds << "M_AREA_PATH_CHANGED";
    break;
  case EVENT::S_AREA_PATH_CHANGED:
    ds << "S_AREA_PATH_CHANGED";
    break;
  case EVENT::CORRIDOR_PATH_CHANGED:
    ds << "CORRIDOR_PATH_CHANGED";
    break;
  case EVENT::M_AREA_TILES_CHANGED:
    ds << "M_AREA_TILES_CHANGED";
    break;
  case EVENT::M_AREA_PROGRESS_CHANGED:
    ds << "M_AREA_PROGRESS_CHANGED";
    break;
  case EVENT::J_AREA_UPDATED:
    ds << "J_AREA_UPDATED";
    break;
  case EVENT::DEPOT_CHANGED:
    ds << "DEPOT_CHANGED";
    break;
  case EVENT::SURVEY_DESTROYED:
    ds << "SURVEY_DESTROYED";
    break;
361 362 363
  case EVENT::MISSION_ITEMS_DESTROYED:
    ds << "MISSION_ITEMS_DESTROYED";
    break;
364 365 366 367 368 369
  case EVENT::SURVEY_UPDATE_TRIGGERED:
    ds << "SURVEY_UPDATE_TRIGGERED";
    break;
  case EVENT::SURVEY_UPDATED:
    ds << "SURVEY_UPDATED";
    break;
370 371 372
  case EVENT::PATH_CHANGED:
    ds << "PATH_CHANGED";
    break;
373 374 375 376 377 378 379 380
  case EVENT::PATH_UPDATED:
    ds << "PATH_UPDATED";
    break;
  }
  return ds;
}

} // namespace wima_planer_detail