Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add error metrics for scale error #480

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions evo/common_ape_rpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def get_pose_relation(args: argparse.Namespace) -> PoseRelation:
pose_relation = PoseRelation.point_distance
elif args.pose_relation == "point_distance_error_ratio":
pose_relation = PoseRelation.point_distance_error_ratio
elif args.pose_relation == "scale_error":
pose_relation = PoseRelation.scale_error
return pose_relation


Expand Down
24 changes: 22 additions & 2 deletions evo/core/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class PoseRelation(Enum):
rotation_angle_deg = "rotation angle in degrees"
point_distance = "point distance"
point_distance_error_ratio = "point distance error ratio"
scale_error = "scale error"


class Unit(Enum):
Expand Down Expand Up @@ -198,7 +199,8 @@ def __init__(self,
if pose_relation in (PoseRelation.translation_part,
PoseRelation.point_distance):
self.unit = Unit.meters
elif pose_relation == PoseRelation.point_distance_error_ratio:
elif pose_relation in (PoseRelation.point_distance_error_ratio,
PoseRelation.scale_error):
self.unit = Unit.percent
elif pose_relation == PoseRelation.rotation_angle_deg:
self.unit = Unit.degrees
Expand Down Expand Up @@ -280,6 +282,23 @@ def process_data(self, data: PathPair) -> None:
self.delta_ids = [self.delta_ids[i] for i in nonzero]
self.error = np.divide(self.error[nonzero],
ref_distances[nonzero]) * 100
elif self.pose_relation == PoseRelation.scale_error:
# Compares the magnitude of the traveled distance.
ref_traveled_distances = np.array([
traj_ref.distances[i] - traj_ref.distances[j] for i, j in id_pairs
])
est_traveled_distances = np.array([
traj_est.distances[i] - traj_est.distances[j] for i, j in id_pairs
])
self.error = est_traveled_distances
nonzero = ref_traveled_distances.nonzero()[0]
if nonzero.size != ref_traveled_distances.size:
logger.warning(
f"Ignoring {ref_traveled_distances.size - nonzero.size} zero "
"divisions in ratio calculations.")
self.delta_ids = [self.delta_ids[i] for i in nonzero]
self.error = (np.divide(self.error[nonzero],
ref_traveled_distances[nonzero]) - 1) * 100
else:
# All other pose relations require the full pose error.
self.E = [
Expand All @@ -298,7 +317,8 @@ def process_data(self, data: PathPair) -> None:
self.pose_relation.value))

if self.pose_relation in (PoseRelation.point_distance,
PoseRelation.point_distance_error_ratio):
PoseRelation.point_distance_error_ratio,
PoseRelation.scale_error):
# Already computed, see above.
pass
elif self.pose_relation == PoseRelation.translation_part:
Expand Down
2 changes: 1 addition & 1 deletion evo/main_rpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def parser() -> argparse.ArgumentParser:
"-r", "--pose_relation", default="trans_part",
help="pose relation on which the RPE is based", choices=[
"full", "trans_part", "rot_part", "angle_deg", "angle_rad",
"point_distance", "point_distance_error_ratio"
"point_distance", "point_distance_error_ratio", "scale_error"
])
algo_opts.add_argument("-a", "--align",
help="alignment with Umeyama's method (no scale)",
Expand Down