blob: c7a715a7b526042862701f9c5ac1511b16e22d8e [file] [log] [blame]
James Kuszmaul48671362020-12-24 13:54:16 -08001#include "frc971/analysis/in_process_plotter.h"
2
3#include "aos/configuration.h"
4
5namespace frc971 {
6namespace analysis {
7
8namespace {
9const char *kDataPath = "frc971/analysis";
10const char *kConfigPath = "frc971/analysis/plotter.json";
11} // namespace
12
13Plotter::Plotter()
14 : config_(aos::configuration::ReadConfig(kConfigPath)),
15 event_loop_factory_(&config_.message()),
16 event_loop_(event_loop_factory_.MakeEventLoop("plotter")),
17 plot_sender_(event_loop_->MakeSender<Plot>("/analysis")),
18 web_proxy_(event_loop_.get(), -1),
19 builder_(plot_sender_.MakeBuilder()) {
20 web_proxy_.SetDataPath(kDataPath);
21 event_loop_->SkipTimingReport();
22 color_wheel_.push_back(Color(1, 0, 0));
23 color_wheel_.push_back(Color(0, 1, 0));
24 color_wheel_.push_back(Color(0, 0, 1));
25 color_wheel_.push_back(Color(1, 1, 0));
26 color_wheel_.push_back(Color(0, 1, 1));
27 color_wheel_.push_back(Color(1, 0, 1));
28}
29
30void Plotter::Spin() { event_loop_factory_.Run(); }
31
32void Plotter::Title(std::string_view title) {
33 title_ = builder_.fbb()->CreateString(title);
34}
35
36void Plotter::AddFigure(std::string_view title, double width, double height) {
37 MaybeFinishFigure();
38
39 if (!title.empty()) {
40 figure_title_ = builder_.fbb()->CreateString(title);
41 }
42
43 // For positioning, just stack figures vertically.
44 auto position_builder = builder_.MakeBuilder<Position>();
45 position_builder.add_top(next_top_);
46 position_builder.add_left(0);
47 position_builder.add_width(width);
48 position_builder.add_height(height);
49 position_ = position_builder.Finish();
50
51 next_top_ += height;
52}
53
54void Plotter::XLabel(std::string_view label) {
55 xlabel_ = builder_.fbb()->CreateString(label);
56}
57
58void Plotter::YLabel(std::string_view label) {
59 ylabel_ = builder_.fbb()->CreateString(label);
60}
61
62void Plotter::AddLine(const std::vector<double> &x,
63 const std::vector<double> &y, std::string_view label) {
64 CHECK_EQ(x.size(), y.size());
65 CHECK(!position_.IsNull())
66 << "You must call AddFigure() before calling AddLine().";
67
68 flatbuffers::Offset<flatbuffers::String> label_offset;
69 if (!label.empty()) {
70 label_offset = builder_.fbb()->CreateString(label);
71 }
72
73 std::vector<Point> points;
74 for (size_t ii = 0; ii < x.size(); ++ii) {
75 points.emplace_back(x[ii], y[ii]);
76 }
milind1f1dca32021-07-03 13:50:07 -070077 const flatbuffers::Offset<flatbuffers::Vector<const Point *>> points_offset =
78 builder_.fbb()->CreateVectorOfStructs(points);
James Kuszmaul48671362020-12-24 13:54:16 -080079
80 const Color *color = &color_wheel_.at(color_wheel_position_);
81 color_wheel_position_ = (color_wheel_position_ + 1) % color_wheel_.size();
82
83 auto line_builder = builder_.MakeBuilder<Line>();
84 line_builder.add_label(label_offset);
85 line_builder.add_points(points_offset);
86 line_builder.add_color(color);
87 lines_.push_back(line_builder.Finish());
88}
89
90void Plotter::MaybeFinishFigure() {
91 if (!lines_.empty()) {
92 const flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Line>>>
93 lines_offset = builder_.fbb()->CreateVector(lines_);
94 auto figure_builder = builder_.MakeBuilder<Figure>();
95 figure_builder.add_title(figure_title_);
96 figure_builder.add_position(position_);
97 figure_builder.add_lines(lines_offset);
98 figure_builder.add_xlabel(xlabel_);
99 figure_builder.add_share_x_axis(share_x_axis_);
100 figure_builder.add_ylabel(ylabel_);
101 figures_.push_back(figure_builder.Finish());
102 }
103 lines_.clear();
104 figure_title_.o = 0;
105 xlabel_.o = 0;
106 ylabel_.o = 0;
107 position_.o = 0;
108 share_x_axis_ = false;
109 color_wheel_position_ = 0;
110}
111
112void Plotter::Publish() {
113 MaybeFinishFigure();
114 const flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Figure>>>
115 figures_offset = builder_.fbb()->CreateVector(figures_);
116
117 auto plot_builder = builder_.MakeBuilder<Plot>();
118 plot_builder.add_title(title_);
119 plot_builder.add_figures(figures_offset);
120
milind1f1dca32021-07-03 13:50:07 -0700121 CHECK_EQ(builder_.Send(plot_builder.Finish()),
122 aos::RawSender::Error::kOk);
James Kuszmaul48671362020-12-24 13:54:16 -0800123
124 builder_ = plot_sender_.MakeBuilder();
125
126 title_.o = 0;
127 figures_.clear();
128 next_top_ = 0;
129}
130
131} // namespace analysis
132} // namespace frc971