"""Door robot arm: the fit's linear carriage schedules (c = A + B * door x, as the rig's driver) for one design, scored along every quarter frame of both doors (dra_fit3d.evaluate). 2026-10-18, scale-up. python build/dra_fit3d_linear.py '' c_closed,c_closed.. c_open,c_open.. """ import sys import json import math sys.path.insert(0, __import__("os").path.dirname(__import__("os").path.abspath(__file__))) import dra_fit3d as F3 # noqa: E402 def run(Dz, c_closed, c_open, step=4, keys=("AFT", "FORE"), verbose=False): worst = (9.0, None) rows = [] for key in keys: sg = 1.0 if key == "AFT" else -1.0 dr = F3.BASE["doors"][key] cc = c_closed if key == "AFT" else 2 * 3.05 - c_closed co = c_open if key == "AFT" else 2 * 3.05 - c_open B = (cc - co) / (dr["closed_x"] - dr["open_x"]) A = cc - B * dr["closed_x"] for f, x, y, z in F3.DP[key][::step]: c = A + B * x w = F3.evaluate(Dz, key, (x, y, z), c) s = F3.score(w) rows.append((key, f, round(c, 3), round(s, 3), w)) if s < worst[0]: worst = (s, (key, f, round(c, 3), w)) return worst, rows if __name__ == "__main__": d = json.loads(sys.argv[1]) Dz = F3.make_design(**d) for ccl in [float(a) for a in sys.argv[2].split(",")]: for cop in [float(a) for a in sys.argv[3].split(",")]: (s, info), rows = run(Dz, ccl, cop, step=int(sys.argv[4]) if len(sys.argv) > 4 else 8) w = info[3] print("c_closed %.2f c_open %.2f -> min score %+.3f at %s f%s c %.2f | lev %d %s/%s door %.2f joints %.1f %s" % ( ccl, cop, s, info[0], info[1], info[2], w["lev"], w["link"], str(w["who"])[:30], w["door"], w["joint"], w.get("jname", "")), flush=True)