SlamNode.cpp
Go to the documentation of this file.
00001 /*
00002  * SlamNode.cpp
00003  *
00004  *  Created on: 05.05.2014
00005  *      Author: phil
00006  */
00007 
00008 #include "SlamNode.h"
00009 #include "ThreadMapping.h"
00010 #include "ThreadGrid.h"
00011 #include "ThreadLocalize.h"
00012 
00013 #include "obcore/math/mathbase.h"
00014 
00015 
00016 namespace ohm_tsd_slam
00017 {
00018 SlamNode::SlamNode(void)
00019 {
00020   ros::NodeHandle prvNh("~");
00021   int iVar                   = 0;
00022   double gridPublishInterval = 0.0;
00023   double loopRateVar         = 0.0;
00024   double truncationRadius    = 0.0;
00025   double cellSize            = 0.0;
00026   unsigned int octaveFactor  = 0;
00027   double xOffset = 0.0;
00028   double yOffset = 0.0;
00029   std::string topicLaser;
00030   prvNh.param<int>("robot_nbr", iVar, 1);
00031   unsigned int robotNbr = static_cast<unsigned int>(iVar);
00032   prvNh.param<double>("x_off_factor", _xOffFactor, 0.5);
00033   prvNh.param<double>("y_off_factor", _yOffFactor, 0.5);
00034   prvNh.param<double>("x_offset", xOffset, 0.0);
00035   prvNh.param<double>("y_offset", yOffset, 0.0);
00036 
00037 
00038   prvNh.param<int>("map_size", iVar, 10);
00039   octaveFactor = static_cast<unsigned int>(iVar);
00040   prvNh.param<double>("cellsize", cellSize, 0.025);
00041   prvNh.param<int>("truncation_radius", iVar, 3);
00042   truncationRadius = static_cast<double>(iVar);
00043   prvNh.param<double>("occ_grid_time_interval", gridPublishInterval, 2.0);
00044   prvNh.param<double>("loop_rate", loopRateVar, 40.0);
00045   prvNh.param<std::string>("laser_topic", topicLaser, "scan");
00046 
00047   _loopRate = new ros::Rate(loopRateVar);
00048   _gridInterval = new ros::Duration(gridPublishInterval);
00049 
00050   if(octaveFactor > 15)
00051   {
00052     ROS_ERROR_STREAM("Error! Unknown map size -> set to default!" << std::endl);
00053     octaveFactor = 10;
00054   }
00055   //instanciate representation
00056   _grid = new obvious::TsdGrid(cellSize, obvious::LAYOUT_32x32, static_cast<obvious::EnumTsdGridLayout>(octaveFactor));  //obvious::LAYOUT_8192x8192
00057   _grid->setMaxTruncation(truncationRadius * cellSize);
00058   unsigned int cellsPerSide = pow(2, octaveFactor);
00059   double sideLength = static_cast<double>(cellsPerSide) * cellSize;
00060   ROS_INFO_STREAM("Creating representation with " << cellsPerSide << "x" << cellsPerSide << "cells, representating " <<
00061                   sideLength << "x" << sideLength << "m^2" << std::endl);
00062   //instanciate mapping threads
00063   _threadMapping = new ThreadMapping(_grid);
00064   _threadGrid    = new ThreadGrid(_grid, &_nh, xOffset, yOffset);
00065 
00066   ThreadLocalize* threadLocalize = NULL;
00067   ros::Subscriber subs;
00068   std::string nameSpace;
00069 
00070   //instanciate localization threads
00071   if(robotNbr == 1)  //single slam
00072   {
00073     nameSpace = "";   //empty namespace
00074     threadLocalize = new ThreadLocalize(_grid,_threadMapping, &_nh, nameSpace, xOffset, yOffset);
00075     subs = _nh.subscribe(topicLaser, 1, &ThreadLocalize::laserCallBack, threadLocalize);
00076     _subsLaser.push_back(subs);
00077     _localizers.push_back(threadLocalize);
00078     ROS_INFO_STREAM("Single SLAM started" << std::endl);
00079   }
00080   else
00081   {
00082     for(unsigned int i = 0; i < robotNbr; i++)   //multi slam
00083     {
00084       std::stringstream sstream;
00085       sstream << "robot";
00086       sstream << i << "/namespace";
00087       std::string dummy = sstream.str();
00088       prvNh.param(dummy, nameSpace, std::string("default_ns"));
00089       threadLocalize = new ThreadLocalize(_grid,_threadMapping, &_nh, nameSpace, xOffset, yOffset);
00090       subs = _nh.subscribe(nameSpace + "/" + topicLaser, 1, &ThreadLocalize::laserCallBack, threadLocalize);
00091       _subsLaser.push_back(subs);
00092       _localizers.push_back(threadLocalize);
00093       ROS_INFO_STREAM("started for thread for " << nameSpace << std::endl);
00094     }
00095     ROS_INFO_STREAM("Multi SLAM started!");
00096   }
00097 }
00098 
00099 SlamNode::~SlamNode()
00100 {
00101   //stop all localization threads
00102   for(std::vector<ThreadLocalize*>::iterator iter = _localizers.begin(); iter < _localizers.end(); iter++)
00103   {
00104     (*iter)->terminateThread();
00105     while((*iter)->alive(THREAD_TERM_MS))
00106       usleep(THREAD_TERM_MS);
00107     delete *iter;
00108   }
00109   delete _loopRate;
00110   delete _gridInterval;
00111   //stop mapping threads
00112   _threadGrid->terminateThread();
00113   while(_threadGrid->alive(THREAD_TERM_MS))
00114     usleep(THREAD_TERM_MS);
00115   delete _threadGrid;
00116   _threadMapping->terminateThread();
00117   while(_threadMapping->alive(THREAD_TERM_MS))
00118     usleep(THREAD_TERM_MS);
00119   delete _threadMapping;
00120   delete _grid;
00121 }
00122 
00123 void SlamNode::timedGridPub(void)
00124 {
00125   static ros::Time lastMap = ros::Time::now();
00126   ros::Time curTime = ros::Time::now();
00127   if((curTime - lastMap).toSec() > _gridInterval->toSec())
00128   {
00129     _threadGrid->unblock();
00130     lastMap = ros::Time::now();
00131   }
00132 }
00133 
00134 void SlamNode::run(void)
00135 {
00136   ROS_INFO_STREAM("Waiting for first laser scan to initialize node...\n");
00137   while(ros::ok())
00138   {
00139     ros::spinOnce();
00140     this->timedGridPub();
00141     _loopRate->sleep();
00142   }
00143 }
00144 
00145 } /* namespace ohm_tsd_slam */


ohm_tsd_slam
Author(s): Philipp Koch, Stefan May, Markus Kühn
autogenerated on Thu Jun 6 2019 17:41:12