running Multiview
This commit is contained in:
@@ -488,6 +488,77 @@ def project_points(
|
||||
return projected.reshape(-1, 2)
|
||||
|
||||
|
||||
def compute_soft_constraint_residuals(
|
||||
robot_state: Dict[str, float],
|
||||
robot_markers: Dict[int, Dict[str, Any]],
|
||||
link_transforms: Dict[str, np.ndarray],
|
||||
robot: Dict[str, Any],
|
||||
enabled_constraints: Dict[str, ConstraintResult]
|
||||
) -> List[float]:
|
||||
"""
|
||||
Compute residuals from soft constraints (kinematic consistency, rigid body distances).
|
||||
Returns a list of constraint residuals to append to the total residual vector.
|
||||
"""
|
||||
residuals = []
|
||||
weight_scale = 0.1 # Weight for soft constraints relative to reprojection errors
|
||||
|
||||
# Constraint 1: Rigid body distances within each link
|
||||
if enabled_constraints['RigidBodyDistances'].enabled:
|
||||
for link_name in ['Arm1', 'Ellbow', 'Arm2']:
|
||||
link_markers = [m for m in robot_markers.values() if m['link_name'] == link_name]
|
||||
if len(link_markers) < 2:
|
||||
continue
|
||||
|
||||
# Compute all pairwise distances in world coords
|
||||
for i in range(len(link_markers)):
|
||||
for j in range(i + 1, len(link_markers)):
|
||||
m_i = link_markers[i]
|
||||
m_j = link_markers[j]
|
||||
|
||||
pos_i = compute_marker_world_position(m_i, link_transforms)
|
||||
pos_j = compute_marker_world_position(m_j, link_transforms)
|
||||
|
||||
dist_world = np.linalg.norm(pos_i - pos_j)
|
||||
|
||||
# Reference distance in local coords
|
||||
dist_local = np.linalg.norm(m_i['position_m'] - m_j['position_m'])
|
||||
|
||||
# Residual: difference should be zero (rigid body)
|
||||
error = dist_world - dist_local
|
||||
residuals.append(error * weight_scale * 0.1) # Very soft weight
|
||||
|
||||
# Constraint 2: Fixed X-distances between links (Arm1 <-> Ellbow)
|
||||
if enabled_constraints['InterLinkXDistances'].enabled:
|
||||
arm1_markers = [m for m in robot_markers.values() if m['link_name'] == 'Arm1']
|
||||
ellbow_markers = [m for m in robot_markers.values() if m['link_name'] == 'Ellbow']
|
||||
|
||||
if len(arm1_markers) >= 1 and len(ellbow_markers) >= 1:
|
||||
# Get first marker from each link
|
||||
m_arm1 = arm1_markers[0]
|
||||
m_ellbow = ellbow_markers[0]
|
||||
|
||||
pos_arm1 = compute_marker_world_position(m_arm1, link_transforms)
|
||||
pos_ellbow = compute_marker_world_position(m_ellbow, link_transforms)
|
||||
|
||||
# X-distance in world should match reference (relative position)
|
||||
# Since both rotate around X-axis at different points, we check consistency
|
||||
x_diff_world = pos_ellbow[0] - pos_arm1[0]
|
||||
x_diff_ref = m_ellbow['position_m'][0] - m_arm1['position_m'][0]
|
||||
|
||||
error = x_diff_world - x_diff_ref
|
||||
residuals.append(error * weight_scale)
|
||||
|
||||
return residuals
|
||||
|
||||
|
||||
def compute_marker_world_position(marker: Dict[str, Any], link_transforms: Dict[str, np.ndarray]) -> np.ndarray:
|
||||
"""Compute the world position of a marker given current link transforms."""
|
||||
link_transform = link_transforms[marker['link_name']]
|
||||
local_pos = np.concatenate([marker['position_m'], [1.0]])
|
||||
world_pos = (link_transform @ local_pos)[:3]
|
||||
return world_pos
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Optimization
|
||||
# ------------------------------------------------------------------
|
||||
@@ -520,12 +591,15 @@ def residuals_for_parameters(
|
||||
robot_markers: Dict[int, Dict[str, Any]],
|
||||
robot: Dict[str, Any],
|
||||
scale: float,
|
||||
default_state: Dict[str, float]
|
||||
default_state: Dict[str, float],
|
||||
enabled_constraints: Dict[str, ConstraintResult]
|
||||
) -> np.ndarray:
|
||||
robot_state, camera_params = unpack_parameters(params, len(views))
|
||||
link_transforms = compute_link_transforms(robot, robot_state, scale)
|
||||
|
||||
residuals = []
|
||||
|
||||
# Reprojection residuals (primary observation)
|
||||
for obs in observations:
|
||||
marker = robot_markers[obs['marker_id']]
|
||||
world_corners = compute_marker_world_corners(marker, link_transforms)
|
||||
@@ -535,6 +609,7 @@ def residuals_for_parameters(
|
||||
weight = math.sqrt(obs['confidence'])
|
||||
residuals.extend((diffs * weight).reshape(-1))
|
||||
|
||||
# Weak priors on robot state
|
||||
for key in STATE_KEYS:
|
||||
diff = robot_state[key] - default_state.get(key, 0.0)
|
||||
if key in ('x', 'y', 'z', 'e'):
|
||||
@@ -543,9 +618,16 @@ def residuals_for_parameters(
|
||||
w = 0.01
|
||||
residuals.append(diff * w)
|
||||
|
||||
# Soft constraints (kinematic consistency, rigid body constraints)
|
||||
soft_constraint_residuals = compute_soft_constraint_residuals(
|
||||
robot_state, robot_markers, link_transforms, robot, enabled_constraints
|
||||
)
|
||||
residuals.extend(soft_constraint_residuals)
|
||||
|
||||
return np.asarray(residuals, dtype=np.float64)
|
||||
|
||||
|
||||
|
||||
def estimate_uncertainty(result: Any, n_params: int) -> np.ndarray:
|
||||
if result.jac is None:
|
||||
return np.full(n_params, float('nan'), dtype=np.float64)
|
||||
@@ -563,9 +645,97 @@ def estimate_uncertainty(result: Any, n_params: int) -> np.ndarray:
|
||||
return np.sqrt(np.diag(cov))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Output assembly
|
||||
# ------------------------------------------------------------------
|
||||
def print_constraint_sanity_check(
|
||||
robot_state: Dict[str, float],
|
||||
robot_markers: Dict[int, Dict[str, Any]],
|
||||
link_transforms: Dict[str, np.ndarray],
|
||||
robot: Dict[str, Any],
|
||||
enabled_constraints: Dict[str, ConstraintResult]
|
||||
) -> None:
|
||||
"""
|
||||
Print sanity checks for all constraints to verify the optimization result.
|
||||
"""
|
||||
print("\n" + "=" * 70)
|
||||
print("CONSTRAINT SANITY CHECKS (after optimization)")
|
||||
print("=" * 70)
|
||||
|
||||
# Check 1: Rigid body distances
|
||||
if enabled_constraints['RigidBodyDistances'].enabled:
|
||||
print("\n1. RIGID BODY DISTANCES")
|
||||
for link_name in ['Arm1', 'Ellbow', 'Arm2']:
|
||||
link_markers = [m for m in robot_markers.values() if m['link_name'] == link_name]
|
||||
if len(link_markers) < 2:
|
||||
continue
|
||||
|
||||
max_error = 0.0
|
||||
for i in range(len(link_markers)):
|
||||
for j in range(i + 1, len(link_markers)):
|
||||
m_i = link_markers[i]
|
||||
m_j = link_markers[j]
|
||||
|
||||
pos_i = compute_marker_world_position(m_i, link_transforms)
|
||||
pos_j = compute_marker_world_position(m_j, link_transforms)
|
||||
|
||||
dist_world = np.linalg.norm(pos_i - pos_j)
|
||||
dist_local = np.linalg.norm(m_i['position_m'] - m_j['position_m'])
|
||||
error = abs(dist_world - dist_local)
|
||||
max_error = max(max_error, error)
|
||||
|
||||
status = "✓" if max_error < 1.0 else "⚠" if max_error < 5.0 else "✗"
|
||||
print(f" {link_name:10s}: max_error = {max_error:.3f} mm {status}")
|
||||
|
||||
# Check 2: Inter-link X distances
|
||||
if enabled_constraints['InterLinkXDistances'].enabled:
|
||||
print("\n2. INTER-LINK X-DISTANCES")
|
||||
arm1_markers = [m for m in robot_markers.values() if m['link_name'] == 'Arm1']
|
||||
ellbow_markers = [m for m in robot_markers.values() if m['link_name'] == 'Ellbow']
|
||||
|
||||
if len(arm1_markers) >= 1 and len(ellbow_markers) >= 1:
|
||||
m_arm1 = arm1_markers[0]
|
||||
m_ellbow = ellbow_markers[0]
|
||||
|
||||
pos_arm1 = compute_marker_world_position(m_arm1, link_transforms)
|
||||
pos_ellbow = compute_marker_world_position(m_ellbow, link_transforms)
|
||||
|
||||
x_diff_world = pos_ellbow[0] - pos_arm1[0]
|
||||
x_diff_ref = m_ellbow['position_m'][0] - m_arm1['position_m'][0]
|
||||
error = abs(x_diff_world - x_diff_ref)
|
||||
|
||||
status = "✓" if error < 1.0 else "⚠" if error < 5.0 else "✗"
|
||||
print(f" Arm1 <-> Ellbow: error = {error:.3f} mm {status}")
|
||||
|
||||
# Check 3: Arm2 sin(a) dependency
|
||||
if enabled_constraints['Arm2SinADependency'].enabled:
|
||||
print("\n3. ARM2 sin(a) DEPENDENCY (sanity check)")
|
||||
arm2_markers = [m for m in robot_markers.values() if m['link_name'] == 'Arm2']
|
||||
if len(arm2_markers) >= 2:
|
||||
# Check that markers with different Z values have different X spreads
|
||||
a_rad = math.radians(robot_state['a'])
|
||||
sin_a = math.sin(a_rad)
|
||||
cos_a = math.cos(a_rad)
|
||||
|
||||
z_variations = {}
|
||||
for m in arm2_markers:
|
||||
z_local = m['position_m'][2]
|
||||
x_local = m['position_m'][0]
|
||||
pos_world = compute_marker_world_position(m, link_transforms)
|
||||
x_world = pos_world[0]
|
||||
|
||||
# Expected: x_world = 90 + x_local * cos(a) - z_local * sin(a)
|
||||
x_expected = 90 * (robot.get('renderingInfo', {}).get('metric', 'mm') == 'mm' and 0.09 or 0.09) + x_local * cos_a - z_local * sin_a
|
||||
x_error = abs(x_world - x_expected)
|
||||
|
||||
if z_local not in z_variations:
|
||||
z_variations[z_local] = []
|
||||
z_variations[z_local].append(x_error)
|
||||
|
||||
max_error = max(max(errors) for errors in z_variations.values()) if z_variations else 0.0
|
||||
status = "✓" if max_error < 5.0 else "⚠" if max_error < 10.0 else "⚠"
|
||||
print(f" X-consistency with sin(a): max_error = {max_error:.3f} mm {status}")
|
||||
print(f" (Note: this is a consistency check, not a hard constraint)")
|
||||
|
||||
print("=" * 70)
|
||||
|
||||
|
||||
def camera_position_world(rvec: np.ndarray, tvec: np.ndarray) -> np.ndarray:
|
||||
R, _ = cv2.Rodrigues(rvec)
|
||||
@@ -705,6 +875,16 @@ def main() -> None:
|
||||
}
|
||||
|
||||
robot_markers = extract_markers(robot, scale)
|
||||
|
||||
# Validate constraints
|
||||
print("\n" + "=" * 70)
|
||||
print("CONSTRAINT VALIDATION")
|
||||
print("=" * 70)
|
||||
enabled_constraints = validate_constraints(robot, robot_markers)
|
||||
for constraint_name, result in enabled_constraints.items():
|
||||
print(result)
|
||||
print("=" * 70)
|
||||
|
||||
views, observations = collect_views_and_observations(args.detections, robot_markers)
|
||||
|
||||
camera_guesses = []
|
||||
@@ -725,7 +905,7 @@ def main() -> None:
|
||||
progress['iter'] += 1
|
||||
now = time.time()
|
||||
if progress['iter'] == 1 or now - progress['last_print'] >= 1.0:
|
||||
res = residuals_for_parameters(xk, views, observations, robot_markers, robot, scale, default_state)
|
||||
res = residuals_for_parameters(xk, views, observations, robot_markers, robot, scale, default_state, enabled_constraints)
|
||||
cost = 0.5 * float(np.dot(res, res))
|
||||
delta_cost = None
|
||||
convergence = ''
|
||||
@@ -751,7 +931,7 @@ def main() -> None:
|
||||
result = least_squares(
|
||||
residuals_for_parameters,
|
||||
x0,
|
||||
args=(views, observations, robot_markers, robot, scale, default_state),
|
||||
args=(views, observations, robot_markers, robot, scale, default_state, enabled_constraints),
|
||||
jac='2-point',
|
||||
method='trf',
|
||||
loss='soft_l1',
|
||||
@@ -762,6 +942,10 @@ def main() -> None:
|
||||
|
||||
robot_state, camera_params = unpack_parameters(result.x, len(views))
|
||||
uncertainties = estimate_uncertainty(result, len(result.x))
|
||||
|
||||
# Print constraint sanity checks
|
||||
link_transforms = compute_link_transforms(robot, robot_state, scale)
|
||||
print_constraint_sanity_check(robot_state, robot_markers, link_transforms, robot, enabled_constraints)
|
||||
|
||||
output = build_output(robot_state, uncertainties[:len(STATE_KEYS)], views, camera_params, observations, robot_markers, scale, robot, robot_json_path)
|
||||
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,31 +1,31 @@
|
||||
{
|
||||
"final_cost": 25086.49759096419,
|
||||
"final_cost": 24986.21700952237,
|
||||
"status": 0,
|
||||
"message": "The maximum number of function evaluations is exceeded.",
|
||||
"robot_state": {
|
||||
"state": {
|
||||
"x": 100.74147204793623,
|
||||
"y": 29.650679871841962,
|
||||
"z": -35.519338413527834,
|
||||
"a": -119.76253895286006,
|
||||
"b": 22.000000000000124,
|
||||
"c": 91.00000000000006,
|
||||
"e": 9.999999999999991
|
||||
"x": 100.65052085564044,
|
||||
"y": 29.661249073864987,
|
||||
"z": -35.948789524024555,
|
||||
"a": -119.85307495241203,
|
||||
"b": 21.99999999999959,
|
||||
"c": 90.99999999999991,
|
||||
"e": 10.000000000000025
|
||||
},
|
||||
"uncertainty": {
|
||||
"x_mm": 5958.291819057341,
|
||||
"y_mm": 1161.4246555312698,
|
||||
"z_mm": 548.5614212936815,
|
||||
"a_deg": 3375.9445110397996,
|
||||
"b_deg": 13762.367585907954,
|
||||
"c_deg": 13762.368814943879,
|
||||
"e_mm": 137623.68210441121
|
||||
"x_mm": 1490.1455410993876,
|
||||
"y_mm": 429.51650769405427,
|
||||
"z_mm": 477.27281993275335,
|
||||
"a_deg": 3533.703361743133,
|
||||
"b_deg": 13152.589314453906,
|
||||
"c_deg": 13152.589314528996,
|
||||
"e_mm": 131525.9153573403
|
||||
},
|
||||
"confidence": {
|
||||
"x": 1.7166198945166287e-259,
|
||||
"y": 3.630513831255408e-51,
|
||||
"z": 1.5006526335068334e-24,
|
||||
"a": 2.424335742250214e-147,
|
||||
"x": 1.922212631331247e-65,
|
||||
"y": 2.219908541429891e-19,
|
||||
"z": 1.8719954726562647e-21,
|
||||
"a": 3.4136023686230135e-154,
|
||||
"b": 0.0,
|
||||
"c": 0.0,
|
||||
"e": 0.36787944117144233
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"created_utc": "2026-05-28T15:11:26Z",
|
||||
"created_utc": "2026-05-28T15:43:43Z",
|
||||
"vision_config": {
|
||||
"MarkerType": "DICT_4X4_250",
|
||||
"MarkerSize": 0.025
|
||||
@@ -46,7 +46,7 @@
|
||||
},
|
||||
"detections": [
|
||||
{
|
||||
"observation_id": "a0864373-2016-4c0c-be4d-c8b66b185bd7",
|
||||
"observation_id": "713817fc-5f5b-486d-850a-2b1915ab7eac",
|
||||
"type": "aruco",
|
||||
"marker_id": 102,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -100,7 +100,7 @@
|
||||
"confidence": 0.9494437061622057
|
||||
},
|
||||
{
|
||||
"observation_id": "2d237a4b-33db-4a97-aad0-2b69922e5c27",
|
||||
"observation_id": "cc667670-1b39-4632-8f1c-1a5fdf0e0c7e",
|
||||
"type": "aruco",
|
||||
"marker_id": 243,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -154,7 +154,7 @@
|
||||
"confidence": 0.8899728634608616
|
||||
},
|
||||
{
|
||||
"observation_id": "a01227d1-d980-435e-ad0f-453789a6e941",
|
||||
"observation_id": "0cd34a97-e5d7-4bbf-aac9-a4e203b31583",
|
||||
"type": "aruco",
|
||||
"marker_id": 210,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -208,7 +208,7 @@
|
||||
"confidence": 0.5673043275049208
|
||||
},
|
||||
{
|
||||
"observation_id": "8044b2a7-1af6-457d-b112-8566c669e961",
|
||||
"observation_id": "5632f4b1-0db1-4a98-b8d3-9ebbbb4b126f",
|
||||
"type": "aruco",
|
||||
"marker_id": 247,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -262,7 +262,7 @@
|
||||
"confidence": 0.8796777163094818
|
||||
},
|
||||
{
|
||||
"observation_id": "dac561f0-1939-438d-9ed1-5d057d5132dd",
|
||||
"observation_id": "75ae283a-9ba7-43bc-bb54-ba44e24e235f",
|
||||
"type": "aruco",
|
||||
"marker_id": 246,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -316,7 +316,7 @@
|
||||
"confidence": 0.8015179238063419
|
||||
},
|
||||
{
|
||||
"observation_id": "33c3c11c-f7d2-4038-ac2c-e4332bcf5b79",
|
||||
"observation_id": "7c280cd2-7b94-476a-be3e-7d89e6e35ed3",
|
||||
"type": "aruco",
|
||||
"marker_id": 101,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -370,7 +370,7 @@
|
||||
"confidence": 0.3325004465415643
|
||||
},
|
||||
{
|
||||
"observation_id": "3ae8ec72-f806-457c-8c60-403428368c0a",
|
||||
"observation_id": "2e554970-1749-4924-ac98-3ac4debec51b",
|
||||
"type": "aruco",
|
||||
"marker_id": 215,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -424,7 +424,7 @@
|
||||
"confidence": 0.7952557920267838
|
||||
},
|
||||
{
|
||||
"observation_id": "755f017d-cb90-461d-bd57-25768e592696",
|
||||
"observation_id": "cc766bc2-4f75-4520-baf3-e10c62f6c25d",
|
||||
"type": "aruco",
|
||||
"marker_id": 124,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -478,7 +478,7 @@
|
||||
"confidence": 0.34091855704160245
|
||||
},
|
||||
{
|
||||
"observation_id": "45854ae6-7ba9-4906-87a6-2c7d9356cb85",
|
||||
"observation_id": "c7cc54fc-982b-46e8-b176-82eefba18404",
|
||||
"type": "aruco",
|
||||
"marker_id": 229,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -532,7 +532,7 @@
|
||||
"confidence": 0.26810902547334975
|
||||
},
|
||||
{
|
||||
"observation_id": "de3abf0b-4ae2-4fee-9215-2039b0f5e3da",
|
||||
"observation_id": "7cd2ae3d-740e-4005-a8b8-b23b0ea0082a",
|
||||
"type": "aruco",
|
||||
"marker_id": 122,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -586,7 +586,7 @@
|
||||
"confidence": 0.18665602922528673
|
||||
},
|
||||
{
|
||||
"observation_id": "5577fb36-2186-41f8-8fbf-40266f9e767c",
|
||||
"observation_id": "95fcb10e-a4e9-4d43-8950-8d0523fe95aa",
|
||||
"type": "aruco",
|
||||
"marker_id": 198,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -640,7 +640,7 @@
|
||||
"confidence": 0.20150745250271476
|
||||
},
|
||||
{
|
||||
"observation_id": "54aec13c-2b54-49d8-a9c6-e873eb94dfef",
|
||||
"observation_id": "e14fdb7d-e877-4a87-9e58-430ac0f56f18",
|
||||
"type": "aruco",
|
||||
"marker_id": 211,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -694,7 +694,7 @@
|
||||
"confidence": 0.6412317666518965
|
||||
},
|
||||
{
|
||||
"observation_id": "4cf08f15-d8f2-416d-8397-8a68f564d0a8",
|
||||
"observation_id": "7a8a865f-1251-4024-9255-278cb4cb527f",
|
||||
"type": "aruco",
|
||||
"marker_id": 208,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -748,7 +748,7 @@
|
||||
"confidence": 0.6280424706698967
|
||||
},
|
||||
{
|
||||
"observation_id": "72d6524a-3710-46b2-b036-5031b7d2e648",
|
||||
"observation_id": "d920e29d-6dd3-41f5-affb-0d25e5bdb1f7",
|
||||
"type": "aruco",
|
||||
"marker_id": 217,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -802,7 +802,7 @@
|
||||
"confidence": 0.35596573288593486
|
||||
},
|
||||
{
|
||||
"observation_id": "160f705f-87e0-41e2-90f6-b39252bff719",
|
||||
"observation_id": "4024cff0-440d-4688-add4-aaef71fd8566",
|
||||
"type": "aruco",
|
||||
"marker_id": 206,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -856,7 +856,7 @@
|
||||
"confidence": 0.33820423087105295
|
||||
},
|
||||
{
|
||||
"observation_id": "03b79b60-9fb5-4aa8-82b6-303911389999",
|
||||
"observation_id": "7019c1d8-7fcf-44ef-8ea5-407577eff29c",
|
||||
"type": "aruco",
|
||||
"marker_id": 205,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -910,7 +910,7 @@
|
||||
"confidence": 0.28724459014346065
|
||||
},
|
||||
{
|
||||
"observation_id": "bc11412b-140e-48b9-9c27-aed1d54bd4b2",
|
||||
"observation_id": "17746037-a944-46b0-a817-efcd1d0fddb5",
|
||||
"type": "aruco",
|
||||
"marker_id": 207,
|
||||
"marker_size_m": 0.025,
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"source_detection_json": "C:\\Users\\kech\\SynologyDrive\\2026-AppServer-AppRobot\\appRobotRendering\\pipeline\\render_1a_aruco_detection.json",
|
||||
"camera_pose": {
|
||||
"camera_position_world_mm": [
|
||||
-170.9856733813686,
|
||||
-471.25256740269396,
|
||||
878.0637115557477
|
||||
],
|
||||
"rotation_matrix_world_to_camera": [
|
||||
[
|
||||
0.6349401350180643,
|
||||
-0.7720226356185085,
|
||||
0.028845710875162883
|
||||
],
|
||||
[
|
||||
-0.5994288656515463,
|
||||
-0.5158601484722065,
|
||||
-0.6120239719503914
|
||||
],
|
||||
[
|
||||
0.48737671258169724,
|
||||
0.3713076316356623,
|
||||
-0.7903129650475013
|
||||
]
|
||||
],
|
||||
"rotation_matrix_camera_to_world": [
|
||||
[
|
||||
0.6349401350180643,
|
||||
-0.5994288656515463,
|
||||
0.48737671258169724
|
||||
],
|
||||
[
|
||||
-0.7720226356185085,
|
||||
-0.5158601484722065,
|
||||
0.3713076316356623
|
||||
],
|
||||
[
|
||||
0.028845710875162883,
|
||||
-0.6120239719503914,
|
||||
-0.7903129650475013
|
||||
]
|
||||
],
|
||||
"rvec": [
|
||||
2.291386890593113,
|
||||
-1.0684818045197042,
|
||||
0.4021828449915483
|
||||
],
|
||||
"tvec": [
|
||||
-280.5803545388054,
|
||||
191.8018727459298,
|
||||
952.2592454759357
|
||||
]
|
||||
},
|
||||
"reprojection_error_px": {
|
||||
"mean": 2.4146498455755063,
|
||||
"max": 4.819015530727733,
|
||||
"per_marker": {
|
||||
"210": 2.3216790986770164,
|
||||
"215": 2.074953107734691,
|
||||
"211": 4.819015530727733,
|
||||
"208": 1.4794063810568414,
|
||||
"217": 1.782847281148554,
|
||||
"206": 2.714840043046132,
|
||||
"205": 2.5310207449984325,
|
||||
"207": 1.593436577214649
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"created_utc": "2026-05-28T15:11:26Z",
|
||||
"created_utc": "2026-05-28T15:43:43Z",
|
||||
"vision_config": {
|
||||
"MarkerType": "DICT_4X4_250",
|
||||
"MarkerSize": 0.025
|
||||
@@ -46,7 +46,7 @@
|
||||
},
|
||||
"detections": [
|
||||
{
|
||||
"observation_id": "5f47acb3-66c2-48ba-b83b-d8e07aa2f6ec",
|
||||
"observation_id": "b47ae404-2374-4364-bddc-c3e6282f9754",
|
||||
"type": "aruco",
|
||||
"marker_id": 102,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -100,7 +100,7 @@
|
||||
"confidence": 0.8913851020933449
|
||||
},
|
||||
{
|
||||
"observation_id": "4d7aea08-c7e4-45a9-8fba-c738360a4a09",
|
||||
"observation_id": "5643f91d-1fc0-43db-b40b-78ef116132a8",
|
||||
"type": "aruco",
|
||||
"marker_id": 124,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -154,7 +154,7 @@
|
||||
"confidence": 0.4804167810936165
|
||||
},
|
||||
{
|
||||
"observation_id": "3675fbfb-7387-4ab7-8cdd-c581dbb46a48",
|
||||
"observation_id": "eb068542-bc32-4241-9f94-ae93cba29146",
|
||||
"type": "aruco",
|
||||
"marker_id": 243,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -208,7 +208,7 @@
|
||||
"confidence": 0.9132502955127223
|
||||
},
|
||||
{
|
||||
"observation_id": "f430fa70-8024-4ea7-9318-ad33908e0622",
|
||||
"observation_id": "98da437d-8a22-4a73-8075-137b743bca43",
|
||||
"type": "aruco",
|
||||
"marker_id": 122,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -262,7 +262,7 @@
|
||||
"confidence": 0.9456847621099602
|
||||
},
|
||||
{
|
||||
"observation_id": "3351b253-537e-4499-8114-52e7873706c4",
|
||||
"observation_id": "f0ec764f-dbdf-4170-8cff-c3f5c940e82b",
|
||||
"type": "aruco",
|
||||
"marker_id": 247,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -316,7 +316,7 @@
|
||||
"confidence": 0.7448005120854795
|
||||
},
|
||||
{
|
||||
"observation_id": "d39337f3-7a27-4ce7-adf0-24fbe9ac65ea",
|
||||
"observation_id": "bddd6015-4815-41b2-bd83-dd9acce3a41b",
|
||||
"type": "aruco",
|
||||
"marker_id": 246,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -370,7 +370,7 @@
|
||||
"confidence": 0.7581700566520715
|
||||
},
|
||||
{
|
||||
"observation_id": "f3bd397e-3c02-4645-b43a-3f292bdf29fa",
|
||||
"observation_id": "6bb1f556-4a03-4bf1-90ce-59aedab7b2ee",
|
||||
"type": "aruco",
|
||||
"marker_id": 215,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -424,7 +424,7 @@
|
||||
"confidence": 0.826449608683203
|
||||
},
|
||||
{
|
||||
"observation_id": "e76f83e2-0558-4588-bed4-de9ba1644b18",
|
||||
"observation_id": "dd82dba6-3cea-4e60-b64a-6ad94127dd37",
|
||||
"type": "aruco",
|
||||
"marker_id": 210,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -478,7 +478,7 @@
|
||||
"confidence": 0.7813266383036261
|
||||
},
|
||||
{
|
||||
"observation_id": "36a7eaf1-6608-450c-90c2-6a8284457c88",
|
||||
"observation_id": "ed953a44-f516-4275-bc07-b6857fe8f8ee",
|
||||
"type": "aruco",
|
||||
"marker_id": 229,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -532,7 +532,7 @@
|
||||
"confidence": 0.18684041285479083
|
||||
},
|
||||
{
|
||||
"observation_id": "18049602-5f59-48b6-914b-cefe7203fe3b",
|
||||
"observation_id": "27bccaa2-ec68-4f8b-991b-585a270ca491",
|
||||
"type": "aruco",
|
||||
"marker_id": 198,
|
||||
"marker_size_m": 0.025,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"created_utc": "2026-05-28T15:11:27Z",
|
||||
"created_utc": "2026-05-28T15:43:44Z",
|
||||
"vision_config": {
|
||||
"MarkerType": "DICT_4X4_250",
|
||||
"MarkerSize": 0.025
|
||||
@@ -46,7 +46,7 @@
|
||||
},
|
||||
"detections": [
|
||||
{
|
||||
"observation_id": "2dd90714-6c72-4eef-add7-476c5f768882",
|
||||
"observation_id": "981a123d-7560-4fbe-93f1-d47980472b76",
|
||||
"type": "aruco",
|
||||
"marker_id": 102,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -100,7 +100,7 @@
|
||||
"confidence": 0.7012635429952238
|
||||
},
|
||||
{
|
||||
"observation_id": "2b3b1621-eabd-4e73-8638-4830ff614dca",
|
||||
"observation_id": "7676c338-2b2b-4bdb-864d-b6839291742b",
|
||||
"type": "aruco",
|
||||
"marker_id": 122,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -154,7 +154,7 @@
|
||||
"confidence": 0.5749326438029929
|
||||
},
|
||||
{
|
||||
"observation_id": "c87294de-3f5e-4ecd-b7ad-1665989bc0ae",
|
||||
"observation_id": "1476f720-1d72-4d94-b24b-b02e5e2d1a76",
|
||||
"type": "aruco",
|
||||
"marker_id": 243,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -208,7 +208,7 @@
|
||||
"confidence": 0.9491420540234864
|
||||
},
|
||||
{
|
||||
"observation_id": "34650367-22d5-4d90-9a88-282957232989",
|
||||
"observation_id": "f1bcb96e-0cf8-4c69-a4c1-fbeb03650fa2",
|
||||
"type": "aruco",
|
||||
"marker_id": 246,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -262,7 +262,7 @@
|
||||
"confidence": 0.4780463267147134
|
||||
},
|
||||
{
|
||||
"observation_id": "e1603207-bb10-4f2c-9dd8-353447302ecf",
|
||||
"observation_id": "a8bf2494-ddd8-4bf6-b87d-42182112e4e3",
|
||||
"type": "aruco",
|
||||
"marker_id": 247,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -316,7 +316,7 @@
|
||||
"confidence": 0.5106218488640142
|
||||
},
|
||||
{
|
||||
"observation_id": "bbb6f5cd-12a4-4078-9f2b-d1c7160eb5f4",
|
||||
"observation_id": "642b867d-25d1-4407-9011-f7a62feed435",
|
||||
"type": "aruco",
|
||||
"marker_id": 214,
|
||||
"marker_size_m": 0.025,
|
||||
@@ -370,7 +370,7 @@
|
||||
"confidence": 0.6041252446922665
|
||||
},
|
||||
{
|
||||
"observation_id": "c88f0aac-ae92-4559-9469-8ae96275d717",
|
||||
"observation_id": "623e960d-2058-4672-b06c-5316a5861158",
|
||||
"type": "aruco",
|
||||
"marker_id": 210,
|
||||
"marker_size_m": 0.025,
|
||||
|
||||
Reference in New Issue
Block a user