controls  3.0.0
DebugPrint.h
Go to the documentation of this file.
1 #ifndef CONTROLS_UTILS_DEBUG_PRINT_H
2 #define CONTROLS_UTILS_DEBUG_PRINT_H
3 
4 #include <algorithm>
5 #include <iomanip>
6 #include <sstream>
7 #include <string>
8 
9 #include "utils/Transforms.h"
10 
11 constexpr int PRINT_PRECISION = 3;
12 inline const Eigen::IOFormat EigFmt(PRINT_PRECISION, 0, ", ", ";\n", "", "", "[", "]");
13 
18 template <typename Derived>
19 std::string fmt_eigen(const Eigen::MatrixBase<Derived>& m) {
20  std::ostringstream oss;
21  oss << std::fixed;
22  if (m.cols() == 1) {
23  oss << m.transpose().format(EigFmt);
24  } else {
25  oss << m.format(EigFmt);
26  }
27  return oss.str();
28 }
29 
33 inline std::string fmt_pose(const Pose& pose) {
34  Vector6d n = pose2n(pose);
35  n.tail<3>() *= RAD2DEG;
36  std::ostringstream oss;
37  oss << std::fixed << std::setprecision(PRINT_PRECISION) << "pos=" << n.head<3>().transpose().format(EigFmt)
38  << " rpy=" << n.tail<3>().transpose().format(EigFmt) << " deg";
39  return oss.str();
40 }
41 
45 inline std::string fmt_state(const State& state) {
46  Vector6d n = pose2n(state.pose);
47  n.tail<3>() *= RAD2DEG;
48  std::ostringstream oss;
49  oss << std::fixed << std::setprecision(PRINT_PRECISION) << "pose=" << n.transpose().format(EigFmt)
50  << " (xyz m, rpy deg)\n"
51  << "twist=" << state.twist.transpose().format(EigFmt) << "\n"
52  << "accel=" << state.acceleration.transpose().format(EigFmt);
53  return oss.str();
54 }
55 
56 // ── Box-drawing table helpers ──────────────────────────────────────────
57 
58 inline void fmt_hline(std::ostringstream& s, int w, const char* l, const char* r) {
59  s << l;
60  for (int i = 0; i < w; ++i) s << "\xe2\x94\x80";
61  s << r << "\n";
62 }
63 
64 inline void fmt_row(std::ostringstream& s, int w, const std::string& content) {
65  int pad = w - static_cast<int>(content.size());
66  s << "\xe2\x94\x82" << content << std::string(std::max(pad, 0), ' ') << "\xe2\x94\x82\n";
67 }
68 
69 inline std::string fmt_f(double v, int w = 7, int prec = 2) {
70  std::ostringstream s;
71  s << std::fixed << std::setprecision(prec) << std::setw(w) << v;
72  return s.str();
73 }
74 
75 inline std::string fmt_v3(const char* lbl, double a, double b, double c, const char* tag = "") {
76  std::ostringstream r;
77  r << " " << std::setw(14) << std::left << lbl << std::right << "[" << fmt_f(a, 8) << "," << fmt_f(b, 8) << ","
78  << fmt_f(c, 8) << "]";
79  if (tag[0]) r << " " << tag;
80  return r.str();
81 }
82 
83 inline std::string fmt_v6(const char* lbl, double a, double b, double c, double d, double e, double g) {
84  std::ostringstream r;
85  r << " " << std::setw(10) << std::left << lbl << std::right << "[" << fmt_f(a) << "," << fmt_f(b) << ","
86  << fmt_f(c) << "," << fmt_f(d) << "," << fmt_f(e) << "," << fmt_f(g) << "]";
87  return r.str();
88 }
89 
90 inline std::string fmt_scalar(const char* lbl, double v) {
91  std::ostringstream r;
92  r << " " << std::setw(18) << std::left << lbl << std::right << fmt_f(v, 8);
93  return r.str();
94 }
95 
101 template <typename Params>
102 std::string fmt_config(const Params& c) {
103  static constexpr int W = 68;
104  auto hl = [](std::ostringstream& s, const char* l, const char* r) { fmt_hline(s, W, l, r); };
105  auto r = [](std::ostringstream& s, const std::string& content) { fmt_row(s, W, content); };
106 
107  // clang-format off
108  std::ostringstream os;
109  os << "\n";
110 
111  hl(os, "\xe2\x94\x8c", "\xe2\x94\x90");
112  r(os, " Vehicle Configuration");
113  hl(os, "\xe2\x94\x9c", "\xe2\x94\xa4");
114 
115  r(os, " Dynamics");
116  r(os, fmt_scalar("mass", c.mass));
117  r(os, fmt_scalar("buoyancy_factor", c.buoyancy_factor));
118  r(os, fmt_v3("inertia", c.i_xx, c.i_yy, c.i_zz, "xx yy zz"));
119  r(os, fmt_v3("", c.i_xy, c.i_xz, c.i_yz, "xy xz yz"));
120  r(os, fmt_v3("added_mass", c.ma_x, c.ma_y, c.ma_z, "x y z"));
121  r(os, fmt_v3("", c.ma_roll, c.ma_pitch, c.ma_yaw, "r p w"));
122  r(os, fmt_v3("lin_drag", c.dl_x, c.dl_y, c.dl_z, "x y z"));
123  r(os, fmt_v3("", c.dl_roll, c.dl_pitch, c.dl_yaw, "r p w"));
124  r(os, fmt_v3("nl_drag", c.dnl_x, c.dnl_y, c.dnl_z, "x y z"));
125  r(os, fmt_v3("", c.dnl_roll, c.dnl_pitch, c.dnl_yaw, "r p w"));
126  r(os, fmt_v3("r_bb", c.rbb_x, c.rbb_y, c.rbb_z));
127  r(os, fmt_v3("r_gb", c.rgb_x, c.rgb_y, c.rgb_z));
128 
129  hl(os, "\xe2\x94\x9c", "\xe2\x94\xa4");
130  r(os, " Controller");
131  r(os, fmt_scalar("ff", c.ff_gain));
132  r(os, fmt_scalar("fb", c.fb_gain));
133  r(os, fmt_scalar("buoyancy", c.buoyancy_gain));
134  r(os, " scheduling " + std::string(c.surface_gain_scheduling ? "ON" : "OFF") + " (threshold " + fmt_f(c.surface_threshold, 4) + ")");
135  r(os, "");
136  r(os, " x y z r p w");
137  r(os, fmt_v6("ax_gain", c.axis_gain_x, c.axis_gain_y, c.axis_gain_z, c.axis_gain_roll, c.axis_gain_pitch, c.axis_gain_yaw));
138  r(os, fmt_v6("Kp", c.kp_x, c.kp_y, c.kp_z, c.kp_roll, c.kp_pitch, c.kp_yaw));
139  r(os, fmt_v6("Ki", c.ki_x, c.ki_y, c.ki_z, c.ki_roll, c.ki_pitch, c.ki_yaw));
140  r(os, fmt_v6("Kd", c.kd_x, c.kd_y, c.kd_z, c.kd_roll, c.kd_pitch, c.kd_yaw));
141  r(os, fmt_v6("Kp_sf", c.kp_x_surface, c.kp_y_surface, c.kp_z_surface, c.kp_roll_surface, c.kp_pitch_surface, c.kp_yaw_surface));
142  r(os, fmt_v6("Ki_sf", c.ki_x_surface, c.ki_y_surface, c.ki_z_surface, c.ki_roll_surface, c.ki_pitch_surface, c.ki_yaw_surface));
143  r(os, fmt_v6("Kd_sf", c.kd_x_surface, c.kd_y_surface, c.kd_z_surface, c.kd_roll_surface, c.kd_pitch_surface, c.kd_yaw_surface));
144 
145  hl(os, "\xe2\x94\x9c", "\xe2\x94\xa4");
146  r(os, " Trajectory Limits");
147  r(os, " vel acc jerk");
148  r(os, fmt_v3("xy", c.max_xy_vel, c.max_xy_acc, c.max_xy_jerk));
149  r(os, fmt_v3("z", c.max_z_vel, c.max_z_acc, c.max_z_jerk));
150  r(os, fmt_v3("yaw", c.max_yaw_vel, c.max_yaw_acc, c.max_yaw_jerk));
151  r(os, fmt_scalar("slow_down_gain", c.slow_down_gain));
152 
153  hl(os, "\xe2\x94\x9c", "\xe2\x94\xa4");
154  r(os, " Thrust Allocation");
155  r(os, fmt_v3("cg_offset", c.cg_offset_x, c.cg_offset_y, c.cg_offset_z));
156  hl(os, "\xe2\x94\x94", "\xe2\x94\x98");
157  // clang-format on
158 
159  return os.str();
160 }
161 
162 #endif // CONTROLS_UTILS_DEBUG_PRINT_H
std::string fmt_v3(const char *lbl, double a, double b, double c, const char *tag="")
Definition: DebugPrint.h:75
std::string fmt_pose(const Pose &pose)
Formats a Pose as "pos=[x, y, z] rpy=[r, p, y] deg".
Definition: DebugPrint.h:33
const Eigen::IOFormat EigFmt(PRINT_PRECISION, 0, ", ", ";\n", "", "", "[", "]")
constexpr int PRINT_PRECISION
Definition: DebugPrint.h:11
std::string fmt_scalar(const char *lbl, double v)
Definition: DebugPrint.h:90
void fmt_row(std::ostringstream &s, int w, const std::string &content)
Definition: DebugPrint.h:64
std::string fmt_eigen(const Eigen::MatrixBase< Derived > &m)
Formats any Eigen matrix/vector as a string.
Definition: DebugPrint.h:19
std::string fmt_f(double v, int w=7, int prec=2)
Definition: DebugPrint.h:69
std::string fmt_state(const State &state)
Formats a State (pose + twist + acceleration) as a multi-line string.
Definition: DebugPrint.h:45
std::string fmt_v6(const char *lbl, double a, double b, double c, double d, double e, double g)
Definition: DebugPrint.h:83
void fmt_hline(std::ostringstream &s, int w, const char *l, const char *r)
Definition: DebugPrint.h:58
std::string fmt_config(const Params &c)
Formats a vehicle config struct as a boxed table string.
Definition: DebugPrint.h:102
Vector6d pose2n(const Pose &pose)
Converts a Pose to a 6-element XYZRPY vector.
Definition: Transforms.cpp:15
Eigen::Matrix< double, 6, 1 > Vector6d
Definition: Types.h:29
constexpr double RAD2DEG
Definition: Types.h:42
6DOF rigid-body pose as a 3D position and unit quaternion orientation
Definition: Types.h:49
Full kinematic state of the vehicle.
Definition: Types.h:63
Vector6d acceleration
Body-frame acceleration [ax, ay, az, αx, αy, αz] in m/s² and rad/s²
Definition: Types.h:71
Pose pose
6DOF pose (position + orientation) in the world frame
Definition: Types.h:65
Vector6d twist
Body-frame velocity [u, v, w, p, q, r] in m/s and rad/s.
Definition: Types.h:68