blob: c145c8708b0e4e4b500407e6460755234fe000a7 [file] [log] [blame]
Stephan Pleines7463f602024-04-03 20:16:54 -07001#include <unistd.h>
2
3#include <iostream>
4
Austin Schuh99f7c6a2024-06-25 22:07:44 -07005#include "absl/flags/flag.h"
Stephan Pleines7463f602024-04-03 20:16:54 -07006
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
Austin Schuh99f7c6a2024-06-25 22:07:44 -070013ABSL_FLAG(int32_t, priority, -1, "If set, the RT priority to run at.");
14ABSL_FLAG(double, max_jitter, 10.00,
15 "The max time in seconds between messages before considering the "
16 "camera processes dead.");
17ABSL_FLAG(double, grace_period, 10.00,
18 "The grace period at startup before enforcing that messages must "
19 "flow from the camera processes.");
Stephan Pleines7463f602024-04-03 20:16:54 -070020
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>(
Austin Schuh99f7c6a2024-06-25 22:07:44 -070041 std::chrono::duration<double>(
42 absl::GetFlag(FLAGS_grace_period))),
Stephan Pleines7463f602024-04-03 20:16:54 -070043 std::chrono::milliseconds(1000));
44 });
45 }
46
47 void HandleMessage(const aos::Context &context) {
James Kuszmaul97772342024-05-04 13:40:48 -070048 if (last_time_ == aos::monotonic_clock::min_time) {
49 LOG(INFO) << "First message on " << channel_name_;
50 }
Stephan Pleines7463f602024-04-03 20:16:54 -070051 last_time_ = context.monotonic_event_time;
52 }
53
54 void RunHealthCheck(aos::EventLoop *event_loop) {
55 if (last_time_ + std::chrono::duration_cast<std::chrono::nanoseconds>(
Austin Schuh99f7c6a2024-06-25 22:07:44 -070056 std::chrono::duration<double>(
57 absl::GetFlag(FLAGS_max_jitter))) <
Stephan Pleines7463f602024-04-03 20:16:54 -070058 event_loop->monotonic_now()) {
59 // Restart camera services
60 LOG(INFO) << "Restarting camera services";
James Kuszmaul97772342024-05-04 13:40:48 -070061 LOG(INFO) << "Channel " << channel_name_ << " has not received a message "
Austin Schuh99f7c6a2024-06-25 22:07:44 -070062 << absl::GetFlag(FLAGS_max_jitter) << " seconds";
Stephan Pleines7463f602024-04-03 20:16:54 -070063 CHECK_EQ(std::system("aos_starter stop argus_camera0"), 0);
64 CHECK_EQ(std::system("aos_starter stop argus_camera1"), 0);
65 CHECK_EQ(std::system("sudo systemctl restart nvargus-daemon.service"), 0);
66 CHECK_EQ(std::system("aos_starter start argus_camera0"), 0);
67 CHECK_EQ(std::system("aos_starter start argus_camera1"), 0);
68
69 std::exit(0);
70 return;
71 }
72 }
73
74 private:
75 const Channel *channel_;
76
77 std::string channel_name_;
78
79 aos::monotonic_clock::time_point last_time_ = aos::monotonic_clock::min_time;
80
81 aos::TimerHandler *timer_handle_;
82};
83
84} // namespace aos
85
86int main(int argc, char **argv) {
87 aos::InitGoogle(&argc, &argv);
88
89 aos::CliUtilInfo cli_info;
90 if (cli_info.Initialize(
91 &argc, &argv,
92 [&cli_info](const aos::Channel *channel) {
93 return aos::configuration::ChannelIsReadableOnNode(
94 channel, cli_info.event_loop->node());
95 },
96 "channel is readeable on node", true)) {
97 return 0;
98 }
99
100 std::vector<std::unique_ptr<aos::State>> states;
101
102 for (const aos::Channel *channel : cli_info.found_channels) {
103 states.emplace_back(
104 std::make_unique<aos::State>(&(cli_info.event_loop.value()), channel));
105 }
106
Austin Schuh99f7c6a2024-06-25 22:07:44 -0700107 if (absl::GetFlag(FLAGS_priority) > 0) {
108 cli_info.event_loop->SetRuntimeRealtimePriority(
109 absl::GetFlag(FLAGS_priority));
Stephan Pleines7463f602024-04-03 20:16:54 -0700110 }
111
112 cli_info.event_loop->Run();
113
114 return 0;
115}