(self, args: Args)
| 149 | |
| 150 | class PathEditor: |
| 151 | def __init__(self, args: Args): |
| 152 | self.args = args |
| 153 | self.map_dir = args.tinynav_map_path |
| 154 | self.paths_json_path = self.map_dir / args.paths_json_name |
| 155 | self.sdf_map_path = self.map_dir / args.sdf_map_name |
| 156 | self.default_sdf_map_path = self.map_dir / args.default_sdf_map_name |
| 157 | |
| 158 | self.occupancy_grid = np.load(self.map_dir / "occupancy_grid.npy") |
| 159 | self.occupancy_meta = np.load(self.map_dir / "occupancy_meta.npy") |
| 160 | self.origin = self.occupancy_meta[:3].astype(np.float32) |
| 161 | self.resolution = float(self.occupancy_meta[3]) |
| 162 | self.shape = tuple(int(v) for v in self.occupancy_grid.shape) |
| 163 | self.current_sdf_map = self._load_sdf_file(self.sdf_map_path) |
| 164 | self.default_sdf_map = self._load_sdf_file(self.default_sdf_map_path) |
| 165 | if self.default_sdf_map is None: |
| 166 | # Before the first replacement there is no separate backup, so the active file is the default map. |
| 167 | self.default_sdf_map = self.current_sdf_map |
| 168 | |
| 169 | self.paths = _load_json(self.paths_json_path) |
| 170 | self.path_id_counter = (max(self.paths.keys()) + 1) if self.paths else 0 |
| 171 | self.selected_path_id: int | None = next(iter(self.paths.keys()), None) |
| 172 | |
| 173 | self.server = viser.ViserServer(host=args.host, port=args.port) |
| 174 | self.server.scene.world_axes.visible = True |
| 175 | self.server.scene.set_up_direction("+z") |
| 176 | |
| 177 | self.path_line_handles: dict[int, viser.SceneHandle] = {} |
| 178 | self.point_handles: dict[tuple[int, int], viser.SceneHandle] = {} |
| 179 | self.gizmo_handles: dict[tuple[int, int], viser.SceneHandle] = {} |
| 180 | self.sdf_preview_handle: viser.SceneHandle | None = None |
| 181 | self.status = None |
| 182 | |
| 183 | def _load_sdf_file(self, path: Path) -> np.ndarray | None: |
| 184 | if not path.exists(): |
nothing calls this directly
no test coverage detected