James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 1 | #ifndef FRC971_ANALYSIS_IN_PROCESS_PLOTTER_H_ |
| 2 | #define FRC971_ANALYSIS_IN_PROCESS_PLOTTER_H_ |
| 3 | |
| 4 | #include <vector> |
| 5 | |
Stephan Pleines | 85b295c | 2024-02-04 17:50:26 -0800 | [diff] [blame] | 6 | #include "aos/analysis/plot_data_generated.h" |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 7 | #include "aos/events/simulated_event_loop.h" |
| 8 | #include "aos/network/web_proxy.h" |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 9 | |
Stephan Pleines | d99b1ee | 2024-02-02 20:56:44 -0800 | [diff] [blame] | 10 | namespace frc971::analysis { |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 11 | |
| 12 | // This class wraps the WebProxy class to provide a convenient C++ interface to |
| 13 | // dynamically generate plots. |
| 14 | // Currently, the main useful interface that this provides is a matplotlib-like |
| 15 | // interface--see in_process_plotter_demo.cc for sample usage. It doesn't |
| 16 | // precisely follow matplotlib's conventions, but the basic style does mimic |
| 17 | // matplotlib. Future iterations may ditch this in favor of a more modern |
| 18 | // interface where we actually return handles for plots and lines and the such. |
| 19 | // |
| 20 | // Note that currently the port for the seb server is hard-coded to 8080, so |
| 21 | // only one instance of the Plotter can be present at once. |
| 22 | // |
| 23 | // You must call Spin() for the web server to actually do anything helpful. |
| 24 | class Plotter { |
| 25 | public: |
| 26 | Plotter(); |
| 27 | |
| 28 | // matplotlib-like interface |
| 29 | // The basic pattern is: |
| 30 | // 1) Call Figure() |
Philipp Schrader | a671252 | 2023-07-05 20:25:11 -0700 | [diff] [blame] | 31 | // 2) Set up the lines, labels, etc. for the figure. |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 32 | // 3) Repeat 1-2 however many times. |
| 33 | // 4) Call Publish(). |
| 34 | // 5) Repeat 1-5 however many times. |
| 35 | // |
| 36 | // Publish() actually pushes the figures that you setup to the web-page, |
| 37 | // either with an autogenerated title or the title set by Title(). All state |
| 38 | // is cleared (or should be cleared) by the call to Publish(). |
| 39 | |
| 40 | // Sets the title for the current set of plots; if you |
| 41 | void Title(std::string_view title); |
Austin Schuh | 5ec17ef | 2022-07-15 14:37:16 -0700 | [diff] [blame] | 42 | void AddFigure(std::string_view title = "", double width = 0, |
| 43 | double height = 0); |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 44 | struct LineOptions { |
| 45 | std::string_view label = ""; |
| 46 | std::string_view line_style = "*-"; |
| 47 | std::string_view color = ""; |
Austin Schuh | 69d0b73 | 2022-07-20 21:19:32 -0700 | [diff] [blame] | 48 | double point_size = 3.0; |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 49 | }; |
| 50 | |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 51 | void AddLine(const std::vector<double> &x, const std::vector<double> &y, |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 52 | std::string_view label) { |
| 53 | AddLine(x, y, LineOptions{.label = label}); |
| 54 | } |
| 55 | void AddLine(const std::vector<double> &x, const std::vector<double> &y, |
| 56 | std::string_view label, std::string_view line_style) { |
| 57 | AddLine(x, y, LineOptions{.label = label, .line_style = line_style}); |
| 58 | } |
| 59 | void AddLine(const std::vector<double> &x, const std::vector<double> &y, |
| 60 | LineOptions options); |
| 61 | |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 62 | void ShareXAxis(bool share) { share_x_axis_ = share; } |
| 63 | void XLabel(std::string_view label); |
| 64 | void YLabel(std::string_view label); |
| 65 | void Publish(); |
| 66 | |
| 67 | void Spin(); |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 68 | |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 69 | private: |
| 70 | void MaybeFinishFigure(); |
| 71 | |
| 72 | aos::FlatbufferDetachedBuffer<aos::Configuration> config_; |
| 73 | aos::SimulatedEventLoopFactory event_loop_factory_; |
| 74 | std::unique_ptr<aos::EventLoop> event_loop_; |
| 75 | aos::Sender<Plot> plot_sender_; |
| 76 | aos::web_proxy::WebProxy web_proxy_; |
| 77 | |
| 78 | aos::Sender<Plot>::Builder builder_; |
| 79 | flatbuffers::Offset<flatbuffers::String> title_; |
| 80 | flatbuffers::Offset<flatbuffers::String> figure_title_; |
| 81 | flatbuffers::Offset<flatbuffers::String> xlabel_; |
| 82 | flatbuffers::Offset<flatbuffers::String> ylabel_; |
| 83 | bool share_x_axis_ = false; |
| 84 | float next_top_ = 0; |
| 85 | flatbuffers::Offset<Position> position_; |
| 86 | std::vector<flatbuffers::Offset<Figure>> figures_; |
| 87 | std::vector<flatbuffers::Offset<Line>> lines_; |
| 88 | |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 89 | struct ColorWheelColor { |
| 90 | std::string name; |
| 91 | Color color; |
| 92 | }; |
| 93 | |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 94 | size_t color_wheel_position_ = 0; |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 95 | std::vector<ColorWheelColor> color_wheel_; |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 96 | }; |
| 97 | |
Stephan Pleines | d99b1ee | 2024-02-02 20:56:44 -0800 | [diff] [blame] | 98 | } // namespace frc971::analysis |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 99 | #endif // FRC971_ANALYSIS_IN_PROCESS_PLOTTER_H_ |