diff --git a/apps/navlog-viewer/navlog-viewer-ui.cpp b/apps/navlog-viewer/navlog-viewer-ui.cpp index de4a7cae3c..7feb287f5c 100644 --- a/apps/navlog-viewer/navlog-viewer-ui.cpp +++ b/apps/navlog-viewer/navlog-viewer-ui.cpp @@ -259,6 +259,9 @@ NavlogViewerApp::NavlogViewerApp() lambdaAddSmallFontBtn(layer, "Export current log entry...", [this]() { OnmnuExportSelected(); }); + lambdaAddSmallFontBtn( + layer, "Localization vs odom report...", + [this]() { OnmnuGenerateOdometryVsLocalizationReport(); }); } // ===== TAB: Manually pick trajectory @@ -585,9 +588,19 @@ void NavlogViewerApp::updateVisualization() std::to_string(log.nSelectedPTG) + "from [0-"s + std::to_string(log.nPTGs - 1) + "]"s); - m_txtTimeIndex->setCaption( - "Time index: "s + std::to_string(log_idx) + " / "s + - std::to_string(std::max(1U, m_logdata.size()) - 1)); + { + std::string timeIndexStr = "Time index: "s + std::to_string(log_idx) + + " / "s + std::to_string(std::max(1U, m_logdata.size()) - 1); + + if (auto itTim = log.timestamps.find("tim_start_iteration"); + itTim != log.timestamps.end()) + { + timeIndexStr += " (tim_start_iteration="s + + mrpt::system::dateTimeLocalToString(itTim->second) + + " [local time])"s; + } + m_txtTimeIndex->setCaption(timeIndexStr); + } const bool is_NOP_cmd = log.ptg_index_NOP >= 0; const int sel_ptg_idx = !is_NOP_cmd ? log.nSelectedPTG : log.ptg_index_NOP; @@ -1060,8 +1073,28 @@ void NavlogViewerApp::updateVisualization() "cur_vel_local=[%.02f m/s, %0.2f m/s, %.02f dps]", log.cur_vel_local.vx, log.cur_vel_local.vy, mrpt::RAD2DEG(log.cur_vel_local.omega))); - ADD_WIN_TEXTMSG(mrpt::format( - "robot_pose=%s", log.robotPoseLocalization.asString().c_str())); + { + static TPose2D formerPoseLoc = log.robotPoseLocalization; + + ADD_WIN_TEXTMSG(mrpt::format( + "robot_pose =%35s | Increment since last step=%s", + log.robotPoseLocalization.asString().c_str(), + (log.robotPoseLocalization - formerPoseLoc).asString().c_str())); + + formerPoseLoc = log.robotPoseLocalization; + } + + { + static TPose2D formerPoseOdo = log.robotPoseOdometry; + + ADD_WIN_TEXTMSG(mrpt::format( + "robot_odometry=%35s | Increment since last step=%s", + log.robotPoseOdometry.asString().c_str(), + (log.robotPoseOdometry - formerPoseOdo).asString().c_str())); + + formerPoseOdo = log.robotPoseOdometry; + } + { for (unsigned int i = 0; i < log.WS_targets_relative.size(); i++) { @@ -1607,6 +1640,59 @@ void NavlogViewerApp::OnmnuSeePTGParamsSelected() NANOGUI_END_TRY(*m_win) } +void NavlogViewerApp::OnmnuGenerateOdometryVsLocalizationReport() +{ + NANOGUI_START_TRY + + const std::string fileName = nanogui::file_dialog( + {{"txt", "Save localization vs odometry report"}}, true /*save*/); + if (fileName.empty()) return; + + std::ofstream f(fileName); + ASSERT_(f.is_open()); + + f << "% timestamp localizationPoseIncr odometryPoseIncr\n"; + + std::optional lastOdo, lastLocPose; + + const size_t N = m_logdata.size(); + for (size_t i = 0; i < N; i++) + { + const CLogFileRecord::Ptr logsptr = + std::dynamic_pointer_cast(m_logdata[i]); + const CLogFileRecord* logptr = logsptr.get(); + if (!logptr) continue; + const auto& log = *logptr; + + const auto& odo = log.robotPoseOdometry; + const auto& pose = log.robotPoseLocalization; + + if (lastOdo && lastLocPose) + { + const auto odoIncr = odo - *lastOdo; + const auto locIncr = pose - *lastLocPose; + + if (!log.timestamps.empty()) + f << mrpt::format( + "%.03f ", + mrpt::Clock::toDouble(log.timestamps.begin()->second)); + else + f << "0 "; + + for (int k = 0; k < 3; k++) + f << locIncr[k] << " "; + for (int k = 0; k < 3; k++) + f << odoIncr[k] << " "; + f << "\n"; + } + + lastOdo = odo; + lastLocPose = pose; + } + + NANOGUI_END_TRY(*m_win) +} + void NavlogViewerApp::OnmnuSaveScoreMatrixSelected() { NANOGUI_START_TRY diff --git a/apps/navlog-viewer/navlog-viewer-ui.h b/apps/navlog-viewer/navlog-viewer-ui.h index cac954dc97..3e4b2577a2 100644 --- a/apps/navlog-viewer/navlog-viewer-ui.h +++ b/apps/navlog-viewer/navlog-viewer-ui.h @@ -78,6 +78,7 @@ class NavlogViewerApp void OnmnuMatlabPlotsSelected(); void OnmnuSeePTGParamsSelected(); void OnmnuSaveScoreMatrixSelected(); + void OnmnuGenerateOdometryVsLocalizationReport(); void OntimMouseXY(); void OnmnuMatlabExportPaths(); void OnmnuExportSelected(std::string filename = {}); diff --git a/appveyor.yml b/appveyor.yml index c02980cb23..868f67a0f4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ # version format -version: 2.4.2-{branch}-build{build} +version: 2.4.3-{branch}-build{build} os: Visual Studio 2019 diff --git a/doc/source/download-mrpt.rst b/doc/source/download-mrpt.rst index 501647d751..cd2266acbf 100644 --- a/doc/source/download-mrpt.rst +++ b/doc/source/download-mrpt.rst @@ -22,7 +22,7 @@ Next step: :ref:`compiling` Debian/Ubuntu official repositories --------------------------------------- -Install the `official version `_ for your distribution with: +Install the `official version `_ for your distribution with: .. code-block:: bash @@ -30,7 +30,7 @@ Install the `official version `_ .. note:: - Versions in `official repositories `_ + Versions in `official repositories `_ may be quite outdated. It is strongly recommended to use the PPAs (read below) or build from sources instead. diff --git a/doc/source/doxygen-docs/changelog.md b/doc/source/doxygen-docs/changelog.md index fdc9639bcf..e492577d93 100644 --- a/doc/source/doxygen-docs/changelog.md +++ b/doc/source/doxygen-docs/changelog.md @@ -1,5 +1,14 @@ \page changelog Change Log +# Version 2.4.3: Released Feb 22nd, 2022 +- Changes in applications: + - navlog-viewer: + - The timestamp is now always shown. +- BUG FIXES: + - Do not run offscreen rendering unit tests in MIPS arch, since they seem to fail in autobuilders. + - mrpt::vision::checkerBoardCameraCalibration() did not return the distortion model (so if parameters are printed, it would look like no distortion at all!). + - mrpt::gui::CDisplayWindowGUI::createManagedSubWindow() created the subwindows helper UI on top of the other user windows. It now remains on the back of other windows. + # Version 2.4.2: Released Feb 3rd, 2022 - Changes in libraries: - \ref mrpt_containers_grp diff --git a/libs/expr/include/mrpt/3rdparty/exprtk.hpp b/libs/expr/include/mrpt/3rdparty/exprtk.hpp old mode 100755 new mode 100644 diff --git a/libs/gui/src/CDisplayWindowGUI.cpp b/libs/gui/src/CDisplayWindowGUI.cpp index 5bec191e8a..49236b3d58 100644 --- a/libs/gui/src/CDisplayWindowGUI.cpp +++ b/libs/gui/src/CDisplayWindowGUI.cpp @@ -265,15 +265,16 @@ nanogui::Window* CDisplayWindowGUI::createManagedSubWindow( { constexpr std::size_t MAX_MINIMIZED_TITLE_LEN = 20; + // Create UI on first call: + // Create it before the user-requested window so it doesn't get on top. + createSubWindowsControlUI(); + // Create subwindow: const int thisWinIndex = m_subWindows.windows.size(); auto w = new SubWindow(*this, thisWinIndex, this, title); m_subWindows.windows.push_back(w); - // Create UI on first call: - createSubWindowsControlUI(); - // Append to combo: ASSERT_(m_subWindows.uiCombo); auto items = m_subWindows.uiCombo->items(); diff --git a/libs/opengl/src/CFBORender_unittest.cpp b/libs/opengl/src/CFBORender_unittest.cpp index 7722005aaf..41ec830c4d 100644 --- a/libs/opengl/src/CFBORender_unittest.cpp +++ b/libs/opengl/src/CFBORender_unittest.cpp @@ -23,6 +23,22 @@ #include // for MRPT_HAS_* #include +#if MRPT_HAS_OPENCV && MRPT_HAS_OPENGL_GLUT && MRPT_HAS_EGL +#define RUN_OFFSCREEN_RENDER_TESTS +#endif + +// In MIPS, these tests crash in autobuilders, skip them: +#if defined(__mips__) || defined(__mips) +#undef RUN_OFFSCREEN_RENDER_TESTS +#endif +// Idem with PowerPC: +#if defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || \ + defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__) || \ + defined(_ARCH_PPC) || defined(__PPC64__) || defined(__ppc64__) || \ + defined(_ARCH_PPC64) +#undef RUN_OFFSCREEN_RENDER_TESTS +#endif + static float imageDiff( const mrpt::img::CImage& im1, const mrpt::img::CImage& im2) { @@ -228,7 +244,7 @@ static void test_opengl_CFBORender(const bool useCameraFromIntrinsics) } } -#if MRPT_HAS_OPENCV && MRPT_HAS_OPENGL_GLUT && MRPT_HAS_EGL +#if defined(RUN_OFFSCREEN_RENDER_TESTS) TEST(OpenGL, CFBORender_camera_intrinsics) #else TEST(OpenGL, DISABLED_CFBORender_camera_intrinsics) @@ -237,7 +253,7 @@ TEST(OpenGL, DISABLED_CFBORender_camera_intrinsics) test_opengl_CFBORender(true); } -#if MRPT_HAS_OPENCV && MRPT_HAS_OPENGL_GLUT && MRPT_HAS_EGL +#if defined(RUN_OFFSCREEN_RENDER_TESTS) TEST(OpenGL, CFBORender_camera_fov) #else TEST(OpenGL, DISABLED_CFBORender_camera_fov) diff --git a/libs/vision/src/checkerboard_cam_calib.cpp b/libs/vision/src/checkerboard_cam_calib.cpp index 99f4446fea..4aa89c23ae 100644 --- a/libs/vision/src/checkerboard_cam_calib.cpp +++ b/libs/vision/src/checkerboard_cam_calib.cpp @@ -293,6 +293,7 @@ bool mrpt::vision::checkerBoardCameraCalibration( out_camera_params.intrinsicParams = M; } + out_camera_params.distortion = DistortionModel::plumb_bob; out_camera_params.dist.fill(0); for (int k = 0; k < 5; k++) out_camera_params.dist[k] = distCoeffs.ptr()[k]; diff --git a/package.xml b/package.xml index 27116efa46..6be95f711d 100644 --- a/package.xml +++ b/package.xml @@ -5,7 +5,7 @@ --> mrpt2 - 2.4.2 + 2.4.3 Mobile Robot Programming Toolkit (MRPT) version 2.x Jose-Luis Blanco-Claraco diff --git a/version_prefix.txt b/version_prefix.txt index 7bb7d8fc57..80f773ad3a 100644 --- a/version_prefix.txt +++ b/version_prefix.txt @@ -1,4 +1,4 @@ -2.4.2 +2.4.3 # IMPORTANT: This file is parsed by CMake, don't add any comment to # the first line. # This file is used in both Windows and Linux scripts to automatically