From 95e3ea6c354e9bfdee4570811f480480a6a79876 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Fri, 23 Apr 2021 11:42:33 -0400 Subject: [PATCH 01/14] add factory functions --- argoverse/utils/sim2.py | 20 ++++++++++++++ tests/test_data/a_Sim2_b.json | 1 + tests/test_sim2.py | 39 +++++++++++++++++++++++++++ tests/test_simple_track_dataloader.py | 26 ++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 tests/test_data/a_Sim2_b.json diff --git a/argoverse/utils/sim2.py b/argoverse/utils/sim2.py index 0939daeb..d490358c 100644 --- a/argoverse/utils/sim2.py +++ b/argoverse/utils/sim2.py @@ -6,6 +6,7 @@ https://github.com/borglab/gtsam/blob/develop/gtsam/geometry/Similarity3.h """ +import json from typing import Union import numpy as np @@ -108,3 +109,22 @@ def transform_from(self, point_cloud: np.ndarray) -> np.ndarray: def transform_point_cloud(self, point_cloud: np.ndarray) -> np.ndarray: """Alias for `transform_from()`, for synchrony w/ API provided by SE(2) and SE(3) classes.""" return self.transform_from(point_cloud) + + @classmethod + def from_json(cls, json_fpath: str) -> "Sim2": + """Generate class inst. from a JSON file containing Sim(2) parameters as flattened matrices (row-major).""" + with open(json_fpath, "r") as f: + json_data = json.load(f) + + R = np.array(json_data["R"]).reshape(2, 2) + t = np.array(json_data["t"]).reshape(2) + s = float(json_data["s"]) + return cls(R, t, s) + + @classmethod + def from_matrix(cls, T: np.ndarray) -> "Sim2": + """Generate class instance from a 3x3 Numpy matrix """ + R = T[:2, :2] + t = T[:2, 2] + s = 1 / T[2, 2] + return cls(R, t, s) diff --git a/tests/test_data/a_Sim2_b.json b/tests/test_data/a_Sim2_b.json new file mode 100644 index 00000000..b94cb76c --- /dev/null +++ b/tests/test_data/a_Sim2_b.json @@ -0,0 +1 @@ +{"R": [1.0, 0.0, 0.0, 1.0], "t": [3930.0, 3240.0], "s": 1.6666666666666667} \ No newline at end of file diff --git a/tests/test_sim2.py b/tests/test_sim2.py index 4776a7ac..55e12436 100644 --- a/tests/test_sim2.py +++ b/tests/test_sim2.py @@ -1,4 +1,5 @@ import copy +from pathlib import Path import numpy as np import pytest @@ -6,6 +7,8 @@ from argoverse.utils.se2 import SE2 from argoverse.utils.sim2 import Sim2 +TEST_DATA_ROOT = Path(__file__).resolve().parent / "test_data" + def test_constructor() -> None: """Sim(2) to perform p_b = bSa * p_a""" @@ -112,6 +115,29 @@ def test_matrix() -> None: assert np.allclose(bSa_expected, bSa.matrix) +def test_from_matrix() -> None: + """Ensure that classmethod can construct an object instance from a 3x3 numpy matrix.""" + + bRa = np.array([[0, -1], [1, 0]]) + bta = np.array([1, 2]) + bsa = 3.0 + bSa = Sim2(R=bRa, t=bta, s=bsa) + + bSa_ = Sim2.from_matrix(bSa.matrix) + + # ensure we can reconstruct new instance from matrix + assert bSa == bSa_ + + # ensure generated class object has correct attributes + assert np.allclose(bSa_.rotation, bRa) + assert np.allclose(bSa_.translation, bta) + assert np.isclose(bSa_.scale, bsa) + + # ensure generated class object has correct 3x3 matrix attribute + bSa_expected = np.array([[0, -1, 1], [1, 0, 2], [0, 0, 1 / 3]]) + assert np.allclose(bSa_expected, bSa_.matrix) + + def test_matrix_homogenous_transform() -> None: """ Ensure 3x3 matrix transforms homogenous points as expected.""" expected_img_pts = np.array([[6, 4], [4, 6], [0, 0], [1, 7]]) @@ -193,3 +219,16 @@ def test_cannot_set_zero_scale() -> None: with pytest.raises(ZeroDivisionError) as e_info: aSb = Sim2(R, t, s) + + +def test_from_json() -> None: + """Ensure that classmethod can construct an object instance from a json file.""" + json_fpath = TEST_DATA_ROOT / "a_Sim2_b.json" + aSb = Sim2.from_json(json_fpath) + + expected_rotation = np.array([[1.0, 0.0], [0.0, 1.0]]) + expected_translation = np.array([3930.0, 3240.0]) + expected_scale = 1.6666666666666667 + assert np.allclose(aSb.rotation, expected_rotation) + assert np.allclose(aSb.translation, expected_translation) + assert np.isclose(aSb.scale, expected_scale) diff --git a/tests/test_simple_track_dataloader.py b/tests/test_simple_track_dataloader.py index e415218d..f7fc38b9 100644 --- a/tests/test_simple_track_dataloader.py +++ b/tests/test_simple_track_dataloader.py @@ -3,9 +3,12 @@ import os import pathlib +import numpy as np import pytest +from scipy.spatial.transform import Rotation from argoverse.data_loading.simple_track_dataloader import SimpleArgoverseTrackingDataLoader +from argoverse.utils.calibration import CameraConfig _TEST_DATA = pathlib.Path(__file__).parent / "test_data" / "tracking" _LOG_ID = "1" @@ -27,6 +30,29 @@ def test_get_log_calibration_data( assert data_loader.get_log_calibration_data(_LOG_ID) +def test_get_log_camera_config(data_loader: SimpleArgoverseTrackingDataLoader): + """Ensure attributes of CameraConfig object are generated correctly.""" + camera_name = "ring_front_center" + cam_config = data_loader.get_log_camera_config(_LOG_ID, camera_name) + assert isinstance(cam_config, CameraConfig) + + assert cam_config.img_height == 1200 + assert cam_config.img_width == 1920 + + # check intrinsics, should be 3x4 since we use 4x4 extrinsics + expected_K = np.array([[1392.11, 0, 980.18, 0],[0, 1392.11, 604.35, 0],[0, 0, 1, 0]]) + assert np.allclose(expected_K, cam_config.intrinsic, atol=0.01) + assert cam_config.distortion_coeffs == [-0.1720396447593493, 0.11689572230654095, -0.02511932396889168] + + # check extrinsics + qw, qx, qy, qz = 0.49605542988442836, -0.49896196582115804, 0.5027901707576079, -0.5021633313331392 + R = Rotation.from_quat([qx,qy,qz,qw]).as_matrix() + t = [1.6519358245144808, -0.0005354981581146487, 1.3613890006792675] + egoTc = np.eye(4) + egoTc[:3,:3] = R + egoTc[:3,3] = t + assert np.allclose(cam_config.extrinsic, np.linalg.inv(egoTc), atol=1e-2) + def test_get_city_SE3_egovehicle( data_loader: SimpleArgoverseTrackingDataLoader, ) -> None: From 7298ec2e274267ba41f97939a5429f1a03e56884 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Fri, 23 Apr 2021 11:42:49 -0400 Subject: [PATCH 02/14] add new helper to reduce boilerplate --- argoverse/data_loading/simple_track_dataloader.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/argoverse/data_loading/simple_track_dataloader.py b/argoverse/data_loading/simple_track_dataloader.py index 4c695991..9910eb8a 100644 --- a/argoverse/data_loading/simple_track_dataloader.py +++ b/argoverse/data_loading/simple_track_dataloader.py @@ -9,6 +9,7 @@ from argoverse.data_loading.pose_loader import get_city_SE3_egovehicle_at_sensor_t, read_city_name from argoverse.data_loading.synchronization_database import SynchronizationDB +from argoverse.utils.calibration import get_calibration_config, CameraConfig from argoverse.utils.json_utils import read_json_file from argoverse.utils.se3 import SE3 from argoverse.utils.transform import quat2rotmat @@ -55,6 +56,12 @@ def get_log_calibration_data(self, log_id: str) -> Mapping[str, Any]: assert isinstance(log_calib_data, dict) return log_calib_data + def get_log_camera_config(self, log_id: str, camera_name: str) -> CameraConfig: + """Return an object containing camera extrinsics, intrinsics, and image dimensions.""" + log_calib_data = self.get_log_calibration_data(log_id) + camera_config = get_calibration_config(log_calib_data, camera_name) + return camera_config + def get_city_to_egovehicle_se3(self, log_id: str, timestamp: int) -> Optional[SE3]: """Deprecated version of get_city_SE3_egovehicle() below, as does not follow standard naming convention Args: From c2742fe809df397e477e2bb19051d7c7467e82e4 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 6 May 2021 15:20:37 -0400 Subject: [PATCH 03/14] support PathLike arguments --- argoverse/utils/sim2.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/argoverse/utils/sim2.py b/argoverse/utils/sim2.py index d490358c..d15b29f0 100644 --- a/argoverse/utils/sim2.py +++ b/argoverse/utils/sim2.py @@ -7,6 +7,7 @@ """ import json +import os from typing import Union import numpy as np @@ -111,7 +112,7 @@ def transform_point_cloud(self, point_cloud: np.ndarray) -> np.ndarray: return self.transform_from(point_cloud) @classmethod - def from_json(cls, json_fpath: str) -> "Sim2": + def from_json(cls, json_fpath: Union[str, "os.PathLike[str]"]) -> "Sim2": """Generate class inst. from a JSON file containing Sim(2) parameters as flattened matrices (row-major).""" with open(json_fpath, "r") as f: json_data = json.load(f) From bb5c27618be08f56515ffc431db6ee0ca551eb7a Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 6 May 2021 18:37:44 -0400 Subject: [PATCH 04/14] make types consistent --- argoverse/data_loading/simple_track_dataloader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/argoverse/data_loading/simple_track_dataloader.py b/argoverse/data_loading/simple_track_dataloader.py index 9910eb8a..30abe1a7 100644 --- a/argoverse/data_loading/simple_track_dataloader.py +++ b/argoverse/data_loading/simple_track_dataloader.py @@ -3,7 +3,7 @@ import glob import sys from pathlib import Path -from typing import Any, List, Mapping, Optional +from typing import Any, Dict, List, Mapping, Optional import numpy as np @@ -43,7 +43,7 @@ def get_city_name(self, log_id: str) -> str: assert isinstance(city_name, str) return city_name - def get_log_calibration_data(self, log_id: str) -> Mapping[str, Any]: + def get_log_calibration_data(self, log_id: str) -> Dict[str, Any]: """ Args: log_id: str From be2b97dd209441984da78360e07e94b2a539e6e0 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 6 May 2021 20:31:37 -0400 Subject: [PATCH 05/14] add another unit test --- argoverse/utils/sim2.py | 5 ++++- tests/test_data/a_Sim2_b.json | 2 +- tests/test_sim2.py | 8 ++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/argoverse/utils/sim2.py b/argoverse/utils/sim2.py index d15b29f0..ee206b05 100644 --- a/argoverse/utils/sim2.py +++ b/argoverse/utils/sim2.py @@ -124,7 +124,10 @@ def from_json(cls, json_fpath: Union[str, "os.PathLike[str]"]) -> "Sim2": @classmethod def from_matrix(cls, T: np.ndarray) -> "Sim2": - """Generate class instance from a 3x3 Numpy matrix """ + """Generate class instance from a 3x3 Numpy matrix.""" + if np.isclose(T[2, 2], 0.0): + raise ZeroDivisionError("Sim(2) scale calculation would lead to division by zero") + R = T[:2, :2] t = T[:2, 2] s = 1 / T[2, 2] diff --git a/tests/test_data/a_Sim2_b.json b/tests/test_data/a_Sim2_b.json index b94cb76c..7f866103 100644 --- a/tests/test_data/a_Sim2_b.json +++ b/tests/test_data/a_Sim2_b.json @@ -1 +1 @@ -{"R": [1.0, 0.0, 0.0, 1.0], "t": [3930.0, 3240.0], "s": 1.6666666666666667} \ No newline at end of file +{"R": [1, 0, 0, 1], "t": [3930, 3240], "s": 1.6666666666666667} diff --git a/tests/test_sim2.py b/tests/test_sim2.py index 55e12436..5a22b03e 100644 --- a/tests/test_sim2.py +++ b/tests/test_sim2.py @@ -232,3 +232,11 @@ def test_from_json() -> None: assert np.allclose(aSb.rotation, expected_rotation) assert np.allclose(aSb.translation, expected_translation) assert np.isclose(aSb.scale, expected_scale) + + +def test_from_json_invalid_scale() -> None: + """Ensure that classmethod raises an error with invalid JSON input.""" + json_fpath = TEST_DATA_ROOT / "a_Sim2_b___invalid.json" + + with pytest.raises(ZeroDivisionError) as e_info: + aSb = Sim2.from_json(json_fpath) From 88c6843289bc2e40e6fb7882b5374c2cc450ca3a Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 6 May 2021 20:35:08 -0400 Subject: [PATCH 06/14] reduce required precision --- tests/test_sim2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_sim2.py b/tests/test_sim2.py index 5a22b03e..b394572c 100644 --- a/tests/test_sim2.py +++ b/tests/test_sim2.py @@ -208,7 +208,7 @@ def test_transform_point_cloud() -> None: pts_a = aTb.transform_point_cloud(copy.deepcopy(pts_b)) pts_a_ = aSb.transform_point_cloud(copy.deepcopy(pts_b)) - assert np.allclose(pts_a, pts_a_, atol=1e-7) + assert np.allclose(pts_a, pts_a_, atol=1e-6) def test_cannot_set_zero_scale() -> None: From a7d7f4d89f8b332ed6f2fd3b64339c609394428d Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 6 May 2021 20:47:45 -0400 Subject: [PATCH 07/14] add another unit test --- tests/test_data/a_Sim2_b___invalid.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/test_data/a_Sim2_b___invalid.json diff --git a/tests/test_data/a_Sim2_b___invalid.json b/tests/test_data/a_Sim2_b___invalid.json new file mode 100644 index 00000000..006cc193 --- /dev/null +++ b/tests/test_data/a_Sim2_b___invalid.json @@ -0,0 +1 @@ +{"R": [1, 0, 0, 1], "t": [3930, 3240], "s": 0.0} From 4a8082a7722ecdcf0df2ef0edda72713c7a6529e Mon Sep 17 00:00:00 2001 From: John Lambert Date: Fri, 7 May 2021 00:42:09 -0400 Subject: [PATCH 08/14] improve docstrings and reformat w/ black --- argoverse/data_loading/simple_track_dataloader.py | 4 ++-- tests/test_simple_track_dataloader.py | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/argoverse/data_loading/simple_track_dataloader.py b/argoverse/data_loading/simple_track_dataloader.py index 30abe1a7..62b81148 100644 --- a/argoverse/data_loading/simple_track_dataloader.py +++ b/argoverse/data_loading/simple_track_dataloader.py @@ -9,7 +9,7 @@ from argoverse.data_loading.pose_loader import get_city_SE3_egovehicle_at_sensor_t, read_city_name from argoverse.data_loading.synchronization_database import SynchronizationDB -from argoverse.utils.calibration import get_calibration_config, CameraConfig +from argoverse.utils.calibration import CameraConfig, get_calibration_config from argoverse.utils.json_utils import read_json_file from argoverse.utils.se3 import SE3 from argoverse.utils.transform import quat2rotmat @@ -31,7 +31,7 @@ def __init__(self, data_dir: str, labels_dir: str) -> None: self.sdb = SynchronizationDB(data_dir) def get_city_name(self, log_id: str) -> str: - """ + """Return the name of the city where the log of interest was cpatured. Args: log_id: str diff --git a/tests/test_simple_track_dataloader.py b/tests/test_simple_track_dataloader.py index f7fc38b9..a6f8d319 100644 --- a/tests/test_simple_track_dataloader.py +++ b/tests/test_simple_track_dataloader.py @@ -40,19 +40,20 @@ def test_get_log_camera_config(data_loader: SimpleArgoverseTrackingDataLoader): assert cam_config.img_width == 1920 # check intrinsics, should be 3x4 since we use 4x4 extrinsics - expected_K = np.array([[1392.11, 0, 980.18, 0],[0, 1392.11, 604.35, 0],[0, 0, 1, 0]]) + expected_K = np.array([[1392.11, 0, 980.18, 0], [0, 1392.11, 604.35, 0], [0, 0, 1, 0]]) assert np.allclose(expected_K, cam_config.intrinsic, atol=0.01) assert cam_config.distortion_coeffs == [-0.1720396447593493, 0.11689572230654095, -0.02511932396889168] # check extrinsics qw, qx, qy, qz = 0.49605542988442836, -0.49896196582115804, 0.5027901707576079, -0.5021633313331392 - R = Rotation.from_quat([qx,qy,qz,qw]).as_matrix() + R = Rotation.from_quat([qx, qy, qz, qw]).as_matrix() t = [1.6519358245144808, -0.0005354981581146487, 1.3613890006792675] egoTc = np.eye(4) - egoTc[:3,:3] = R - egoTc[:3,3] = t + egoTc[:3, :3] = R + egoTc[:3, 3] = t assert np.allclose(cam_config.extrinsic, np.linalg.inv(egoTc), atol=1e-2) + def test_get_city_SE3_egovehicle( data_loader: SimpleArgoverseTrackingDataLoader, ) -> None: @@ -119,7 +120,7 @@ def test_get_closest_lidar_fpath_no_match( def test_get_ordered_log_cam_fpaths( data_loader: SimpleArgoverseTrackingDataLoader, ) -> None: - """ Make sure all images for one camera in one log are returned in correct order. """ + """Make sure all images for one camera in one log are returned in correct order.""" camera_name = "ring_rear_right" cam_img_fpaths = data_loader.get_ordered_log_cam_fpaths(_LOG_ID, camera_name) gt_cam_img_fpaths = [ From 1a26e4c483dc204d58b0648c4cba1d4365c18fbc Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 13 May 2021 11:34:53 -0400 Subject: [PATCH 09/14] add json serialization function --- argoverse/utils/sim2.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/argoverse/utils/sim2.py b/argoverse/utils/sim2.py index ee206b05..f24eb56c 100644 --- a/argoverse/utils/sim2.py +++ b/argoverse/utils/sim2.py @@ -13,6 +13,7 @@ import numpy as np from argoverse.utils.helpers import assert_np_array_shape +from argoverse.utils.json_utils import save_json_dict class Sim2: @@ -111,6 +112,19 @@ def transform_point_cloud(self, point_cloud: np.ndarray) -> np.ndarray: """Alias for `transform_from()`, for synchrony w/ API provided by SE(2) and SE(3) classes.""" return self.transform_from(point_cloud) + def save_as_json(self, save_fpath: Union[str, "os.PathLike[str]"]) -> None: + """Save the Sim(2) object to a JSON representation on disk. + + Args: + save_fpath: path to where json file should be saved to + """ + dict_for_serialization = { + "R": self.rotation.flatten().tolist(), + "t": self.translation.flatten().tolist(), + "s": self.scale, + } + save_json_dict(save_fpath, dict_for_serialization) + @classmethod def from_json(cls, json_fpath: Union[str, "os.PathLike[str]"]) -> "Sim2": """Generate class inst. from a JSON file containing Sim(2) parameters as flattened matrices (row-major).""" From f4974fc298a40db7f252880a8a5cc667aedfb1a5 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 13 May 2021 11:45:38 -0400 Subject: [PATCH 10/14] add unit test on serialization --- tests/test_sim2.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_sim2.py b/tests/test_sim2.py index 089fb87b..cfaa3130 100644 --- a/tests/test_sim2.py +++ b/tests/test_sim2.py @@ -4,6 +4,7 @@ import numpy as np import pytest +from argoverse.utils.json_utils import read_json_file from argoverse.utils.se2 import SE2 from argoverse.utils.sim2 import Sim2 @@ -240,3 +241,25 @@ def test_from_json_invalid_scale() -> None: with pytest.raises(ZeroDivisionError) as e_info: aSb = Sim2.from_json(json_fpath) + + +def test_save_as_json() -> None: + """Ensure that JSON serialization of a class instance works correctly.""" + bSc = Sim2(R=np.array([[0, 1], [1, 0]]), t=np.array([-5, 5]), s=0.1) + save_fpath = TEST_DATA_ROOT / "b_Sim2_c.json" + bSc.save_as_json(save_fpath=save_fpath) + + bSc_dict = read_json_file(save_fpath) + assert bSc_dict["R"] == [0, 1, 1, 0] + assert bSc_dict["t"] == [-5, 5] + assert bSc_dict["s"] == 0.1 + + +def test_round_trip() -> None: + """Test round trip of serialization, then de-serialization.""" + bSc = Sim2(R=np.array([[0, 1], [1, 0]]), t=np.array([-5, 5]), s=0.1) + save_fpath = TEST_DATA_ROOT / "b_Sim2_c.json" + bSc.save_as_json(save_fpath=save_fpath) + + bSc_ = Sim2.from_json(save_fpath) + assert bSc_ == bSc From a3314bda560e807551010a47eb1c50d6f46d5bbb Mon Sep 17 00:00:00 2001 From: John Lambert Date: Thu, 13 May 2021 12:16:32 -0400 Subject: [PATCH 11/14] clean up docstrings --- argoverse/utils/sim2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/argoverse/utils/sim2.py b/argoverse/utils/sim2.py index f24eb56c..3a51c121 100644 --- a/argoverse/utils/sim2.py +++ b/argoverse/utils/sim2.py @@ -1,7 +1,7 @@ """ Utility for 2d rigid body transformations with scaling. -Refs: +References: http://ethaneade.com/lie_groups.pdf https://github.com/borglab/gtsam/blob/develop/gtsam/geometry/Similarity3.h """ @@ -116,7 +116,7 @@ def save_as_json(self, save_fpath: Union[str, "os.PathLike[str]"]) -> None: """Save the Sim(2) object to a JSON representation on disk. Args: - save_fpath: path to where json file should be saved to + save_fpath: path to where json file should be saved """ dict_for_serialization = { "R": self.rotation.flatten().tolist(), From 80d86515c7e0d2caab863fe4e290ea913dbf1d7e Mon Sep 17 00:00:00 2001 From: John Lambert Date: Wed, 23 Jun 2021 10:22:28 -0400 Subject: [PATCH 12/14] fix typo --- argoverse/data_loading/simple_track_dataloader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/argoverse/data_loading/simple_track_dataloader.py b/argoverse/data_loading/simple_track_dataloader.py index 2a5fa424..d1172af8 100644 --- a/argoverse/data_loading/simple_track_dataloader.py +++ b/argoverse/data_loading/simple_track_dataloader.py @@ -27,7 +27,7 @@ def __init__(self, data_dir: str, labels_dir: str) -> None: self.sdb = SynchronizationDB(data_dir) def get_city_name(self, log_id: str) -> str: - """Return the name of the city where the log of interest was cpatured. + """Return the name of the city where the log of interest was captured. Args: log_id: str From bc7246670febe2bc628298ccb7b15a7286cab2cb Mon Sep 17 00:00:00 2001 From: John Lambert Date: Wed, 30 Jun 2021 16:10:26 -0400 Subject: [PATCH 13/14] define _PathLike macro --- argoverse/utils/sim2.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/argoverse/utils/sim2.py b/argoverse/utils/sim2.py index c90e5d4c..fb41892d 100644 --- a/argoverse/utils/sim2.py +++ b/argoverse/utils/sim2.py @@ -15,6 +15,8 @@ from argoverse.utils.helpers import assert_np_array_shape from argoverse.utils.json_utils import save_json_dict +_PathLike = Union[str, "os.PathLike[str]"] + class Sim2: """Implements the Similarity(2) class.""" @@ -145,7 +147,7 @@ def transform_point_cloud(self, point_cloud: np.ndarray) -> np.ndarray: """Alias for `transform_from()`, for synchrony w/ API provided by SE(2) and SE(3) classes.""" return self.transform_from(point_cloud) - def save_as_json(self, save_fpath: Union[str, "os.PathLike[str]"]) -> None: + def save_as_json(self, save_fpath: _PathLike) -> None: """Save the Sim(2) object to a JSON representation on disk. Args: @@ -159,7 +161,7 @@ def save_as_json(self, save_fpath: Union[str, "os.PathLike[str]"]) -> None: save_json_dict(save_fpath, dict_for_serialization) @classmethod - def from_json(cls, json_fpath: Union[str, "os.PathLike[str]"]) -> "Sim2": + def from_json(cls, json_fpath: _PathLike) -> "Sim2": """Generate class inst. from a JSON file containing Sim(2) parameters as flattened matrices (row-major).""" with open(json_fpath, "r") as f: json_data = json.load(f) From c792207e6ab83ce15de819fa988fc393f7c41979 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Wed, 30 Jun 2021 16:15:22 -0400 Subject: [PATCH 14/14] add period to ZeroDivisionError message --- argoverse/utils/sim2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/argoverse/utils/sim2.py b/argoverse/utils/sim2.py index fb41892d..2540e8ab 100644 --- a/argoverse/utils/sim2.py +++ b/argoverse/utils/sim2.py @@ -175,7 +175,7 @@ def from_json(cls, json_fpath: _PathLike) -> "Sim2": def from_matrix(cls, T: np.ndarray) -> "Sim2": """Generate class instance from a 3x3 Numpy matrix.""" if np.isclose(T[2, 2], 0.0): - raise ZeroDivisionError("Sim(2) scale calculation would lead to division by zero") + raise ZeroDivisionError("Sim(2) scale calculation would lead to division by zero.") R = T[:2, :2] t = T[:2, 2]