def run(args): import evo.common_ape_rpe as common from evo import EvoException from evo.core import sync from evo.tools import file_interface, log from evo.tools.settings import SETTINGS log.configure_logging(args.verbose, args.silent, args.debug, local_logfile=args.logfile) if args.debug: from pprint import pformat parser_str = pformat({arg: getattr(args, arg) for arg in vars(args)}) logger.debug("main_parser config:\n{}".format(parser_str)) logger.debug(SEP) if (args.plot or args.save_plot or args.serialize_plot) and args.all_pairs: raise EvoException( "all_pairs mode cannot be used with plotting functions") traj_ref, traj_est, ref_name, est_name = common.load_trajectories(args) pose_relation = common.get_pose_relation(args) delta_unit = common.get_delta_unit(args) traj_ref_full = None if args.plot_full_ref: import copy traj_ref_full = copy.deepcopy(traj_ref) if args.subcommand != "kitti": logger.debug("Synchronizing trajectories...") traj_ref, traj_est = sync.associate_trajectories( traj_ref, traj_est, args.t_max_diff, args.t_offset, first_name=ref_name, snd_name=est_name) result = rpe( traj_ref=traj_ref, traj_est=traj_est, pose_relation=pose_relation, delta=args.delta, delta_unit=delta_unit, rel_delta_tol=args.delta_tol, all_pairs=args.all_pairs, align=args.align, correct_scale=args.correct_scale, align_origin=args.align_origin, ref_name=ref_name, est_name=est_name, ) if args.plot or args.save_plot or args.serialize_plot: common.plot(args, result, traj_ref, result.trajectories[est_name], traj_ref_full=traj_ref_full) if args.save_results: logger.debug(SEP) if not SETTINGS.save_traj_in_zip: del result.trajectories[ref_name] del result.trajectories[est_name] file_interface.save_res_file(args.save_results, result, confirm_overwrite=not args.no_warnings)
def run(args: argparse.Namespace) -> None: log.configure_logging(args.verbose, args.silent, args.debug, local_logfile=args.logfile) if args.debug: from pprint import pformat parser_str = pformat({arg: getattr(args, arg) for arg in vars(args)}) logger.debug("main_parser config:\n{}".format(parser_str)) logger.debug(SEP) traj_ref, traj_est, ref_name, est_name = common.load_trajectories(args) traj_ref_full = None if args.plot_full_ref: import copy traj_ref_full = copy.deepcopy(traj_ref) if isinstance(traj_ref, PoseTrajectory3D) and isinstance( traj_est, PoseTrajectory3D): logger.debug("Synchronizing trajectories...") traj_ref, traj_est = sync.associate_trajectories(traj_ref, traj_est, args.t_max_diff, args.t_offset, first_name=ref_name, snd_name=est_name) pose_relation = common.get_pose_relation(args) result = ape( traj_ref=traj_ref, traj_est=traj_est, pose_relation=pose_relation, align=args.align, correct_scale=args.correct_scale, n_to_align=args.n_to_align, align_origin=args.align_origin, ref_name=ref_name, est_name=est_name, ) if args.plot or args.save_plot or args.serialize_plot: common.plot_result(args, result, traj_ref, result.trajectories[est_name], traj_ref_full=traj_ref_full) if args.save_results: logger.debug(SEP) if not SETTINGS.save_traj_in_zip: del result.trajectories[ref_name] del result.trajectories[est_name] file_interface.save_res_file(args.save_results, result, confirm_overwrite=not args.no_warnings)
def test_write_read_integrity(self): result_out = Result() result_out.add_np_array("test-array", np.ones(1000)) result_out.add_info({"name": "test", "number": 666}) result_out.add_trajectory("traj", helpers.fake_trajectory(1000, 0.1)) file_interface.save_res_file(self.mock_file, result_out) result_in = file_interface.load_res_file(self.mock_file, load_trajectories=True) self.assertEqual(result_in, result_out)
def run(args): import evo.common_ape_rpe as common from evo.tools import file_interface, log from evo.tools.settings import SETTINGS log.configure_logging(args.verbose, args.silent, args.debug, local_logfile=args.logfile) if args.debug: from pprint import pformat parser_str = pformat({arg: getattr(args, arg) for arg in vars(args)}) logger.debug("main_parser config:\n{}".format(parser_str)) logger.debug(SEP) if (args.plot or args.save_plot or args.serialize_plot) and args.all_pairs: raise NotImplementedError( "all_pairs mode cannot be used with plotting functions") traj_ref, traj_est, ref_name, est_name = common.load_trajectories(args) pose_relation = common.get_pose_relation(args) delta_unit = common.get_delta_unit(args) result = rpe( traj_ref=traj_ref, traj_est=traj_est, pose_relation=pose_relation, delta=args.delta, delta_unit=delta_unit, rel_delta_tol=args.delta_tol, all_pairs=args.all_pairs, align=args.align, correct_scale=args.correct_scale, ref_name=ref_name, est_name=est_name, ) if args.plot or args.save_plot or args.serialize_plot: common.plot(args, result, result.trajectories[ref_name], result.trajectories[est_name]) if args.save_results: logger.debug(SEP) if not SETTINGS.save_traj_in_zip: del result.trajectories[ref_name] del result.trajectories[est_name] file_interface.save_res_file(args.save_results, result, confirm_overwrite=not args.no_warnings)
def run(args): import evo.common_ape_rpe as common from evo.tools import file_interface, log from evo.tools.settings import SETTINGS log.configure_logging(args.verbose, args.silent, args.debug, local_logfile=args.logfile) if args.debug: from pprint import pformat parser_str = pformat({arg: getattr(args, arg) for arg in vars(args)}) logger.debug("main_parser config:\n{}".format(parser_str)) logger.debug(SEP) traj_ref, traj_est, ref_name, est_name = common.load_trajectories(args) pose_relation = common.get_pose_relation(args) result = ape( traj_ref=traj_ref, traj_est=traj_est, pose_relation=pose_relation, align=args.align, correct_scale=args.correct_scale, ref_name=ref_name, est_name=est_name, ) if args.plot or args.save_plot or args.serialize_plot: common.plot(args, result, result.trajectories[ref_name], result.trajectories[est_name]) if args.save_results: logger.debug(SEP) if not SETTINGS.save_traj_in_zip: del result.trajectories[ref_name] del result.trajectories[est_name] file_interface.save_res_file(args.save_results, result, confirm_overwrite=not args.no_warnings)
def run(args): import evo.common_ape_rpe as common from evo.tools import file_interface, log from evo.tools.settings import SETTINGS log.configure_logging(args.verbose, args.silent, args.debug) if args.debug: from pprint import pformat parser_str = pformat({arg: getattr(args, arg) for arg in vars(args)}) logger.debug("main_parser config:\n{}".format(parser_str)) logger.debug(SEP) traj_ref, traj_est, ref_name, est_name = common.load_trajectories(args) pose_relation = common.get_pose_relation(args) result = ape( traj_ref=traj_ref, traj_est=traj_est, pose_relation=pose_relation, align=args.align, correct_scale=args.correct_scale, ref_name=ref_name, est_name=est_name, ) if args.plot or args.save_plot or args.serialize_plot: common.plot( args, result, result.trajectories[ref_name], result.trajectories[est_name]) if args.save_results: logger.debug(SEP) if not SETTINGS.save_traj_in_zip: del result.trajectories[ref_name] del result.trajectories[est_name] file_interface.save_res_file( args.save_results, result, confirm_overwrite=not args.no_warnings)
def main_ape(traj_ref, traj_est, pose_relation, align=True, correct_scale=False, ref_name="", est_name="", show_plot=False, save_plot=None, plot_mode=None, save_results=None, no_warnings=False, serialize_plot=None): from evo.algorithms import metrics from evo.algorithms import trajectory from evo.tools import file_interface from evo.tools.settings import SETTINGS only_scale = correct_scale and not align if align or correct_scale: logging.debug(SEP) if only_scale: logging.debug("correcting scale...") else: logging.debug("aligning using Umeyama's method..." + ( " (with scale correction)" if correct_scale else "")) traj_est = trajectory.align_trajectory(traj_est, traj_ref, correct_scale, only_scale) logging.debug(SEP) # calculate APE data = (traj_ref, traj_est) ape_metric = metrics.APE(pose_relation) ape_metric.process_data(data) ape_statistics = ape_metric.get_all_statistics() title = str(ape_metric) if align and not correct_scale: title += "\n(with SE(3) Umeyama alignment)" elif align and correct_scale: title += "\n(with Sim(3) Umeyama alignment)" elif only_scale: title += "\n(scale corrected)" else: title += "\n(not aligned)" logging.debug(SEP) res_str = "" for name, val in sorted(ape_statistics.items()): res_str += "{:>10}".format(name) + "\t" + "{0:.6f}".format(val) + "\n" logging.info("\nstatistics of " + title + ":\n\n" + res_str) if show_plot or save_plot or save_results or serialize_plot: if isinstance(traj_est, trajectory.PoseTrajectory3D): seconds_from_start = [ t - traj_est.timestamps[0] for t in traj_est.timestamps ] else: seconds_from_start = None if show_plot or save_plot or serialize_plot: from evo.tools import plot import matplotlib.pyplot as plt logging.debug(SEP) logging.debug("plotting results... ") fig1 = plt.figure(figsize=(SETTINGS.plot_figsize[0], SETTINGS.plot_figsize[1])) # metric values plot.error_array( fig1, ape_metric.error, x_array=seconds_from_start, statistics=ape_statistics, name="APE" + (" (" + ape_metric.unit.value + ")") if ape_metric.unit else "", title=title, xlabel="$t$ (s)" if seconds_from_start else "index") # info text if SETTINGS.plot_info_text and est_name and ref_name: ax = fig1.gca() ax.text(0, -0.12, "estimate: " + est_name + "\nreference: " + ref_name, transform=ax.transAxes, fontsize=8, color="gray") # trajectory colormapped fig2 = plt.figure(figsize=(SETTINGS.plot_figsize[0], SETTINGS.plot_figsize[1])) plot_mode = plot_mode if plot_mode is not None else plot.PlotMode.xyz ax = plot.prepare_axis(fig2, plot_mode) plot.traj(ax, plot_mode, traj_ref, '--', 'gray', 'reference', alpha=0.0 if SETTINGS.plot_hideref else 1.0) plot.traj_colormap(ax, traj_est, ape_metric.error, plot_mode, min_map=ape_statistics["min"], max_map=ape_statistics["max"], title="APE mapped onto trajectory") fig2.axes.append(ax) plot_collection = plot.PlotCollection(title) plot_collection.add_figure("raw", fig1) plot_collection.add_figure("map", fig2) if show_plot: plot_collection.show() if save_plot: plot_collection.export(save_plot, confirm_overwrite=not no_warnings) if serialize_plot: logging.debug(SEP) plot_collection.serialize(serialize_plot, confirm_overwrite=not no_warnings) if save_results: logging.debug(SEP) file_interface.save_res_file(save_results, ape_metric, ape_statistics, title, ref_name, est_name, seconds_from_start, traj_ref, traj_est, confirm_overwrite=not no_warnings) return ape_statistics, ape_metric.error
def run(args: argparse.Namespace) -> None: print('using this main_ape') log.configure_logging(args.verbose, args.silent, args.debug, local_logfile=args.logfile) if args.debug: from pprint import pformat parser_str = pformat({arg: getattr(args, arg) for arg in vars(args)}) logger.debug("main_parser config:\n{}".format(parser_str)) logger.debug(SEP) traj_ref, traj_est, ref_name, est_name = common.load_trajectories(args) traj_ref_full = None if args.plot_full_ref: import copy traj_ref_full = copy.deepcopy(traj_ref) if args.flip_xy: print("flip xy", args.flip_xy) flip_rotation = transformations.rotation_matrix(math.pi / 2, [0, 0, 1]) print('transformation matrix,', flip_rotation) traj_est.transform_rotation_only(flip_rotation) if isinstance(traj_ref, PoseTrajectory3D) and isinstance( traj_est, PoseTrajectory3D): logger.debug(SEP) if args.t_start or args.t_end: if args.t_start: logger.info("Using time range start: {}s".format(args.t_start)) if args.t_end: logger.info("Using time range end: {}s".format(args.t_end)) traj_ref.reduce_to_time_range(args.t_start, args.t_end) logger.debug("Synchronizing trajectories...") traj_ref, traj_est = sync.associate_trajectories(traj_ref, traj_est, args.t_max_diff, args.t_offset, first_name=ref_name, snd_name=est_name) pose_relation = common.get_pose_relation(args) print('align_odom: ', args.align_odom) result = ape( traj_ref=traj_ref, traj_est=traj_est, pose_relation=pose_relation, align=args.align, correct_scale=args.correct_scale, n_to_align=args.n_to_align, align_origin=args.align_origin, align_odom=args.align_odom, ref_name=ref_name, est_name=est_name, ) if args.plot or args.save_plot or args.serialize_plot: common.plot_result(args, result, traj_ref, result.trajectories[est_name], traj_ref_full=traj_ref_full) if args.save_results: logger.debug(SEP) if not SETTINGS.save_traj_in_zip: del result.trajectories[ref_name] del result.trajectories[est_name] file_interface.save_res_file(args.save_results, result, confirm_overwrite=not args.no_warnings)
def main_rpe_for_each(traj_ref, traj_est, pose_relation, mode, bins, rel_tols, align=False, correct_scale=False, ref_name="", est_name="", show_plot=False, save_plot=None, save_results=None, no_warnings=False, serialize_plot=None): from evo.algorithms import metrics from evo.algorithms import filters from evo.algorithms import trajectory from evo.tools import file_interface from evo.tools.settings import SETTINGS if not bins or not rel_tols: raise RuntimeError( "bins and tolerances must have more than one element") if len(bins) != len(rel_tols): raise RuntimeError( "bins and tolerances must have the same number of elements") if mode in {"speed", "angular_speed" } and traj_est is trajectory.PosePath3D: raise RuntimeError("timestamps are required for mode: " + mode) bin_unit = None if mode == "speed": bin_unit = metrics.VelUnit.meters_per_sec elif mode == "path": bin_unit = metrics.Unit.meters elif mode == "angle": bin_unit = metrics.Unit.degrees elif mode == "angular_speed": bin_unit = metrics.VelUnit.degrees_per_sec rpe_unit = None if pose_relation is metrics.PoseRelation.translation_part: rpe_unit = metrics.Unit.meters elif pose_relation is metrics.PoseRelation.rotation_angle_deg: rpe_unit = metrics.Unit.degrees elif pose_relation is metrics.PoseRelation.rotation_angle_rad: rpe_unit = metrics.Unit.radians correct_only_scale = correct_scale and not align if align or correct_scale: logging.debug(SEP) if correct_only_scale: logging.debug("correcting scale...") else: logging.debug("aligning using Umeyama's method..." + ( " (with scale correction)" if correct_scale else "")) traj_est = trajectory.align_trajectory(traj_est, traj_ref, correct_scale, correct_only_scale) results = [] for bin, rel_tol, in zip(bins, rel_tols): logging.debug(SEP) logging.info("calculating RPE for each sub-sequence of " + str(bin) + " (" + bin_unit.value + ")") tol = bin * rel_tol id_pairs = [] if mode == "path": id_pairs = filters.filter_pairs_by_path(traj_ref.poses_se3, bin, tol, all_pairs=True) elif mode == "angle": id_pairs = filters.filter_pairs_by_angle(traj_ref.poses_se3, bin, tol, degrees=True) elif mode == "speed": id_pairs = filters.filter_pairs_by_speed(traj_ref.poses_se3, traj_ref.timestamps, bin, tol) elif mode == "angular_speed": id_pairs = filters.filter_pairs_by_angular_speed( traj_ref.poses_se3, traj_ref.timestamps, bin, tol, True) if len(id_pairs) == 0: raise RuntimeError("bin " + str(bin) + " (" + str(bin_unit.value) + ") " + "produced empty index list - try other values") # calculate RPE with all IDs (delta 1 frames) data = (traj_ref, traj_est) # the delta here has nothing to do with the bin - 1f delta just to use all poses of the bin rpe_metric = metrics.RPE(pose_relation, delta=1, delta_unit=metrics.Unit.frames, all_pairs=True) rpe_metric.process_data(data, id_pairs) mean = rpe_metric.get_statistic(metrics.StatisticsType.mean) results.append(mean) if SETTINGS.plot_usetex: mode.replace("_", "\_") title = "mean RPE w.r.t. " + pose_relation.value + "\nfor different " + mode + " sub-sequences" if align and not correct_scale: title += "\n(with SE(3) Umeyama alignment)" elif align and correct_scale: title += "\n(with Sim(3) Umeyama alignment)" elif correct_only_scale: title += "\n(scale corrected)" else: title += "\n(not aligned)" logging.debug(SEP) logging.info("\n" + title + "\n") res_str = "" for bin, result in zip(bins, results): res_str += "{:>10}".format(str(bin) + "(" + bin_unit.value + ")") res_str += "\t" + "{0:.6f}".format(result) + "\n" logging.info(res_str) if show_plot or save_plot or serialize_plot: from evo.tools import plot import matplotlib.pyplot as plt plot_collection = plot.PlotCollection(title) fig = plt.figure(figsize=(SETTINGS.plot_figsize[0], SETTINGS.plot_figsize[1])) plot.error_array(fig, results, x_array=bins, name="mean RPE" + (" (" + rpe_unit.value + ")") if rpe_unit else "", marker="o", title=title, xlabel=mode + " sub-sequences " + " (" + bin_unit.value + ")") # info text if SETTINGS.plot_info_text and est_name and ref_name: ax = fig.gca() ax.text(0, -0.12, "estimate: " + est_name + "\nreference: " + ref_name, transform=ax.transAxes, fontsize=8, color="gray") plt.title(title) plot_collection.add_figure("raw", fig) if show_plot: plot_collection.show() if save_plot: plot_collection.export(save_plot, confirm_overwrite=not no_warnings) if serialize_plot: logging.debug(SEP) plot_collection.serialize(serialize_plot, confirm_overwrite=not no_warnings) rpe_statistics = {bin: result for bin, result in zip(bins, results)} if save_results: logging.debug(SEP) # utility class to trick save_res_file class Metric: unit = rpe_unit error = results file_interface.save_res_file(save_results, Metric, rpe_statistics, title, ref_name, est_name, bins, traj_ref, traj_est, xlabel=mode + " sub-sequences " + " (" + bin_unit.value + ")", confirm_overwrite=not no_warnings) return rpe_statistics, results
res.info["title"] = title res.info["est_name"] = est_name err_arr = [] ts_arr = [] for j in range(len(csv_data[i])): err_arr.append(csv_data[i][j][0]) ts_arr.append(j) res.add_np_array("error_array", err_arr) res.add_np_array("timestamps", ts_arr) rmse_arr = [] for j in range(len(csv_data[i])): rmse_arr.append(csv_data[i][j][2]) statsdict = { "mean": mean(err_arr), "median": median(err_arr), "rmse": mean(rmse_arr) } res.add_stats(statsdict) save_path = args.save + est_name save_path = save_path[:-4] + ".zip" print("\nSaving consolidated results to:\n {}".format(save_path)) evof.save_res_file(save_path, res)
def main(res_file, new_name): result = file_interface.load_res_file(res_file) result.info["est_name"] = new_name file_interface.save_res_file(res_file, result)
def main_rpe(traj_ref, traj_est, pose_relation, delta, delta_unit, rel_delta_tol=0.1, all_pairs=False, align=False, correct_scale=False, ref_name="", est_name="", show_plot=False, save_plot=None, plot_mode=None, save_results=None, no_warnings=False, support_loop=False, serialize_plot=None): from evo.core import metrics, result from evo.core import trajectory from evo.tools import file_interface from evo.tools.settings import SETTINGS if (show_plot or save_plot or serialize_plot) and all_pairs: raise metrics.MetricsException( "all_pairs mode cannot be used with plotting functions") only_scale = correct_scale and not align if align or correct_scale: logging.debug(SEP) if only_scale: logging.debug("correcting scale...") else: logging.debug("aligning using Umeyama's method..." + ( " (with scale correction)" if correct_scale else "")) traj_est = trajectory.align_trajectory(traj_est, traj_ref, correct_scale, only_scale) logging.debug(SEP) # calculate RPE data = (traj_ref, traj_est) rpe_metric = metrics.RPE(pose_relation, delta, delta_unit, rel_delta_tol, all_pairs) rpe_metric.process_data(data) rpe_statistics = rpe_metric.get_all_statistics() title = str(rpe_metric) if align and not correct_scale: title += "\n(with SE(3) Umeyama alignment)" elif align and correct_scale: title += "\n(with Sim(3) Umeyama alignment)" elif only_scale: title += "\n(scale corrected)" else: title += "\n(not aligned)" rpe_result = result.from_metric(rpe_metric, title, ref_name, est_name) logging.debug(SEP) logging.info(rpe_result.pretty_str()) # restrict trajectories to delta ids if support_loop: # avoid overwriting if called repeatedly e.g. in Jupyter notebook import copy traj_ref = copy.deepcopy(traj_ref) traj_est = copy.deepcopy(traj_est) traj_ref.reduce_to_ids(rpe_metric.delta_ids) traj_est.reduce_to_ids(rpe_metric.delta_ids) if isinstance(traj_est, trajectory.PoseTrajectory3D) and not all_pairs: seconds_from_start = [ t - traj_est.timestamps[0] for t in traj_est.timestamps ] rpe_result.add_np_array("seconds_from_start", seconds_from_start) else: seconds_from_start = None if show_plot or save_plot or serialize_plot and not all_pairs: from evo.tools import plot import matplotlib.pyplot as plt logging.debug(SEP) logging.debug("plotting results... ") fig1 = plt.figure(figsize=(SETTINGS.plot_figsize[0], SETTINGS.plot_figsize[1])) # metric values plot.error_array( fig1, rpe_metric.error, x_array=seconds_from_start, statistics=rpe_statistics, name="RPE" + (" (" + rpe_metric.unit.value + ")") if rpe_metric.unit else "", title=title, xlabel="$t$ (s)" if seconds_from_start else "index") # info text if SETTINGS.plot_info_text and est_name and ref_name: ax = fig1.gca() ax.text(0, -0.12, "estimate: " + est_name + "\nreference: " + ref_name, transform=ax.transAxes, fontsize=8, color="gray") # trajectory colormapped fig2 = plt.figure(figsize=(SETTINGS.plot_figsize[0], SETTINGS.plot_figsize[1])) plot_mode = plot_mode if plot_mode is not None else plot.PlotMode.xyz ax = plot.prepare_axis(fig2, plot_mode) plot.traj(ax, plot_mode, traj_ref, '--', 'gray', 'reference', alpha=0 if SETTINGS.plot_hideref else 1) plot.traj_colormap(ax, traj_est, rpe_metric.error, plot_mode, min_map=rpe_statistics["min"], max_map=rpe_statistics["max"], title="RPE mapped onto trajectory") fig2.axes.append(ax) plot_collection = plot.PlotCollection(title) plot_collection.add_figure("raw", fig1) plot_collection.add_figure("map", fig2) if show_plot: plot_collection.show() if save_plot: plot_collection.export(save_plot, confirm_overwrite=not no_warnings) if serialize_plot: logging.debug(SEP) plot_collection.serialize(serialize_plot, confirm_overwrite=not no_warnings) if save_results: logging.debug(SEP) if SETTINGS.save_traj_in_zip: rpe_result.add_trajectory("traj_ref", traj_ref) rpe_result.add_trajectory("traj_est", traj_est) file_interface.save_res_file(save_results, rpe_result, confirm_overwrite=not no_warnings) return rpe_result
# print(loc_tra) results = [] odom_result = ape( traj_ref=mocap, traj_est=odom, pose_relation=metrics.PoseRelation.translation_part, align=False, correct_scale=False, align_origin=True, ref_name="mocap", est_name="odom", ) results.append(odom_result) file_interface.save_res_file("/home/kostas/results/res_files/odom", odom_result, confirm_overwrite=False) slam_result = ape( traj_ref=mocap, traj_est=slam, pose_relation=metrics.PoseRelation.translation_part, align=False, correct_scale=False, align_origin=True, ref_name="mocap", est_name="slam", ) results.append(slam_result) file_interface.save_res_file("/home/kostas/results/res_files/slam", slam_result,