oxihuman_export/
haptic_frame_export.rs1#![allow(dead_code)]
4
5#[derive(Clone)]
7pub struct HapticFrame {
8 pub time_s: f32,
9 pub force_n: [f32; 3],
10 pub torque_nm: [f32; 3],
11 pub vibration_hz: f32,
12}
13
14pub fn new_haptic_frame(t: f32, force: [f32; 3], vibration_hz: f32) -> HapticFrame {
15 HapticFrame {
16 time_s: t,
17 force_n: force,
18 torque_nm: [0.0; 3],
19 vibration_hz,
20 }
21}
22
23pub fn haptic_frame_to_bytes(frame: &HapticFrame) -> Vec<u8> {
24 let mut out = Vec::with_capacity(7 * 4);
25 out.extend_from_slice(&frame.time_s.to_le_bytes());
26 for &v in &frame.force_n {
27 out.extend_from_slice(&v.to_le_bytes());
28 }
29 for &v in &frame.torque_nm {
30 out.extend_from_slice(&v.to_le_bytes());
31 }
32 out.extend_from_slice(&frame.vibration_hz.to_le_bytes());
33 out
34}
35
36pub fn haptic_sequence_to_bytes(frames: &[HapticFrame]) -> Vec<u8> {
37 let mut out = Vec::with_capacity(frames.len() * 7 * 4);
38 for frame in frames {
39 out.extend(haptic_frame_to_bytes(frame));
40 }
41 out
42}
43
44pub fn haptic_max_force(frames: &[HapticFrame]) -> f32 {
45 frames
46 .iter()
47 .map(|f| {
48 let v = f.force_n;
49 (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]).sqrt()
50 })
51 .fold(0.0f32, f32::max)
52}
53
54pub fn haptic_frame_duration(frames: &[HapticFrame]) -> f32 {
55 if frames.len() < 2 {
56 return 0.0;
57 }
58 frames.last().map_or(0.0, |f| f.time_s) - frames.first().map_or(0.0, |f| f.time_s)
59}
60
61pub fn haptic_frame_count(frames: &[HapticFrame]) -> usize {
62 frames.len()
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn test_new_haptic_frame() {
71 let f = new_haptic_frame(0.0, [1.0, 0.0, 0.0], 200.0);
72 assert!((f.force_n[0] - 1.0).abs() < 1e-5);
73 assert!((f.vibration_hz - 200.0).abs() < 1e-4);
74 }
75
76 #[test]
77 fn test_haptic_frame_to_bytes_len() {
78 let f = new_haptic_frame(0.0, [0.0; 3], 0.0);
80 assert_eq!(haptic_frame_to_bytes(&f).len(), 32);
81 }
82
83 #[test]
84 fn test_haptic_sequence_to_bytes_len() {
85 let frames = vec![
87 new_haptic_frame(0.0, [0.0; 3], 100.0),
88 new_haptic_frame(1.0, [0.0; 3], 100.0),
89 ];
90 assert_eq!(haptic_sequence_to_bytes(&frames).len(), 64);
91 }
92
93 #[test]
94 fn test_haptic_max_force() {
95 let frames = vec![
96 new_haptic_frame(0.0, [3.0, 4.0, 0.0], 100.0),
97 new_haptic_frame(1.0, [1.0, 0.0, 0.0], 100.0),
98 ];
99 assert!((haptic_max_force(&frames) - 5.0).abs() < 1e-4);
100 }
101
102 #[test]
103 fn test_haptic_frame_duration() {
104 let frames = vec![
105 new_haptic_frame(0.1, [0.0; 3], 100.0),
106 new_haptic_frame(2.1, [0.0; 3], 100.0),
107 ];
108 assert!((haptic_frame_duration(&frames) - 2.0).abs() < 1e-4);
109 }
110
111 #[test]
112 fn test_haptic_frame_count() {
113 let frames = vec![new_haptic_frame(0.0, [0.0; 3], 100.0); 5];
114 assert_eq!(haptic_frame_count(&frames), 5);
115 }
116
117 #[test]
118 fn test_haptic_frame_duration_single() {
119 let frames = vec![new_haptic_frame(1.0, [0.0; 3], 100.0)];
120 assert!((haptic_frame_duration(&frames) - 0.0).abs() < 1e-6);
121 }
122}