octomap_saver.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2013, A. Hornung, University of Freiburg
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the University of Freiburg nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <ros/ros.h>
32 #include <octomap/octomap.h>
33 #include <fstream>
34 
35 #include <octomap_msgs/GetOctomap.h>
36 using octomap_msgs::GetOctomap;
37 
38 #define USAGE "\nUSAGE: octomap_saver [-f] <mapfile.[bt|ot]>\n" \
39  " -f: Query for the full occupancy octree, instead of just the compact binary one\n" \
40  " mapfile.bt: filename of map to be saved (.bt: binary tree, .ot: general octree)\n"
41 
42 using namespace std;
43 using namespace octomap;
44 
45 class MapSaver{
46 public:
47  MapSaver(const std::string& mapname, bool full){
49  std::string servname = "octomap_binary";
50  if (full)
51  servname = "octomap_full";
52  ROS_INFO("Requesting the map from %s...", n.resolveName(servname).c_str());
53  GetOctomap::Request req;
54  GetOctomap::Response resp;
55  while(n.ok() && !ros::service::call(servname, req, resp))
56  {
57  ROS_WARN("Request to %s failed; trying again...", n.resolveName(servname).c_str());
58  usleep(1000000);
59  }
60 
61  if (n.ok()){ // skip when CTRL-C
62 
63  AbstractOcTree* tree = octomap_msgs::msgToMap(resp.map);
64  AbstractOccupancyOcTree* octree = NULL;
65  if (tree){
66  octree = dynamic_cast<AbstractOccupancyOcTree*>(tree);
67  } else {
68  ROS_ERROR("Error creating octree from received message");
69  if (resp.map.id == "ColorOcTree")
70  ROS_WARN("You requested a binary map for a ColorOcTree - this is currently not supported. Please add -f to request a full map");
71  }
72 
73  if (octree){
74  ROS_INFO("Map received (%zu nodes, %f m res), saving to %s", octree->size(), octree->getResolution(), mapname.c_str());
75 
76  std::string suffix = mapname.substr(mapname.length()-3, 3);
77  if (suffix== ".bt"){ // write to binary file:
78  if (!octree->writeBinary(mapname)){
79  ROS_ERROR("Error writing to file %s", mapname.c_str());
80  }
81  } else if (suffix == ".ot"){ // write to full .ot file:
82  if (!octree->write(mapname)){
83  ROS_ERROR("Error writing to file %s", mapname.c_str());
84  }
85  } else{
86  ROS_ERROR("Unknown file extension, must be either .bt or .ot");
87  }
88 
89 
90  } else{
91  ROS_ERROR("Error reading OcTree from stream");
92  }
93 
94  delete octree;
95 
96  }
97  }
98 };
99 
100 int main(int argc, char** argv){
101  ros::init(argc, argv, "octomap_saver");
102  std::string mapFilename("");
103  bool fullmap = false;
104  if (argc == 3 && strcmp(argv[1], "-f")==0){
105  fullmap = true;
106  mapFilename = std::string(argv[2]);
107  } else if (argc == 2)
108  mapFilename = std::string(argv[1]);
109  else{
110  ROS_ERROR("%s", USAGE);
111  exit(1);
112  }
113 
114  try{
115  MapSaver ms(mapFilename, fullmap);
116  }catch(std::runtime_error& e){
117  ROS_ERROR("octomap_saver exception: %s", e.what());
118  exit(2);
119  }
120 
121  exit(0);
122 }
123 
124 
int main(int argc, char **argv)
std::string resolveName(const std::string &name, bool remap=true) const
bool call(const std::string &service_name, MReq &req, MRes &res)
static octomap::AbstractOcTree * msgToMap(const Octomap &msg)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
#define ROS_WARN(...)
virtual size_t size() const =0
virtual double getResolution() const =0
#define ROS_INFO(...)
#define USAGE
bool writeBinary(const std::string &filename)
bool write(const std::string &filename) const
MapSaver(const std::string &mapname, bool full)
bool ok() const
#define ROS_ERROR(...)


octomap_server
Author(s): Armin Hornung
autogenerated on Tue Jan 26 2021 03:27:07