nppilot/roverif/supervisor.cc

99 lines
2.1 KiB
C++
Raw Permalink Normal View History

#include "supervisor.h"
#include "roverif.h"
#include <algorithm>
2013-12-29 21:09:31 +01:00
/* Goals:
2013-12-29 21:09:31 +01:00
* Throttle shutdown on start.
* Throttle shutdown when returning to remote.
* Clear throttle shutdown by going to idle.
* None, Remote, or Pilot is in control.
* Can enter pilot mode when enabled by a switch on the remote.
* Enter pilot mode immediately without shutdowns.
*/
Supervisor::Supervisor()
2013-12-29 21:09:31 +01:00
: in_control_(InControl::Invalid), in_shutdown_(true) {
}
void Supervisor::init() {
2013-12-29 21:09:31 +01:00
change(InControl::Initial);
changed();
}
2013-12-29 21:09:31 +01:00
void Supervisor::update_remote(bool throttle_high, bool pilot_allowed) {
bool old = pilot_allowed_;
2013-12-29 21:09:31 +01:00
throttle_high_ = throttle_high;
pilot_allowed_ = pilot_allowed;
remote_seen_.start(500);
2013-12-29 21:09:31 +01:00
remote_ok_ = true;
check();
2013-12-29 21:09:31 +01:00
if (old != pilot_allowed_) {
changed();
}
}
2013-12-29 21:09:31 +01:00
void Supervisor::update_pilot(bool want_control) {
pilot_wants_ = want_control;
pilot_seen_.start(500);
2013-12-29 21:09:31 +01:00
pilot_ok_ = true;
check();
}
void Supervisor::tick() {
remote_seen_.tick();
pilot_seen_.tick();
if (!remote_seen_.running()) {
remote_ok_ = false;
check();
}
if (!pilot_seen_.running()) {
pilot_ok_ = false;
check();
}
}
void Supervisor::check() {
2013-12-29 21:09:31 +01:00
if (remote_ok_ && pilot_ok_) {
if (pilot_wants_ && pilot_allowed_ && !in_shutdown_) {
change(InControl::Pilot);
} else {
change(InControl::Remote);
}
} else if (remote_ok_) {
2013-12-29 21:09:31 +01:00
change(InControl::Remote);
} else {
2013-12-29 21:09:31 +01:00
change(InControl::None);
}
2013-12-29 21:09:31 +01:00
if (in_control_ == InControl::Remote) {
if (in_shutdown_ && !throttle_high_) {
in_shutdown_ = false;
changed();
}
}
}
2013-12-29 21:09:31 +01:00
void Supervisor::change(InControl next) {
if (in_control_ == InControl::Initial && next == InControl::None) {
// Stay in initial.
} else if (in_control_ != next) {
if (next != InControl::Pilot) {
if (!in_shutdown_) {
shutdown();
}
in_shutdown_ = true;
}
in_control_ = next;
changed();
}
}