OctomapServerMultilayer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2013, A. Hornung, M. Philips
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 
31 
32 using namespace octomap;
33 
34 namespace octomap_server{
35 
36 
37 
38 OctomapServerMultilayer::OctomapServerMultilayer(ros::NodeHandle private_nh_)
39 : OctomapServer(private_nh_)
40 {
41 
42  // TODO: callback for arm_navigation attached objects was removed, is
43  // there a replacement functionality?
44 
45  // TODO: param maps, limits
46  // right now 0: base, 1: spine, 2: arms
47  ProjectedMap m;
48  m.name = "projected_base_map";
49  m.minZ = 0.0;
50  m.maxZ = 0.3;
51  m.z = 0.0;
52  m_multiGridmap.push_back(m);
53 
54  m.name = "projected_spine_map";
55  m.minZ = 0.25;
56  m.maxZ = 1.4;
57  m.z = 0.6;
58  m_multiGridmap.push_back(m);
59 
60  m.name = "projected_arm_map";
61  m.minZ = 0.7;
62  m.maxZ = 0.9;
63  m.z = 0.8;
64  m_multiGridmap.push_back(m);
65 
66 
67  for (unsigned i = 0; i < m_multiGridmap.size(); ++i){
68  ros::Publisher* pub = new ros::Publisher(m_nh.advertise<nav_msgs::OccupancyGrid>(m_multiGridmap.at(i).name, 5, m_latchedTopics));
69  m_multiMapPub.push_back(pub);
70  }
71 
72  // init arm links (could be params as well)
73  m_armLinks.push_back("l_elbow_flex_link");
74  m_armLinkOffsets.push_back(0.10);
75  m_armLinks.push_back("l_gripper_l_finger_tip_link");
76  m_armLinkOffsets.push_back(0.03);
77  m_armLinks.push_back("l_gripper_r_finger_tip_link");
78  m_armLinkOffsets.push_back(0.03);
79  m_armLinks.push_back("l_upper_arm_roll_link");
80  m_armLinkOffsets.push_back(0.16);
81  m_armLinks.push_back("l_wrist_flex_link");
82  m_armLinkOffsets.push_back(0.05);
83  m_armLinks.push_back("r_elbow_flex_link");
84  m_armLinkOffsets.push_back(0.10);
85  m_armLinks.push_back("r_gripper_l_finger_tip_link");
86  m_armLinkOffsets.push_back(0.03);
87  m_armLinks.push_back("r_gripper_r_finger_tip_link");
88  m_armLinkOffsets.push_back(0.03);
89  m_armLinks.push_back("r_upper_arm_roll_link");
90  m_armLinkOffsets.push_back(0.16);
91  m_armLinks.push_back("r_wrist_flex_link");
92  m_armLinkOffsets.push_back(0.05);
93 
94 
95 }
96 
98  for (unsigned i = 0; i < m_multiMapPub.size(); ++i){
99  delete m_multiMapPub[i];
100  }
101 
102 }
103 
105  // multilayer server always publishes 2D maps:
106  m_publish2DMap = true;
107  nav_msgs::MapMetaData gridmapInfo = m_gridmap.info;
108 
110 
111 
112  // recalculate height of arm layer (stub, TODO)
113  geometry_msgs::PointStamped vin;
114  vin.point.x = 0;
115  vin.point.y = 0;
116  vin.point.z = 0;
117  vin.header.stamp = rostime;
118  double link_padding = 0.03;
119 
120  double minArmHeight = 2.0;
121  double maxArmHeight = 0.0;
122 
123  for (unsigned i = 0; i < m_armLinks.size(); ++i){
124  vin.header.frame_id = m_armLinks[i];
125  geometry_msgs::PointStamped vout;
126  const bool found_trans =
127  m_tfListener.waitForTransform("base_footprint", m_armLinks.at(i),
128  ros::Time(0), ros::Duration(1.0));
129  ROS_ASSERT_MSG(found_trans, "Timed out waiting for transform to %s",
130  m_armLinks[i].c_str());
131  m_tfListener.transformPoint("base_footprint",vin,vout);
132  maxArmHeight = std::max(maxArmHeight, vout.point.z + (m_armLinkOffsets.at(i) + link_padding));
133  minArmHeight = std::min(minArmHeight, vout.point.z - (m_armLinkOffsets.at(i) + link_padding));
134  }
135  ROS_INFO("Arm layer interval adjusted to (%f,%f)", minArmHeight, maxArmHeight);
136  m_multiGridmap.at(2).minZ = minArmHeight;
137  m_multiGridmap.at(2).maxZ = maxArmHeight;
138  m_multiGridmap.at(2).z = (maxArmHeight+minArmHeight)/2.0;
139 
140 
141 
142 
143 
144  // TODO: also clear multilevel maps in BBX region (see OctomapServer.cpp)?
145 
146  bool mapInfoChanged = mapChanged(gridmapInfo, m_gridmap.info);
147 
148  for (MultilevelGrid::iterator it = m_multiGridmap.begin(); it != m_multiGridmap.end(); ++it){
149  it->map.header = m_gridmap.header;
150  it->map.info = m_gridmap.info;
151  it->map.info.origin.position.z = it->z;
153  ROS_INFO("Map resolution changed, rebuilding complete 2D maps");
154  it->map.data.clear();
155  // init to unknown:
156  it->map.data.resize(it->map.info.width * it->map.info.height, -1);
157  } else if (mapInfoChanged){
158  adjustMapData(it->map, gridmapInfo);
159  }
160  }
161 }
162 
164 
165  // TODO: calc tall / short obs. cells for arm layer, => temp arm layer
166 // std::vector<int> shortObsCells;
167 // for(unsigned int i=0; i<arm_map.data.size(); i++){
168 // if(temp_arm_map.data[i] == 0){
169 // if(map.data[i] == -1)
170 // arm_map.data[i] = -1;
171 // }
172 // else if(arm_map.data[i] == 0)
173 // arm_map.data[i] = 0;
174 // else if(double(arm_map.data[i])/temp_arm_map.data[i] > 0.8)
175 // arm_map.data[i] = 101;
176 // else{
177 // arm_map.data[i] = 100;
178 // shortObsCells.push_back(i);
179 // }
180 // }
181 //
182 // std::vector<int> tallObsCells;
183 // tallObsCells.reserve(shortObsCells.size());
184 // int dxy[8] = {-arm_map.info.width-1, -arm_map.info.width, -arm_map.info.width+1, -1, 1, arm_map.info.width-1, arm_map.info.width, arm_map.info.width+1};
185 // for(unsigned int i=0; i<shortObsCells.size(); i++){
186 // for(int j=0; j<8; j++){
187 // int temp = shortObsCells[i]+dxy[j];
188 // if(temp<0 || temp>=arm_map.data.size())
189 // continue;
190 // if(arm_map.data[temp]==101){
191 // tallObsCells.push_back(shortObsCells[i]);
192 // break;
193 // }
194 // }
195 // }
196 // for(unsigned int i=0; i<tallObsCells.size(); i++)
197 // arm_map.data[tallObsCells[i]] = 101;
198 
199 
200 
202 
203  for (unsigned i = 0; i < m_multiMapPub.size(); ++i){
204  m_multiMapPub[i]->publish(m_multiGridmap.at(i).map);
205  }
206 
207 }
209  double z = it.getZ();
210  double s2 = it.getSize()/2.0;
211 
212  // create a mask on which maps to update:
213  std::vector<bool> inMapLevel(m_multiGridmap.size(), false);
214  for (unsigned i = 0; i < m_multiGridmap.size(); ++i){
215  if (z+s2 >= m_multiGridmap[i].minZ && z-s2 <= m_multiGridmap[i].maxZ){
216  inMapLevel[i] = true;
217  }
218  }
219 
220  if (it.getDepth() == m_maxTreeDepth){
221  unsigned idx = mapIdx(it.getKey());
222  if (occupied)
223  m_gridmap.data[idx] = 100;
224  else if (m_gridmap.data[idx] == -1){
225  m_gridmap.data[idx] = 0;
226  }
227 
228  for (unsigned i = 0; i < inMapLevel.size(); ++i){
229  if (inMapLevel[i]){
230  if (occupied)
231  m_multiGridmap[i].map.data[idx] = 100;
232  else if (m_multiGridmap[i].map.data[idx] == -1)
233  m_multiGridmap[i].map.data[idx] = 0;
234  }
235  }
236 
237  } else {
238  int intSize = 1 << (m_treeDepth - it.getDepth());
239  octomap::OcTreeKey minKey=it.getIndexKey();
240  for(int dx=0; dx < intSize; dx++){
241  int i = (minKey[0]+dx - m_paddedMinKey[0])/m_multires2DScale;
242  for(int dy=0; dy < intSize; dy++){
243  unsigned idx = mapIdx(i, (minKey[1]+dy - m_paddedMinKey[1])/m_multires2DScale);
244  if (occupied)
245  m_gridmap.data[idx] = 100;
246  else if (m_gridmap.data[idx] == -1){
247  m_gridmap.data[idx] = 0;
248  }
249 
250  for (unsigned i = 0; i < inMapLevel.size(); ++i){
251  if (inMapLevel[i]){
252  if (occupied)
253  m_multiGridmap[i].map.data[idx] = 100;
254  else if (m_multiGridmap[i].map.data[idx] == -1)
255  m_multiGridmap[i].map.data[idx] = 0;
256  }
257  }
258  }
259  }
260  }
261 
262 
263 }
264 
265 }
266 
267 
268 
octomap_server::OctomapServer::m_latchedTopics
bool m_latchedTopics
Definition: OctomapServer.h:231
ros::Publisher
octomap_server::OctomapServer::m_paddedMinKey
octomap::OcTreeKey m_paddedMinKey
Definition: OctomapServer.h:264
octomap_server::OctomapServerMultilayer::update2DMap
virtual void update2DMap(const OcTreeT::iterator &it, bool occupied)
updates the downprojected 2D map as either occupied or free
Definition: OctomapServerMultilayer.cpp:208
octomap_server::OctomapServer::handlePreNodeTraversal
virtual void handlePreNodeTraversal(const ros::Time &rostime)
hook that is called before traversing all nodes
Definition: OctomapServer.cpp:943
tf::TransformListener::transformPoint
void transformPoint(const std::string &target_frame, const geometry_msgs::PointStamped &stamped_in, geometry_msgs::PointStamped &stamped_out) const
octomap_server::OctomapServerMultilayer::ProjectedMap::minZ
double minZ
Definition: OctomapServerMultilayer.h:43
octomap_server::OctomapServer::m_multires2DScale
unsigned m_multires2DScale
Definition: OctomapServer.h:265
octomap_server::OctomapServerMultilayer::~OctomapServerMultilayer
virtual ~OctomapServerMultilayer()
Definition: OctomapServerMultilayer.cpp:97
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
octomap_server::OctomapServerMultilayer::m_multiGridmap
MultilevelGrid m_multiGridmap
Definition: OctomapServerMultilayer.h:66
octomap_server::OctomapServer::m_publish2DMap
bool m_publish2DMap
Definition: OctomapServer.h:262
octomap_eraser_cli.max
max
Definition: octomap_eraser_cli.py:24
octomap_server::OctomapServer::mapChanged
bool mapChanged(const nav_msgs::MapMetaData &oldMapInfo, const nav_msgs::MapMetaData &newMapInfo)
Definition: OctomapServer.h:199
octomap_server::OctomapServer::m_nh
ros::NodeHandle m_nh
Definition: OctomapServer.h:207
octomap_server::OctomapServer::adjustMapData
void adjustMapData(nav_msgs::OccupancyGrid &map, const nav_msgs::MapMetaData &oldMapInfo) const
Definition: OctomapServer.cpp:1193
octomap_server::OctomapServerMultilayer::ProjectedMap::maxZ
double maxZ
Definition: OctomapServerMultilayer.h:44
octomap_server::OctomapServer::m_gridmap
nav_msgs::OccupancyGrid m_gridmap
Definition: OctomapServer.h:261
ROS_ASSERT_MSG
#define ROS_ASSERT_MSG(cond,...)
octomap::OcTreeKey
tf::Transformer::waitForTransform
bool waitForTransform(const std::string &target_frame, const ros::Time &target_time, const std::string &source_frame, const ros::Time &source_time, const std::string &fixed_frame, const ros::Duration &timeout, const ros::Duration &polling_sleep_duration=ros::Duration(0.01), std::string *error_msg=NULL) const
octomap_server
Definition: OctomapServer.h:80
OcTreeBaseImpl< OcTreeNode, AbstractOccupancyOcTree >::iterator
leaf_iterator iterator
ros::Time
octomap_server::OctomapServer::m_treeDepth
unsigned m_treeDepth
Definition: OctomapServer.h:235
octomap_server::OctomapServerMultilayer::handlePreNodeTraversal
virtual void handlePreNodeTraversal(const ros::Time &rostime)
hook that is called after traversing all nodes
Definition: OctomapServerMultilayer.cpp:104
octomap_server::OctomapServerMultilayer::ProjectedMap
Definition: OctomapServerMultilayer.h:42
octomap_server::OctomapServer::mapIdx
unsigned mapIdx(int i, int j) const
Definition: OctomapServer.h:181
OctomapServerMultilayer.h
octomap_server::OctomapServerMultilayer::handlePostNodeTraversal
virtual void handlePostNodeTraversal(const ros::Time &rostime)
hook that is called after traversing all nodes
Definition: OctomapServerMultilayer.cpp:163
octomap_server::OctomapServerMultilayer::m_multiMapPub
std::vector< ros::Publisher * > m_multiMapPub
Definition: OctomapServerMultilayer.h:60
octomap_server::OctomapServer
Definition: OctomapServer.h:81
octomap_server::OctomapServer::m_tfListener
tf::TransformListener m_tfListener
Definition: OctomapServer.h:213
octomap_server::OctomapServer::m_projectCompleteMap
bool m_projectCompleteMap
Definition: OctomapServer.h:266
octomap
ROS_INFO
#define ROS_INFO(...)
octomap_server::OctomapServer::m_maxTreeDepth
unsigned m_maxTreeDepth
Definition: OctomapServer.h:236
ros::Duration
octomap_server::OctomapServerMultilayer::m_armLinkOffsets
std::vector< double > m_armLinkOffsets
Definition: OctomapServerMultilayer.h:64
octomap_server::OctomapServerMultilayer::ProjectedMap::name
std::string name
Definition: OctomapServerMultilayer.h:46
octomap_server::OctomapServer::handlePostNodeTraversal
virtual void handlePostNodeTraversal(const ros::Time &rostime)
hook that is called after traversing all nodes
Definition: OctomapServer.cpp:1053
ros::NodeHandle
octomap_server::OctomapServerMultilayer::m_armLinks
std::vector< std::string > m_armLinks
Definition: OctomapServerMultilayer.h:63
octomap_server::OctomapServerMultilayer::ProjectedMap::z
double z
Definition: OctomapServerMultilayer.h:45


octomap_server
Author(s): Armin Hornung
autogenerated on Mon Jan 2 2023 03:18:15