Icarus
Vehicle Simulation as a Transformable Computational Graph, built on Vulcan and Janus
Loading...
Searching...
No Matches
MissionDebrief.hpp
Go to the documentation of this file.
1#pragma once
2
9
13
14#include <algorithm>
15#include <iomanip>
16#include <iostream>
17#include <sstream>
18#include <string>
19#include <vector>
20
21namespace icarus {
22
33
38 std::string name;
39 std::size_t call_count = 0;
40 double total_time_us = 0.0;
41 double avg_time_us = 0.0;
42 double max_time_us = 0.0;
43 double percent_load = 0.0;
44};
45
52 public:
53 explicit MissionDebrief(const Console &console) : console_(console) {}
54
56 void SetExitStatus(ExitStatus status) { exit_status_ = status; }
57
59 void SetExitReason(const std::string &reason) { exit_reason_ = reason; }
60
62 void SetTiming(double sim_time, double wall_time) {
63 sim_time_ = sim_time;
64 wall_time_ = wall_time;
65 if (wall_time > 0) {
66 real_time_factor_ = sim_time / wall_time;
67 }
68 }
69
71 void SetProfilingData(const std::vector<ComponentStats> &stats) { profiling_data_ = stats; }
72
74 [[nodiscard]] std::string Generate() const {
75 std::ostringstream oss;
76
77 oss << Banner::GetDebriefHeader() << "\n";
78
79 // Exit status
80 oss << " Exit Status: " << StatusToString(exit_status_) << "\n";
81 if (!exit_reason_.empty()) {
82 oss << " Exit Reason: " << exit_reason_ << "\n";
83 }
84
85 // Timing
86 oss << " Sim Time: " << std::fixed << std::setprecision(2) << sim_time_ << " s\n";
87 oss << " Wall Time: " << std::scientific << std::setprecision(2) << wall_time_
88 << " s\n";
89
90 // Real-time factor
91 if (wall_time_ > 0) {
92 oss << " Real-Time Factor: " << std::fixed << std::setprecision(1) << real_time_factor_
93 << "x ";
94 if (real_time_factor_ > 1.0) {
95 oss << "(Faster than real-time)\n";
96 } else if (real_time_factor_ < 1.0) {
97 oss << "(Slower than real-time)\n";
98 } else {
99 oss << "(Real-time)\n";
100 }
101 }
102
103 // Profiling data
104 if (!profiling_data_.empty()) {
105 oss << "\n" << GenerateProfilingTable();
106 }
107
108 oss << Banner::GetRule(80) << "\n";
109
110 return oss.str();
111 }
112
114 void Print() const {
115 std::string debrief = Generate();
116 if (console_.IsColorEnabled()) {
117 // Color the status based on success/failure
118 if (exit_status_ == ExitStatus::Success ||
119 exit_status_ == ExitStatus::EndConditionMet) {
120 std::cout << console_.Colorize(debrief, AnsiColor::Green);
121 } else {
122 std::cout << console_.Colorize(debrief, AnsiColor::Red);
123 }
124 } else {
125 std::cout << debrief;
126 }
127 }
128
129 private:
130 const Console &console_;
131
132 ExitStatus exit_status_ = ExitStatus::Success;
133 std::string exit_reason_;
134 double sim_time_ = 0.0;
135 double wall_time_ = 0.0;
136 double real_time_factor_ = 0.0;
137 std::vector<ComponentStats> profiling_data_;
138
139 [[nodiscard]] static std::string StatusToString(ExitStatus status) {
140 switch (status) {
142 return "SUCCESS";
144 return "END CONDITION MET";
146 return "USER ABORT";
148 return "ERROR";
150 return "DIVERGENCE";
151 }
152 return "UNKNOWN";
153 }
154
155 [[nodiscard]] std::string GenerateProfilingTable() const {
156 std::ostringstream oss;
157
158 oss << " [ PROFILE HOTSPOTS ]\n";
159
160 // Sort by percent load (descending)
161 std::vector<ComponentStats> sorted = profiling_data_;
162 std::sort(sorted.begin(), sorted.end(),
163 [](const ComponentStats &a, const ComponentStats &b) {
164 return a.percent_load > b.percent_load;
165 });
166
167 AsciiTable table;
168 table.AddColumn("COMPONENT", 20);
169 table.AddColumn("AVG (μs)", 12, AsciiTable::Align::Right);
170 table.AddColumn("% LOAD", 8, AsciiTable::Align::Right);
171
172 for (const auto &stat : sorted) {
173 std::ostringstream avg;
174 avg << std::fixed << std::setprecision(1) << stat.avg_time_us;
175 std::ostringstream load;
176 load << std::fixed << std::setprecision(1) << stat.percent_load << "%";
177 table.AddRow({stat.name, avg.str(), load.str()});
178 }
179
180 // Indent the table
181 std::istringstream iss(table.Render());
182 std::string line;
183 while (std::getline(iss, line)) {
184 oss << " " << line << "\n";
185 }
186
187 return oss.str();
188 }
189
190 [[nodiscard]] std::string GenerateQuote() const {
191 switch (exit_status_) {
194 return " \"Icarus flew... and this time, he stuck the landing.\"";
196 return " \"Mission aborted. Sometimes discretion is the better part of valor.\"";
198 return " \"Houston, we have a problem.\"";
200 return " \"The numbers went to infinity... and beyond.\"";
201 }
202 return "";
203 }
204};
205
206} // namespace icarus
ASCII table generator with box-drawing characters.
ASCII art banners and headers.
Console abstraction with ANSI color support.
@ Right
Definition AsciiTable.hpp:32
static std::string GetDebriefHeader()
Get the mission debrief header.
Definition Banner.hpp:38
static std::string GetRule(int width=80, char c='=')
Get horizontal rule.
Definition Banner.hpp:43
Console output with color and formatting support.
Definition Console.hpp:111
Base class for all Icarus exceptions.
Definition Error.hpp:52
std::string Generate() const
Generate the full debrief string.
Definition MissionDebrief.hpp:74
void Print() const
Generate and print to console.
Definition MissionDebrief.hpp:114
void SetTiming(double sim_time, double wall_time)
Set timing information.
Definition MissionDebrief.hpp:62
void SetExitReason(const std::string &reason)
Set exit reason message.
Definition MissionDebrief.hpp:59
void SetExitStatus(ExitStatus status)
Set exit status.
Definition MissionDebrief.hpp:56
MissionDebrief(const Console &console)
Definition MissionDebrief.hpp:53
void SetProfilingData(const std::vector< ComponentStats > &stats)
Set profiling data.
Definition MissionDebrief.hpp:71
Definition AggregationTypes.hpp:13
ExitStatus
Exit status codes.
Definition MissionDebrief.hpp:26
@ Divergence
Numerical divergence.
Definition MissionDebrief.hpp:31
@ UserAbort
User requested abort.
Definition MissionDebrief.hpp:29
@ Success
Normal completion.
Definition MissionDebrief.hpp:27
@ EndConditionMet
End condition triggered.
Definition MissionDebrief.hpp:28
@ Error
Error during simulation.
Definition MissionDebrief.hpp:30
static constexpr const char * Red
Definition Console.hpp:58
static constexpr const char * Green
Definition Console.hpp:59
Component timing statistics.
Definition MissionDebrief.hpp:37
double total_time_us
Definition MissionDebrief.hpp:40
double percent_load
Definition MissionDebrief.hpp:43
std::size_t call_count
Definition MissionDebrief.hpp:39
double max_time_us
Definition MissionDebrief.hpp:42
std::string name
Definition MissionDebrief.hpp:38
double avg_time_us
Definition MissionDebrief.hpp:41