Spaces:
Running
Running
Download code/evolvingnav_paper/coverage.py from ZJU4EmbodiedAI/EvolvingNav: direct link, hf CLI and curl.
- Browser
- Download file 3.22 kB
-
https://huggingface.co/spaces/ZJU4EmbodiedAI/EvolvingNav/resolve/main/code/evolvingnav_paper/coverage.py
- Command line
-
hf download hf://spaces/ZJU4EmbodiedAI/EvolvingNav/code/evolvingnav_paper/coverage.py
-
curl -L -o coverage.py https://huggingface.co/spaces/ZJU4EmbodiedAI/EvolvingNav/resolve/main/code/evolvingnav_paper/coverage.py
3.22 kB
| """Project public candidate geometry into an online depth frame (Appendix A.4).""" | |
| from __future__ import annotations | |
| import math | |
| import numpy as np | |
| def candidate_surface_samples(center_xyz, radius_m: float = 0.15, | |
| place_points=None) -> np.ndarray: | |
| """A 5x5 surface grid from public receptacle slots or a center fallback.""" | |
| center = np.asarray(center_xyz, dtype=float) | |
| if place_points: | |
| points = np.asarray(place_points, dtype=float) | |
| xs = np.linspace(points[:, 0].min(), points[:, 0].max(), 5) | |
| zs = np.linspace(points[:, 2].min(), points[:, 2].max(), 5) | |
| height = float(np.median(points[:, 1])) | |
| return np.asarray([[x, height, z] for x in xs for z in zs]) | |
| offsets = np.linspace(-radius_m, radius_m, 5) | |
| return np.asarray([center + [x, 0.0, z] for x in offsets for z in offsets]) | |
| def _rotation(xyzw) -> np.ndarray: | |
| x, y, z, w = np.asarray(xyzw, dtype=float) | |
| norm = x*x + y*y + z*z + w*w | |
| if norm <= 0: | |
| raise ValueError("invalid camera orientation") | |
| s = 2.0 / norm | |
| return np.array([ | |
| [1-s*(y*y+z*z), s*(x*y-z*w), s*(x*z+y*w)], | |
| [s*(x*y+z*w), 1-s*(x*x+z*z), s*(y*z-x*w)], | |
| [s*(x*z-y*w), s*(y*z+x*w), 1-s*(x*x+y*y)], | |
| ]) | |
| def camera_forward(xyzw) -> np.ndarray: | |
| return _rotation(xyzw) @ np.array([0.0, 0.0, -1.0]) | |
| def heading_quaternion(displacement_xyz) -> list[float]: | |
| direction = np.asarray(displacement_xyz, dtype=float) | |
| if math.hypot(direction[0], direction[2]) <= 1e-9: | |
| raise ValueError("heading needs horizontal displacement") | |
| yaw = math.atan2(-direction[0], -direction[2]) | |
| return [0.0, math.sin(yaw / 2), 0.0, math.cos(yaw / 2)] | |
| def depth_quality(depth: np.ndarray) -> float: | |
| values = np.asarray(depth) | |
| return float(np.mean(np.isfinite(values) & (values > 0))) | |
| def camera_transform(agent_xyz, agent_xyzw, sensor_height_m: float = 1.35) -> np.ndarray: | |
| rotation = _rotation(agent_xyzw) | |
| transform = np.eye(4, dtype=float) | |
| transform[:3, :3] = rotation | |
| transform[:3, 3] = np.asarray(agent_xyz, dtype=float) + rotation @ [0, sensor_height_m, 0] | |
| return transform | |
| def visible_sample_ids(samples: np.ndarray, agent_xyz, agent_xyzw, depth: np.ndarray, | |
| hfov_degrees: float, *, sensor_height_m: float = 1.35, | |
| depth_tolerance_m: float = 0.25) -> frozenset[int]: | |
| height, width = depth.shape | |
| transform = camera_transform(agent_xyz, agent_xyzw, sensor_height_m) | |
| rotation = transform[:3, :3] | |
| camera_xyz = transform[:3, 3] | |
| camera_points = (np.asarray(samples, dtype=float) - camera_xyz) @ rotation | |
| focal = width / (2.0 * math.tan(math.radians(hfov_degrees) / 2.0)) | |
| visible: set[int] = set() | |
| for index, (x, y, z) in enumerate(camera_points): | |
| if z >= -0.05: | |
| continue | |
| u = int(round(width / 2 + focal * x / -z)) | |
| v = int(round(height / 2 - focal * y / -z)) | |
| if 0 <= u < width and 0 <= v < height: | |
| measured = float(depth[v, u]) | |
| if math.isfinite(measured) and measured > 0 and abs(measured + z) <= depth_tolerance_m: | |
| visible.add(index) | |
| return frozenset(visible) | |