Example: hwdrivers_swissranger_example
C++ example source code:
/* +------------------------------------------------------------------------+ | Mobile Robot Programming Toolkit (MRPT) | | https://www.mrpt.org/ | | | | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file | | See: https://www.mrpt.org/Authors - All rights reserved. | | Released under BSD License. See: https://www.mrpt.org/License | +------------------------------------------------------------------------+ */ #include <mrpt/gui/CDisplayWindow3D.h> #include <mrpt/hwdrivers/CSwissRanger3DCamera.h> #include <mrpt/img/TColor.h> #include <mrpt/maps/CColouredPointsMap.h> #include <mrpt/obs/CObservation3DRangeScan.h> #include <mrpt/opengl/CGridPlaneXY.h> #include <mrpt/opengl/CPointCloudColoured.h> #include <mrpt/opengl/CTexturedPlane.h> #include <mrpt/opengl/stock_objects.h> #include <mrpt/system/CTicTac.h> #include <chrono> #include <iostream> #include <thread> using namespace mrpt; using namespace mrpt::hwdrivers; using namespace mrpt::math; using namespace mrpt::gui; using namespace mrpt::maps; using namespace mrpt::obs; using namespace mrpt::opengl; using namespace mrpt::system; using namespace mrpt::img; using namespace std; // ------------------------------------------------------ // Test_SwissRanger // ------------------------------------------------------ void Test_SwissRanger() { CSwissRanger3DCamera cam; // Set params: cam.setOpenFromUSB(true); cam.setSave3D(true); cam.setSaveRangeImage(true); cam.setSaveIntensityImage(true); cam.setSaveConfidenceImage(false); // cam.enablePreviewWindow(true); // Open: cam.initialize(); if (cam.isOpen()) cout << "[Test_SwissRanger] Camera open, serial #" << cam.getCameraSerialNumber() << " resolution: " << cam.cols() << "x" << cam.rows() << " max. range: " << cam.getMaxRange() << endl; const double aspect_ratio = cam.rows() / double(cam.cols()); { std::string ver; cam.getMesaLibVersion(ver); cout << "[Test_SwissRanger] Version: " << ver << "\n"; } CObservation3DRangeScan obs; bool there_is_obs = true, hard_error; mrpt::gui::CDisplayWindow3D win3D("3D camera view", 800, 600); win3D.setCameraAzimuthDeg(140); win3D.setCameraElevationDeg(20); win3D.setCameraZoom(6.0); win3D.setCameraPointingToPoint(2.5, 0, 0); // mrpt::gui::CDisplayWindow win2D("2D range image",200,200); // mrpt::gui::CDisplayWindow winInt("Intensity range image",200,200); // win2D.setPos(10,10); // winInt.setPos(350,10); // win3D.setPos(10,290); // win3D.resize(400,200); // mrpt::opengl::CPointCloud::Ptr gl_points = // mrpt::opengl::CPointCloud::Create(); mrpt::opengl::CPointCloudColoured::Ptr gl_points = mrpt::opengl::CPointCloudColoured::Create(); gl_points->setPointSize(4.5); mrpt::opengl::CTexturedPlane::Ptr gl_img_range = mrpt::opengl::CTexturedPlane::Create( 0.5, -0.5, -0.5 * aspect_ratio, 0.5 * aspect_ratio); mrpt::opengl::CTexturedPlane::Ptr gl_img_intensity = mrpt::opengl::CTexturedPlane::Create( 0.5, -0.5, -0.5 * aspect_ratio, 0.5 * aspect_ratio); mrpt::opengl::CTexturedPlane::Ptr gl_img_intensity_rect = mrpt::opengl::CTexturedPlane::Create( 0.5, -0.5, -0.5 * aspect_ratio, 0.5 * aspect_ratio); { mrpt::opengl::Scene::Ptr& scene = win3D.get3DSceneAndLock(); // Create the Opengl object for the point cloud: scene->insert(gl_points); scene->insert(mrpt::opengl::CGridPlaneXY::Create()); scene->insert(mrpt::opengl::stock_objects::CornerXYZ()); const int VW_WIDTH = 200; const int VW_HEIGHT = 150; const int VW_GAP = 10; // Create the Opengl objects for the planar images, as textured planes, // each in a separate viewport: win3D.addTextMessage( 30, -10 - 1 * (VW_GAP + VW_HEIGHT), "Range data", 1); opengl::Viewport::Ptr viewRange = scene->createViewport("view2d_range"); scene->insert(gl_img_range, "view2d_range"); viewRange->setViewportPosition( 5, -10 - 1 * (VW_GAP + VW_HEIGHT), VW_WIDTH, VW_HEIGHT); viewRange->setTransparent(true); viewRange->getCamera().setOrthogonal(true); viewRange->getCamera().setAzimuthDegrees(90); viewRange->getCamera().setElevationDegrees(90); viewRange->getCamera().setZoomDistance(1.0); win3D.addTextMessage( 30, -10 - 2 * (VW_GAP + VW_HEIGHT), "Intensity data", 2); opengl::Viewport::Ptr viewInt = scene->createViewport("view2d_int"); scene->insert(gl_img_intensity, "view2d_int"); viewInt->setViewportPosition( 5, -10 - 2 * (VW_GAP + VW_HEIGHT), VW_WIDTH, VW_HEIGHT); viewInt->setTransparent(true); viewInt->getCamera().setOrthogonal(true); viewInt->getCamera().setAzimuthDegrees(90); viewInt->getCamera().setElevationDegrees(90); viewInt->getCamera().setZoomDistance(1.0); win3D.addTextMessage( 30, -10 - 3 * (VW_GAP + VW_HEIGHT), "Intensity data (undistorted)", 3); opengl::Viewport::Ptr viewIntRect = scene->createViewport("view2d_intrect"); scene->insert(gl_img_intensity_rect, "view2d_intrect"); viewIntRect->setViewportPosition( 5, -10 - 3 * (VW_GAP + VW_HEIGHT), VW_WIDTH, VW_HEIGHT); viewIntRect->setTransparent(true); viewIntRect->getCamera().setOrthogonal(true); viewIntRect->getCamera().setAzimuthDegrees(90); viewIntRect->getCamera().setElevationDegrees(90); viewIntRect->getCamera().setZoomDistance(1.0); win3D.unlockAccess3DScene(); win3D.repaint(); } CTicTac tictac; size_t nImgs = 0; bool endLoop = false; while (there_is_obs && !endLoop && win3D.isOpen()) { // Grab new observation from the camera: cam.getNextObservation(obs, there_is_obs, hard_error); // Show ranges as 2D: if (there_is_obs && obs.hasRangeImage) { mrpt::img::CImage img = obs.rangeImage_getAsImage(); win3D.get3DSceneAndLock(); gl_img_range->assignImage(std::move(img)); win3D.unlockAccess3DScene(); } // Show intensity image: if (there_is_obs && obs.hasIntensityImage) { win3D.get3DSceneAndLock(); gl_img_intensity->assignImage(obs.intensityImage); CImage undistortImg; obs.intensityImage.undistort(undistortImg, obs.cameraParams); gl_img_intensity_rect->assignImage(undistortImg); win3D.unlockAccess3DScene(); } // Show 3D points: if (there_is_obs && obs.hasPoints3D) { // mrpt::maps::CSimplePointsMap pntsMap; CColouredPointsMap pntsMap; pntsMap.colorScheme.scheme = CColouredPointsMap::cmFromIntensityImage; pntsMap.loadFromRangeScan(obs); win3D.get3DSceneAndLock(); gl_points->loadFromPointsMap(&pntsMap); win3D.unlockAccess3DScene(); win3D.repaint(); } nImgs++; if (nImgs > 10) { win3D.get3DSceneAndLock(); win3D.addTextMessage( 0.01, 0.01, format("%.02f Hz", nImgs / tictac.Tac()), 100); win3D.unlockAccess3DScene(); nImgs = 0; tictac.Tic(); } // Process possible keyboard commands: // -------------------------------------- if (win3D.keyHit()) { const int key = tolower(win3D.getPushedKey()); // cout << "key: " << key << endl; switch (key) { case 'h': cam.enableImageHistEqualization( !cam.isEnabledImageHistEqualization()); break; case 'g': cam.enableConvGray(!cam.isEnabledConvGray()); break; case 'd': cam.enableDenoiseANF(!cam.isEnabledDenoiseANF()); break; case 'f': cam.enableMedianFilter(!cam.isEnabledMedianFilter()); break; case 27: endLoop = true; break; } } win3D.get3DSceneAndLock(); win3D.addTextMessage( 0.08, 0.02, format( "Keyboard switches: H (hist.equal: %s) | G (convGray: %s) | D " "(denoise: %s) | F (medianFilter: %s)", cam.isEnabledImageHistEqualization() ? "ON" : "OFF", cam.isEnabledConvGray() ? "ON" : "OFF", cam.isEnabledDenoiseANF() ? "ON" : "OFF", cam.isEnabledMedianFilter() ? "ON" : "OFF"), 110); win3D.unlockAccess3DScene(); std::this_thread::sleep_for(1ms); } } int main(int argc, char** argv) { try { Test_SwissRanger(); return 0; } catch (const std::exception& e) { std::cerr << "MRPT error: " << mrpt::exception_to_str(e) << std::endl; return -1; } catch (...) { printf("Another exception!!"); return -1; } }