blob: 2b54355fc0065b1d57491c1f245884c0d48486de [file] [log] [blame]
#!/usr/bin/env python3
# This script runs the multi camera calibration code through its paces using log data
# It uses the AprilTag output logs, rather than directly from images
import argparse
import os
import subprocess
import sys
import time
from typing import Sequence, Text
# Compare two json files that may have a different timestamp
def compare_files(gt_file: str, calc_file: str):
with open(gt_file, "r") as f_gt:
with open(calc_file, "r") as f_calc:
while True:
line_gt = f_gt.readline()
line_calc = f_calc.readline()
if not line_gt:
if not line_calc:
return True
else:
return False
# timestamp field will be different, so ignore this line
if "timestamp" in line_gt:
if "timestamp" in line_calc:
continue
else:
return False
# Compare line and return False if different
if line_gt != line_calc:
print("Lines don't match!")
print("\tGround truth file:", line_gt, end='')
print("\tCalculated file:", line_calc, end='')
return False
return True
return False
# Run through the calibration routine and file checking with max_pose_error arg
def check_calib_match(args, max_pose_error: float):
calibrate_result = subprocess.run(
[
args.calibrate_binary,
args.logfile,
"--target_type",
"apriltag",
"--team_number",
"971",
"--max_pose_error",
str(max_pose_error),
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="utf-8",
)
calibrate_result.check_returncode()
# Check for the 3 pi's that get calibrated
for pi in [2, 3, 4]:
pi_name = "pi-971-" + str(pi)
# Look for calculated calibration file in /tmp dir with pi_name
calc_calib_dir = "/tmp/"
files = os.listdir(calc_calib_dir)
calc_file = ""
# Read the calculated files in reverse order, so that we pick
# up the most newly created file each time
for file in files[::-1]:
# check if file contains substring pi_name
if pi_name in file:
calc_file = calc_calib_dir + file
# Next find the "ground truth" file with this pi_name
external_dir = 'external/calibrate_multi_cameras_data/'
files = os.listdir(external_dir)
gt_file = ""
for file in files[::-1]:
if pi_name in file:
gt_file = external_dir + file
if calc_file != "" and gt_file != "":
if not compare_files(gt_file, calc_file):
return False
return True
def main(argv: Sequence[Text]):
parser = argparse.ArgumentParser()
parser.add_argument("--logfile",
required=True,
default="calib1",
help="Path to logfile.")
parser.add_argument(
"--calibrate_binary",
required=False,
default=
"/home/jimostrowski/code/FRC/971-Robot-Code/bazel-bin/y2023/vision/calibrate_multi_cameras",
help="Path to calibrate_multi_cameras binary",
)
args = parser.parse_args(argv)
# Run once with correct max_pose_error
# These were the flags used to create the test file
# max_pose_error = 5e-5
# max_pose_error_ratio = 0.4
if not check_calib_match(args, 5e-5):
return -1
# And once with the incorrect value for max_pose_error to see that it fails
if check_calib_match(args, 1e-5):
return -1
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))