Download tests/test_rig.py from kimjunhan/vkgs-sim: direct link, hf CLI and curl.
- Browser
- Download file 3.38 kB
-
https://huggingface.co/kimjunhan/vkgs-sim/resolve/main/tests/test_rig.py
- Command line
-
hf download hf://kimjunhan/vkgs-sim/tests/test_rig.py
-
curl -L -o test_rig.py https://huggingface.co/kimjunhan/vkgs-sim/resolve/main/tests/test_rig.py
3.38 kB
| """μΉ΄λ©λΌ 리그 μν. numpy κ° νμνλ―λ‘ μ»¨ν μ΄λμμ λλ€.""" | |
| import math | |
| import pytest | |
| np = pytest.importorskip("numpy") | |
| from nusim.data.index import CameraCalib, Frame | |
| from nusim.data.rig import camera_pose, quat_to_matrix, rt_to_matrix | |
| def test_identity_quaternion(): | |
| assert np.allclose(quat_to_matrix((1.0, 0.0, 0.0, 0.0)), np.eye(3)) | |
| def test_quaternion_is_orthonormal(): | |
| rng = np.random.default_rng(0) | |
| for _ in range(50): | |
| q = rng.normal(size=4) | |
| q /= np.linalg.norm(q) | |
| r = quat_to_matrix(tuple(q)) | |
| assert np.allclose(r.T @ r, np.eye(3), atol=1e-12) | |
| assert abs(np.linalg.det(r) - 1.0) < 1e-12 | |
| def test_quaternion_90deg_about_z(): | |
| # (w,x,y,z) = (cos45, 0, 0, sin45) β zμΆ +90λ | |
| s = math.sqrt(0.5) | |
| r = quat_to_matrix((s, 0.0, 0.0, s)) | |
| assert np.allclose(r @ np.array([1.0, 0, 0]), [0, 1, 0], atol=1e-12) | |
| def test_degenerate_quaternion_returns_identity(): | |
| # μ κ·ν λΆκ°λ₯ν μ λ ₯μ NaN μ λ΄λλ λμ νλ±νλ ¬λ‘ μμ νκ² λ¨μ΄μ ΈμΌ νλ€ | |
| assert np.allclose(quat_to_matrix((0.0, 0.0, 0.0, 0.0)), np.eye(3)) | |
| def _pose(): | |
| f = Frame(0, "x.jpg", (100.0, 200.0, 0.0), (math.sqrt(0.5), 0.0, 0.0, math.sqrt(0.5)), True) | |
| c = CameraCalib( | |
| translation=(1.7, 0.0, 1.5), | |
| rotation=(0.5, -0.5, 0.5, -0.5), | |
| intrinsic=((1266.4, 0.0, 816.3), (0.0, 1266.4, 491.5), (0.0, 0.0, 1.0)), | |
| width=1600, height=900, | |
| ) | |
| return camera_pose(f, c, "CAM_FRONT") | |
| def test_w2c_inverts_c2w(): | |
| p = _pose() | |
| assert np.allclose(p.w2c @ p.c2w, np.eye(4), atol=1e-12) | |
| def test_camera_is_offset_from_ego_origin(): | |
| p = _pose() | |
| # ego κ° (100,200,0) μ +90λλ‘ μ μκ³ μΉ΄λ©λΌκ° μ λ°© 1.7 m, λμ΄ 1.5 m μ΄λ―λ‘ | |
| # μ μ μ’νμμλ ego μ +y λ°©ν₯μΌλ‘ 1.7 m λ°λ € μμ΄μΌ νλ€. | |
| assert np.allclose(p.position, [100.0, 201.7, 1.5], atol=1e-9) | |
| def test_projection_is_vulkan_clip_space(): | |
| p = _pose() | |
| proj = p.projection(znear=0.1, zfar=100.0) | |
| # znear μ μλ μ μ z_ndc=0, zfar λ 1 μ΄μ΄μΌ νλ€ (OpenGL μ -1..1 μ΄ μλλ€) | |
| for z, expect in ((0.1, 0.0), (100.0, 1.0)): | |
| v = proj @ np.array([0.0, 0.0, z, 1.0]) | |
| assert abs(v[2] / v[3] - expect) < 1e-6 | |
| def test_projection_matches_pixel_projection(): | |
| # μΉ΄λ©λΌ +y λ 'μλ'(OpenCV)μ΄κ³ Vulkan NDC λ y κ° μλλ‘ + λΌ λ€μ§κΈ°κ° μμ΄μΌ νλ€. | |
| # μμμ μ μ K λ‘ ν½μ μ ν¬μν κ²°κ³Όμ NDC κ° μ νν μΌμΉνλμ§ λ³Έλ€. | |
| p = _pose() | |
| proj = p.projection() | |
| for pt in ([0.0, 1.0, 10.0], [3.0, -2.0, 25.0], [-5.0, 0.5, 7.0]): | |
| x, y, z = pt | |
| u = p.K[0, 0] * x / z + p.K[0, 2] | |
| v = p.K[1, 1] * y / z + p.K[1, 2] | |
| c = proj @ np.array([x, y, z, 1.0]) | |
| ndc = c[:2] / c[3] | |
| assert np.allclose(ndc, [2 * u / p.width - 1, 2 * v / p.height - 1], atol=1e-9) | |
| # μλμͺ½ μ (+y)μ NDC μμλ + μ¬μΌ νλ€ | |
| c = proj @ np.array([0.0, 1.0, 10.0, 1.0]) | |
| assert c[1] / c[3] > 0 | |
| def test_fov_matches_nuscenes_front_camera(): | |
| h, v = _pose().fov_deg() | |
| assert 63.0 < h < 66.0 # nuScenes CAM_FRONT μ μ½ 64λ | |
| assert 38.0 < v < 42.0 | |
| def test_rt_to_matrix(): | |
| m = rt_to_matrix(np.eye(3), (1.0, 2.0, 3.0)) | |
| assert np.allclose(m[:3, 3], [1, 2, 3]) | |
| assert m[3, 3] == 1.0 | |