blob: fe32763229bca2bb28bfc8eb4b62ff09c223a726 [file] [log] [blame]
Brian Silvermand8f403a2014-12-13 19:12:04 -05001#ifndef FRC971_WPILIB_LOOP_OUTPUT_HANDLER_H_
2#define FRC971_WPILIB_LOOP_OUTPUT_HANDLER_H_
3
4#include "aos/common/scoped_fd.h"
5#include "aos/common/time.h"
6#include "aos/common/util/log_interval.h"
7
8#include <atomic>
9
10namespace frc971 {
11namespace wpilib {
12
13// Handles sending the output from a single control loop to the hardware.
14//
15// This class implements stopping motors when no new values are received for too
16// long efficiently.
17//
18// The intended use is to have a subclass for each loop which implements the
19// pure virtual methods and is then run in a separate thread. The operator()
20// loops writing values until Quit() is called.
21class LoopOutputHandler {
22 public:
23 LoopOutputHandler();
24
25 void Quit() { run_ = false; }
26
27 void operator()();
28
29 protected:
30 // Read a message from the appropriate queue.
31 // This must block.
32 virtual void Read() = 0;
33
34 // Send the output from the appropriate queue to the hardware.
35 // Read() will always be called at least once before per invocation of this.
36 virtual void Write() = 0;
37
38 // Stop all outputs. This will be called in a separate thread (if at all).
39 // The subclass implementation should handle any appropriate logging.
40 // This will be called exactly once if Read() blocks for too long and once
41 // after Quit is called.
42 virtual void Stop() = 0;
43
44 private:
45 // The thread that actually contains a timerfd to implement timeouts. The
46 // idea is to have a timerfd that is repeatedly set to the timeout expiration
47 // in the future so it will never actually expire unless it is not reset for
48 // too long.
49 //
50 // This class nicely encapsulates the raw fd and manipulating it. Its
51 // operator() loops until Quit() is called, calling Stop() on its associated
52 // LoopOutputHandler whenever the timerfd expires.
53 class Watchdog {
54 public:
55 Watchdog(LoopOutputHandler *handler);
56
57 void operator()();
58
59 void Reset();
60
61 void Quit() { run_ = false; }
62
63 private:
64 LoopOutputHandler *const handler_;
65
66 ::aos::ScopedFD timerfd_;
67
68 ::std::atomic<bool> run_{true};
69 };
70
71 static constexpr ::aos::time::Time kStopTimeout =
72 ::aos::time::Time::InSeconds(0.02);
73
74 Watchdog watchdog_;
75
76 ::std::atomic<bool> run_{true};
77
Brian Silverman699f0cb2015-02-05 19:45:01 -050078 ::aos::util::SimpleLogInterval no_joystick_state_ =
Brian Silvermand8f403a2014-12-13 19:12:04 -050079 ::aos::util::SimpleLogInterval(::aos::time::Time::InSeconds(0.5), INFO,
Brian Silverman699f0cb2015-02-05 19:45:01 -050080 "no joystick state -> not outputting");
81 ::aos::util::SimpleLogInterval fake_joystick_state_ =
Brian Silvermand8f403a2014-12-13 19:12:04 -050082 ::aos::util::SimpleLogInterval(::aos::time::Time::InSeconds(0.5), DEBUG,
Brian Silverman699f0cb2015-02-05 19:45:01 -050083 "fake joystick state -> not outputting");
Brian Silvermand8f403a2014-12-13 19:12:04 -050084};
85
86} // namespace wpilib
87} // namespace frc971
88
89#endif // FRC971_WPILIB_LOOP_OUTPUT_HANDLER_H_