23Utility functions for coverage environment
38from .core
import CoverageSystem, DblVector, DblVectorVector, Parameters, PointVector
44 Class for utility functions for coverage environment
48 def to_tensor(data: object) -> torch.Tensor:
50 Converts various types of data to torch.Tensor
52 Can accept the following types:
62 torch.Tensor: converted data
65 ValueError: if data type is not supported
69 if isinstance(data, numpy.ndarray):
70 return torch.from_numpy(numpy.copy(data.astype(numpy.float32)))
72 if isinstance(data, PointVector):
73 data_tensor = torch.Tensor(len(data), 2)
75 for i, _
in enumerate(data):
76 data_tensor[i] = CoverageEnvUtils.to_tensor(data[i])
80 if isinstance(data, DblVectorVector):
81 data_tensor = torch.Tensor(len(data))
83 for i, _
in enumerate(data):
84 data_tensor[i] = CoverageEnvUtils.to_tensor(data[i])
88 if isinstance(data, DblVector):
89 data_tensor = torch.Tensor(len(data))
91 for i, _
in enumerate(data):
92 data_tensor[i] = float(data[i])
95 raise ValueError(f
"Unknown data type: {type(data)}")
103 env: coverage environment
107 torch.Tensor: raw local maps
110 local_maps = torch.zeros(
111 (env.GetNumRobots(), params.pLocalMapSize, params.pLocalMapSize)
114 for r_idx
in range(env.GetNumRobots()):
115 local_maps[r_idx] = CoverageEnvUtils.to_tensor(env.GetRobotLocalMap(r_idx))
122 Get raw obstacle maps
125 env: coverage environment
129 torch.Tensor: raw obstacle maps
132 obstacle_maps = torch.zeros(
133 (env.GetNumRobots(), params.pLocalMapSize, params.pLocalMapSize)
136 for r_idx
in range(env.GetNumRobots()):
137 obstacle_maps[r_idx] = CoverageEnvUtils.to_tensor(
138 env.GetRobotObstacleMap(r_idx)
145 env: CoverageSystem, params: Parameters, map_size: int
148 Generate communication maps from positions
150 Communication maps are composed of two channels.
151 Each channnel has non-zero values for cells that correspond to the relative positions of the neighbors.
152 For the first channel, the value is the x-coordinate of the relative position divided by the communication range.
153 Similarly, the y-coordinte is used for the second channel.
156 env: coverage environment
158 map_size: size of the map
161 torch.Tensor: communication maps
163 num_robots = env.GetNumRobots()
165 comm_maps = torch.zeros((num_robots, 2, map_size, map_size))
167 for r_idx
in range(num_robots):
168 neighbors_pos = CoverageEnvUtils.to_tensor(
169 env.GetRelativePositonsNeighbors(r_idx)
171 scaled_indices = torch.round(
174 / (params.pCommunicationRange * params.pResolution * 2.0)
175 + (map_size / 2.0 - params.pResolution / 2.0)
179 indices = torch.transpose(scaled_indices, 1, 0)
180 indices = indices.long()
181 values = neighbors_pos / params.pCommunicationRange
184 comm_maps[r_idx][0] = torch.sparse_coo_tensor(
185 indices, values[:, 0], torch.Size([map_size, map_size])
187 comm_maps[r_idx][1] = torch.sparse_coo_tensor(
188 indices, values[:, 1], torch.Size([map_size, map_size])
201 def resize_maps(maps: torch.Tensor, resized_map_size: int) -> torch.Tensor:
203 Resize maps to a given size
204 Uses bilinear interpolation from torchvision.transforms.functional.resize
205 Options: antialias=True
209 resized_map_size: size of the resized maps
212 torch.Tensor: resized maps
216 maps = maps.view(-1, maps.shape[-2], maps.shape[-1])
217 maps = torchvision.transforms.functional.resize(
219 (resized_map_size, resized_map_size),
220 interpolation=torchvision.transforms.InterpolationMode.BILINEAR,
223 maps = maps.view(shape[:-2] + maps.shape[-2:])
231 resized_map_size: int,
235 Get maps for the coverage environment
238 env: coverage environment
240 resized_map_size: size of the resized maps
241 use_comm_map: whether to use communication maps
248 num_robots = env.GetNumRobots()
249 raw_local_maps = CoverageEnvUtils.get_raw_local_maps(env, params)
250 resized_local_maps = CoverageEnvUtils.resize_maps(
251 raw_local_maps, resized_map_size
253 raw_obstacle_maps = CoverageEnvUtils.get_raw_obstacle_maps(env, params)
254 resized_obstacle_maps = CoverageEnvUtils.resize_maps(
255 raw_obstacle_maps, resized_map_size
259 comm_maps = env.GetCommunicationMaps(resized_map_size)
261 comm_maps = CoverageEnvUtils.get_communication_maps(
262 env, params, resized_map_size
266 resized_local_maps.unsqueeze(1),
268 resized_obstacle_maps.unsqueeze(1),
274 [resized_local_maps.unsqueeze(1), resized_obstacle_maps.unsqueeze(1)], 1
285 env: coverage environment
288 torch.Tensor: voronoi features
290 features = env.GetRobotVoronoiFeatures()
291 tensor_features = torch.zeros((len(features), len(features[0])))
293 for r_idx, _
in enumerate(features):
294 tensor_features[r_idx] = CoverageEnvUtils.to_tensor(features[r_idx])
296 return tensor_features
304 env: coverage environment
307 torch.Tensor: robot positions
309 robot_positions = CoverageEnvUtils.to_tensor(env.GetRobotPositions())
311 return robot_positions
314 def get_weights(env: CoverageSystem, params: Parameters) -> torch.Tensor:
316 Get edge weights for the communication graph
319 env: coverage environment
323 torch.Tensor: edge weights
325 onebyexp = 1.0 / math.exp(1.0)
326 robot_positions = CoverageEnvUtils.to_tensor(env.GetRobotPositions())
327 pairwise_distances = torch.cdist(robot_positions, robot_positions, 2)
328 edge_weights = torch.exp(
329 -(pairwise_distances.square())
330 / (params.pCommunicationRange * params.pCommunicationRange)
332 edge_weights.masked_fill_(edge_weights < onebyexp, 0)
333 edge_weights.fill_diagonal_(0)
344 ) -> torch_geometric.data.Data:
346 Get torch geometric data
347 In this function, the edge weights are binary
350 env: coverage environment
352 use_cnn: whether to use CNN
353 use_comm_map: whether to use communication maps
354 map_size: size of the maps
357 torch_geometric.data.Data: torch geometric data
362 features = CoverageEnvUtils.get_maps(env, params, map_size, use_comm_map)
364 features = CoverageEnvUtils.get_voronoi_features(env)
365 edge_weights = CoverageEnvUtils.get_weights(env, params).to_sparse().coalesce()
366 edge_index = edge_weights.indices().long()
367 weights = edge_weights.values().float()
368 pos = CoverageEnvUtils.get_robot_positions(env)
369 pos = (pos + params.pWorldMapSize / 2.0) / params.pWorldMapSize
370 data = torch_geometric.data.Data(
372 edge_index=edge_index.clone().detach(),
373 edge_weight=weights.clone().detach(),
374 pos=pos.clone().detach(),
Class for utility functions for coverage environment.
torch.Tensor get_weights(CoverageSystem env, Parameters params)
Get edge weights for the communication graph.
torch.Tensor resize_maps(torch.Tensor maps, int resized_map_size)
Resize maps to a given size Uses bilinear interpolation from torchvision.transforms....
torch.Tensor get_voronoi_features(CoverageSystem env)
Get voronoi features.
torch.Tensor to_tensor(object data)
Converts various types of data to torch.Tensor.
torch.Tensor get_communication_maps(CoverageSystem env, Parameters params, int map_size)
Generate communication maps from positions.
torch_geometric.data.Data get_torch_geometric_data(CoverageSystem env, Parameters params, bool use_cnn, bool use_comm_map, int map_size)
Get torch geometric data In this function, the edge weights are binary.
torch.Tensor get_raw_local_maps(CoverageSystem env, Parameters params)
Get raw local maps.
torch.Tensor get_robot_positions(CoverageSystem env)
Get robot positions.
torch.Tensor get_raw_obstacle_maps(CoverageSystem env, Parameters params)
Get raw obstacle maps.
torch.Tensor get_maps(CoverageSystem env, Parameters params, int resized_map_size, bool use_comm_map)
Get maps for the coverage environment.