1use crate::{
2 common::mm,
3 geometry::{Device, Isometry, Point3, Transducer, Translation, UnitQuaternion},
4};
5use getset::Getters;
6use std::fmt::Debug;
7
8#[derive(Clone, Copy, Debug, Getters)]
10pub struct AUTD3<R: Into<UnitQuaternion> + Debug> {
11 pub pos: Point3,
13 pub rot: R,
15}
16
17impl Default for AUTD3<UnitQuaternion> {
18 fn default() -> Self {
19 Self {
20 pos: Point3::origin(),
21 rot: UnitQuaternion::identity(),
22 }
23 }
24}
25
26impl AUTD3<UnitQuaternion> {
27 pub const NUM_TRANS_X: usize = 18;
29 pub const NUM_TRANS_Y: usize = 14;
31 pub const NUM_TRANS_IN_UNIT: usize = Self::NUM_TRANS_X * Self::NUM_TRANS_Y - 3;
33 pub const TRANS_SPACING: f32 = 10.16 * mm;
35 pub const DEVICE_WIDTH: f32 = 192.0 * mm;
37 pub const DEVICE_HEIGHT: f32 = 151.4 * mm;
39
40 #[must_use]
41 const fn is_missing_transducer(x: usize, y: usize) -> bool {
42 if Self::NUM_TRANS_X <= x || Self::NUM_TRANS_Y <= y {
43 return true;
44 }
45 y == 1 && (x == 1 || x == 2 || x == 16)
46 }
47
48 #[must_use]
50 pub const fn grid_id(idx: usize) -> (usize, usize) {
51 let local_id = idx % Self::NUM_TRANS_IN_UNIT;
52 let uid = match local_id {
53 0..19 => local_id,
54 19..32 => local_id + 2,
55 _ => local_id + 3,
56 };
57 (uid % Self::NUM_TRANS_X, uid / Self::NUM_TRANS_X)
58 }
59}
60
61impl<R: Into<UnitQuaternion> + Debug> AUTD3<R> {
62 #[must_use]
64 pub fn new(pos: Point3, rot: R) -> Self {
65 Self { pos, rot }
66 }
67}
68
69impl<R: Into<UnitQuaternion> + Debug> From<AUTD3<R>> for Device {
70 fn from(autd3: AUTD3<R>) -> Self {
71 let rot = autd3.rot.into();
72 let isometry = Isometry {
73 rotation: rot,
74 translation: Translation::from(autd3.pos),
75 };
76 Self::new(
77 rot,
78 itertools::iproduct!(0..AUTD3::NUM_TRANS_Y, 0..AUTD3::NUM_TRANS_X)
79 .filter(|&(y, x)| !AUTD3::is_missing_transducer(x, y))
80 .map(|(y, x)| {
81 isometry
82 * Point3::new(
83 x as f32 * AUTD3::TRANS_SPACING,
84 y as f32 * AUTD3::TRANS_SPACING,
85 0.,
86 )
87 })
88 .map(|p| Transducer::new(p.xyz()))
89 .collect(),
90 )
91 }
92}
93
94#[cfg(test)]
95pub(crate) mod tests {
96 use autd3_core::geometry::{Geometry, Vector3};
97
98 use super::*;
99
100 pub fn create_device() -> Device {
101 AUTD3::default().into()
102 }
103
104 pub fn create_geometry(n: usize) -> crate::geometry::Geometry {
105 Geometry::new((0..n).map(|_| create_device()).collect())
106 }
107
108 #[test]
109 fn num_devices() {
110 let dev: Device = AUTD3::default().into();
111 assert_eq!(AUTD3::NUM_TRANS_IN_UNIT, dev.num_transducers());
112 }
113
114 #[rstest::rstest]
115 #[test]
116 #[case(
117 Point3::new(0., 0., 0.),
118 0,
119 Point3::origin(),
120 UnitQuaternion::identity()
121 )]
122 #[case(
123 Point3::new(AUTD3::TRANS_SPACING, 0., 0.),
124 1,
125 Point3::origin(),
126 UnitQuaternion::identity()
127 )]
128 #[case(
129 Point3::new(0., AUTD3::TRANS_SPACING, 0.),
130 18,
131 Point3::origin(),
132 UnitQuaternion::identity()
133 )]
134 #[case(Point3::new(17. * AUTD3::TRANS_SPACING, 13. * AUTD3::TRANS_SPACING, 0.), 248, Point3::origin(), UnitQuaternion::identity())]
135 #[case(
136 Point3::new(1., 2., 3.),
137 0,
138 Point3::new(1., 2., 3.),
139 UnitQuaternion::identity()
140 )]
141 #[case(
142 Point3::new(AUTD3::TRANS_SPACING + 1., 2., 3.),
143 1,
144 Point3::new(1., 2., 3.),
145 UnitQuaternion::identity()
146 )]
147 #[case(
148 Point3::new(1., AUTD3::TRANS_SPACING + 2., 3.),
149 18,
150 Point3::new(1., 2., 3.),
151 UnitQuaternion::identity()
152 )]
153 #[case(Point3::new(17. * AUTD3::TRANS_SPACING + 1., 13. * AUTD3::TRANS_SPACING + 2., 3.), 248, Point3::new(1., 2., 3.), UnitQuaternion::identity())]
154 #[case(
155 Point3::new(0., 0., 0.),
156 0,
157 Point3::origin(),
158 UnitQuaternion::new(Vector3::y() * std::f32::consts::FRAC_PI_2)
159 )]
160 #[case(
161 Point3::new(0., 0., -AUTD3::TRANS_SPACING),
162 1,
163 Point3::origin(),
164 UnitQuaternion::new(Vector3::y() * std::f32::consts::FRAC_PI_2)
165 )]
166 #[case(
167 Point3::new(0., AUTD3::TRANS_SPACING, 0.),
168 18,
169 Point3::origin(),
170 UnitQuaternion::new(Vector3::y() * std::f32::consts::FRAC_PI_2)
171 )]
172 #[case(Point3::new(0., 13. * AUTD3::TRANS_SPACING, -17. * AUTD3::TRANS_SPACING), 248, Point3::origin(), UnitQuaternion::new(Vector3::y() * std::f32::consts::FRAC_PI_2))]
173 #[case(
174 Point3::new(1., 2., 3.),
175 0,
176 Point3::new(1., 2., 3.),
177 UnitQuaternion::new(Vector3::y() * std::f32::consts::FRAC_PI_2)
178 )]
179 #[case(
180 Point3::new(1., 2., 3. - AUTD3::TRANS_SPACING),
181 1,
182 Point3::new(1., 2., 3.),
183 UnitQuaternion::new(Vector3::y() * std::f32::consts::FRAC_PI_2)
184 )]
185 #[case(
186 Point3::new(1., 2. + AUTD3::TRANS_SPACING, 3.),
187 18,
188 Point3::new(1., 2., 3.),
189 UnitQuaternion::new(Vector3::y() * std::f32::consts::FRAC_PI_2)
190 )]
191 #[case(Point3::new(1., 2. + 13. * AUTD3::TRANS_SPACING, 3. - 17. * AUTD3::TRANS_SPACING), 248, Point3::new(1., 2., 3.), UnitQuaternion::new(Vector3::y() * std::f32::consts::FRAC_PI_2))]
192 fn position(
193 #[case] expected: Point3,
194 #[case] idx: usize,
195 #[case] pos: Point3,
196 #[case] rot: impl Into<UnitQuaternion> + Debug,
197 ) {
198 let dev: Device = AUTD3 { pos, rot }.into();
199 approx::assert_relative_eq!(expected.x, dev[idx].position().x, epsilon = 1e-6);
200 approx::assert_relative_eq!(expected.y, dev[idx].position().y, epsilon = 1e-6);
201 approx::assert_relative_eq!(expected.z, dev[idx].position().z, epsilon = 1e-6);
202 }
203
204 #[rstest::rstest]
205 #[test]
206 #[case(0, 0, false)]
207 #[case(1, 0, false)]
208 #[case(2, 0, false)]
209 #[case(3, 0, false)]
210 #[case(4, 0, false)]
211 #[case(5, 0, false)]
212 #[case(6, 0, false)]
213 #[case(7, 0, false)]
214 #[case(8, 0, false)]
215 #[case(9, 0, false)]
216 #[case(10, 0, false)]
217 #[case(11, 0, false)]
218 #[case(12, 0, false)]
219 #[case(13, 0, false)]
220 #[case(14, 0, false)]
221 #[case(15, 0, false)]
222 #[case(16, 0, false)]
223 #[case(17, 0, false)]
224 #[case(0, 1, false)]
225 #[case(1, 1, true)]
226 #[case(2, 1, true)]
227 #[case(3, 1, false)]
228 #[case(4, 1, false)]
229 #[case(5, 1, false)]
230 #[case(6, 1, false)]
231 #[case(7, 1, false)]
232 #[case(8, 1, false)]
233 #[case(9, 1, false)]
234 #[case(10, 1, false)]
235 #[case(11, 1, false)]
236 #[case(12, 1, false)]
237 #[case(13, 1, false)]
238 #[case(14, 1, false)]
239 #[case(15, 1, false)]
240 #[case(16, 1, true)]
241 #[case(17, 1, false)]
242 #[case(0, 2, false)]
243 #[case(1, 2, false)]
244 #[case(2, 2, false)]
245 #[case(3, 2, false)]
246 #[case(4, 2, false)]
247 #[case(5, 2, false)]
248 #[case(6, 2, false)]
249 #[case(7, 2, false)]
250 #[case(8, 2, false)]
251 #[case(9, 2, false)]
252 #[case(10, 2, false)]
253 #[case(11, 2, false)]
254 #[case(12, 2, false)]
255 #[case(13, 2, false)]
256 #[case(14, 2, false)]
257 #[case(15, 2, false)]
258 #[case(16, 2, false)]
259 #[case(17, 2, false)]
260 #[case(0, 3, false)]
261 #[case(1, 3, false)]
262 #[case(2, 3, false)]
263 #[case(3, 3, false)]
264 #[case(4, 3, false)]
265 #[case(5, 3, false)]
266 #[case(6, 3, false)]
267 #[case(7, 3, false)]
268 #[case(8, 3, false)]
269 #[case(9, 3, false)]
270 #[case(10, 3, false)]
271 #[case(11, 3, false)]
272 #[case(12, 3, false)]
273 #[case(13, 3, false)]
274 #[case(14, 3, false)]
275 #[case(15, 3, false)]
276 #[case(16, 3, false)]
277 #[case(17, 3, false)]
278 #[case(0, 4, false)]
279 #[case(1, 4, false)]
280 #[case(2, 4, false)]
281 #[case(3, 4, false)]
282 #[case(4, 4, false)]
283 #[case(5, 4, false)]
284 #[case(6, 4, false)]
285 #[case(7, 4, false)]
286 #[case(8, 4, false)]
287 #[case(9, 4, false)]
288 #[case(10, 4, false)]
289 #[case(11, 4, false)]
290 #[case(12, 4, false)]
291 #[case(13, 4, false)]
292 #[case(14, 4, false)]
293 #[case(15, 4, false)]
294 #[case(16, 4, false)]
295 #[case(17, 4, false)]
296 #[case(0, 5, false)]
297 #[case(1, 5, false)]
298 #[case(2, 5, false)]
299 #[case(3, 5, false)]
300 #[case(4, 5, false)]
301 #[case(5, 5, false)]
302 #[case(6, 5, false)]
303 #[case(7, 5, false)]
304 #[case(8, 5, false)]
305 #[case(9, 5, false)]
306 #[case(10, 5, false)]
307 #[case(11, 5, false)]
308 #[case(12, 5, false)]
309 #[case(13, 5, false)]
310 #[case(14, 5, false)]
311 #[case(15, 5, false)]
312 #[case(16, 5, false)]
313 #[case(17, 5, false)]
314 #[case(0, 6, false)]
315 #[case(1, 6, false)]
316 #[case(2, 6, false)]
317 #[case(3, 6, false)]
318 #[case(4, 6, false)]
319 #[case(5, 6, false)]
320 #[case(6, 6, false)]
321 #[case(7, 6, false)]
322 #[case(8, 6, false)]
323 #[case(9, 6, false)]
324 #[case(10, 6, false)]
325 #[case(11, 6, false)]
326 #[case(12, 6, false)]
327 #[case(13, 6, false)]
328 #[case(14, 6, false)]
329 #[case(15, 6, false)]
330 #[case(16, 6, false)]
331 #[case(17, 6, false)]
332 #[case(0, 7, false)]
333 #[case(1, 7, false)]
334 #[case(2, 7, false)]
335 #[case(3, 7, false)]
336 #[case(4, 7, false)]
337 #[case(5, 7, false)]
338 #[case(6, 7, false)]
339 #[case(7, 7, false)]
340 #[case(8, 7, false)]
341 #[case(9, 7, false)]
342 #[case(10, 7, false)]
343 #[case(11, 7, false)]
344 #[case(12, 7, false)]
345 #[case(13, 7, false)]
346 #[case(14, 7, false)]
347 #[case(15, 7, false)]
348 #[case(16, 7, false)]
349 #[case(17, 7, false)]
350 #[case(0, 8, false)]
351 #[case(1, 8, false)]
352 #[case(2, 8, false)]
353 #[case(3, 8, false)]
354 #[case(4, 8, false)]
355 #[case(5, 8, false)]
356 #[case(6, 8, false)]
357 #[case(7, 8, false)]
358 #[case(8, 8, false)]
359 #[case(9, 8, false)]
360 #[case(10, 8, false)]
361 #[case(11, 8, false)]
362 #[case(12, 8, false)]
363 #[case(13, 8, false)]
364 #[case(14, 8, false)]
365 #[case(15, 8, false)]
366 #[case(16, 8, false)]
367 #[case(17, 8, false)]
368 #[case(0, 9, false)]
369 #[case(1, 9, false)]
370 #[case(2, 9, false)]
371 #[case(3, 9, false)]
372 #[case(4, 9, false)]
373 #[case(5, 9, false)]
374 #[case(6, 9, false)]
375 #[case(7, 9, false)]
376 #[case(8, 9, false)]
377 #[case(9, 9, false)]
378 #[case(10, 9, false)]
379 #[case(11, 9, false)]
380 #[case(12, 9, false)]
381 #[case(13, 9, false)]
382 #[case(14, 9, false)]
383 #[case(15, 9, false)]
384 #[case(16, 9, false)]
385 #[case(17, 9, false)]
386 #[case(0, 10, false)]
387 #[case(1, 10, false)]
388 #[case(2, 10, false)]
389 #[case(3, 10, false)]
390 #[case(4, 10, false)]
391 #[case(5, 10, false)]
392 #[case(6, 10, false)]
393 #[case(7, 10, false)]
394 #[case(8, 10, false)]
395 #[case(9, 10, false)]
396 #[case(10, 10, false)]
397 #[case(11, 10, false)]
398 #[case(12, 10, false)]
399 #[case(13, 10, false)]
400 #[case(14, 10, false)]
401 #[case(15, 10, false)]
402 #[case(16, 10, false)]
403 #[case(17, 10, false)]
404 #[case(0, 11, false)]
405 #[case(1, 11, false)]
406 #[case(2, 11, false)]
407 #[case(3, 11, false)]
408 #[case(4, 11, false)]
409 #[case(5, 11, false)]
410 #[case(6, 11, false)]
411 #[case(7, 11, false)]
412 #[case(8, 11, false)]
413 #[case(9, 11, false)]
414 #[case(10, 11, false)]
415 #[case(11, 11, false)]
416 #[case(12, 11, false)]
417 #[case(13, 11, false)]
418 #[case(14, 11, false)]
419 #[case(15, 11, false)]
420 #[case(16, 11, false)]
421 #[case(17, 11, false)]
422 #[case(0, 12, false)]
423 #[case(1, 12, false)]
424 #[case(2, 12, false)]
425 #[case(3, 12, false)]
426 #[case(4, 12, false)]
427 #[case(5, 12, false)]
428 #[case(6, 12, false)]
429 #[case(7, 12, false)]
430 #[case(8, 12, false)]
431 #[case(9, 12, false)]
432 #[case(10, 12, false)]
433 #[case(11, 12, false)]
434 #[case(12, 12, false)]
435 #[case(13, 12, false)]
436 #[case(14, 12, false)]
437 #[case(15, 12, false)]
438 #[case(16, 12, false)]
439 #[case(17, 12, false)]
440 #[case(0, 13, false)]
441 #[case(1, 13, false)]
442 #[case(2, 13, false)]
443 #[case(3, 13, false)]
444 #[case(4, 13, false)]
445 #[case(5, 13, false)]
446 #[case(6, 13, false)]
447 #[case(7, 13, false)]
448 #[case(8, 13, false)]
449 #[case(9, 13, false)]
450 #[case(10, 13, false)]
451 #[case(11, 13, false)]
452 #[case(12, 13, false)]
453 #[case(13, 13, false)]
454 #[case(14, 13, false)]
455 #[case(15, 13, false)]
456 #[case(16, 13, false)]
457 #[case(17, 13, false)]
458 fn test_is_missing_transducer(#[case] x: usize, #[case] y: usize, #[case] expected: bool) {
459 assert_eq!(expected, AUTD3::is_missing_transducer(x, y));
460 }
461
462 #[test]
463 fn test_is_missing_transducer_out_of_range() {
464 itertools::iproduct!(18..=256, 0..=256).for_each(|(x, y)| {
465 assert!(AUTD3::is_missing_transducer(x, y));
466 });
467 itertools::iproduct!(0..=256, 14..=256).for_each(|(x, y)| {
468 assert!(AUTD3::is_missing_transducer(x, y));
469 });
470 }
471
472 #[rstest::rstest]
473 #[test]
474 #[case(0, (0, 0))]
475 #[case(1, (1, 0))]
476 #[case(2, (2, 0))]
477 #[case(3, (3, 0))]
478 #[case(4, (4, 0))]
479 #[case(5, (5, 0))]
480 #[case(6, (6, 0))]
481 #[case(7, (7, 0))]
482 #[case(8, (8, 0))]
483 #[case(9, (9, 0))]
484 #[case(10, (10, 0))]
485 #[case(11, (11, 0))]
486 #[case(12, (12, 0))]
487 #[case(13, (13, 0))]
488 #[case(14, (14, 0))]
489 #[case(15, (15, 0))]
490 #[case(16, (16, 0))]
491 #[case(17, (17, 0))]
492 #[case(18, (0, 1))]
493 #[case(19, (3, 1))]
494 #[case(20, (4, 1))]
495 #[case(21, (5, 1))]
496 #[case(22, (6, 1))]
497 #[case(23, (7, 1))]
498 #[case(24, (8, 1))]
499 #[case(25, (9, 1))]
500 #[case(26, (10, 1))]
501 #[case(27, (11, 1))]
502 #[case(28, (12, 1))]
503 #[case(29, (13, 1))]
504 #[case(30, (14, 1))]
505 #[case(31, (15, 1))]
506 #[case(32, (17, 1))]
507 #[case(33, (0, 2))]
508 #[case(34, (1, 2))]
509 #[case(35, (2, 2))]
510 #[case(36, (3, 2))]
511 #[case(37, (4, 2))]
512 #[case(38, (5, 2))]
513 #[case(39, (6, 2))]
514 #[case(40, (7, 2))]
515 #[case(41, (8, 2))]
516 #[case(42, (9, 2))]
517 #[case(43, (10, 2))]
518 #[case(44, (11, 2))]
519 #[case(45, (12, 2))]
520 #[case(46, (13, 2))]
521 #[case(47, (14, 2))]
522 #[case(48, (15, 2))]
523 #[case(49, (16, 2))]
524 #[case(50, (17, 2))]
525 #[case(51, (0, 3))]
526 #[case(52, (1, 3))]
527 #[case(53, (2, 3))]
528 #[case(54, (3, 3))]
529 #[case(55, (4, 3))]
530 #[case(56, (5, 3))]
531 #[case(57, (6, 3))]
532 #[case(58, (7, 3))]
533 #[case(59, (8, 3))]
534 #[case(60, (9, 3))]
535 #[case(61, (10, 3))]
536 #[case(62, (11, 3))]
537 #[case(63, (12, 3))]
538 #[case(64, (13, 3))]
539 #[case(65, (14, 3))]
540 #[case(66, (15, 3))]
541 #[case(67, (16, 3))]
542 #[case(68, (17, 3))]
543 #[case(69, (0, 4))]
544 #[case(70, (1, 4))]
545 #[case(71, (2, 4))]
546 #[case(72, (3, 4))]
547 #[case(73, (4, 4))]
548 #[case(74, (5, 4))]
549 #[case(75, (6, 4))]
550 #[case(76, (7, 4))]
551 #[case(77, (8, 4))]
552 #[case(78, (9, 4))]
553 #[case(79, (10, 4))]
554 #[case(80, (11, 4))]
555 #[case(81, (12, 4))]
556 #[case(82, (13, 4))]
557 #[case(83, (14, 4))]
558 #[case(84, (15, 4))]
559 #[case(85, (16, 4))]
560 #[case(86, (17, 4))]
561 #[case(87, (0, 5))]
562 #[case(88, (1, 5))]
563 #[case(89, (2, 5))]
564 #[case(90, (3, 5))]
565 #[case(91, (4, 5))]
566 #[case(92, (5, 5))]
567 #[case(93, (6, 5))]
568 #[case(94, (7, 5))]
569 #[case(95, (8, 5))]
570 #[case(96, (9, 5))]
571 #[case(97, (10, 5))]
572 #[case(98, (11, 5))]
573 #[case(99, (12, 5))]
574 #[case(100, (13, 5))]
575 #[case(101, (14, 5))]
576 #[case(102, (15, 5))]
577 #[case(103, (16, 5))]
578 #[case(104, (17, 5))]
579 #[case(105, (0, 6))]
580 #[case(106, (1, 6))]
581 #[case(107, (2, 6))]
582 #[case(108, (3, 6))]
583 #[case(109, (4, 6))]
584 #[case(110, (5, 6))]
585 #[case(111, (6, 6))]
586 #[case(112, (7, 6))]
587 #[case(113, (8, 6))]
588 #[case(114, (9, 6))]
589 #[case(115, (10, 6))]
590 #[case(116, (11, 6))]
591 #[case(117, (12, 6))]
592 #[case(118, (13, 6))]
593 #[case(119, (14, 6))]
594 #[case(120, (15, 6))]
595 #[case(121, (16, 6))]
596 #[case(122, (17, 6))]
597 #[case(123, (0, 7))]
598 #[case(124, (1, 7))]
599 #[case(125, (2, 7))]
600 #[case(126, (3, 7))]
601 #[case(127, (4, 7))]
602 #[case(128, (5, 7))]
603 #[case(129, (6, 7))]
604 #[case(130, (7, 7))]
605 #[case(131, (8, 7))]
606 #[case(132, (9, 7))]
607 #[case(133, (10, 7))]
608 #[case(134, (11, 7))]
609 #[case(135, (12, 7))]
610 #[case(136, (13, 7))]
611 #[case(137, (14, 7))]
612 #[case(138, (15, 7))]
613 #[case(139, (16, 7))]
614 #[case(140, (17, 7))]
615 #[case(141, (0, 8))]
616 #[case(142, (1, 8))]
617 #[case(143, (2, 8))]
618 #[case(144, (3, 8))]
619 #[case(145, (4, 8))]
620 #[case(146, (5, 8))]
621 #[case(147, (6, 8))]
622 #[case(148, (7, 8))]
623 #[case(149, (8, 8))]
624 #[case(150, (9, 8))]
625 #[case(151, (10, 8))]
626 #[case(152, (11, 8))]
627 #[case(153, (12, 8))]
628 #[case(154, (13, 8))]
629 #[case(155, (14, 8))]
630 #[case(156, (15, 8))]
631 #[case(157, (16, 8))]
632 #[case(158, (17, 8))]
633 #[case(159, (0, 9))]
634 #[case(160, (1, 9))]
635 #[case(161, (2, 9))]
636 #[case(162, (3, 9))]
637 #[case(163, (4, 9))]
638 #[case(164, (5, 9))]
639 #[case(165, (6, 9))]
640 #[case(166, (7, 9))]
641 #[case(167, (8, 9))]
642 #[case(168, (9, 9))]
643 #[case(169, (10, 9))]
644 #[case(170, (11, 9))]
645 #[case(171, (12, 9))]
646 #[case(172, (13, 9))]
647 #[case(173, (14, 9))]
648 #[case(174, (15, 9))]
649 #[case(175, (16, 9))]
650 #[case(176, (17, 9))]
651 #[case(177, (0, 10))]
652 #[case(178, (1, 10))]
653 #[case(179, (2, 10))]
654 #[case(180, (3, 10))]
655 #[case(181, (4, 10))]
656 #[case(182, (5, 10))]
657 #[case(183, (6, 10))]
658 #[case(184, (7, 10))]
659 #[case(185, (8, 10))]
660 #[case(186, (9, 10))]
661 #[case(187, (10, 10))]
662 #[case(188, (11, 10))]
663 #[case(189, (12, 10))]
664 #[case(190, (13, 10))]
665 #[case(191, (14, 10))]
666 #[case(192, (15, 10))]
667 #[case(193, (16, 10))]
668 #[case(194, (17, 10))]
669 #[case(195, (0, 11))]
670 #[case(196, (1, 11))]
671 #[case(197, (2, 11))]
672 #[case(198, (3, 11))]
673 #[case(199, (4, 11))]
674 #[case(200, (5, 11))]
675 #[case(201, (6, 11))]
676 #[case(202, (7, 11))]
677 #[case(203, (8, 11))]
678 #[case(204, (9, 11))]
679 #[case(205, (10, 11))]
680 #[case(206, (11, 11))]
681 #[case(207, (12, 11))]
682 #[case(208, (13, 11))]
683 #[case(209, (14, 11))]
684 #[case(210, (15, 11))]
685 #[case(211, (16, 11))]
686 #[case(212, (17, 11))]
687 #[case(213, (0, 12))]
688 #[case(214, (1, 12))]
689 #[case(215, (2, 12))]
690 #[case(216, (3, 12))]
691 #[case(217, (4, 12))]
692 #[case(218, (5, 12))]
693 #[case(219, (6, 12))]
694 #[case(220, (7, 12))]
695 #[case(221, (8, 12))]
696 #[case(222, (9, 12))]
697 #[case(223, (10, 12))]
698 #[case(224, (11, 12))]
699 #[case(225, (12, 12))]
700 #[case(226, (13, 12))]
701 #[case(227, (14, 12))]
702 #[case(228, (15, 12))]
703 #[case(229, (16, 12))]
704 #[case(230, (17, 12))]
705 #[case(231, (0, 13))]
706 #[case(232, (1, 13))]
707 #[case(233, (2, 13))]
708 #[case(234, (3, 13))]
709 #[case(235, (4, 13))]
710 #[case(236, (5, 13))]
711 #[case(237, (6, 13))]
712 #[case(238, (7, 13))]
713 #[case(239, (8, 13))]
714 #[case(240, (9, 13))]
715 #[case(241, (10, 13))]
716 #[case(242, (11, 13))]
717 #[case(243, (12, 13))]
718 #[case(244, (13, 13))]
719 #[case(245, (14, 13))]
720 #[case(246, (15, 13))]
721 #[case(247, (16, 13))]
722 #[case(248, (17, 13))]
723 fn test_grid_id(#[case] idx: usize, #[case] expected: (usize, usize)) {
724 assert_eq!(expected, AUTD3::grid_id(idx));
725 }
726}