fwt_software/include/fgc/CaptureScheduler.h

64 lines
2.0 KiB
C++

#pragma once
#include "fgc/ICameraSource.h"
#include "fgc/IControlChannel.h"
#include "fgc/IMotorController.h"
#include <functional>
#include <string>
namespace fgc {
// The capture control loop, extracted from the old main() while-loop and
// expressed against the I/O interfaces so it can be unit-tested with mocks.
//
// Each tick():
// 1. polls the control channel (updates control code / target heading,
// echoes the code back as status),
// 2. reads motor telemetry,
// 3. runs the capture cycle: when the configured interval elapses, stops /
// points the gimbal, then software-triggers the cameras.
//
// ControlCode 0 = automatic sweep ("p"); ControlCode 1 = drive to the
// MQTT-supplied target heading ("kd<heading>").
class CaptureScheduler {
public:
// now_ms: monotonic millisecond clock; defaults to steady_clock. Injectable
// for deterministic tests.
CaptureScheduler(IMotorController& motor, ICameraSource& camera,
IControlChannel& channel, double image_rate,
std::function<long long()> now_ms = {});
void setCaptureActive(bool active); // mirrors the old cam_started flag
bool captureActive() const { return capture_active_; }
void setImageRate(double rate); // images per second
double imageRate() const { return image_rate_; }
// Run one iteration of the control logic.
void tick();
// Inspection (mainly for tests).
int controlCode() const { return control_code_; }
std::string targetHeading() const { return target_heading_; }
private:
long long elapsedMs() const;
void resetTimer();
IMotorController& motor_;
ICameraSource& camera_;
IControlChannel& channel_;
std::function<long long()> now_ms_;
double image_rate_;
long long timer_start_ = 0;
bool capture_active_ = false;
int control_code_ = 0;
std::string target_heading_ = "0";
bool trigger_after_stopping_ = false;
};
} // namespace fgc