Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
costmap_2d.py
1 #! /usr/bin/env python3
2 # Copyright 2021 Samsung Research America
3 # Copyright 2022 Stevedan Ogochukwu Omodolor
4 # Copyright 2022 Jaehun Jackson Kim
5 # Copyright 2022 Afif Swaidan
6 #
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
10 #
11 # http://www.apache.org/licenses/LICENSE-2.0
12 #
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
18 
19 """
20 This is a Python3 API for costmap 2d messages from the stack.
21 
22 It provides the basic conversion, get/set,
23 and handling semantics found in the costmap 2d C++ API.
24 """
25 
26 from typing import Optional
27 
28 from builtin_interfaces.msg import Time
29 from nav_msgs.msg import OccupancyGrid
30 import numpy as np
31 from numpy.typing import NDArray
32 
33 
35  """
36  PyCostmap2D.
37 
38  Costmap Python3 API for OccupancyGrids to populate from published messages
39  """
40 
41  def __init__(self, occupancy_map: OccupancyGrid) -> None:
42  """
43  Initialize costmap2D.
44 
45  Args
46  ----
47  occupancy_map (OccupancyGrid): 2D OccupancyGrid Map
48 
49  Returns
50  -------
51  None
52 
53  """
54  self.size_x: int = occupancy_map.info.width
55  self.size_y: int = occupancy_map.info.height
56  self.resolution: float = occupancy_map.info.resolution
57  self.origin_x: float = occupancy_map.info.origin.position.x
58  self.origin_y: float = occupancy_map.info.origin.position.y
59  self.global_frame_id: str = occupancy_map.header.frame_id
60  self.costmap_timestamp: Time = occupancy_map.header.stamp
61  # Extract costmap
62  self.costmap: NDArray[np.uint8] = np.array(occupancy_map.data, dtype=np.uint8)
63 
64  def getSizeInCellsX(self) -> int:
65  """Get map width in cells."""
66  return self.size_x
67 
68  def getSizeInCellsY(self) -> int:
69  """Get map height in cells."""
70  return self.size_y
71 
72  def getSizeInMetersX(self) -> float:
73  """Get x axis map size in meters."""
74  return (self.size_x - 1 + 0.5) * self.resolution
75 
76  def getSizeInMetersY(self) -> float:
77  """Get y axis map size in meters."""
78  return (self.size_y - 1 + 0.5) * self.resolution
79 
80  def getOriginX(self) -> float:
81  """Get the origin x axis of the map [m]."""
82  return self.origin_x
83 
84  def getOriginY(self) -> float:
85  """Get the origin y axis of the map [m]."""
86  return self.origin_y
87 
88  def getResolution(self) -> float:
89  """Get map resolution [m/cell]."""
90  return self.resolution
91 
92  def getGlobalFrameID(self) -> str:
93  """Get global frame_id."""
94  return self.global_frame_id
95 
96  def getCostmapTimestamp(self) -> Time:
97  """Get costmap timestamp."""
98  return self.costmap_timestamp
99 
100  def getCostXY(self, mx: int, my: int) -> np.uint8:
101  """
102  Get the cost of a cell in the costmap using map coordinate XY.
103 
104  Args
105  ----
106  mx (int): map coordinate X to get cost
107  my (int): map coordinate Y to get cost
108 
109  Returns
110  -------
111  np.uint8: cost of a cell
112 
113  """
114  return np.uint8(self.costmap[self.getIndexgetIndex(mx, my)])
115 
116  def getCostIdx(self, index: int) -> np.uint8:
117  """
118  Get the cost of a cell in the costmap using Index.
119 
120  Args
121  ----
122  index (int): index of cell to get cost
123 
124  Returns
125  -------
126  np.uint8: cost of a cell
127 
128  """
129  return np.uint8(self.costmap[index])
130 
131  def setCost(self, mx: int, my: int, cost: np.uint8) -> None:
132  """
133  Set the cost of a cell in the costmap using map coordinate XY.
134 
135  Args
136  ----
137  mx (int): map coordinate X to get cost
138  my (int): map coordinate Y to get cost
139  cost (np.uint8): The cost to set the cell
140 
141  Returns
142  -------
143  None
144 
145  """
146  self.costmap[self.getIndexgetIndex(mx, my)] = cost
147 
148  def mapToWorld(self, mx: int, my: int) -> tuple[float, float]:
149  """
150  Get the world coordinate XY using map coordinate XY.
151 
152  Args
153  ----
154  mx (int): map coordinate X to get world coordinate
155  my (int): map coordinate Y to get world coordinate
156 
157  Returns
158  -------
159  tuple of float: wx, wy
160  wx (float) [m]: world coordinate X
161  wy (float) [m]: world coordinate Y
162 
163  """
164  wx = self.origin_x + (mx + 0.5) * self.resolution
165  wy = self.origin_y + (my + 0.5) * self.resolution
166  return (wx, wy)
167 
168  def worldToMapValidated(self, wx: float, wy: float) -> tuple[Optional[int], Optional[int]]:
169  """
170  Get the map coordinate XY using world coordinate XY.
171 
172  Args
173  ----
174  wx (float) [m]: world coordinate X to get map coordinate
175  wy (float) [m]: world coordinate Y to get map coordinate
176 
177  Returns
178  -------
179  (None, None): if coordinates are invalid
180  tuple of int: mx, my (if coordinates are valid)
181  mx (int): map coordinate X
182  my (int): map coordinate Y
183 
184  """
185  if wx < self.origin_x or wy < self.origin_y:
186  return (None, None)
187  mx = int((wx - self.origin_x) // self.resolution)
188  my = int((wy - self.origin_y) // self.resolution)
189  if mx < self.size_x and my < self.size_y:
190  return (mx, my)
191  return (None, None)
192 
193  def getIndex(self, mx: int, my: int) -> int:
194  """
195  Get the index of the cell using map coordinate XY.
196 
197  Args
198  ----
199  mx (int): map coordinate X to get Index
200  my (int): map coordinate Y to get Index
201 
202  Returns
203  -------
204  int: The index of the cell
205 
206  """
207  return my * self.size_x + mx
tuple[float, float] mapToWorld(self, int mx, int my)
Definition: costmap_2d.py:148
None setCost(self, int mx, int my, np.uint8 cost)
Definition: costmap_2d.py:131
None __init__(self, OccupancyGrid occupancy_map)
Definition: costmap_2d.py:41
tuple[Optional[int], Optional[int]] worldToMapValidated(self, float wx, float wy)
Definition: costmap_2d.py:168
np.uint8 getCostXY(self, int mx, int my)
Definition: costmap_2d.py:100
np.uint8 getCostIdx(self, int index)
Definition: costmap_2d.py:116