blob: 8f129b2e6377b0d6330dd310f28a9185917fcb5e [file] [log] [blame]
Stephan Pleines7463f602024-04-03 20:16:54 -07001#include <unistd.h>
2
3#include <iostream>
4
5#include "gflags/gflags.h"
6
7#include "aos/aos_cli_utils.h"
8#include "aos/configuration.h"
9#include "aos/init.h"
10#include "aos/json_to_flatbuffer.h"
11#include "aos/realtime.h"
12
13DEFINE_int32(priority, -1, "If set, the RT priority to run at.");
14DEFINE_double(max_jitter, 5.00,
15 "The max time in seconds between messages before considering the "
16 "camera processes dead.");
17DEFINE_double(grace_period, 10.00,
18 "The grace period at startup before enforcing that messages must "
19 "flow from the camera processes.");
20
21namespace aos {
22
23class State {
24 public:
25 State(aos::EventLoop *event_loop, const Channel *channel)
26 : channel_(channel),
27 channel_name_(aos::configuration::StrippedChannelToString(channel_)) {
28 LOG(INFO) << "Watching for healthy message sends on " << channel_name_;
29
30 event_loop->MakeRawNoArgWatcher(
31 channel_,
32 [this](const aos::Context &context) { HandleMessage(context); });
33
34 timer_handle_ = event_loop->AddTimer(
35 [this, event_loop]() { RunHealthCheck(event_loop); });
36 timer_handle_->set_name("jitter");
37 event_loop->OnRun([this, event_loop]() {
38 timer_handle_->Schedule(
39 event_loop->monotonic_now() +
40 std::chrono::duration_cast<std::chrono::nanoseconds>(
41 std::chrono::duration<double>(FLAGS_grace_period)),
42 std::chrono::milliseconds(1000));
43 });
44 }
45
46 void HandleMessage(const aos::Context &context) {
47 last_time_ = context.monotonic_event_time;
48 }
49
50 void RunHealthCheck(aos::EventLoop *event_loop) {
51 if (last_time_ + std::chrono::duration_cast<std::chrono::nanoseconds>(
52 std::chrono::duration<double>(FLAGS_max_jitter)) <
53 event_loop->monotonic_now()) {
54 // Restart camera services
55 LOG(INFO) << "Restarting camera services";
56 CHECK_EQ(std::system("aos_starter stop argus_camera0"), 0);
57 CHECK_EQ(std::system("aos_starter stop argus_camera1"), 0);
58 CHECK_EQ(std::system("sudo systemctl restart nvargus-daemon.service"), 0);
59 CHECK_EQ(std::system("aos_starter start argus_camera0"), 0);
60 CHECK_EQ(std::system("aos_starter start argus_camera1"), 0);
61
62 std::exit(0);
63 return;
64 }
65 }
66
67 private:
68 const Channel *channel_;
69
70 std::string channel_name_;
71
72 aos::monotonic_clock::time_point last_time_ = aos::monotonic_clock::min_time;
73
74 aos::TimerHandler *timer_handle_;
75};
76
77} // namespace aos
78
79int main(int argc, char **argv) {
80 aos::InitGoogle(&argc, &argv);
81
82 aos::CliUtilInfo cli_info;
83 if (cli_info.Initialize(
84 &argc, &argv,
85 [&cli_info](const aos::Channel *channel) {
86 return aos::configuration::ChannelIsReadableOnNode(
87 channel, cli_info.event_loop->node());
88 },
89 "channel is readeable on node", true)) {
90 return 0;
91 }
92
93 std::vector<std::unique_ptr<aos::State>> states;
94
95 for (const aos::Channel *channel : cli_info.found_channels) {
96 states.emplace_back(
97 std::make_unique<aos::State>(&(cli_info.event_loop.value()), channel));
98 }
99
100 if (FLAGS_priority > 0) {
101 cli_info.event_loop->SetRuntimeRealtimePriority(FLAGS_priority);
102 }
103
104 cli_info.event_loop->Run();
105
106 return 0;
107}