yxma commited on
Commit
bd31aeb
·
verified ·
1 Parent(s): 404666a

rebuild sim/ from the probe package

Browse files
sim/calibration/T_gel_to_rigid_left.json ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "method": "dual_ball_multi_pose",
3
+ "refball_center_in_rigid_mm": [
4
+ -33.51740422401229,
5
+ 12.100255314675977,
6
+ -17.699792261606614
7
+ ],
8
+ "gelball_center_in_rigid_mm": [
9
+ -43.47382768891848,
10
+ -41.22508071829758,
11
+ -35.7960391945282
12
+ ],
13
+ "gel_axis_in_rigid": [
14
+ -0.17411894520453713,
15
+ -0.9324875086795467,
16
+ -0.31646427772731606
17
+ ],
18
+ "gel_distance_mm": 57.19086670954521,
19
+ "depth_offset_mm": -5.0,
20
+ "gel_center_in_rigid_mm": [
21
+ -42.603232962895795,
22
+ -36.56264317489985,
23
+ -34.21371780589162
24
+ ],
25
+ "consistency": {
26
+ "refball_mean_deviation_mm": 0.4971205477445346,
27
+ "refball_max_deviation_mm": 0.6830937323295619,
28
+ "refball_std_mm": [
29
+ 0.3822793790831837,
30
+ 0.14607220822214068,
31
+ 0.3370989262846435
32
+ ],
33
+ "gelball_mean_deviation_mm": 0.5311059103030308,
34
+ "gelball_max_deviation_mm": 0.7146199631539334,
35
+ "gelball_std_mm": [
36
+ 0.23387391401966107,
37
+ 0.402760954424785,
38
+ 0.30624407553769517
39
+ ],
40
+ "axis_max_angle_deg": 1.069223796324866,
41
+ "ball_distance_std_mm": 0.09592190067940498
42
+ },
43
+ "mocap_scale": 1000.0,
44
+ "raw_data": [
45
+ {
46
+ "pose_id": 0,
47
+ "rigid_position_mm": [
48
+ 209.704,
49
+ 67.29599999999999,
50
+ 288.7
51
+ ],
52
+ "rigid_quaternion": [
53
+ -0.03045,
54
+ 0.5291786,
55
+ 0.72056156,
56
+ 0.447052
57
+ ],
58
+ "refball_mocap_mm": [
59
+ 213.805,
60
+ 32.849000000000004,
61
+ 307.12899999999996
62
+ ],
63
+ "refball_rigid_mm": [
64
+ -33.064365762599664,
65
+ 12.164420770736669,
66
+ -17.37287066173849
67
+ ],
68
+ "gelball_mocap_mm": [
69
+ 247.768,
70
+ 13.639999999999999,
71
+ 265.48699999999997
72
+ ],
73
+ "gelball_rigid_mm": [
74
+ -43.61612381039666,
75
+ -40.65963065991089,
76
+ -36.20919744147588
77
+ ],
78
+ "ball_distance_mm": 57.0659899940411,
79
+ "axis_in_rigid": [
80
+ -0.18490449475946746,
81
+ -0.9256660830060691,
82
+ -0.33007973368558585
83
+ ]
84
+ },
85
+ {
86
+ "pose_id": 1,
87
+ "rigid_position_mm": [
88
+ 207.22,
89
+ 63.50699999999999,
90
+ 137.26
91
+ ],
92
+ "rigid_quaternion": [
93
+ 0.575241,
94
+ 0.53501,
95
+ -0.513944,
96
+ 0.344559
97
+ ],
98
+ "refball_mocap_mm": [
99
+ 226.556,
100
+ 69.48400000000001,
101
+ 172.275
102
+ ],
103
+ "refball_rigid_mm": [
104
+ -33.99941004902249,
105
+ 12.238224727792783,
106
+ -18.163744708359914
107
+ ],
108
+ "gelball_mocap_mm": [
109
+ 179.374,
110
+ 93.761,
111
+ 193.90099999999998
112
+ ],
113
+ "gelball_rigid_mm": [
114
+ -43.661251420623046,
115
+ -41.44844032643957,
116
+ -35.70194717225823
117
+ ],
118
+ "ball_distance_mm": 57.29919483727493,
119
+ "axis_in_rigid": [
120
+ -0.16862089247570416,
121
+ -0.936953219093185,
122
+ -0.3060811327926228
123
+ ]
124
+ },
125
+ {
126
+ "pose_id": 2,
127
+ "rigid_position_mm": [
128
+ 261.399,
129
+ 57.67,
130
+ 194.732
131
+ ],
132
+ "rigid_quaternion": [
133
+ -0.63276,
134
+ 0.187712,
135
+ 0.37411,
136
+ 0.65147
137
+ ],
138
+ "refball_mocap_mm": [
139
+ 235.038,
140
+ 31.395,
141
+ 208.37800000000001
142
+ ],
143
+ "refball_rigid_mm": [
144
+ -33.48843686041472,
145
+ 11.898120445498478,
146
+ -17.562761414721432
147
+ ],
148
+ "gelball_mocap_mm": [
149
+ 271.628,
150
+ 16.011,
151
+ 249.575
152
+ ],
153
+ "gelball_rigid_mm": [
154
+ -43.14410783573577,
155
+ -41.5671711685423,
156
+ -35.4769729698505
157
+ ],
158
+ "ball_distance_mm": 57.2074152973196,
159
+ "axis_in_rigid": [
160
+ -0.16878355585789684,
161
+ -0.9345867373341344,
162
+ -0.3131449211964034
163
+ ]
164
+ }
165
+ ]
166
+ }
sim/calibration/T_gel_to_rigid_right.json ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "method": "dual_ball_multi_pose",
3
+ "refball_center_in_rigid_mm": [
4
+ -17.372443520938578,
5
+ 0.2688573520951536,
6
+ 38.571757518679924
7
+ ],
8
+ "gelball_center_in_rigid_mm": [
9
+ 3.1680846750991996,
10
+ -53.986407194707084,
11
+ 47.297869103141956
12
+ ],
13
+ "gel_axis_in_rigid": [
14
+ 0.3501488269090003,
15
+ -0.9248037787338816,
16
+ 0.148774224426762
17
+ ],
18
+ "gel_distance_mm": 58.67110647491247,
19
+ "depth_offset_mm": 0.0,
20
+ "gel_center_in_rigid_mm": [
21
+ 3.1680846750991996,
22
+ -53.986407194707084,
23
+ 47.297869103141956
24
+ ],
25
+ "consistency": {
26
+ "refball_mean_deviation_mm": 0.4043795279250868,
27
+ "refball_max_deviation_mm": 0.5722584634835464,
28
+ "refball_std_mm": [
29
+ 0.305325273790818,
30
+ 0.1894397197001601,
31
+ 0.23772566675184065
32
+ ],
33
+ "gelball_mean_deviation_mm": 0.7191394130923946,
34
+ "gelball_max_deviation_mm": 1.044514511519201,
35
+ "gelball_std_mm": [
36
+ 0.13210638866223554,
37
+ 0.258334234777561,
38
+ 0.7129747489275182
39
+ ],
40
+ "axis_max_angle_deg": 1.0670723640750364,
41
+ "ball_distance_std_mm": 0.1918993038441838
42
+ },
43
+ "mocap_scale": 1000.0,
44
+ "raw_data": [
45
+ {
46
+ "pose_id": 0,
47
+ "rigid_position_mm": [
48
+ 308.47,
49
+ 92.09,
50
+ 161.42000000000002
51
+ ],
52
+ "rigid_quaternion": [
53
+ 0.0631,
54
+ -0.18618,
55
+ -0.33139,
56
+ -0.92278
57
+ ],
58
+ "refball_mocap_mm": [
59
+ 307.62899999999996,
60
+ 91.333,
61
+ 203.91500000000002
62
+ ],
63
+ "refball_rigid_mm": [
64
+ -17.42214690726894,
65
+ 0.24440448450872054,
66
+ 38.77517786663904
67
+ ],
68
+ "gelball_mocap_mm": [
69
+ 359.197,
70
+ 63.277,
71
+ 203.299
72
+ ],
73
+ "gelball_rigid_mm": [
74
+ 2.9816863949711774,
75
+ -54.181252282163626,
76
+ 47.0400848891515
77
+ ],
78
+ "ball_distance_mm": 58.70926005324889,
79
+ "axis_in_rigid": [
80
+ 0.3475402906412716,
81
+ -0.927037007744752,
82
+ 0.14077688962552495
83
+ ]
84
+ },
85
+ {
86
+ "pose_id": 1,
87
+ "rigid_position_mm": [
88
+ 353.27599999999995,
89
+ 105.303,
90
+ 229.32
91
+ ],
92
+ "rigid_quaternion": [
93
+ -0.28615,
94
+ -0.956937,
95
+ 0.017508,
96
+ -0.045615
97
+ ],
98
+ "refball_mocap_mm": [
99
+ 371.03799999999995,
100
+ 93.362,
101
+ 192.52700000000002
102
+ ],
103
+ "refball_rigid_mm": [
104
+ -17.719051737135942,
105
+ 0.05003692040386909,
106
+ 38.70185623252837
107
+ ],
108
+ "gelball_mocap_mm": [
109
+ 324.832,
110
+ 59.405,
111
+ 181.358
112
+ ],
113
+ "gelball_rigid_mm": [
114
+ 3.272234055436968,
115
+ -53.6213442033486,
116
+ 48.27095310963361
117
+ ],
118
+ "ball_distance_mm": 58.419336233818946,
119
+ "axis_in_rigid": [
120
+ 0.35932085411852144,
121
+ -0.9187263085108816,
122
+ 0.163800164363485
123
+ ]
124
+ },
125
+ {
126
+ "pose_id": 2,
127
+ "rigid_position_mm": [
128
+ 223.578,
129
+ 72.762,
130
+ 125.58900000000001
131
+ ],
132
+ "rigid_quaternion": [
133
+ 0.267991,
134
+ -0.024821,
135
+ -0.319484,
136
+ -0.908567
137
+ ],
138
+ "refball_mocap_mm": [
139
+ 204.961,
140
+ 82.694,
141
+ 161.719
142
+ ],
143
+ "refball_rigid_mm": [
144
+ -16.976131918410857,
145
+ 0.5121306513728712,
146
+ 38.23823845687237
147
+ ],
148
+ "gelball_mocap_mm": [
149
+ 252.446,
150
+ 62.707,
151
+ 190.23399999999998
152
+ ],
153
+ "gelball_rigid_mm": [
154
+ 3.250333574889453,
155
+ -54.15662509860903,
156
+ 46.582569310640764
157
+ ],
158
+ "ball_distance_mm": 58.884723137669575,
159
+ "axis_in_rigid": [
160
+ 0.3434925803423043,
161
+ -0.9284030362538862,
162
+ 0.14170620848908067
163
+ ]
164
+ }
165
+ ]
166
+ }
sim/calibration/T_mocap_to_cam_left.json ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "description": "T_mocap_to_cam: maps OptiTrack (mm) -> camera frame (mm)",
3
+ "T_mocap_to_cam": [
4
+ [
5
+ -0.810677868162443,
6
+ -0.4417948639462208,
7
+ -0.38421178048354576,
8
+ 158.37843079282737
9
+ ],
10
+ [
11
+ -0.2945501948324127,
12
+ 0.8748721945072194,
13
+ -0.3844981482430172,
14
+ 284.86657177938224
15
+ ],
16
+ [
17
+ 0.5060055106377637,
18
+ -0.19853448433171958,
19
+ -0.8393702888090293,
20
+ 685.6891619250176
21
+ ],
22
+ [
23
+ 0.0,
24
+ 0.0,
25
+ 0.0,
26
+ 1.0
27
+ ]
28
+ ],
29
+ "camera_serial": "104122062574",
30
+ "intrinsics": {
31
+ "fx": 608.4557495117188,
32
+ "fy": 608.1494750976562,
33
+ "ppx": 316.0635986328125,
34
+ "ppy": 224.6374053955078,
35
+ "width": 640,
36
+ "height": 480
37
+ },
38
+ "mocap_scale": 1000.0,
39
+ "num_points": 6,
40
+ "rmse_mm": 4.747439312142084,
41
+ "residuals_mm": [
42
+ 3.140296552809229,
43
+ 4.349449571685337,
44
+ 4.871127835377674,
45
+ 2.593150843339738,
46
+ 3.17090715166062,
47
+ 8.120525615331562
48
+ ],
49
+ "points_cam_mm": [
50
+ [
51
+ 16.711177825927734,
52
+ 89.64736938476562,
53
+ 786.0000610351562
54
+ ],
55
+ [
56
+ 90.5625228881836,
57
+ 48.319942474365234,
58
+ 766.0000610351562
59
+ ],
60
+ [
61
+ 83.88683319091797,
62
+ 15.152631759643555,
63
+ 811.0000610351562
64
+ ],
65
+ [
66
+ -216.6715087890625,
67
+ 79.90221405029297,
68
+ 928.0000610351562
69
+ ],
70
+ [
71
+ -252.9880828857422,
72
+ -4.093912601470947,
73
+ 944.0000610351562
74
+ ],
75
+ [
76
+ -326.0710144042969,
77
+ 26.836889266967773,
78
+ 940.0000610351562
79
+ ]
80
+ ],
81
+ "points_mocap_mm": [
82
+ [
83
+ 225.43099999999998,
84
+ 47.395,
85
+ 127.916
86
+ ],
87
+ [
88
+ 169.44400000000002,
89
+ 48.577000000000005,
90
+ 192.14600000000002
91
+ ],
92
+ [
93
+ 207.466,
94
+ 27.64,
95
+ 225.561
96
+ ],
97
+ [
98
+ 487.104,
99
+ 17.412,
100
+ 63.24
101
+ ],
102
+ [
103
+ 546.218,
104
+ 51.876,
105
+ 121.794
106
+ ],
107
+ [
108
+ 589.725,
109
+ 72.872,
110
+ 64.61
111
+ ]
112
+ ],
113
+ "created_at": "2026-05-12T22:16:20",
114
+ "up_axis": "z"
115
+ }
sim/calibration/T_mocap_to_cam_left.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:988e1af7deb27f0eb179437794b2ebeb37e1c70f2922ecaef683b866e00eafae
3
+ size 256
sim/calibration/T_mocap_to_cam_middle.json ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "description": "T_mocap_to_cam: maps OptiTrack (mm) -> camera frame (mm)",
3
+ "T_mocap_to_cam": [
4
+ [
5
+ 0.9987689323019825,
6
+ 0.04789247635294343,
7
+ 0.012920161653051267,
8
+ -394.4763993373926
9
+ ],
10
+ [
11
+ 0.04826421351573066,
12
+ -0.9983784326630464,
13
+ -0.030183950818081413,
14
+ -270.493443209141
15
+ ],
16
+ [
17
+ 0.011453626590133171,
18
+ 0.030770373771911365,
19
+ -0.9994608539286934,
20
+ 826.019809512672
21
+ ],
22
+ [
23
+ 0.0,
24
+ 0.0,
25
+ 0.0,
26
+ 1.0
27
+ ]
28
+ ],
29
+ "camera_serial": "217222066989",
30
+ "intrinsics": {
31
+ "fx": 609.06005859375,
32
+ "fy": 608.275390625,
33
+ "ppx": 332.47943115234375,
34
+ "ppy": 239.3525390625,
35
+ "width": 640,
36
+ "height": 480
37
+ },
38
+ "mocap_scale": 1000.0,
39
+ "num_points": 8,
40
+ "rmse_mm": 5.298559912741648,
41
+ "residuals_mm": [
42
+ 5.6271211125758995,
43
+ 10.154049290401456,
44
+ 5.295565503833297,
45
+ 3.904543899485634,
46
+ 4.413577550470772,
47
+ 1.7606626889517276,
48
+ 3.887479237641652,
49
+ 2.9745783556701872
50
+ ],
51
+ "points_cam_mm": [
52
+ [
53
+ -138.17422485351562,
54
+ -176.80650329589844,
55
+ 783.0000610351562
56
+ ],
57
+ [
58
+ -203.81289672851562,
59
+ -122.2757797241211,
60
+ 764.0000610351562
61
+ ],
62
+ [
63
+ -176.41786193847656,
64
+ -83.21672058105469,
65
+ 799.0000610351562
66
+ ],
67
+ [
68
+ -160.75990295410156,
69
+ -65.39496612548828,
70
+ 806.0000610351562
71
+ ],
72
+ [
73
+ -45.515159606933594,
74
+ -123.39057159423828,
75
+ 804.0000610351562
76
+ ],
77
+ [
78
+ -18.994951248168945,
79
+ -117.36901092529297,
80
+ 799.0000610351562
81
+ ],
82
+ [
83
+ 36.103763580322266,
84
+ -105.6508560180664,
85
+ 771.0000610351562
86
+ ],
87
+ [
88
+ 53.24198913574219,
89
+ -181.49072265625,
90
+ 781.0000610351562
91
+ ]
92
+ ],
93
+ "points_mocap_mm": [
94
+ [
95
+ 261.084,
96
+ 48.644,
97
+ 84.548
98
+ ],
99
+ [
100
+ 195.857,
101
+ 50.153999999999996,
102
+ 138.387
103
+ ],
104
+ [
105
+ 228.08700000000002,
106
+ 29.228,
107
+ 177.35799999999998
108
+ ],
109
+ [
110
+ 242.60999999999999,
111
+ 20.526,
112
+ 195.374
113
+ ],
114
+ [
115
+ 355.329,
116
+ 17.682,
117
+ 130.42100000000002
118
+ ],
119
+ [
120
+ 382.233,
121
+ 28.935,
122
+ 135.28799999999998
123
+ ],
124
+ [
125
+ 437.52000000000004,
126
+ 51.916,
127
+ 144.34900000000002
128
+ ],
129
+ [
130
+ 449.58799999999997,
131
+ 50.361000000000004,
132
+ 70.165
133
+ ]
134
+ ],
135
+ "created_at": "2026-05-12T20:34:29",
136
+ "up_axis": "z"
137
+ }
sim/calibration/T_mocap_to_cam_middle.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:10a38035fdf31dce089f824c971cf4184dfac5f888aac982d051436f8ccfa1a7
3
+ size 256
sim/calibration/T_mocap_to_cam_right.json ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "description": "T_mocap_to_cam: maps OptiTrack (mm) -> camera frame (mm)",
3
+ "T_mocap_to_cam": [
4
+ [
5
+ -0.7060810935772296,
6
+ 0.6950316252373175,
7
+ 0.13557481039174474,
8
+ 605.2919096634614
9
+ ],
10
+ [
11
+ 0.5284341378626592,
12
+ 0.644604762743106,
13
+ -0.5524871598419762,
14
+ -100.86727498691573
15
+ ],
16
+ [
17
+ -0.47138821711422957,
18
+ -0.3184583799633454,
19
+ -0.8224216734723081,
20
+ 1061.7990457647895
21
+ ],
22
+ [
23
+ 0.0,
24
+ 0.0,
25
+ 0.0,
26
+ 1.0
27
+ ]
28
+ ],
29
+ "camera_serial": "143322063538",
30
+ "intrinsics": {
31
+ "fx": 608.547607421875,
32
+ "fy": 606.7799072265625,
33
+ "ppx": 314.88201904296875,
34
+ "ppy": 243.41900634765625,
35
+ "width": 640,
36
+ "height": 480
37
+ },
38
+ "mocap_scale": 1000.0,
39
+ "num_points": 6,
40
+ "rmse_mm": 7.520075033441005,
41
+ "residuals_mm": [
42
+ 5.862949060495028,
43
+ 5.926871764374507,
44
+ 9.172862106825736,
45
+ 3.5435031927827803,
46
+ 8.811105858313384,
47
+ 9.77106902542866
48
+ ],
49
+ "points_cam_mm": [
50
+ [
51
+ 150.92872619628906,
52
+ 131.20069885253906,
53
+ 740.0000610351562
54
+ ],
55
+ [
56
+ 138.0159454345703,
57
+ 81.08906555175781,
58
+ 799.0000610351562
59
+ ],
60
+ [
61
+ 189.72586059570312,
62
+ 98.56414794921875,
63
+ 824.0000610351562
64
+ ],
65
+ [
66
+ 216.35919189453125,
67
+ 107.14408874511719,
68
+ 838.0000610351562
69
+ ],
70
+ [
71
+ 367.6980285644531,
72
+ -94.39984130859375,
73
+ 964.0000610351562
74
+ ],
75
+ [
76
+ 363.8806457519531,
77
+ -169.8037872314453,
78
+ 1006.0000610351562
79
+ ]
80
+ ],
81
+ "points_mocap_mm": [
82
+ [
83
+ 589.6700000000001,
84
+ 72.957,
85
+ 64.666
86
+ ],
87
+ [
88
+ 545.219,
89
+ 53.733999999999995,
90
+ 120.568
91
+ ],
92
+ [
93
+ 506.815,
94
+ 28.365000000000002,
95
+ 92.73
96
+ ],
97
+ [
98
+ 487.085,
99
+ 17.403,
100
+ 63.273999999999994
101
+ ],
102
+ [
103
+ 225.428,
104
+ 47.405,
105
+ 127.916
106
+ ],
107
+ [
108
+ 169.442,
109
+ 48.574,
110
+ 192.152
111
+ ]
112
+ ],
113
+ "created_at": "2026-05-12T22:31:39",
114
+ "up_axis": "z"
115
+ }
sim/calibration/T_mocap_to_cam_right.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9ac69dfdd478b46617d468368d305c270bcfef7f9f924c7e5338814e0981d7cd
3
+ size 256
sim/index.html ADDED
@@ -0,0 +1,428 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html><meta charset="utf-8">
2
+ <title>React — interactive sensor simulator</title>
3
+ <meta name="viewport" content="width=device-width,initial-scale=1">
4
+ <style>
5
+ :root{color-scheme:dark}
6
+ body{margin:0;background:#0e1116;color:#e8eaed;
7
+ font:14px/1.5 ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif}
8
+ header{padding:14px 18px 6px}
9
+ h1{font-size:17px;margin:0 0 4px;font-weight:600}
10
+ .sub{color:#9aa3ad;font-size:12.5px;max-width:76ch}
11
+ main{padding:10px 18px 28px}
12
+ .row{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:10px}
13
+ .tile{position:relative;flex:0 0 auto;border-radius:6px;overflow:hidden;
14
+ background:#000;line-height:0}
15
+ .tile img{display:block;width:100%;height:auto}
16
+ /* width AND height, both, in CSS. The HTML width/height attributes are
17
+ presentational hints: setting only the CSS width let the img and its
18
+ canvas resolve to different heights and every marker sat ~90 px off
19
+ while every number in the page stayed correct. */
20
+ .tile canvas{position:absolute;inset:0;width:100%;height:100%}
21
+ .cap{position:absolute;left:0;top:0;padding:2px 6px;font-size:11px;
22
+ background:rgba(0,0,0,.55);color:#cfd6de;line-height:1.4;z-index:2}
23
+ .frozen{position:absolute;right:0;bottom:0;padding:2px 6px;font-size:11px;
24
+ background:rgba(120,60,0,.72);color:#ffd9a8;line-height:1.4;z-index:2}
25
+ .panel{display:flex;gap:22px;flex-wrap:wrap;align-items:flex-start;
26
+ background:#151a21;border:1px solid #232a33;border-radius:8px;
27
+ padding:12px 16px;margin-top:4px}
28
+ .panel h2{font-size:12px;letter-spacing:.06em;text-transform:uppercase;
29
+ color:#8d97a2;margin:0 0 6px;font-weight:600}
30
+ kbd{background:#222933;border:1px solid #333c47;border-bottom-width:2px;
31
+ border-radius:4px;padding:0 5px;font:12px ui-monospace,monospace;color:#dfe5ec}
32
+ table{border-collapse:collapse;font-size:12.5px}
33
+ td{padding:1px 10px 1px 0;vertical-align:top}
34
+ .num{font:12.5px ui-monospace,monospace;color:#bfe6ff}
35
+ .sel{font-weight:600}
36
+ .warn{color:#ffb86b}
37
+ .pill{display:inline-block;padding:1px 8px;border-radius:99px;font-size:12px;
38
+ background:#1d2630;border:1px solid #2c3844;margin-right:6px}
39
+ </style>
40
+ <header>
41
+ <h1>Interactive sensor simulator</h1>
42
+ <p class="sub" data-tactile-note>Drive either GelSight with the keyboard and
43
+ watch its projected frame move. <b>The photographs are frozen</b> — the three
44
+ camera views and both tactile images are a single recorded instant and do not
45
+ respond to the action. Only the overlay moves. No model is wired in yet, so
46
+ nothing here is a prediction of what the sensor would see.</p>
47
+ </header>
48
+ <main>
49
+ <div class="row" id="views"></div>
50
+ <div class="row" id="tactile"></div>
51
+ <div class="panel">
52
+ <div>
53
+ <h2>Driving</h2>
54
+ <table>
55
+ <tr><td><kbd>Tab</kbd></td><td>switch sensor</td></tr>
56
+ <tr><td><kbd>←</kbd><kbd>→</kbd></td><td>world x</td></tr>
57
+ <tr><td><kbd>↑</kbd><kbd>↓</kbd></td><td>world y</td></tr>
58
+ <tr><td><kbd>[</kbd><kbd>]</kbd></td><td>world z (up)</td></tr>
59
+ <tr><td><kbd>A</kbd><kbd>D</kbd></td><td>rotate about x</td></tr>
60
+ <tr><td><kbd>W</kbd><kbd>S</kbd></td><td>rotate about y</td></tr>
61
+ <tr><td><kbd>Q</kbd><kbd>E</kbd></td><td>rotate about z</td></tr>
62
+ <tr><td><kbd>R</kbd></td><td>reset</td></tr>
63
+ </table>
64
+ </div>
65
+ <div>
66
+ <h2>Action so far</h2>
67
+ <table>
68
+ <tr><td>driving</td><td class="num sel" id="side">—</td></tr>
69
+ <tr><td>translation</td><td class="num" id="tr">0, 0, 0 mm</td></tr>
70
+ <tr><td>rotation</td><td class="num" id="rt">0.0&deg;</td></tr>
71
+ <tr><td>gel centre</td><td class="num" id="gc">—</td></tr>
72
+ </table>
73
+ </div>
74
+ <div>
75
+ <h2>Frame</h2>
76
+ <table>
77
+ <tr><td>episode</td><td class="num" id="ep">—</td></tr>
78
+ <tr><td>row</td><td class="num" id="rw">—</td></tr>
79
+ <tr><td>world</td><td class="num" id="ua">—</td></tr>
80
+ </table>
81
+ <p class="sub" style="margin:8px 0 0;max-width:34ch">
82
+ Rotation pivots on the <b>gel centre</b>, not on the marker cluster the
83
+ pose vector describes — the cluster is 65.7&nbsp;mm away and moves.</p>
84
+ </div>
85
+ </div>
86
+ </main>
87
+ <script>
88
+ const AXC = ["#ff5a5a", "#5aff8f", "#5aa8ff"]; // x, y, z
89
+ const COL = {left: "#ffd23f", right: "#4fc3f7"};
90
+ let D = null, S = null;
91
+
92
+ /* ---- small matrix helpers, scalar-LAST quaternions (scipy from_quat) ---- */
93
+ function quatMat(q){
94
+ const [x,y,z,w]=q, n=Math.hypot(x,y,z,w)||1;
95
+ const X=x/n,Y=y/n,Z=z/n,W=w/n;
96
+ return [[1-2*(Y*Y+Z*Z), 2*(X*Y-Z*W), 2*(X*Z+Y*W)],
97
+ [2*(X*Y+Z*W), 1-2*(X*X+Z*Z), 2*(Y*Z-X*W)],
98
+ [2*(X*Z-Y*W), 2*(Y*Z+X*W), 1-2*(X*X+Y*Y)]];
99
+ }
100
+ function matQuat(M){ // -> x, y, z, w
101
+ const t=M[0][0]+M[1][1]+M[2][2];
102
+ let x,y,z,w;
103
+ if(t>0){const s=Math.sqrt(t+1)*2; w=.25*s;
104
+ x=(M[2][1]-M[1][2])/s; y=(M[0][2]-M[2][0])/s; z=(M[1][0]-M[0][1])/s;}
105
+ else if(M[0][0]>M[1][1]&&M[0][0]>M[2][2]){
106
+ const s=Math.sqrt(1+M[0][0]-M[1][1]-M[2][2])*2;
107
+ w=(M[2][1]-M[1][2])/s; x=.25*s; y=(M[0][1]+M[1][0])/s; z=(M[0][2]+M[2][0])/s;}
108
+ else if(M[1][1]>M[2][2]){
109
+ const s=Math.sqrt(1+M[1][1]-M[0][0]-M[2][2])*2;
110
+ w=(M[0][2]-M[2][0])/s; x=(M[0][1]+M[1][0])/s; y=.25*s; z=(M[1][2]+M[2][1])/s;}
111
+ else{const s=Math.sqrt(1+M[2][2]-M[0][0]-M[1][1])*2;
112
+ w=(M[1][0]-M[0][1])/s; x=(M[0][2]+M[2][0])/s; y=(M[1][2]+M[2][1])/s; z=.25*s;}
113
+ return [x,y,z,w];
114
+ }
115
+ function mv(M,v){return [M[0][0]*v[0]+M[0][1]*v[1]+M[0][2]*v[2],
116
+ M[1][0]*v[0]+M[1][1]*v[1]+M[1][2]*v[2],
117
+ M[2][0]*v[0]+M[2][1]*v[1]+M[2][2]*v[2]];}
118
+ function mm(A,B){return A.map((r,i)=>[0,1,2].map(j=>
119
+ A[i][0]*B[0][j]+A[i][1]*B[1][j]+A[i][2]*B[2][j]));}
120
+ function axisRot(k, deg){ // rotation about world axis k
121
+ const t=deg*Math.PI/180, c=Math.cos(t), s=Math.sin(t);
122
+ if(k===0) return [[1,0,0],[0,c,-s],[0,s,c]];
123
+ if(k===1) return [[c,0,s],[0,1,0],[-s,0,c]];
124
+ return [[c,-s,0],[s,c,0],[0,0,1]];
125
+ }
126
+ const add=(a,b)=>[a[0]+b[0],a[1]+b[1],a[2]+b[2]];
127
+ const sub=(a,b)=>[a[0]-b[0],a[1]-b[1],a[2]-b[2]];
128
+ function project(Xw, cam){
129
+ const T=cam.T;
130
+ const c=[T[0]*Xw[0]+T[1]*Xw[1]+T[2]*Xw[2]+T[3],
131
+ T[4]*Xw[0]+T[5]*Xw[1]+T[6]*Xw[2]+T[7],
132
+ T[8]*Xw[0]+T[9]*Xw[1]+T[10]*Xw[2]+T[11]];
133
+ if(c[2]<=1) return null;
134
+ return [cam.fx*c[0]/c[2]+cam.ppx, cam.fy*c[1]/c[2]+cam.ppy];
135
+ }
136
+
137
+ /* ---- the pose a side is currently at ---------------------------------- */
138
+ /* Composition matches react_toolbox.synth_actions.make_rotation_set:
139
+ the gel centre is the pivot, the delta pre-multiplies (world frame), and
140
+ the published origin is back-solved from the pivot. Rotating the origin
141
+ instead would drag the gel 30-50 mm sideways. */
142
+ function poseOf(side){
143
+ const p = D.pose[side], g = D.gel[side];
144
+ const R0 = quatMat(p.slice(3,7));
145
+ const pivot = add([p[0]*1000, p[1]*1000, p[2]*1000], mv(R0, g));
146
+ const st = S.d[side];
147
+ const R = mm(st.R, R0);
148
+ const gel = add(pivot, st.t);
149
+ return {R, gel, origin: sub(gel, mv(R, g)), quat: matQuat(R)};
150
+ }
151
+ function pointsFor(side, view){
152
+ const cam = D.cams[view], g = D.gel[side], P = poseOf(side);
153
+ const tips = [];
154
+ for(let k=0;k<3;k++){const e=[0,0,0]; e[k]=60;
155
+ tips.push(project(add(P.origin, mv(P.R, add(g,e))), cam));}
156
+ return {centre: project(P.gel, cam), origin: project(P.origin, cam), tips};
157
+ }
158
+
159
+ /* ---- drawing ----------------------------------------------------------- */
160
+ function gizmo(g, view, w){
161
+ if(view!=="middle") return;
162
+ const T=D.cams[view].T, ox=88, oy=84, L=42;
163
+ g.save();
164
+ g.globalAlpha=.55; g.fillStyle="#12161f";
165
+ g.beginPath(); g.arc(ox,oy,L+11,0,7); g.fill(); g.globalAlpha=1;
166
+ g.strokeStyle="#46505f"; g.lineWidth=1.5; g.beginPath();
167
+ g.arc(ox,oy,L+11,0,7); g.stroke();
168
+ const R=[[T[0],T[1],T[2]],[T[4],T[5],T[6]],[T[8],T[9],T[10]]];
169
+ for(let k=0;k<3;k++){
170
+ const e=[0,0,0]; e[k]=1; const d=mv(R,e);
171
+ const inp=Math.hypot(d[0],d[1]);
172
+ g.strokeStyle=AXC[k]; g.fillStyle=AXC[k]; g.lineWidth=3;
173
+ if(inp>0.12){
174
+ g.beginPath(); g.moveTo(ox,oy); g.lineTo(ox+d[0]*L, oy+d[1]*L); g.stroke();
175
+ g.font="600 15px ui-monospace,monospace";
176
+ g.fillText("xyz"[k], ox+d[0]*(L+14)-4, oy+d[1]*(L+14)+5);
177
+ }
178
+ if(Math.abs(d[2])>0.55){ // out of plane: dot / cross
179
+ g.beginPath(); g.arc(ox,oy,5,0,7); g.stroke();
180
+ if(d[2]<0){g.beginPath(); g.arc(ox,oy,2,0,7); g.fill();}
181
+ else{g.beginPath(); g.moveTo(ox-3,oy-3); g.lineTo(ox+3,oy+3);
182
+ g.moveTo(ox-3,oy+3); g.lineTo(ox+3,oy-3); g.stroke();}
183
+ g.font="600 15px ui-monospace,monospace";
184
+ g.fillText("xyz"[k], ox+13, oy-11);
185
+ }
186
+ }
187
+ g.fillStyle="#dfe6ee"; g.font="600 13px ui-sans-serif";
188
+ g.fillText("world ("+D.up_axis+"-up)", ox-48, oy+L+30);
189
+ g.restore();
190
+ }
191
+ function drawView(cv, view){
192
+ const g=cv.getContext("2d");
193
+ g.clearRect(0,0,cv.width,cv.height);
194
+ for(const side of ["left","right"]){
195
+ const r=pointsFor(side,view);
196
+ if(!r.centre) continue;
197
+ if(r.origin){ // stem to the marker cluster
198
+ g.strokeStyle="rgba(200,200,200,.55)"; g.lineWidth=1;
199
+ g.beginPath(); g.moveTo(r.origin[0],r.origin[1]);
200
+ g.lineTo(r.centre[0],r.centre[1]); g.stroke();
201
+ g.fillStyle="rgba(220,220,220,.75)";
202
+ g.beginPath(); g.arc(r.origin[0],r.origin[1],2.5,0,7); g.fill();
203
+ }
204
+ for(let k=0;k<3;k++){const t=r.tips[k]; if(!t) continue;
205
+ g.strokeStyle=AXC[k]; g.lineWidth=(side===S.side)?3.2:1.6;
206
+ g.beginPath(); g.moveTo(r.centre[0],r.centre[1]);
207
+ g.lineTo(t[0],t[1]); g.stroke();}
208
+ g.fillStyle=COL[side];
209
+ g.beginPath(); g.arc(r.centre[0],r.centre[1],5,0,7); g.fill();
210
+ g.strokeStyle=(side===S.side)?"#fff":"rgba(255,255,255,.45)";
211
+ g.lineWidth=(side===S.side)?2:1; g.stroke();
212
+ g.fillStyle="#fff"; g.font="600 15px ui-sans-serif";
213
+ g.fillText(side[0].toUpperCase()+(side===S.side?" *":""),
214
+ r.centre[0]+8, r.centre[1]-8);
215
+ }
216
+ gizmo(g, view, cv.width);
217
+ }
218
+ function redraw(){
219
+ for(const v of ["left","middle","right"]){
220
+ const cv=document.querySelector(`[data-stream="view_${v}"] canvas`);
221
+ if(cv) drawView(cv, v);
222
+ }
223
+ const st=S.d[S.side], P=poseOf(S.side);
224
+ const tr=Math.acos(Math.min(1,Math.max(-1,(st.R[0][0]+st.R[1][1]+st.R[2][2]-1)/2)));
225
+ document.getElementById("side").textContent=S.side;
226
+ document.getElementById("tr").textContent =
227
+ st.t.map(v=>v.toFixed(1)).join(", ")+" mm";
228
+ document.getElementById("rt").textContent=(tr*180/Math.PI).toFixed(1)+"°";
229
+ document.getElementById("gc").textContent =
230
+ P.gel.map(v=>v.toFixed(1)).join(", ")+" mm";
231
+ }
232
+
233
+ /* ---- input ------------------------------------------------------------- */
234
+ const TRANS={ArrowRight:[0,+1],ArrowLeft:[0,-1],ArrowUp:[1,+1],ArrowDown:[1,-1],
235
+ BracketRight:[2,+1],BracketLeft:[2,-1]};
236
+ const ROT={KeyD:[0,+1],KeyA:[0,-1],KeyW:[1,+1],KeyS:[1,-1],
237
+ KeyE:[2,+1],KeyQ:[2,-1]};
238
+ function apply(code){
239
+ if(code==="Tab"){S.side = S.side==="right" ? "left" : "right"; redraw(); return true;}
240
+ if(code==="KeyR"){reset(); redraw(); return true;}
241
+ const st=S.d[S.side];
242
+ if(TRANS[code]){const [k,s]=TRANS[code]; st.t[k]+=s*D.step_mm; redraw(); return true;}
243
+ if(ROT[code]){const [k,s]=ROT[code];
244
+ st.R = mm(axisRot(k, s*D.step_deg), st.R); redraw(); return true;}
245
+ return false;
246
+ }
247
+ function reset(){
248
+ S.d={left:{t:[0,0,0],R:[[1,0,0],[0,1,0],[0,0,1]]},
249
+ right:{t:[0,0,0],R:[[1,0,0],[0,1,0],[0,0,1]]}};
250
+ }
251
+
252
+ /* ---- build ------------------------------------------------------------- */
253
+ function tile(stream, frozen){
254
+ const [w,h]=D.size[stream];
255
+ const d=document.createElement("div");
256
+ d.className="tile"; d.dataset.stream=stream;
257
+ // The cameras are what you drive; the tactile pair is frozen. Giving them
258
+ // equal area put the most weight on the one thing that does NOT respond.
259
+ d.style.width=(frozen?230:Math.min(w,470))+"px";
260
+ d.innerHTML=`<img src="${stream}.jpg" width="${w}" height="${h}" alt="${stream}">`
261
+ +`<canvas width="${w}" height="${h}"></canvas>`
262
+ +`<span class="cap">${stream.replace("_"," ")}</span>`
263
+ +(frozen?`<span class="frozen" data-frozen>frozen — not simulated</span>`:``);
264
+ return d;
265
+ }
266
+ /* The data is INLINED, not fetched. A page that fetch()es its own JSON is
267
+ blank when opened from file:// -- Chrome blocks the request as
268
+ cross-origin -- so it would only ever work on the Space. sim.json is still
269
+ written beside it for tools and tests, and test_sim.py asserts the two
270
+ copies are identical so they cannot drift. */
271
+ (function(d){
272
+ D=d; S={side:"right", d:null}; reset();
273
+ const vs=document.getElementById("views"), ts=document.getElementById("tactile");
274
+ for(const v of ["left","middle","right"]) vs.appendChild(tile("view_"+v,false));
275
+ for(const s of ["left","right"]) ts.appendChild(tile("tactile_"+s,true));
276
+ document.getElementById("ep").textContent=D.key;
277
+ document.getElementById("rw").textContent=D.row;
278
+ document.getElementById("ua").textContent=D.up_axis+"-up";
279
+ redraw();
280
+ addEventListener("keydown", e=>{ if(apply(e.code)) e.preventDefault(); });
281
+ /* Test hooks. __sim() reports the state the page is actually drawing from,
282
+ so a test compares the PAGE against the library rather than against the
283
+ page's own arithmetic. */
284
+ window.__key = code => apply(code);
285
+ window.__sim = () => {
286
+ const P=poseOf(S.side), O=poseOf(S.side==="right"?"left":"right");
287
+ const pts={};
288
+ for(const v of ["left","middle","right"]){
289
+ pts[v]={};
290
+ for(const s of ["left","right"]) pts[v][s]=pointsFor(s,v);
291
+ }
292
+ return {side:S.side, gel_mm:P.gel, origin_mm:P.origin, quat:P.quat,
293
+ other_gel_mm:O.gel, t_mm:S.d[S.side].t, points:pts};
294
+ };
295
+ })({
296
+ "date": "2026-05-10",
297
+ "episode": "episode_002",
298
+ "key": "2026-05-10/episode_002",
299
+ "row": 7016,
300
+ "streams": [
301
+ "view_left",
302
+ "view_middle",
303
+ "view_right",
304
+ "tactile_left",
305
+ "tactile_right"
306
+ ],
307
+ "size": {
308
+ "view_left": [
309
+ 640,
310
+ 480
311
+ ],
312
+ "view_middle": [
313
+ 640,
314
+ 480
315
+ ],
316
+ "view_right": [
317
+ 640,
318
+ 480
319
+ ],
320
+ "tactile_left": [
321
+ 640,
322
+ 480
323
+ ],
324
+ "tactile_right": [
325
+ 640,
326
+ 480
327
+ ]
328
+ },
329
+ "cams": {
330
+ "left": {
331
+ "T": [
332
+ -0.810677868162443,
333
+ -0.4417948639462208,
334
+ -0.38421178048354576,
335
+ 158.37843079282737,
336
+ -0.2945501948324127,
337
+ 0.8748721945072194,
338
+ -0.3844981482430172,
339
+ 284.86657177938224,
340
+ 0.5060055106377637,
341
+ -0.19853448433171958,
342
+ -0.8393702888090293,
343
+ 685.6891619250176
344
+ ],
345
+ "fx": 608.4557495117188,
346
+ "fy": 608.1494750976562,
347
+ "ppx": 316.0635986328125,
348
+ "ppy": 224.6374053955078
349
+ },
350
+ "middle": {
351
+ "T": [
352
+ 0.9987689323019825,
353
+ 0.04789247635294343,
354
+ 0.012920161653051267,
355
+ -394.4763993373926,
356
+ 0.04826421351573066,
357
+ -0.9983784326630464,
358
+ -0.030183950818081413,
359
+ -270.493443209141,
360
+ 0.011453626590133171,
361
+ 0.030770373771911365,
362
+ -0.9994608539286934,
363
+ 826.019809512672
364
+ ],
365
+ "fx": 609.06005859375,
366
+ "fy": 608.275390625,
367
+ "ppx": 332.47943115234375,
368
+ "ppy": 239.3525390625
369
+ },
370
+ "right": {
371
+ "T": [
372
+ -0.7060810935772296,
373
+ 0.6950316252373175,
374
+ 0.13557481039174474,
375
+ 605.2919096634614,
376
+ 0.5284341378626592,
377
+ 0.644604762743106,
378
+ -0.5524871598419762,
379
+ -100.86727498691573,
380
+ -0.47138821711422957,
381
+ -0.3184583799633454,
382
+ -0.8224216734723081,
383
+ 1061.7990457647895
384
+ ],
385
+ "fx": 608.547607421875,
386
+ "fy": 606.7799072265625,
387
+ "ppx": 314.88201904296875,
388
+ "ppy": 243.41900634765625
389
+ }
390
+ },
391
+ "gel": {
392
+ "left": [
393
+ -42.603232962895795,
394
+ -36.56264317489985,
395
+ -34.21371780589162
396
+ ],
397
+ "right": [
398
+ 3.1680846750991996,
399
+ -53.986407194707084,
400
+ 47.297869103141956
401
+ ]
402
+ },
403
+ "pose": {
404
+ "left": [
405
+ 0.4233657121658325,
406
+ -0.24574513733386993,
407
+ 0.08017350733280182,
408
+ -0.4738748027746301,
409
+ -0.05678169627152034,
410
+ -0.37848914494994457,
411
+ -0.7930728071362012
412
+ ],
413
+ "right": [
414
+ 0.5881050825119019,
415
+ -0.31359246373176575,
416
+ 0.12186302989721298,
417
+ -0.5861687022005775,
418
+ -0.6556183573677075,
419
+ -0.2969039358322237,
420
+ -0.3720468719533799
421
+ ]
422
+ },
423
+ "step_mm": 5.0,
424
+ "step_deg": 3.0,
425
+ "up_axis": "z",
426
+ "note": "the photos are frozen; only the projected sensor frame moves. No model is wired in yet."
427
+ });
428
+ </script>
sim/sim.json ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "date": "2026-05-10",
3
+ "episode": "episode_002",
4
+ "key": "2026-05-10/episode_002",
5
+ "row": 7016,
6
+ "streams": [
7
+ "view_left",
8
+ "view_middle",
9
+ "view_right",
10
+ "tactile_left",
11
+ "tactile_right"
12
+ ],
13
+ "size": {
14
+ "view_left": [
15
+ 640,
16
+ 480
17
+ ],
18
+ "view_middle": [
19
+ 640,
20
+ 480
21
+ ],
22
+ "view_right": [
23
+ 640,
24
+ 480
25
+ ],
26
+ "tactile_left": [
27
+ 640,
28
+ 480
29
+ ],
30
+ "tactile_right": [
31
+ 640,
32
+ 480
33
+ ]
34
+ },
35
+ "cams": {
36
+ "left": {
37
+ "T": [
38
+ -0.810677868162443,
39
+ -0.4417948639462208,
40
+ -0.38421178048354576,
41
+ 158.37843079282737,
42
+ -0.2945501948324127,
43
+ 0.8748721945072194,
44
+ -0.3844981482430172,
45
+ 284.86657177938224,
46
+ 0.5060055106377637,
47
+ -0.19853448433171958,
48
+ -0.8393702888090293,
49
+ 685.6891619250176
50
+ ],
51
+ "fx": 608.4557495117188,
52
+ "fy": 608.1494750976562,
53
+ "ppx": 316.0635986328125,
54
+ "ppy": 224.6374053955078
55
+ },
56
+ "middle": {
57
+ "T": [
58
+ 0.9987689323019825,
59
+ 0.04789247635294343,
60
+ 0.012920161653051267,
61
+ -394.4763993373926,
62
+ 0.04826421351573066,
63
+ -0.9983784326630464,
64
+ -0.030183950818081413,
65
+ -270.493443209141,
66
+ 0.011453626590133171,
67
+ 0.030770373771911365,
68
+ -0.9994608539286934,
69
+ 826.019809512672
70
+ ],
71
+ "fx": 609.06005859375,
72
+ "fy": 608.275390625,
73
+ "ppx": 332.47943115234375,
74
+ "ppy": 239.3525390625
75
+ },
76
+ "right": {
77
+ "T": [
78
+ -0.7060810935772296,
79
+ 0.6950316252373175,
80
+ 0.13557481039174474,
81
+ 605.2919096634614,
82
+ 0.5284341378626592,
83
+ 0.644604762743106,
84
+ -0.5524871598419762,
85
+ -100.86727498691573,
86
+ -0.47138821711422957,
87
+ -0.3184583799633454,
88
+ -0.8224216734723081,
89
+ 1061.7990457647895
90
+ ],
91
+ "fx": 608.547607421875,
92
+ "fy": 606.7799072265625,
93
+ "ppx": 314.88201904296875,
94
+ "ppy": 243.41900634765625
95
+ }
96
+ },
97
+ "gel": {
98
+ "left": [
99
+ -42.603232962895795,
100
+ -36.56264317489985,
101
+ -34.21371780589162
102
+ ],
103
+ "right": [
104
+ 3.1680846750991996,
105
+ -53.986407194707084,
106
+ 47.297869103141956
107
+ ]
108
+ },
109
+ "pose": {
110
+ "left": [
111
+ 0.4233657121658325,
112
+ -0.24574513733386993,
113
+ 0.08017350733280182,
114
+ -0.4738748027746301,
115
+ -0.05678169627152034,
116
+ -0.37848914494994457,
117
+ -0.7930728071362012
118
+ ],
119
+ "right": [
120
+ 0.5881050825119019,
121
+ -0.31359246373176575,
122
+ 0.12186302989721298,
123
+ -0.5861687022005775,
124
+ -0.6556183573677075,
125
+ -0.2969039358322237,
126
+ -0.3720468719533799
127
+ ]
128
+ },
129
+ "step_mm": 5.0,
130
+ "step_deg": 3.0,
131
+ "up_axis": "z",
132
+ "note": "the photos are frozen; only the projected sensor frame moves. No model is wired in yet."
133
+ }
sim/tactile_left.jpg ADDED
sim/tactile_right.jpg ADDED
sim/view_left.jpg ADDED
sim/view_middle.jpg ADDED
sim/view_right.jpg ADDED