22 #include <Eigen/Eigen>
23 #include <boost/filesystem.hpp>
30 #ifdef HAVE_PYTHONLIBS
41 std::map<std::string, std::string> params_value, params_bound;
42 params_value.insert({
"label",
"error"});
43 params_value.insert({
"linestyle",
"-"});
44 params_value.insert({
"color",
"blue"});
45 params_bound.insert({
"label",
"3 sigma bound"});
46 params_bound.insert({
"linestyle",
"--"});
47 params_bound.insert({
"color",
"red"});
54 for (
size_t i = 0; i < sx.
timestamps.size(); i++) {
65 for (
size_t i = 0; i < sy.
timestamps.size(); i++) {
76 for (
size_t i = 0; i < sz.
timestamps.size(); i++) {
85 int main(
int argc,
char **argv) {
92 PRINT_ERROR(
RED "ERROR: Please specify a align mode, groudtruth, and algorithm run file\n" RESET);
93 PRINT_ERROR(
RED "ERROR: ./error_singlerun <align_mode> <file_gt.txt> <file_est.txt>\n" RESET);
94 PRINT_ERROR(
RED "ERROR: rosrun ov_eval error_singlerun <align_mode> <file_gt.txt> <file_est.txt>\n" RESET);
95 std::exit(EXIT_FAILURE);
99 boost::filesystem::path path_gt(argv[2]);
100 std::vector<double> times;
101 std::vector<Eigen::Matrix<double, 7, 1>> poses;
102 std::vector<Eigen::Matrix3d> cov_ori, cov_pos;
106 PRINT_DEBUG(
"[COMP]: %d poses in %s => length of %.2f meters\n", (
int)times.size(), path_gt.stem().string().c_str(), length);
120 PRINT_INFO(
"======================================\n");
122 PRINT_INFO(
"======================================\n");
125 PRINT_INFO(
"min_ori = %.3f | min_pos = %.3f\n", error_ori.
min, error_pos.
min);
126 PRINT_INFO(
"max_ori = %.3f | max_pos = %.3f\n", error_ori.
max, error_pos.
max);
127 PRINT_INFO(
"std_ori = %.3f | std_pos = %.3f\n", error_ori.
std, error_pos.
std);
134 std::vector<double> segments = {8.0, 16.0, 24.0, 32.0, 40.0};
135 std::map<double, std::pair<ov_eval::Statistics, ov_eval::Statistics>> error_rpe;
139 PRINT_INFO(
"======================================\n");
141 PRINT_INFO(
"======================================\n");
142 for (
const auto &seg : error_rpe) {
143 PRINT_INFO(
"seg %d - median_ori = %.3f | median_pos = %.3f (%d samples)\n", (
int)seg.first, seg.second.first.median,
144 seg.second.second.median, (
int)seg.second.second.values.size());
148 #ifdef HAVE_PYTHONLIBS
151 std::map<std::string, std::string> params_rpe;
152 params_rpe.insert({
"notch",
"true"});
153 params_rpe.insert({
"sym",
""});
161 std::vector<double>
xticks;
162 std::vector<std::string> labels;
163 for (
const auto &seg : error_rpe) {
165 labels.push_back(std::to_string((
int)seg.first));
183 for (
const auto &seg : error_rpe) {
207 PRINT_INFO(
"======================================\n");
208 PRINT_INFO(
"Normalized Estimation Error Squared\n");
209 PRINT_INFO(
"======================================\n");
211 PRINT_INFO(
"min_ori = %.3f | min_pos = %.3f\n", nees_ori.
min, nees_pos.
min);
212 PRINT_INFO(
"max_ori = %.3f | max_pos = %.3f\n", nees_ori.
max, nees_pos.
max);
213 PRINT_INFO(
"std_ori = %.3f | std_pos = %.3f\n", nees_ori.
std, nees_pos.
std);
214 PRINT_INFO(
"======================================\n");
216 #ifdef HAVE_PYTHONLIBS
218 if (!nees_ori.
values.empty() && !nees_pos.
values.empty()) {
222 for (
size_t i = 0; i < nees_ori.
timestamps.size(); i++) {
231 std::map<std::string, std::string> params_neesp, params_neeso;
232 params_neesp.insert({
"label",
"nees position"});
233 params_neesp.insert({
"linestyle",
"-"});
234 params_neesp.insert({
"color",
"blue"});
235 params_neeso.insert({
"label",
"nees orientation"});
236 params_neeso.insert({
"linestyle",
"-"});
237 params_neeso.insert({
"color",
"blue"});
266 traj.
calculate_error(posx, posy, posz, orix, oriy, oriz, roll, pitch, yaw);
271 for (
size_t i = 0; i < posx.
timestamps.size(); i++) {
283 #ifdef HAVE_PYTHONLIBS
288 plot_3errors(posx, posy, posz);
310 plot_3errors(orix, oriy, oriz);
332 plot_3errors(roll, pitch, yaw);