/* * Copyright 2010 SRI International * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include /** * Sample code to demonstrate karto map creation * Create a laser range finder device and three "dummy" range scans. * Add the device and range scans to a karto Mapper. */ karto::Dataset* CreateMap(karto::Mapper* pMapper) { karto::Dataset* pDataset = new karto::Dataset(); ///////////////////////////////////// // Create a laser range finder device - use SmartPointer to let karto subsystem manage memory. karto::Name name("laser0"); karto::LaserRangeFinder* pLaserRangeFinder = karto::LaserRangeFinder::CreateLaserRangeFinder(karto::LaserRangeFinder_Custom, name); pLaserRangeFinder->SetOffsetPose(karto::Pose2(1.0, 0.0, 0.0)); pLaserRangeFinder->SetAngularResolution(karto::math::DegreesToRadians(0.5)); pLaserRangeFinder->SetRangeThreshold(12.0); pDataset->Add(pLaserRangeFinder); ///////////////////////////////////// // Create three localized range scans, all using the same range readings, but with different poses. karto::LocalizedRangeScan* pLocalizedRangeScan = NULL; // 1. localized range scan // Create a vector of range readings. Simple example where all the measurements are the same value. std::vector readings; for (int i=0; i<361; i++) { readings.push_back(3.0); } // create localized range scan pLocalizedRangeScan = new karto::LocalizedRangeScan(name, readings); pLocalizedRangeScan->SetOdometricPose(karto::Pose2(0.0, 0.0, 0.0)); pLocalizedRangeScan->SetCorrectedPose(karto::Pose2(0.0, 0.0, 0.0)); // Add the localized range scan to the mapper pMapper->Process(pLocalizedRangeScan); std::cout << "Pose: " << pLocalizedRangeScan->GetOdometricPose() << " Corrected Pose: " << pLocalizedRangeScan->GetCorrectedPose() << std::endl; // Add the localized range scan to the dataset pDataset->Add(pLocalizedRangeScan); // 2. localized range scan // create localized range scan pLocalizedRangeScan = new karto::LocalizedRangeScan(name, readings); pLocalizedRangeScan->SetOdometricPose(karto::Pose2(1.0, 0.0, 1.57)); pLocalizedRangeScan->SetCorrectedPose(karto::Pose2(1.0, 0.0, 1.57)); // Add the localized range scan to the mapper pMapper->Process(pLocalizedRangeScan); std::cout << "Pose: " << pLocalizedRangeScan->GetOdometricPose() << " Corrected Pose: " << pLocalizedRangeScan->GetCorrectedPose() << std::endl; // Add the localized range scan to the dataset pDataset->Add(pLocalizedRangeScan); // 3. localized range scan // create localized range scan pLocalizedRangeScan = new karto::LocalizedRangeScan(name, readings); pLocalizedRangeScan->SetOdometricPose(karto::Pose2(1.0, -1.0, 2.35619449)); pLocalizedRangeScan->SetCorrectedPose(karto::Pose2(1.0, -1.0, 2.35619449)); // Add the localized range scan to the mapper pMapper->Process(pLocalizedRangeScan); std::cout << "Pose: " << pLocalizedRangeScan->GetOdometricPose() << " Corrected Pose: " << pLocalizedRangeScan->GetCorrectedPose() << std::endl; // Add the localized range scan to the dataset pDataset->Add(pLocalizedRangeScan); return pDataset; } /** * Sample code to demonstrate basic occupancy grid creation and print occupancy grid. */ karto::OccupancyGrid* CreateOccupancyGrid(karto::Mapper* pMapper, kt_double resolution) { std::cout << "Generating map..." << std::endl; // Create a map (occupancy grid) - time it karto::OccupancyGrid* pOccupancyGrid = karto::OccupancyGrid::CreateFromScans(pMapper->GetAllProcessedScans(), resolution); return pOccupancyGrid; } /** * Sample code to print a basic occupancy grid */ void PrintOccupancyGrid(karto::OccupancyGrid* pOccupancyGrid) { if (pOccupancyGrid != NULL) { // Output ASCII representation of map kt_int32s width = pOccupancyGrid->GetWidth(); kt_int32s height = pOccupancyGrid->GetHeight(); karto::Vector2 offset = pOccupancyGrid->GetCoordinateConverter()->GetOffset(); std::cout << "width = " << width << ", height = " << height << ", scale = " << pOccupancyGrid->GetCoordinateConverter()->GetScale() << ", offset: " << offset.GetX() << ", " << offset.GetY() << std::endl; for (kt_int32s y=height-1; y>=0; y--) { for (kt_int32s x=0; xGetValue(karto::Vector2(x, y)); switch (value) { case karto::GridStates_Unknown: std::cout << "*"; break; case karto::GridStates_Occupied: std::cout << "X"; break; case karto::GridStates_Free: std::cout << " "; break; default: std::cout << "?"; } } std::cout << std::endl; } std::cout << std::endl; } } int main(int /*argc*/, char **/*argv*/) { // use try/catch to catch karto exceptions that might be thrown by the karto subsystem. ///////////////////////////////////// // Get karto default mapper karto::Mapper* pMapper = new karto::Mapper(); if (pMapper != NULL) { karto::OccupancyGrid* pOccupancyGrid = NULL; ///////////////////////////////////// // sample code that creates a map from sample device and sample localized range scans std::cout << "Tutorial 1 ----------------" << std::endl << std::endl; // clear mapper pMapper->Reset(); // create map from created dataset karto::Dataset* pDataset = CreateMap(pMapper); // create occupancy grid at 0.1 resolution and print grid pOccupancyGrid = CreateOccupancyGrid(pMapper, 0.1); PrintOccupancyGrid(pOccupancyGrid); delete pOccupancyGrid; // delete mapper delete pMapper; delete pDataset; } return 0; }