Skip to main content

piper_driver/
state.rs

1//! Driver 模块状态结构定义
2
3use crate::fps_stats::FpsStatistics;
4use arc_swap::ArcSwap;
5use std::sync::{Arc, RwLock};
6
7/// 关节位置状态(帧组同步)
8///
9/// 更新频率:~500Hz
10/// CAN ID:0x2A5-0x2A7
11#[derive(Debug, Clone, Default)]
12pub struct JointPositionState {
13    /// 硬件时间戳(微秒,来自完整帧组的最后一帧)
14    ///
15    /// **注意**:这是CAN硬件时间戳,反映数据在CAN总线上的实际传输时间。
16    pub hardware_timestamp_us: u64,
17
18    /// 系统接收时间戳(微秒,系统接收到完整帧组的时间)
19    ///
20    /// **注意**:这是系统时间戳,用于计算接收延迟和系统处理时间。
21    pub system_timestamp_us: u64,
22
23    /// 关节位置(弧度)[J1, J2, J3, J4, J5, J6]
24    pub joint_pos: [f64; 6],
25
26    /// 帧组有效性掩码(Bit 0-2 对应 0x2A5, 0x2A6, 0x2A7)
27    /// - 1 表示该CAN帧已收到
28    /// - 0 表示该CAN帧未收到(可能丢包)
29    pub frame_valid_mask: u8,
30}
31
32impl JointPositionState {
33    /// 检查是否接收到了完整的帧组 (0x2A5, 0x2A6, 0x2A7)
34    ///
35    /// **返回值**:
36    /// - `true`:所有3个CAN帧都已收到,数据完整
37    /// - `false`:部分CAN帧丢失,数据不完整
38    pub fn is_fully_valid(&self) -> bool {
39        self.frame_valid_mask == 0b0000_0111 // Bit 0-2 全部为 1
40    }
41
42    /// 获取丢失的CAN帧索引(用于调试)
43    ///
44    /// **返回值**:丢失的CAN帧索引列表(0=0x2A5, 1=0x2A6, 2=0x2A7)
45    pub fn missing_frames(&self) -> Vec<usize> {
46        (0..3).filter(|&i| (self.frame_valid_mask & (1 << i)) == 0).collect()
47    }
48}
49
50/// 末端位姿状态(帧组同步)
51///
52/// 更新频率:~500Hz
53/// CAN ID:0x2A2-0x2A4
54#[derive(Debug, Clone, Default)]
55pub struct EndPoseState {
56    /// 硬件时间戳(微秒,来自完整帧组的最后一帧)
57    pub hardware_timestamp_us: u64,
58
59    /// 系统接收时间戳(微秒,系统接收到完整帧组的时间)
60    pub system_timestamp_us: u64,
61
62    /// 末端位姿 [X, Y, Z, Rx, Ry, Rz]
63    /// - X, Y, Z: 位置(米)
64    ///   - **注意**:`EndPoseFeedback1.x()`, `.y()`, `EndPoseFeedback2.z()` 返回的是**毫米**,需要除以 1000.0 转换为米
65    /// - Rx, Ry, Rz: 姿态角(弧度,欧拉角或旋转向量)
66    pub end_pose: [f64; 6],
67
68    /// 帧组有效性掩码(Bit 0-2 对应 0x2A2, 0x2A3, 0x2A4)
69    pub frame_valid_mask: u8,
70}
71
72impl EndPoseState {
73    /// 检查是否接收到了完整的帧组 (0x2A2, 0x2A3, 0x2A4)
74    ///
75    /// **返回值**:
76    /// - `true`:所有3个CAN帧都已收到,数据完整
77    /// - `false`:部分CAN帧丢失,数据不完整
78    pub fn is_fully_valid(&self) -> bool {
79        self.frame_valid_mask == 0b0000_0111 // Bit 0-2 全部为 1
80    }
81
82    /// 获取丢失的CAN帧索引(用于调试)
83    ///
84    /// **返回值**:丢失的CAN帧索引列表(0=0x2A2, 1=0x2A3, 2=0x2A4)
85    pub fn missing_frames(&self) -> Vec<usize> {
86        (0..3).filter(|&i| (self.frame_valid_mask & (1 << i)) == 0).collect()
87    }
88}
89
90/// 运动状态快照(逻辑原子性)
91///
92/// 用于在同一时刻捕获多个运动相关状态,保证逻辑上的原子性。
93/// 这是一个栈上对象(Stack Allocated),开销极小。
94#[derive(Debug, Clone)]
95pub struct MotionSnapshot {
96    /// 关节位置状态
97    pub joint_position: JointPositionState,
98
99    /// 末端位姿状态
100    pub end_pose: EndPoseState,
101    // 关节动态状态(可选,未来可能需要)
102    // pub joint_dynamic: JointDynamicState,
103}
104
105/// 关节动态状态(独立帧,但通过缓冲提交保证一致性)
106///
107/// 更新频率:500Hz
108/// 大小:< 150 字节,Clone 开销低
109/// 同步机制:Buffered Commit(收集 6 个关节的速度帧,集齐或超时后一次性提交)
110/// 时间同步性:通过 Group Commit 机制,保证 6 个关节数据来自同一 CAN 传输周期
111#[derive(Debug, Clone, Default)]
112pub struct JointDynamicState {
113    /// 整个组的大致时间戳(最新一帧的时间,微秒)
114    ///
115    /// **注意**:存储的是硬件时间戳(来自 `PiperFrame.timestamp_us`),不是 UNIX 时间戳。
116    /// 硬件时间戳是设备相对时间,用于帧间时间差计算,不能直接与系统时间戳比较。
117    pub group_timestamp_us: u64,
118
119    // === 关节速度/电流(来自 0x251-0x256,独立帧) ===
120    /// 关节速度(rad/s)[J1, J2, J3, J4, J5, J6]
121    pub joint_vel: [f64; 6],
122    /// 关节电流(A)[J1, J2, J3, J4, J5, J6]
123    ///
124    /// **注意**:扭矩可以通过 `get_torque(joint_index)` 方法从电流值实时计算得到。
125    /// - 关节 1-3 (J1, J2, J3): `torque = current * COEFFICIENT_1_3` (1.18125)
126    /// - 关节 4-6 (J4, J5, J6): `torque = current * COEFFICIENT_4_6` (0.95844)
127    pub joint_current: [f64; 6],
128
129    /// 每个关节的具体更新时间(用于调试或高阶插值)
130    pub timestamps: [u64; 6],
131
132    /// 有效性掩码(Bit 0-5 对应 Joint 1-6)
133    /// - 1 表示本周期内已更新
134    /// - 0 表示未更新(可能是丢帧)
135    pub valid_mask: u8,
136}
137
138impl JointDynamicState {
139    /// 关节 1-3 的力矩系数(CAN ID: 0x251~0x253)
140    ///
141    /// 根据官方参考实现,关节 1、2、3 使用此系数计算力矩。
142    /// 公式:torque = current * COEFFICIENT_1_3
143    pub const COEFFICIENT_1_3: f64 = 1.18125;
144
145    /// 关节 4-6 的力矩系数(CAN ID: 0x254~0x256)
146    ///
147    /// 根据官方参考实现,关节 4、5、6 使用此系数计算力矩。
148    /// 公式:torque = current * COEFFICIENT_4_6
149    pub const COEFFICIENT_4_6: f64 = 0.95844;
150
151    /// 根据关节索引和电流值计算扭矩(N·m)
152    ///
153    /// # 参数
154    /// - `joint_index`: 关节索引(0-5,对应 J1-J6)
155    /// - `current`: 电流值(A)
156    ///
157    /// # 返回值
158    /// 计算得到的力矩值(N·m)
159    ///
160    /// # 示例
161    /// ```rust
162    /// # use piper_driver::JointDynamicState;
163    /// // 计算 J1(索引 0)的扭矩,电流为 2.0A
164    /// let torque = JointDynamicState::calculate_torque(0, 2.0);
165    /// // 结果:2.0 * 1.18125 = 2.3625 N·m
166    /// ```
167    pub fn calculate_torque(joint_index: usize, current: f64) -> f64 {
168        let coefficient = if joint_index < 3 {
169            Self::COEFFICIENT_1_3
170        } else {
171            Self::COEFFICIENT_4_6
172        };
173        current * coefficient
174    }
175
176    /// 获取指定关节的扭矩(N·m)
177    ///
178    /// 从当前存储的电流值实时计算扭矩,无需额外存储空间。
179    ///
180    /// # 参数
181    /// - `joint_index`: 关节索引(0-5,对应 J1-J6)
182    ///
183    /// # 返回值
184    /// 关节扭矩值(N·m),如果索引超出范围则返回 0.0
185    ///
186    /// # 示例
187    /// ```rust
188    /// # use piper_driver::JointDynamicState;
189    /// let mut state = JointDynamicState::default();
190    /// state.joint_current[0] = 2.0; // 设置 J1 的电流为 2.0A
191    /// let torque_j1 = state.get_torque(0); // 获取 J1 的扭矩:2.0 * 1.18125 = 2.3625 N·m
192    /// ```
193    pub fn get_torque(&self, joint_index: usize) -> f64 {
194        if joint_index < 6 {
195            Self::calculate_torque(joint_index, self.joint_current[joint_index])
196        } else {
197            0.0
198        }
199    }
200
201    /// 获取所有关节的扭矩(N·m)
202    ///
203    /// 一次性计算并返回所有6个关节的扭矩值,比多次调用 `get_torque()` 更高效。
204    ///
205    /// # 返回值
206    /// 包含所有关节扭矩的数组 `[J1, J2, J3, J4, J5, J6]`(N·m)
207    ///
208    /// # 示例
209    /// ```rust
210    /// # use piper_driver::JointDynamicState;
211    /// let mut state = JointDynamicState::default();
212    /// state.joint_current = [1.0, 2.0, 0.5, 1.0, 2.0, 0.5];
213    /// let all_torques = state.get_all_torques();
214    /// // all_torques[0] = 1.0 * 1.18125 = 1.18125 N·m (J1)
215    /// // all_torques[3] = 1.0 * 0.95844 = 0.95844 N·m (J4)
216    /// ```
217    pub fn get_all_torques(&self) -> [f64; 6] {
218        [
219            Self::calculate_torque(0, self.joint_current[0]),
220            Self::calculate_torque(1, self.joint_current[1]),
221            Self::calculate_torque(2, self.joint_current[2]),
222            Self::calculate_torque(3, self.joint_current[3]),
223            Self::calculate_torque(4, self.joint_current[4]),
224            Self::calculate_torque(5, self.joint_current[5]),
225        ]
226    }
227
228    /// 检查所有关节是否都已更新(`valid_mask == 0x3F`)
229    pub fn is_complete(&self) -> bool {
230        self.valid_mask == 0b111111
231    }
232
233    /// 获取未更新的关节索引(用于调试)
234    pub fn missing_joints(&self) -> Vec<usize> {
235        (0..6).filter(|&i| (self.valid_mask & (1 << i)) == 0).collect()
236    }
237}
238
239/// 机器人控制状态
240///
241/// 更新频率:~200Hz
242/// CAN ID:0x2A1
243#[derive(Debug, Clone, Default)]
244pub struct RobotControlState {
245    /// 硬件时间戳(微秒)
246    pub hardware_timestamp_us: u64,
247
248    /// 系统接收时间戳(微秒)
249    pub system_timestamp_us: u64,
250
251    /// 控制模式
252    pub control_mode: u8,
253
254    /// 机器人状态
255    pub robot_status: u8,
256
257    /// MOVE 模式
258    pub move_mode: u8,
259
260    /// 示教状态
261    pub teach_status: u8,
262
263    /// 运动状态
264    pub motion_status: u8,
265
266    /// 轨迹点索引
267    pub trajectory_point_index: u8,
268
269    /// 故障码:角度超限位(位掩码,Bit 0-5 对应 J1-J6)
270    ///
271    /// **优化**:使用位掩码而非 `[bool; 6]`,节省内存并提高Cache Locality
272    pub fault_angle_limit_mask: u8,
273
274    /// 故障码:通信异常(位掩码,Bit 0-5 对应 J1-J6)
275    pub fault_comm_error_mask: u8,
276
277    /// 使能状态(从 robot_status 推导)
278    pub is_enabled: bool,
279
280    /// 反馈指令计数器(如果协议支持,用于检测链路卡死)
281    ///
282    /// **注意**:如果协议中没有循环计数器,此字段为 0
283    pub feedback_counter: u8,
284}
285
286impl RobotControlState {
287    /// 检查指定关节是否角度超限位
288    pub fn is_angle_limit(&self, joint_index: usize) -> bool {
289        if joint_index >= 6 {
290            return false;
291        }
292        (self.fault_angle_limit_mask >> joint_index) & 1 == 1
293    }
294
295    /// 检查指定关节是否通信异常
296    pub fn is_comm_error(&self, joint_index: usize) -> bool {
297        if joint_index >= 6 {
298            return false;
299        }
300        (self.fault_comm_error_mask >> joint_index) & 1 == 1
301    }
302}
303
304/// 夹爪状态
305///
306/// 更新频率:~200Hz
307/// CAN ID:0x2A8
308#[derive(Debug, Clone, Default)]
309pub struct GripperState {
310    /// 硬件时间戳(微秒)
311    pub hardware_timestamp_us: u64,
312
313    /// 系统接收时间戳(微秒)
314    pub system_timestamp_us: u64,
315
316    /// 夹爪行程(mm)
317    pub travel: f64,
318
319    /// 夹爪扭矩(N·m)
320    pub torque: f64,
321
322    /// 夹爪状态码(原始状态字节,来自 0x2A8 Byte 6)
323    ///
324    /// **优化**:保持原始数据的纯度,通过方法解析状态位
325    pub status_code: u8,
326
327    /// 上次行程值(用于计算是否在运动)
328    ///
329    /// **注意**:用于判断夹爪是否在运动(通过 travel 变化率推算)
330    pub last_travel: f64,
331}
332
333impl GripperState {
334    /// 检查电压是否过低
335    pub fn is_voltage_low(&self) -> bool {
336        self.status_code & 1 == 1
337    }
338
339    /// 检查电机是否过温
340    pub fn is_motor_over_temp(&self) -> bool {
341        (self.status_code >> 1) & 1 == 1
342    }
343
344    /// 检查是否过流
345    pub fn is_over_current(&self) -> bool {
346        (self.status_code >> 2) & 1 == 1
347    }
348
349    /// 检查驱动器是否过温
350    pub fn is_driver_over_temp(&self) -> bool {
351        (self.status_code >> 3) & 1 == 1
352    }
353
354    /// 检查传感器是否异常
355    pub fn is_sensor_error(&self) -> bool {
356        (self.status_code >> 4) & 1 == 1
357    }
358
359    /// 检查驱动器是否错误
360    pub fn is_driver_error(&self) -> bool {
361        (self.status_code >> 5) & 1 == 1
362    }
363
364    /// 检查是否使能
365    pub fn is_enabled(&self) -> bool {
366        (self.status_code >> 6) & 1 == 1
367    }
368
369    /// 检查是否已回零
370    pub fn is_homed(&self) -> bool {
371        (self.status_code >> 7) & 1 == 1
372    }
373
374    /// 检查夹爪是否在运动(通过 travel 变化率判断)
375    ///
376    /// **阈值**:如果 travel 变化超过 0.1mm,认为在运动
377    pub fn is_moving(&self) -> bool {
378        (self.travel - self.last_travel).abs() > 0.1
379    }
380}
381
382/// 关节驱动器低速反馈状态
383///
384/// 更新频率:~40Hz
385/// CAN ID:0x261-0x266(每个关节一个CAN ID)
386/// 同步机制:ArcSwap(Wait-Free,适合高频读)
387///
388/// **优化**:使用位掩码而非 `[bool; 6]`,节省内存并提高Cache Locality
389#[derive(Debug, Clone, Default)]
390pub struct JointDriverLowSpeedState {
391    /// 硬件时间戳(微秒,来自最新一帧)
392    pub hardware_timestamp_us: u64,
393
394    /// 系统接收时间戳(微秒)
395    pub system_timestamp_us: u64,
396
397    // === 温度(来自 0x261-0x266) ===
398    /// 电机温度(°C)[J1, J2, J3, J4, J5, J6]
399    pub motor_temps: [f32; 6],
400    /// 驱动器温度(°C)[J1, J2, J3, J4, J5, J6]
401    pub driver_temps: [f32; 6],
402
403    // === 电压/电流(来自 0x261-0x266) ===
404    /// 各关节电压(V)[J1, J2, J3, J4, J5, J6]
405    pub joint_voltage: [f32; 6],
406    /// 各关节母线电流(A)[J1, J2, J3, J4, J5, J6]
407    pub joint_bus_current: [f32; 6],
408
409    // === 驱动器状态(来自 0x261-0x266,位掩码优化) ===
410    /// 驱动器状态:电压过低(位掩码,Bit 0-5 对应 J1-J6)
411    pub driver_voltage_low_mask: u8,
412    /// 驱动器状态:电机过温(位掩码,Bit 0-5 对应 J1-J6)
413    pub driver_motor_over_temp_mask: u8,
414    /// 驱动器状态:过流(位掩码,Bit 0-5 对应 J1-J6)
415    pub driver_over_current_mask: u8,
416    /// 驱动器状态:驱动器过温(位掩码,Bit 0-5 对应 J1-J6)
417    pub driver_over_temp_mask: u8,
418    /// 驱动器状态:碰撞保护触发(位掩码,Bit 0-5 对应 J1-J6)
419    pub driver_collision_protection_mask: u8,
420    /// 驱动器状态:驱动器错误(位掩码,Bit 0-5 对应 J1-J6)
421    pub driver_error_mask: u8,
422    /// 驱动器状态:使能状态(位掩码,Bit 0-5 对应 J1-J6)
423    pub driver_enabled_mask: u8,
424    /// 驱动器状态:堵转保护触发(位掩码,Bit 0-5 对应 J1-J6)
425    pub driver_stall_protection_mask: u8,
426
427    // === 时间戳(每个关节独立) ===
428    /// 每个关节的硬件时间戳(微秒)[J1, J2, J3, J4, J5, J6]
429    pub hardware_timestamps: [u64; 6],
430    /// 每个关节的系统接收时间戳(微秒)[J1, J2, J3, J4, J5, J6]
431    pub system_timestamps: [u64; 6],
432
433    // === 有效性掩码 ===
434    /// 有效性掩码(Bit 0-5 对应 J1-J6)
435    /// - 1 表示本周期内已更新
436    /// - 0 表示未更新(可能是丢帧)
437    pub valid_mask: u8,
438}
439
440impl JointDriverLowSpeedState {
441    /// 检查所有关节是否都已更新(`valid_mask == 0x3F`)
442    pub fn is_fully_valid(&self) -> bool {
443        self.valid_mask == 0b111111
444    }
445
446    /// 获取未更新的关节索引(用于调试)
447    pub fn missing_joints(&self) -> Vec<usize> {
448        (0..6).filter(|&i| (self.valid_mask & (1 << i)) == 0).collect()
449    }
450
451    /// 检查指定关节是否电压过低
452    pub fn is_voltage_low(&self, joint_index: usize) -> bool {
453        if joint_index >= 6 {
454            return false;
455        }
456        (self.driver_voltage_low_mask >> joint_index) & 1 == 1
457    }
458
459    /// 检查指定关节是否电机过温
460    pub fn is_motor_over_temp(&self, joint_index: usize) -> bool {
461        if joint_index >= 6 {
462            return false;
463        }
464        (self.driver_motor_over_temp_mask >> joint_index) & 1 == 1
465    }
466
467    /// 检查指定关节是否过流
468    pub fn is_over_current(&self, joint_index: usize) -> bool {
469        if joint_index >= 6 {
470            return false;
471        }
472        (self.driver_over_current_mask >> joint_index) & 1 == 1
473    }
474
475    /// 检查指定关节是否驱动器过温
476    pub fn is_driver_over_temp(&self, joint_index: usize) -> bool {
477        if joint_index >= 6 {
478            return false;
479        }
480        (self.driver_over_temp_mask >> joint_index) & 1 == 1
481    }
482
483    /// 检查指定关节是否碰撞保护触发
484    pub fn is_collision_protection(&self, joint_index: usize) -> bool {
485        if joint_index >= 6 {
486            return false;
487        }
488        (self.driver_collision_protection_mask >> joint_index) & 1 == 1
489    }
490
491    /// 检查指定关节是否驱动器错误
492    pub fn is_driver_error(&self, joint_index: usize) -> bool {
493        if joint_index >= 6 {
494            return false;
495        }
496        (self.driver_error_mask >> joint_index) & 1 == 1
497    }
498
499    /// 检查指定关节是否使能
500    pub fn is_enabled(&self, joint_index: usize) -> bool {
501        if joint_index >= 6 {
502            return false;
503        }
504        (self.driver_enabled_mask >> joint_index) & 1 == 1
505    }
506
507    /// 检查指定关节是否堵转保护触发
508    pub fn is_stall_protection(&self, joint_index: usize) -> bool {
509        if joint_index >= 6 {
510            return false;
511        }
512        (self.driver_stall_protection_mask >> joint_index) & 1 == 1
513    }
514}
515
516/// 碰撞保护状态(冷数据)
517///
518/// 更新频率:按需查询(通常只在设置碰撞保护等级后收到反馈)
519/// CAN ID:0x47B
520/// 同步机制:RwLock(按需查询,更新频率极低)
521///
522/// **注意**:碰撞保护等级范围是 0-8,其中 0 表示不检测碰撞。
523#[derive(Debug, Clone, Default)]
524pub struct CollisionProtectionState {
525    /// 硬件时间戳(微秒,来自 CAN 帧)
526    pub hardware_timestamp_us: u64,
527
528    /// 系统接收时间戳(微秒)
529    pub system_timestamp_us: u64,
530
531    /// 各关节碰撞保护等级(0-8)[J1, J2, J3, J4, J5, J6]
532    ///
533    /// **注意**:
534    /// - 0:不检测碰撞
535    /// - 1-8:碰撞保护等级(数字越大,保护越严格)
536    pub protection_levels: [u8; 6],
537}
538
539/// 关节限制配置状态(冷数据)
540///
541/// 更新频率:按需查询(需要查询6次,每个关节一次)
542/// CAN ID:0x473(MotorLimitFeedback)
543/// 同步机制:RwLock(按需查询,更新频率极低)
544///
545/// **注意**:
546/// - `MotorLimitFeedback.max_angle()` 和 `.min_angle()` 返回的是**度**,需要转换为弧度。
547/// - `MotorLimitFeedback.max_velocity()` 已经返回 rad/s,无需转换。
548#[derive(Debug, Clone, Default)]
549pub struct JointLimitConfigState {
550    /// 最后更新时间戳(硬件时间戳,微秒)
551    pub last_update_hardware_timestamp_us: u64,
552
553    /// 最后更新时间戳(系统时间戳,微秒)
554    pub last_update_system_timestamp_us: u64,
555
556    // === 关节限制配置(来自 0x473,需要查询6次) ===
557    /// 关节角度上限(弧度)[J1, J2, J3, J4, J5, J6]
558    pub joint_limits_max: [f64; 6],
559    /// 关节角度下限(弧度)[J1, J2, J3, J4, J5, J6]
560    pub joint_limits_min: [f64; 6],
561    /// 各关节最大速度(rad/s)[J1, J2, J3, J4, J5, J6]
562    pub joint_max_velocity: [f64; 6],
563
564    // === 时间戳(每个关节独立) ===
565    /// 每个关节的硬件时间戳(微秒)[J1, J2, J3, J4, J5, J6]
566    pub joint_update_hardware_timestamps: [u64; 6],
567    /// 每个关节的系统接收时间戳(微秒)[J1, J2, J3, J4, J5, J6]
568    pub joint_update_system_timestamps: [u64; 6],
569
570    // === 有效性掩码 ===
571    /// 有效性掩码(Bit 0-5 对应 J1-J6)
572    /// - 1 表示该关节的配置已更新
573    /// - 0 表示该关节的配置未更新(可能未查询)
574    pub valid_mask: u8,
575}
576
577impl JointLimitConfigState {
578    /// 检查所有关节是否都已更新(`valid_mask == 0x3F`)
579    pub fn is_fully_valid(&self) -> bool {
580        self.valid_mask == 0b111111
581    }
582
583    /// 获取未更新的关节索引(用于调试)
584    pub fn missing_joints(&self) -> Vec<usize> {
585        (0..6).filter(|&i| (self.valid_mask & (1 << i)) == 0).collect()
586    }
587}
588
589/// 关节加速度限制配置状态(冷数据)
590///
591/// 更新频率:按需查询(需要查询6次,每个关节一次)
592/// CAN ID:0x47C(MotorMaxAccelFeedback)
593/// 同步机制:RwLock(按需查询,更新频率极低)
594///
595/// **注意**:`MotorMaxAccelFeedback.max_accel()` 已经返回 rad/s²,无需转换。
596#[derive(Debug, Clone, Default)]
597pub struct JointAccelConfigState {
598    /// 最后更新时间戳(硬件时间戳,微秒)
599    pub last_update_hardware_timestamp_us: u64,
600
601    /// 最后更新时间戳(系统时间戳,微秒)
602    pub last_update_system_timestamp_us: u64,
603
604    // === 关节加速度限制配置(来自 0x47C,需要查询6次) ===
605    /// 各关节最大加速度(rad/s²)[J1, J2, J3, J4, J5, J6]
606    pub max_acc_limits: [f64; 6],
607
608    // === 时间戳(每个关节独立) ===
609    /// 每个关节的硬件时间戳(微秒)[J1, J2, J3, J4, J5, J6]
610    pub joint_update_hardware_timestamps: [u64; 6],
611    /// 每个关节的系统接收时间戳(微秒)[J1, J2, J3, J4, J5, J6]
612    pub joint_update_system_timestamps: [u64; 6],
613
614    // === 有效性掩码 ===
615    /// 有效性掩码(Bit 0-5 对应 J1-J6)
616    /// - 1 表示该关节的配置已更新
617    /// - 0 表示该关节的配置未更新(可能未查询)
618    pub valid_mask: u8,
619}
620
621impl JointAccelConfigState {
622    /// 检查所有关节是否都已更新(`valid_mask == 0x3F`)
623    pub fn is_fully_valid(&self) -> bool {
624        self.valid_mask == 0b111111
625    }
626
627    /// 获取未更新的关节索引(用于调试)
628    pub fn missing_joints(&self) -> Vec<usize> {
629        (0..6).filter(|&i| (self.valid_mask & (1 << i)) == 0).collect()
630    }
631}
632
633/// 末端限制配置状态(冷数据)
634///
635/// 更新频率:按需查询(单帧响应)
636/// CAN ID:0x478(EndVelocityAccelFeedback)
637/// 同步机制:RwLock(按需查询,更新频率极低)
638///
639/// **注意**:所有字段的单位已经在协议层转换完成,无需额外转换。
640#[derive(Debug, Clone, Default)]
641pub struct EndLimitConfigState {
642    /// 最后更新时间戳(硬件时间戳,微秒)
643    pub last_update_hardware_timestamp_us: u64,
644
645    /// 最后更新时间戳(系统时间戳,微秒)
646    pub last_update_system_timestamp_us: u64,
647
648    // === 末端限制配置(来自 0x478,单帧响应) ===
649    /// 末端最大线速度(m/s)
650    pub max_end_linear_velocity: f64,
651    /// 末端最大角速度(rad/s)
652    pub max_end_angular_velocity: f64,
653    /// 末端最大线加速度(m/s²)
654    pub max_end_linear_accel: f64,
655    /// 末端最大角加速度(rad/s²)
656    pub max_end_angular_accel: f64,
657
658    // === 有效性标记 ===
659    /// 是否已更新(单帧响应,收到即有效)
660    pub is_valid: bool,
661}
662
663// ============================================================================
664// 固件版本状态
665// ============================================================================
666
667/// 固件版本状态
668///
669/// 更新频率:按需查询
670/// CAN ID:0x4AF(多帧累积)
671/// 同步机制:RwLock(冷数据,更新频率低)
672#[derive(Debug, Clone, Default)]
673pub struct FirmwareVersionState {
674    /// 硬件时间戳(微秒,最后一帧的时间)
675    pub hardware_timestamp_us: u64,
676
677    /// 系统接收时间戳(微秒)
678    pub system_timestamp_us: u64,
679
680    /// 累积的固件数据(字节数组)
681    /// 注意:版本字符串需要从累积数据中解析
682    pub firmware_data: Vec<u8>,
683
684    /// 是否已收到完整数据
685    /// 注意:判断条件需要根据实际情况确定(例如收到特定结束标记)
686    pub is_complete: bool,
687
688    /// 解析后的版本字符串(缓存)
689    /// 如果 firmware_data 中包含有效的版本字符串,这里存储解析结果
690    pub version_string: Option<String>,
691}
692
693impl FirmwareVersionState {
694    /// 清空累积的固件数据(用于开始新的查询)
695    ///
696    /// 在发送新的固件版本查询命令前调用此方法,清空之前累积的数据。
697    pub fn clear(&mut self) {
698        self.firmware_data.clear();
699        self.version_string = None;
700        self.is_complete = false;
701        self.hardware_timestamp_us = 0;
702        self.system_timestamp_us = 0;
703    }
704
705    /// 检查数据是否完整(是否找到 S-V 标记且有足够数据)
706    ///
707    /// 数据完整的条件:
708    /// 1. 找到 "S-V" 标记
709    /// 2. 从 S-V 开始至少有 8 字节数据
710    ///
711    /// # 返回值
712    /// 如果数据完整,返回 `true` 并更新 `is_complete` 字段
713    pub fn check_completeness(&mut self) -> bool {
714        if let Some(version_start) = self.firmware_data.windows(3).position(|w| w == b"S-V") {
715            // 找到 S-V 标记,检查是否有足够的数据(至少 8 字节)
716            let required_length = version_start + 8;
717            self.is_complete = self.firmware_data.len() >= required_length;
718        } else {
719            self.is_complete = false;
720        }
721        self.is_complete
722    }
723
724    /// 尝试从累积数据中解析版本字符串
725    ///
726    /// 解析成功时会自动更新 `version_string` 和 `is_complete` 状态。
727    pub fn parse_version(&mut self) -> Option<String> {
728        // 导入 FirmwareReadFeedback 的 parse_version_string 方法
729        use piper_protocol::feedback::FirmwareReadFeedback;
730        if let Some(version) = FirmwareReadFeedback::parse_version_string(&self.firmware_data) {
731            self.version_string = Some(version.clone());
732            // 同时更新完整性状态
733            self.check_completeness();
734            Some(version)
735        } else {
736            self.version_string = None;
737            self.is_complete = false;
738            None
739        }
740    }
741
742    /// 获取版本字符串(如果已解析)
743    pub fn version_string(&self) -> Option<&String> {
744        self.version_string.as_ref()
745    }
746}
747
748// ============================================================================
749// 主从模式控制指令状态
750// ============================================================================
751
752/// 主从模式控制模式指令状态
753///
754/// 更新频率:~200Hz(取决于主臂发送频率)
755/// CAN ID:0x151
756/// 同步机制:ArcSwap(温数据,高频访问)
757#[derive(Debug, Clone, Default)]
758pub struct MasterSlaveControlModeState {
759    /// 硬件时间戳(微秒)
760    pub hardware_timestamp_us: u64,
761
762    /// 系统接收时间戳(微秒)
763    pub system_timestamp_us: u64,
764
765    /// 控制模式指令(来自 0x151)
766    pub control_mode: u8, // ControlModeCommand as u8
767    pub move_mode: u8, // MoveMode as u8
768    pub speed_percent: u8,
769    pub mit_mode: u8, // MitMode as u8
770    pub trajectory_stay_time: u8,
771    pub install_position: u8, // InstallPosition as u8
772
773    /// 是否有效(已收到至少一帧)
774    pub is_valid: bool,
775}
776
777/// 主从模式关节控制指令状态(帧组同步)
778///
779/// 更新频率:~500Hz(取决于主臂发送频率)
780/// CAN ID:0x155-0x157(帧组:J1-J2, J3-J4, J5-J6)
781/// 同步机制:ArcSwap(温数据,帧组同步)
782///
783/// **注意**:这是一个帧组,类似于 `JointPositionState`,需要集齐 3 帧后一起提交
784#[derive(Debug, Clone, Default)]
785pub struct MasterSlaveJointControlState {
786    /// 硬件时间戳(微秒,来自完整帧组的最后一帧)
787    pub hardware_timestamp_us: u64,
788
789    /// 系统接收时间戳(微秒,系统接收到完整帧组的时间)
790    pub system_timestamp_us: u64,
791
792    /// 关节目标角度(度,0.001°单位)[J1, J2, J3, J4, J5, J6]
793    pub joint_target_deg: [i32; 6],
794
795    /// 帧组有效性掩码(Bit 0-2 对应 0x155, 0x156, 0x157)
796    /// - 1 表示该CAN帧已收到
797    /// - 0 表示该CAN帧未收到(可能丢包)
798    pub frame_valid_mask: u8,
799}
800
801impl MasterSlaveJointControlState {
802    /// 检查是否接收到了完整的帧组 (0x155, 0x156, 0x157)
803    ///
804    /// **返回值**:
805    /// - `true`:所有3个CAN帧都已收到,数据完整
806    /// - `false`:部分CAN帧丢失,数据不完整
807    pub fn is_fully_valid(&self) -> bool {
808        self.frame_valid_mask == 0b0000_0111 // Bit 0-2 全部为 1
809    }
810
811    /// 获取丢失的CAN帧索引(用于调试)
812    ///
813    /// **返回值**:丢失的CAN帧索引列表(0=0x155, 1=0x156, 2=0x157)
814    pub fn missing_frames(&self) -> Vec<usize> {
815        (0..3).filter(|&i| (self.frame_valid_mask & (1 << i)) == 0).collect()
816    }
817
818    /// 获取关节目标角度(度)
819    pub fn joint_target_deg(&self, joint_index: usize) -> Option<f64> {
820        if joint_index < 6 {
821            Some(self.joint_target_deg[joint_index] as f64 / 1000.0)
822        } else {
823            None
824        }
825    }
826
827    /// 获取关节目标角度(弧度)
828    pub fn joint_target_rad(&self, joint_index: usize) -> Option<f64> {
829        self.joint_target_deg(joint_index).map(|deg| deg * std::f64::consts::PI / 180.0)
830    }
831}
832
833/// 主从模式夹爪控制指令状态
834///
835/// 更新频率:~200Hz(取决于主臂发送频率)
836/// CAN ID:0x159
837/// 同步机制:ArcSwap(温数据,高频访问)
838#[derive(Debug, Clone, Default)]
839pub struct MasterSlaveGripperControlState {
840    /// 硬件时间戳(微秒)
841    pub hardware_timestamp_us: u64,
842
843    /// 系统接收时间戳(微秒)
844    pub system_timestamp_us: u64,
845
846    /// 夹爪目标行程(mm,0.001mm单位)
847    pub gripper_target_travel_mm: i32,
848
849    /// 夹爪目标扭矩(N·m,0.001N·m单位)
850    pub gripper_target_torque_nm: i16,
851
852    /// 夹爪状态码
853    pub gripper_status_code: u8,
854
855    /// 夹爪回零设置
856    pub gripper_set_zero: u8,
857
858    /// 是否有效(已收到至少一帧)
859    pub is_valid: bool,
860}
861
862impl MasterSlaveGripperControlState {
863    /// 获取夹爪目标行程(mm)
864    pub fn gripper_target_travel(&self) -> f64 {
865        self.gripper_target_travel_mm as f64 / 1000.0
866    }
867
868    /// 获取夹爪目标扭矩(N·m)
869    pub fn gripper_target_torque(&self) -> f64 {
870        self.gripper_target_torque_nm as f64 / 1000.0
871    }
872}
873
874/// 钩子管理器(v1.2.1)
875///
876/// 专门管理运行时回调列表。
877///
878/// # 设计理由
879///
880/// - **Config vs Context 分离**:
881///   - `PipelineConfig` 应该是 POD(Plain Old Data),用于序列化
882///   - `PiperContext` 管理运行时状态和动态组件(如回调)
883///
884/// # 线程安全
885///
886/// 使用 `RwLock<HookManager>` 确保回调列表的线程安全。
887///
888/// # 使用示例
889///
890/// ```rust
891/// use piper_driver::hooks::HookManager;
892/// use piper_driver::hooks::FrameCallback;
893/// use piper_driver::recording::AsyncRecordingHook;
894/// use piper_driver::state::PiperContext;
895/// use std::sync::Arc;
896///
897/// // 添加录制钩子
898/// let context = PiperContext::new();
899/// let (hook, _rx) = AsyncRecordingHook::new();
900/// let callback = Arc::new(hook) as Arc<dyn FrameCallback>;
901///
902/// if let Ok(mut hooks) = context.hooks.write() {
903///     hooks.add_callback(callback);
904/// }
905/// ```
906use crate::hooks::HookManager;
907
908/// Piper 上下文(所有状态的聚合)
909pub struct PiperContext {
910    // === 热数据(500Hz,高频运动数据)===
911    // 使用 ArcSwap,无锁读取,适合高频控制循环
912    /// 关节位置状态(帧组同步:0x2A5-0x2A7)
913    pub joint_position: Arc<ArcSwap<JointPositionState>>,
914    /// 末端位姿状态(帧组同步:0x2A2-0x2A4)
915    pub end_pose: Arc<ArcSwap<EndPoseState>>,
916    /// 关节动态状态(独立帧 + Buffered Commit:关节速度 + 电流)
917    pub joint_dynamic: Arc<ArcSwap<JointDynamicState>>,
918
919    // === 温数据(200Hz,控制状态)===
920    // 使用 ArcSwap,更新频率中等,但需要原子性
921    /// 机器人控制状态(单个CAN帧:0x2A1)
922    pub robot_control: Arc<ArcSwap<RobotControlState>>,
923
924    /// 夹爪状态(单个CAN帧:0x2A8)
925    pub gripper: Arc<ArcSwap<GripperState>>,
926
927    // === 温数据(40Hz,诊断数据)===
928    // 使用 ArcSwap,Wait-Free 读取,适合高频读
929    /// 关节驱动器低速反馈状态(单个CAN帧:0x261-0x266)
930    pub joint_driver_low_speed: Arc<ArcSwap<JointDriverLowSpeedState>>,
931
932    // === 冷数据(10Hz 或按需,诊断和配置)===
933    // 使用 RwLock,读取频率低,避免内存分配
934    /// 碰撞保护状态(按需查询:0x47B)
935    pub collision_protection: Arc<RwLock<CollisionProtectionState>>,
936
937    /// 关节限制配置状态(按需查询:0x473)
938    pub joint_limit_config: Arc<RwLock<JointLimitConfigState>>,
939
940    /// 关节加速度限制配置状态(按需查询:0x47C)
941    pub joint_accel_config: Arc<RwLock<JointAccelConfigState>>,
942
943    /// 末端限制配置状态(按需查询:0x478)
944    pub end_limit_config: Arc<RwLock<EndLimitConfigState>>,
945
946    // === 冷数据(固件版本)===
947    /// 固件版本状态(按需查询:0x4AF)
948    pub firmware_version: Arc<RwLock<FirmwareVersionState>>,
949
950    // === 温数据(主从模式)===
951    /// 主从模式控制模式指令状态(主从模式:0x151)
952    pub master_slave_control_mode: Arc<ArcSwap<MasterSlaveControlModeState>>,
953
954    /// 主从模式关节控制指令状态(主从模式:0x155-0x157,帧组同步)
955    pub master_slave_joint_control: Arc<ArcSwap<MasterSlaveJointControlState>>,
956
957    /// 主从模式夹爪控制指令状态(主从模式:0x159)
958    pub master_slave_gripper_control: Arc<ArcSwap<MasterSlaveGripperControlState>>,
959
960    // === FPS 统计 ===
961    // 使用原子计数器,无锁读取,适合实时监控
962    /// FPS 统计(各状态的更新频率统计)
963    ///
964    /// 使用 `ArcSwap` 支持在运行中原子性"重置统计窗口"(替换为新的 `FpsStatistics`),
965    /// 且不引入每帧的锁开销。
966    pub fps_stats: Arc<ArcSwap<FpsStatistics>>,
967
968    // === 连接监控 ===
969    /// 连接监控(用于检测机器人是否仍在响应)
970    ///
971    /// 使用 App Start Relative Time 模式,确保时间单调性。
972    pub connection_monitor: crate::heartbeat::ConnectionMonitor,
973
974    // === 钩子管理(v1.2.1)===
975    /// 钩子管理器(用于运行时回调注册)
976    ///
977    /// 使用 `RwLock` 支持动态添加/移除回调,同时保证线程安全。
978    ///
979    /// # 设计理由(v1.2.1)
980    ///
981    /// - **Config vs Context 分离**: `PipelineConfig` 保持为 POD(Plain Old Data),
982    ///   `PiperContext` 管理运行时状态和动态组件(如回调)
983    /// - **动态注册**: 运行时可以添加/移除回调,无需重新配置 pipeline
984    /// - **线程安全**: 使用 `RwLock` 保证并发访问安全
985    ///
986    /// # 示例
987    ///
988    /// ```rust
989    /// use piper_driver::recording::AsyncRecordingHook;
990    /// use piper_driver::hooks::FrameCallback;
991    /// use piper_driver::state::PiperContext;
992    /// use std::sync::Arc;
993    ///
994    /// // 创建上下文和录制钩子
995    /// let context = PiperContext::new();
996    /// let (hook, _rx) = AsyncRecordingHook::new();
997    ///
998    /// // 注册为回调
999    /// if let Ok(mut hooks) = context.hooks.write() {
1000    ///     hooks.add_callback(Arc::new(hook) as Arc<dyn FrameCallback>);
1001    /// }
1002    /// ```
1003    pub hooks: Arc<RwLock<HookManager>>,
1004}
1005
1006impl PiperContext {
1007    /// 创建新的上下文
1008    ///
1009    /// 初始化所有状态结构,包括:
1010    /// - 热数据(ArcSwap):`joint_position`, `end_pose`, `joint_dynamic`
1011    /// - 温数据(ArcSwap):`robot_control`, `gripper`, `joint_driver_low_speed`
1012    /// - 冷数据(RwLock):`collision_protection`, `joint_limit_config`, `joint_accel_config`, `end_limit_config`
1013    /// - FPS 统计:`fps_stats`
1014    ///
1015    /// # Example
1016    ///
1017    /// ```
1018    /// use piper_driver::PiperContext;
1019    ///
1020    /// let ctx = PiperContext::new();
1021    /// let joint_pos = ctx.joint_position.load();
1022    /// assert_eq!(joint_pos.hardware_timestamp_us, 0);
1023    /// ```
1024    pub fn new() -> Self {
1025        Self {
1026            // 热数据:ArcSwap,无锁读取
1027            joint_position: Arc::new(ArcSwap::from_pointee(JointPositionState::default())),
1028            end_pose: Arc::new(ArcSwap::from_pointee(EndPoseState::default())),
1029            joint_dynamic: Arc::new(ArcSwap::from_pointee(JointDynamicState::default())),
1030
1031            // 温数据:ArcSwap
1032            robot_control: Arc::new(ArcSwap::from_pointee(RobotControlState::default())),
1033            gripper: Arc::new(ArcSwap::from_pointee(GripperState::default())),
1034            joint_driver_low_speed: Arc::new(ArcSwap::from_pointee(
1035                JointDriverLowSpeedState::default(),
1036            )),
1037
1038            // 冷数据:RwLock
1039            collision_protection: Arc::new(RwLock::new(CollisionProtectionState::default())),
1040            joint_limit_config: Arc::new(RwLock::new(JointLimitConfigState::default())),
1041            joint_accel_config: Arc::new(RwLock::new(JointAccelConfigState::default())),
1042            end_limit_config: Arc::new(RwLock::new(EndLimitConfigState::default())),
1043
1044            // 冷数据:固件版本
1045            firmware_version: Arc::new(RwLock::new(FirmwareVersionState::default())),
1046
1047            // 温数据:主从模式控制指令状态
1048            master_slave_control_mode: Arc::new(ArcSwap::from_pointee(
1049                MasterSlaveControlModeState::default(),
1050            )),
1051            master_slave_joint_control: Arc::new(ArcSwap::from_pointee(
1052                MasterSlaveJointControlState::default(),
1053            )),
1054            master_slave_gripper_control: Arc::new(ArcSwap::from_pointee(
1055                MasterSlaveGripperControlState::default(),
1056            )),
1057
1058            // FPS 统计:原子计数器
1059            fps_stats: Arc::new(ArcSwap::from_pointee(FpsStatistics::new())),
1060
1061            // 连接监控:1秒超时(如果1秒内没有收到任何反馈帧,认为连接丢失)
1062            connection_monitor: crate::heartbeat::ConnectionMonitor::new(
1063                std::time::Duration::from_secs(1),
1064            ),
1065
1066            // 钩子管理器(v1.2.1)
1067            hooks: Arc::new(RwLock::new(HookManager::new())),
1068        }
1069    }
1070
1071    /// 捕获运动状态快照(逻辑原子性)
1072    ///
1073    /// 虽然不能保证物理上的完全同步(因为CAN帧本身就不是同时到的),
1074    /// 但可以保证逻辑上的原子性(在同一时刻读取多个状态)。
1075    ///
1076    /// **注意**:返回的状态可能来自不同的CAN传输周期。
1077    ///
1078    /// **性能**:返回栈上对象,开销极小(仅包含 Arc 的克隆,不复制实际数据)
1079    ///
1080    /// # Example
1081    ///
1082    /// ```
1083    /// use piper_driver::PiperContext;
1084    ///
1085    /// let ctx = PiperContext::new();
1086    /// let snapshot = ctx.capture_motion_snapshot();
1087    /// println!("Joint positions: {:?}", snapshot.joint_position.joint_pos);
1088    /// println!("End pose: {:?}", snapshot.end_pose.end_pose);
1089    /// ```
1090    pub fn capture_motion_snapshot(&self) -> MotionSnapshot {
1091        MotionSnapshot {
1092            joint_position: self.joint_position.load().as_ref().clone(),
1093            end_pose: self.end_pose.load().as_ref().clone(),
1094        }
1095    }
1096}
1097
1098impl Default for PiperContext {
1099    fn default() -> Self {
1100        Self::new()
1101    }
1102}
1103
1104/// 组合运动状态(所有热数据)
1105pub struct CombinedMotionState {
1106    pub joint_position: JointPositionState,
1107    pub end_pose: EndPoseState,
1108    pub joint_dynamic: JointDynamicState,
1109}
1110
1111/// 时间对齐后的运动状态
1112///
1113/// 用于力控算法,确保位置和速度数据的时间戳差异在可接受范围内。
1114#[derive(Debug)]
1115pub struct AlignedMotionState {
1116    pub joint_pos: [f64; 6],
1117    pub joint_vel: [f64; 6],
1118    pub joint_current: [f64; 6],
1119    pub end_pose: [f64; 6],
1120    pub timestamp: u64,    // 基准时间戳(来自位置数据)
1121    pub time_diff_us: i64, // 速度数据与位置数据的时间差(用于调试)
1122}
1123
1124/// 时间对齐结果
1125///
1126/// 即使时间戳不对齐,也返回状态数据,让用户有选择权(是急停还是继续运行)。
1127#[derive(Debug)]
1128pub enum AlignmentResult {
1129    /// 时间戳对齐,数据可靠
1130    Ok(AlignedMotionState),
1131    /// 时间戳不对齐,但数据仍然返回(让用户决定是急停还是容忍延迟)
1132    Misaligned {
1133        state: AlignedMotionState,
1134        diff_us: u64,
1135    },
1136}
1137
1138#[cfg(test)]
1139mod tests {
1140    use super::{EndPoseState, JointPositionState, MotionSnapshot, PiperContext};
1141    use std::f64::consts::PI;
1142
1143    use super::JointDynamicState;
1144
1145    #[test]
1146    fn test_joint_dynamic_state_is_complete() {
1147        let state = JointDynamicState {
1148            valid_mask: 0b111111, // 所有关节已更新
1149            ..Default::default()
1150        };
1151        assert!(state.is_complete());
1152
1153        let state2 = JointDynamicState {
1154            valid_mask: 0b111110, // J6 未更新
1155            ..Default::default()
1156        };
1157        assert!(!state2.is_complete());
1158    }
1159
1160    #[test]
1161    fn test_joint_dynamic_state_missing_joints() {
1162        // 0b111100 = 0b00111100 (二进制),表示 bit 0-1 未更新 (J1, J2)
1163        // 如果要表示 J5, J6 未更新,应该使用 0b001111 (bit 4-5 为 0)
1164        let state = JointDynamicState {
1165            valid_mask: 0b001111, // J5, J6 未更新 (只有 bit 0-3 为 1)
1166            ..Default::default()
1167        };
1168        let missing = state.missing_joints();
1169        assert_eq!(missing, vec![4, 5]); // 索引 4, 5 (J5, J6)
1170
1171        // 测试另一个场景:只有 J1 和 J3 已更新
1172        let state2 = JointDynamicState {
1173            valid_mask: 0b000101, // bit 0 和 bit 2 为 1
1174            ..Default::default()
1175        };
1176        let missing = state2.missing_joints();
1177        assert_eq!(missing, vec![1, 3, 4, 5]); // J2, J4, J5, J6 未更新
1178    }
1179
1180    #[test]
1181    fn test_joint_dynamic_state_calculate_torque() {
1182        // 测试关节 1-3(使用 COEFFICIENT_1_3 = 1.18125)
1183        let torque_j1 = JointDynamicState::calculate_torque(0, 1.0);
1184        assert!((torque_j1 - 1.18125).abs() < 0.0001);
1185
1186        let torque_j2 = JointDynamicState::calculate_torque(1, 2.0);
1187        assert!((torque_j2 - 2.3625).abs() < 0.0001);
1188
1189        let torque_j3 = JointDynamicState::calculate_torque(2, 0.5);
1190        assert!((torque_j3 - 0.590625).abs() < 0.0001);
1191
1192        // 测试关节 4-6(使用 COEFFICIENT_4_6 = 0.95844)
1193        let torque_j4 = JointDynamicState::calculate_torque(3, 1.0);
1194        assert!((torque_j4 - 0.95844).abs() < 0.0001);
1195
1196        let torque_j5 = JointDynamicState::calculate_torque(4, 2.0);
1197        assert!((torque_j5 - 1.91688).abs() < 0.0001);
1198
1199        let torque_j6 = JointDynamicState::calculate_torque(5, 0.5);
1200        assert!((torque_j6 - 0.47922).abs() < 0.0001);
1201    }
1202
1203    #[test]
1204    fn test_joint_dynamic_state_get_torque() {
1205        let state = JointDynamicState {
1206            joint_current: [1.0, 2.0, 0.5, 1.0, 2.0, 0.5],
1207            ..Default::default()
1208        };
1209
1210        // 测试关节 1-3(使用 COEFFICIENT_1_3 = 1.18125)
1211        assert!((state.get_torque(0) - 1.18125).abs() < 0.0001); // 1.0 * 1.18125
1212        assert!((state.get_torque(1) - 2.3625).abs() < 0.0001); // 2.0 * 1.18125
1213        assert!((state.get_torque(2) - 0.590625).abs() < 0.0001); // 0.5 * 1.18125
1214
1215        // 测试关节 4-6(使用 COEFFICIENT_4_6 = 0.95844)
1216        assert!((state.get_torque(3) - 0.95844).abs() < 0.0001); // 1.0 * 0.95844
1217        assert!((state.get_torque(4) - 1.91688).abs() < 0.0001); // 2.0 * 0.95844
1218        assert!((state.get_torque(5) - 0.47922).abs() < 0.0001); // 0.5 * 0.95844
1219
1220        // 测试超出范围的索引
1221        assert_eq!(state.get_torque(6), 0.0);
1222        assert_eq!(state.get_torque(100), 0.0);
1223    }
1224
1225    #[test]
1226    fn test_joint_dynamic_state_get_all_torques() {
1227        let state = JointDynamicState {
1228            joint_current: [1.0, 2.0, 0.5, 1.0, 2.0, 0.5],
1229            ..Default::default()
1230        };
1231
1232        let all_torques = state.get_all_torques();
1233
1234        // 验证关节 1-3(使用 COEFFICIENT_1_3 = 1.18125)
1235        assert!((all_torques[0] - 1.18125).abs() < 0.0001); // 1.0 * 1.18125
1236        assert!((all_torques[1] - 2.3625).abs() < 0.0001); // 2.0 * 1.18125
1237        assert!((all_torques[2] - 0.590625).abs() < 0.0001); // 0.5 * 1.18125
1238
1239        // 验证关节 4-6(使用 COEFFICIENT_4_6 = 0.95844)
1240        assert!((all_torques[3] - 0.95844).abs() < 0.0001); // 1.0 * 0.95844
1241        assert!((all_torques[4] - 1.91688).abs() < 0.0001); // 2.0 * 0.95844
1242        assert!((all_torques[5] - 0.47922).abs() < 0.0001); // 0.5 * 0.95844
1243
1244        // 验证与单独调用 get_torque() 的一致性
1245        for (i, &torque) in all_torques.iter().enumerate() {
1246            assert!((torque - state.get_torque(i)).abs() < 0.0001);
1247        }
1248    }
1249
1250    #[test]
1251    fn test_joint_dynamic_state_default() {
1252        let state = JointDynamicState::default();
1253        assert_eq!(state.group_timestamp_us, 0);
1254        assert_eq!(state.joint_vel, [0.0; 6]);
1255        assert_eq!(state.joint_current, [0.0; 6]);
1256        assert_eq!(state.timestamps, [0; 6]);
1257        assert_eq!(state.valid_mask, 0);
1258        assert!(!state.is_complete());
1259        assert_eq!(state.missing_joints(), vec![0, 1, 2, 3, 4, 5]);
1260        // 测试默认状态下扭矩为 0(因为电流为 0)
1261        assert_eq!(state.get_torque(0), 0.0);
1262        assert_eq!(state.get_torque(5), 0.0);
1263    }
1264
1265    use super::*;
1266
1267    #[test]
1268    fn test_piper_context_new() {
1269        let ctx = PiperContext::new();
1270        // 验证所有 Arc/ArcSwap 都已初始化
1271        let joint_pos = ctx.joint_position.load();
1272        assert_eq!(joint_pos.hardware_timestamp_us, 0);
1273        assert_eq!(joint_pos.joint_pos, [0.0; 6]);
1274
1275        let end_pose = ctx.end_pose.load();
1276        assert_eq!(end_pose.hardware_timestamp_us, 0);
1277        assert_eq!(end_pose.end_pose, [0.0; 6]);
1278
1279        let joint_dynamic = ctx.joint_dynamic.load();
1280        assert_eq!(joint_dynamic.group_timestamp_us, 0);
1281
1282        let robot_control = ctx.robot_control.load();
1283        assert_eq!(robot_control.hardware_timestamp_us, 0);
1284
1285        let driver_state = ctx.joint_driver_low_speed.load();
1286        assert_eq!(driver_state.hardware_timestamp_us, 0);
1287
1288        let limits = ctx.joint_limit_config.read().unwrap();
1289        assert_eq!(limits.joint_limits_max, [0.0; 6]);
1290    }
1291
1292    #[test]
1293    fn test_joint_dynamic_state_clone() {
1294        let state = JointDynamicState {
1295            group_timestamp_us: 1000,
1296            joint_vel: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0],
1297            joint_current: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
1298            timestamps: [100, 200, 300, 400, 500, 600],
1299            valid_mask: 0b111111,
1300        };
1301        let cloned = state.clone();
1302        assert_eq!(state.group_timestamp_us, cloned.group_timestamp_us);
1303        assert_eq!(state.joint_vel, cloned.joint_vel);
1304        assert_eq!(state.joint_current, cloned.joint_current);
1305        assert_eq!(state.timestamps, cloned.timestamps);
1306        assert_eq!(state.valid_mask, cloned.valid_mask);
1307        assert_eq!(state.is_complete(), cloned.is_complete());
1308        // 验证扭矩计算的一致性
1309        for i in 0..6 {
1310            assert!((state.get_torque(i) - cloned.get_torque(i)).abs() < 0.0001);
1311        }
1312    }
1313
1314    #[test]
1315    fn test_aligned_motion_state_debug() {
1316        let state = AlignedMotionState {
1317            joint_pos: [1.0; 6],
1318            joint_vel: [2.0; 6],
1319            joint_current: [3.0; 6],
1320            end_pose: [4.0; 6],
1321            timestamp: 1000,
1322            time_diff_us: 500,
1323        };
1324        let debug_str = format!("{:?}", state);
1325        assert!(debug_str.contains("AlignedMotionState"));
1326    }
1327
1328    #[test]
1329    fn test_alignment_result_debug() {
1330        let state = AlignedMotionState {
1331            joint_pos: [1.0; 6],
1332            joint_vel: [2.0; 6],
1333            joint_current: [3.0; 6],
1334            end_pose: [4.0; 6],
1335            timestamp: 1000,
1336            time_diff_us: 500,
1337        };
1338        let result_ok = AlignmentResult::Ok(state);
1339        let debug_str = format!("{:?}", result_ok);
1340        assert!(debug_str.contains("Ok") || debug_str.contains("AlignmentResult"));
1341
1342        let state2 = AlignedMotionState {
1343            joint_pos: [1.0; 6],
1344            joint_vel: [2.0; 6],
1345            joint_current: [3.0; 6],
1346            end_pose: [4.0; 6],
1347            timestamp: 1000,
1348            time_diff_us: 500,
1349        };
1350        let result_mis = AlignmentResult::Misaligned {
1351            state: state2,
1352            diff_us: 10000,
1353        };
1354        let debug_str2 = format!("{:?}", result_mis);
1355        assert!(debug_str2.contains("Misaligned") || debug_str2.contains("AlignmentResult"));
1356    }
1357
1358    // ============================================================
1359    // 测试新状态结构:JointPositionState 和 EndPoseState
1360    // ============================================================
1361
1362    #[test]
1363    fn test_joint_position_state_default() {
1364        let state = JointPositionState::default();
1365        assert_eq!(state.hardware_timestamp_us, 0);
1366        assert_eq!(state.system_timestamp_us, 0);
1367        assert_eq!(state.joint_pos, [0.0; 6]);
1368        assert_eq!(state.frame_valid_mask, 0);
1369    }
1370
1371    #[test]
1372    fn test_joint_position_state_is_fully_valid() {
1373        // 完整帧组(所有3帧都收到)
1374        let state = JointPositionState {
1375            hardware_timestamp_us: 1000,
1376            system_timestamp_us: 2000,
1377            joint_pos: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0],
1378            frame_valid_mask: 0b0000_0111, // Bit 0-2 全部为 1
1379        };
1380        assert!(state.is_fully_valid());
1381
1382        // 不完整帧组(只有2帧)
1383        let state_incomplete = JointPositionState {
1384            frame_valid_mask: 0b0000_0011, // 只有 Bit 0-1
1385            ..state
1386        };
1387        assert!(!state_incomplete.is_fully_valid());
1388
1389        // 完全不完整(没有帧)
1390        let state_empty = JointPositionState {
1391            frame_valid_mask: 0b0000_0000,
1392            ..state
1393        };
1394        assert!(!state_empty.is_fully_valid());
1395    }
1396
1397    #[test]
1398    fn test_joint_position_state_missing_frames() {
1399        // 完整帧组
1400        let state_complete = JointPositionState {
1401            frame_valid_mask: 0b0000_0111,
1402            ..Default::default()
1403        };
1404        assert_eq!(state_complete.missing_frames(), Vec::<usize>::new());
1405
1406        // 缺少第一帧(0x2A5)
1407        let state_missing_first = JointPositionState {
1408            frame_valid_mask: 0b0000_0110, // Bit 1-2 有,Bit 0 没有
1409            ..Default::default()
1410        };
1411        assert_eq!(state_missing_first.missing_frames(), vec![0]);
1412
1413        // 缺少中间帧(0x2A6)
1414        let state_missing_middle = JointPositionState {
1415            frame_valid_mask: 0b0000_0101, // Bit 0 和 2 有,Bit 1 没有
1416            ..Default::default()
1417        };
1418        assert_eq!(state_missing_middle.missing_frames(), vec![1]);
1419
1420        // 缺少最后一帧(0x2A7)
1421        let state_missing_last = JointPositionState {
1422            frame_valid_mask: 0b0000_0011, // Bit 0-1 有,Bit 2 没有
1423            ..Default::default()
1424        };
1425        assert_eq!(state_missing_last.missing_frames(), vec![2]);
1426
1427        // 缺少多帧
1428        let state_missing_multiple = JointPositionState {
1429            frame_valid_mask: 0b0000_0001, // 只有 Bit 0
1430            ..Default::default()
1431        };
1432        let missing = state_missing_multiple.missing_frames();
1433        assert_eq!(missing.len(), 2);
1434        assert!(missing.contains(&1));
1435        assert!(missing.contains(&2));
1436    }
1437
1438    #[test]
1439    fn test_joint_position_state_clone() {
1440        let state = JointPositionState {
1441            hardware_timestamp_us: 1000,
1442            system_timestamp_us: 2000,
1443            joint_pos: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0],
1444            frame_valid_mask: 0b0000_0111,
1445        };
1446        let cloned = state.clone();
1447        assert_eq!(state.hardware_timestamp_us, cloned.hardware_timestamp_us);
1448        assert_eq!(state.system_timestamp_us, cloned.system_timestamp_us);
1449        assert_eq!(state.joint_pos, cloned.joint_pos);
1450        assert_eq!(state.frame_valid_mask, cloned.frame_valid_mask);
1451        assert_eq!(state.is_fully_valid(), cloned.is_fully_valid());
1452    }
1453
1454    #[test]
1455    fn test_end_pose_state_default() {
1456        let state = EndPoseState::default();
1457        assert_eq!(state.hardware_timestamp_us, 0);
1458        assert_eq!(state.system_timestamp_us, 0);
1459        assert_eq!(state.end_pose, [0.0; 6]);
1460        assert_eq!(state.frame_valid_mask, 0);
1461    }
1462
1463    #[test]
1464    fn test_end_pose_state_is_fully_valid() {
1465        // 完整帧组(所有3帧都收到)
1466        let state = EndPoseState {
1467            hardware_timestamp_us: 1000,
1468            system_timestamp_us: 2000,
1469            end_pose: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
1470            frame_valid_mask: 0b0000_0111, // Bit 0-2 全部为 1
1471        };
1472        assert!(state.is_fully_valid());
1473
1474        // 不完整帧组
1475        let state_incomplete = EndPoseState {
1476            frame_valid_mask: 0b0000_0011, // 只有 Bit 0-1
1477            ..state
1478        };
1479        assert!(!state_incomplete.is_fully_valid());
1480    }
1481
1482    #[test]
1483    fn test_end_pose_state_missing_frames() {
1484        // 完整帧组
1485        let state_complete = EndPoseState {
1486            frame_valid_mask: 0b0000_0111,
1487            ..Default::default()
1488        };
1489        assert_eq!(state_complete.missing_frames(), Vec::<usize>::new());
1490
1491        // 缺少第一帧(0x2A2)
1492        let state_missing_first = EndPoseState {
1493            frame_valid_mask: 0b0000_0110, // Bit 1-2 有,Bit 0 没有
1494            ..Default::default()
1495        };
1496        assert_eq!(state_missing_first.missing_frames(), vec![0]);
1497
1498        // 缺少中间帧(0x2A3)
1499        let state_missing_middle = EndPoseState {
1500            frame_valid_mask: 0b0000_0101, // Bit 0 和 2 有,Bit 1 没有
1501            ..Default::default()
1502        };
1503        assert_eq!(state_missing_middle.missing_frames(), vec![1]);
1504
1505        // 缺少最后一帧(0x2A4)
1506        let state_missing_last = EndPoseState {
1507            frame_valid_mask: 0b0000_0011, // Bit 0-1 有,Bit 2 没有
1508            ..Default::default()
1509        };
1510        assert_eq!(state_missing_last.missing_frames(), vec![2]);
1511    }
1512
1513    #[test]
1514    fn test_end_pose_state_clone() {
1515        let state = EndPoseState {
1516            hardware_timestamp_us: 1000,
1517            system_timestamp_us: 2000,
1518            end_pose: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
1519            frame_valid_mask: 0b0000_0111,
1520        };
1521        let cloned = state.clone();
1522        assert_eq!(state.hardware_timestamp_us, cloned.hardware_timestamp_us);
1523        assert_eq!(state.system_timestamp_us, cloned.system_timestamp_us);
1524        assert_eq!(state.end_pose, cloned.end_pose);
1525        assert_eq!(state.frame_valid_mask, cloned.frame_valid_mask);
1526        assert_eq!(state.is_fully_valid(), cloned.is_fully_valid());
1527    }
1528
1529    #[test]
1530    fn test_motion_snapshot_default() {
1531        let snapshot = MotionSnapshot {
1532            joint_position: JointPositionState::default(),
1533            end_pose: EndPoseState::default(),
1534        };
1535        assert_eq!(snapshot.joint_position.hardware_timestamp_us, 0);
1536        assert_eq!(snapshot.end_pose.hardware_timestamp_us, 0);
1537    }
1538
1539    #[test]
1540    fn test_motion_snapshot_clone() {
1541        let snapshot = MotionSnapshot {
1542            joint_position: JointPositionState {
1543                hardware_timestamp_us: 1000,
1544                system_timestamp_us: 2000,
1545                joint_pos: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0],
1546                frame_valid_mask: 0b0000_0111,
1547            },
1548            end_pose: EndPoseState {
1549                hardware_timestamp_us: 1500,
1550                system_timestamp_us: 2500,
1551                end_pose: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
1552                frame_valid_mask: 0b0000_0111,
1553            },
1554        };
1555        let cloned = snapshot.clone();
1556        assert_eq!(
1557            snapshot.joint_position.joint_pos,
1558            cloned.joint_position.joint_pos
1559        );
1560        assert_eq!(snapshot.end_pose.end_pose, cloned.end_pose.end_pose);
1561    }
1562
1563    #[test]
1564    fn test_piper_context_capture_motion_snapshot() {
1565        let ctx = PiperContext::new();
1566
1567        // 初始状态应该是默认值
1568        let snapshot = ctx.capture_motion_snapshot();
1569        assert_eq!(snapshot.joint_position.hardware_timestamp_us, 0);
1570        assert_eq!(snapshot.end_pose.hardware_timestamp_us, 0);
1571        assert_eq!(snapshot.joint_position.joint_pos, [0.0; 6]);
1572        assert_eq!(snapshot.end_pose.end_pose, [0.0; 6]);
1573    }
1574
1575    #[test]
1576    fn test_piper_context_new_states() {
1577        let ctx = PiperContext::new();
1578
1579        // 验证新状态字段存在且为默认值
1580        let joint_pos = ctx.joint_position.load();
1581        assert_eq!(joint_pos.hardware_timestamp_us, 0);
1582        assert_eq!(joint_pos.joint_pos, [0.0; 6]);
1583
1584        let end_pose = ctx.end_pose.load();
1585        assert_eq!(end_pose.hardware_timestamp_us, 0);
1586        assert_eq!(end_pose.end_pose, [0.0; 6]);
1587    }
1588
1589    // ============================================================
1590    // 测试新状态结构:GripperState 和 RobotControlState
1591    // ============================================================
1592
1593    #[test]
1594    fn test_gripper_state_default() {
1595        let state = GripperState::default();
1596        assert_eq!(state.hardware_timestamp_us, 0);
1597        assert_eq!(state.system_timestamp_us, 0);
1598        assert_eq!(state.travel, 0.0);
1599        assert_eq!(state.torque, 0.0);
1600        assert_eq!(state.status_code, 0);
1601        assert_eq!(state.last_travel, 0.0);
1602    }
1603
1604    #[test]
1605    fn test_gripper_state_status_flags() {
1606        // 测试所有状态位标志
1607        let state_voltage_low = GripperState {
1608            status_code: 0b0000_0001, // Bit 0
1609            ..Default::default()
1610        };
1611        assert!(state_voltage_low.is_voltage_low());
1612        assert!(!state_voltage_low.is_motor_over_temp());
1613
1614        let state_motor_over_temp = GripperState {
1615            status_code: 0b0000_0010, // Bit 1
1616            ..Default::default()
1617        };
1618        assert!(state_motor_over_temp.is_motor_over_temp());
1619        assert!(!state_motor_over_temp.is_voltage_low());
1620
1621        let state_over_current = GripperState {
1622            status_code: 0b0000_0100, // Bit 2
1623            ..Default::default()
1624        };
1625        assert!(state_over_current.is_over_current());
1626
1627        let state_driver_over_temp = GripperState {
1628            status_code: 0b0000_1000, // Bit 3
1629            ..Default::default()
1630        };
1631        assert!(state_driver_over_temp.is_driver_over_temp());
1632
1633        let state_sensor_error = GripperState {
1634            status_code: 0b0001_0000, // Bit 4
1635            ..Default::default()
1636        };
1637        assert!(state_sensor_error.is_sensor_error());
1638
1639        let state_driver_error = GripperState {
1640            status_code: 0b0010_0000, // Bit 5
1641            ..Default::default()
1642        };
1643        assert!(state_driver_error.is_driver_error());
1644
1645        let state_enabled = GripperState {
1646            status_code: 0b0100_0000, // Bit 6
1647            ..Default::default()
1648        };
1649        assert!(state_enabled.is_enabled());
1650
1651        let state_homed = GripperState {
1652            status_code: 0b1000_0000, // Bit 7
1653            ..Default::default()
1654        };
1655        assert!(state_homed.is_homed());
1656
1657        // 测试多个标志同时设置
1658        let state_multiple = GripperState {
1659            status_code: 0b1100_0011, // Bit 0, 1, 6, 7
1660            ..Default::default()
1661        };
1662        assert!(state_multiple.is_voltage_low());
1663        assert!(state_multiple.is_motor_over_temp());
1664        assert!(state_multiple.is_enabled());
1665        assert!(state_multiple.is_homed());
1666        assert!(!state_multiple.is_over_current());
1667    }
1668
1669    #[test]
1670    fn test_gripper_state_is_moving() {
1671        // 静止状态(变化小于阈值)
1672        let state_stationary = GripperState {
1673            travel: 50.0,
1674            last_travel: 50.05, // 变化 0.05mm < 0.1mm
1675            ..Default::default()
1676        };
1677        assert!(!state_stationary.is_moving());
1678
1679        // 运动状态(变化超过阈值)
1680        let state_moving = GripperState {
1681            travel: 50.0,
1682            last_travel: 50.2, // 变化 0.2mm > 0.1mm
1683            ..Default::default()
1684        };
1685        assert!(state_moving.is_moving());
1686
1687        // 反向运动
1688        let state_moving_backward = GripperState {
1689            travel: 50.0,
1690            last_travel: 49.8, // 变化 0.2mm > 0.1mm
1691            ..Default::default()
1692        };
1693        assert!(state_moving_backward.is_moving());
1694    }
1695
1696    #[test]
1697    fn test_gripper_state_clone() {
1698        let state = GripperState {
1699            hardware_timestamp_us: 1000,
1700            system_timestamp_us: 2000,
1701            travel: 50.5,
1702            torque: 2.5,
1703            status_code: 0b1100_0011,
1704            last_travel: 50.0,
1705        };
1706        let cloned = state.clone();
1707        assert_eq!(state.hardware_timestamp_us, cloned.hardware_timestamp_us);
1708        assert_eq!(state.system_timestamp_us, cloned.system_timestamp_us);
1709        assert_eq!(state.travel, cloned.travel);
1710        assert_eq!(state.torque, cloned.torque);
1711        assert_eq!(state.status_code, cloned.status_code);
1712        assert_eq!(state.last_travel, cloned.last_travel);
1713        assert_eq!(state.is_voltage_low(), cloned.is_voltage_low());
1714        assert_eq!(state.is_moving(), cloned.is_moving());
1715    }
1716
1717    #[test]
1718    fn test_robot_control_state_default() {
1719        let state = RobotControlState::default();
1720        assert_eq!(state.hardware_timestamp_us, 0);
1721        assert_eq!(state.system_timestamp_us, 0);
1722        assert_eq!(state.control_mode, 0);
1723        assert_eq!(state.robot_status, 0);
1724        assert_eq!(state.fault_angle_limit_mask, 0);
1725        assert_eq!(state.fault_comm_error_mask, 0);
1726        assert_eq!(state.feedback_counter, 0);
1727        assert!(!state.is_enabled);
1728    }
1729
1730    #[test]
1731    fn test_robot_control_state_is_angle_limit() {
1732        // 测试单个关节角度超限位
1733        let state_j1 = RobotControlState {
1734            fault_angle_limit_mask: 0b0000_0001, // J1
1735            ..Default::default()
1736        };
1737        assert!(state_j1.is_angle_limit(0));
1738        assert!(!state_j1.is_angle_limit(1));
1739        assert!(!state_j1.is_angle_limit(5));
1740
1741        // 测试多个关节角度超限位
1742        // 0b0011_0001 = Bit 0, 5, 6 为 1,对应 J1, J6, J7(但J7不存在,所以只有J1和J6)
1743        // 实际上应该是 0b0010_0001 = Bit 0, 5 为 1,对应 J1, J6
1744        let state_multiple = RobotControlState {
1745            fault_angle_limit_mask: 0b0010_0001, // J1 (Bit 0), J6 (Bit 5)
1746            ..Default::default()
1747        };
1748        assert!(state_multiple.is_angle_limit(0)); // J1
1749        assert!(!state_multiple.is_angle_limit(1)); // J2
1750        assert!(!state_multiple.is_angle_limit(2)); // J3
1751        assert!(!state_multiple.is_angle_limit(3)); // J4
1752        assert!(!state_multiple.is_angle_limit(4)); // J5
1753        assert!(state_multiple.is_angle_limit(5)); // J6
1754
1755        // 测试边界情况
1756        assert!(!state_j1.is_angle_limit(6)); // 超出范围
1757        assert!(!state_j1.is_angle_limit(100)); // 超出范围
1758    }
1759
1760    #[test]
1761    fn test_robot_control_state_is_comm_error() {
1762        // 测试单个关节通信异常
1763        let state_j3 = RobotControlState {
1764            fault_comm_error_mask: 0b0000_0100, // J3
1765            ..Default::default()
1766        };
1767        assert!(!state_j3.is_comm_error(0));
1768        assert!(!state_j3.is_comm_error(1));
1769        assert!(state_j3.is_comm_error(2));
1770        assert!(!state_j3.is_comm_error(3));
1771
1772        // 测试所有关节通信异常
1773        let state_all = RobotControlState {
1774            fault_comm_error_mask: 0b0011_1111, // J1-J6
1775            ..Default::default()
1776        };
1777        for i in 0..6 {
1778            assert!(state_all.is_comm_error(i));
1779        }
1780
1781        // 测试边界情况
1782        assert!(!state_j3.is_comm_error(6)); // 超出范围
1783    }
1784
1785    #[test]
1786    fn test_robot_control_state_clone() {
1787        let state = RobotControlState {
1788            hardware_timestamp_us: 1000,
1789            system_timestamp_us: 2000,
1790            control_mode: 1,
1791            robot_status: 2,
1792            move_mode: 3,
1793            teach_status: 4,
1794            motion_status: 5,
1795            trajectory_point_index: 10,
1796            fault_angle_limit_mask: 0b0011_0001,
1797            fault_comm_error_mask: 0b0000_0100,
1798            is_enabled: true,
1799            feedback_counter: 5,
1800        };
1801        let cloned = state.clone();
1802        assert_eq!(state.hardware_timestamp_us, cloned.hardware_timestamp_us);
1803        assert_eq!(state.control_mode, cloned.control_mode);
1804        assert_eq!(state.fault_angle_limit_mask, cloned.fault_angle_limit_mask);
1805        assert_eq!(state.fault_comm_error_mask, cloned.fault_comm_error_mask);
1806        assert_eq!(state.is_enabled, cloned.is_enabled);
1807        assert_eq!(state.is_angle_limit(0), cloned.is_angle_limit(0));
1808        assert_eq!(state.is_comm_error(2), cloned.is_comm_error(2));
1809    }
1810
1811    #[test]
1812    fn test_piper_context_gripper_and_robot_control() {
1813        let ctx = PiperContext::new();
1814
1815        // 验证 gripper 字段存在且为默认值
1816        let gripper = ctx.gripper.load();
1817        assert_eq!(gripper.hardware_timestamp_us, 0);
1818        assert_eq!(gripper.travel, 0.0);
1819        assert_eq!(gripper.status_code, 0);
1820
1821        // 验证 robot_control 字段存在且为默认值
1822        let robot_control = ctx.robot_control.load();
1823        assert_eq!(robot_control.hardware_timestamp_us, 0);
1824        assert_eq!(robot_control.control_mode, 0);
1825        assert_eq!(robot_control.fault_angle_limit_mask, 0);
1826        assert!(!robot_control.is_enabled);
1827    }
1828
1829    // ============================================================
1830    // 测试新状态结构:JointDriverLowSpeedState
1831    // ============================================================
1832
1833    #[test]
1834    fn test_joint_driver_low_speed_state_default() {
1835        let state = JointDriverLowSpeedState::default();
1836        assert_eq!(state.hardware_timestamp_us, 0);
1837        assert_eq!(state.system_timestamp_us, 0);
1838        assert_eq!(state.motor_temps, [0.0; 6]);
1839        assert_eq!(state.driver_temps, [0.0; 6]);
1840        assert_eq!(state.joint_voltage, [0.0; 6]);
1841        assert_eq!(state.joint_bus_current, [0.0; 6]);
1842        assert_eq!(state.driver_voltage_low_mask, 0);
1843        assert_eq!(state.valid_mask, 0);
1844    }
1845
1846    #[test]
1847    fn test_joint_driver_low_speed_state_is_fully_valid() {
1848        // 完整状态(所有6个关节都已更新)
1849        let state_complete = JointDriverLowSpeedState {
1850            valid_mask: 0b111111, // Bit 0-5 全部为 1
1851            ..Default::default()
1852        };
1853        assert!(state_complete.is_fully_valid());
1854
1855        // 不完整状态(只有部分关节更新)
1856        let state_incomplete = JointDriverLowSpeedState {
1857            valid_mask: 0b001111, // 只有 Bit 0-3
1858            ..Default::default()
1859        };
1860        assert!(!state_incomplete.is_fully_valid());
1861    }
1862
1863    #[test]
1864    fn test_joint_driver_low_speed_state_missing_joints() {
1865        // 完整状态
1866        let state_complete = JointDriverLowSpeedState {
1867            valid_mask: 0b111111,
1868            ..Default::default()
1869        };
1870        assert_eq!(state_complete.missing_joints(), Vec::<usize>::new());
1871
1872        // 缺少 J1 和 J6
1873        let state_missing = JointDriverLowSpeedState {
1874            valid_mask: 0b0011110, // Bit 1-4 有,Bit 0 和 5 没有
1875            ..Default::default()
1876        };
1877        let missing = state_missing.missing_joints();
1878        assert_eq!(missing.len(), 2);
1879        assert!(missing.contains(&0));
1880        assert!(missing.contains(&5));
1881    }
1882
1883    #[test]
1884    fn test_joint_driver_low_speed_state_status_flags() {
1885        // 测试单个关节的状态标志
1886        let state_j1_voltage_low = JointDriverLowSpeedState {
1887            driver_voltage_low_mask: 0b0000_0001, // J1
1888            ..Default::default()
1889        };
1890        assert!(state_j1_voltage_low.is_voltage_low(0));
1891        assert!(!state_j1_voltage_low.is_voltage_low(1));
1892
1893        let state_j3_motor_over_temp = JointDriverLowSpeedState {
1894            driver_motor_over_temp_mask: 0b0000_0100, // J3
1895            ..Default::default()
1896        };
1897        assert!(state_j3_motor_over_temp.is_motor_over_temp(2));
1898        assert!(!state_j3_motor_over_temp.is_motor_over_temp(0));
1899
1900        let state_j6_over_current = JointDriverLowSpeedState {
1901            driver_over_current_mask: 0b0010_0000, // J6
1902            ..Default::default()
1903        };
1904        assert!(state_j6_over_current.is_over_current(5));
1905        assert!(!state_j6_over_current.is_over_current(0));
1906
1907        // 测试多个关节同时设置
1908        let state_multiple = JointDriverLowSpeedState {
1909            driver_voltage_low_mask: 0b0010_0001, // J1, J6
1910            driver_enabled_mask: 0b111111,        // 所有关节使能
1911            ..Default::default()
1912        };
1913        assert!(state_multiple.is_voltage_low(0));
1914        assert!(!state_multiple.is_voltage_low(1));
1915        assert!(state_multiple.is_voltage_low(5));
1916        assert!(state_multiple.is_enabled(0));
1917        assert!(state_multiple.is_enabled(5));
1918    }
1919
1920    #[test]
1921    fn test_joint_driver_low_speed_state_all_status_methods() {
1922        let state = JointDriverLowSpeedState {
1923            driver_voltage_low_mask: 0b0000_0001,          // J1
1924            driver_motor_over_temp_mask: 0b0000_0010,      // J2
1925            driver_over_current_mask: 0b0000_0100,         // J3
1926            driver_over_temp_mask: 0b0000_1000,            // J4
1927            driver_collision_protection_mask: 0b0001_0000, // J5
1928            driver_error_mask: 0b0010_0000,                // J6
1929            driver_enabled_mask: 0b111111,                 // 所有关节使能
1930            driver_stall_protection_mask: 0b0000_0001,     // J1
1931            ..Default::default()
1932        };
1933
1934        assert!(state.is_voltage_low(0));
1935        assert!(state.is_motor_over_temp(1));
1936        assert!(state.is_over_current(2));
1937        assert!(state.is_driver_over_temp(3));
1938        assert!(state.is_collision_protection(4));
1939        assert!(state.is_driver_error(5));
1940        assert!(state.is_enabled(0));
1941        assert!(state.is_enabled(5));
1942        assert!(state.is_stall_protection(0));
1943    }
1944
1945    #[test]
1946    fn test_joint_driver_low_speed_state_clone() {
1947        let state = JointDriverLowSpeedState {
1948            hardware_timestamp_us: 1000,
1949            system_timestamp_us: 2000,
1950            motor_temps: [25.0, 26.0, 27.0, 28.0, 29.0, 30.0],
1951            driver_temps: [35.0, 36.0, 37.0, 38.0, 39.0, 40.0],
1952            joint_voltage: [24.0, 24.1, 24.2, 24.3, 24.4, 24.5],
1953            joint_bus_current: [1.0, 1.1, 1.2, 1.3, 1.4, 1.5],
1954            driver_voltage_low_mask: 0b0000_0001,
1955            driver_motor_over_temp_mask: 0b0000_0010,
1956            driver_over_current_mask: 0b0000_0100,
1957            driver_over_temp_mask: 0b0000_1000,
1958            driver_collision_protection_mask: 0b0001_0000,
1959            driver_error_mask: 0b0010_0000,
1960            driver_enabled_mask: 0b111111,
1961            driver_stall_protection_mask: 0b0000_0001,
1962            hardware_timestamps: [100, 200, 300, 400, 500, 600],
1963            system_timestamps: [1100, 1200, 1300, 1400, 1500, 1600],
1964            valid_mask: 0b111111,
1965        };
1966        let cloned = state.clone();
1967        assert_eq!(state.hardware_timestamp_us, cloned.hardware_timestamp_us);
1968        assert_eq!(state.motor_temps, cloned.motor_temps);
1969        assert_eq!(
1970            state.driver_voltage_low_mask,
1971            cloned.driver_voltage_low_mask
1972        );
1973        assert_eq!(state.valid_mask, cloned.valid_mask);
1974        assert_eq!(state.is_fully_valid(), cloned.is_fully_valid());
1975        assert_eq!(state.is_voltage_low(0), cloned.is_voltage_low(0));
1976    }
1977
1978    #[test]
1979    fn test_piper_context_joint_driver_low_speed() {
1980        let ctx = PiperContext::new();
1981
1982        // 验证 joint_driver_low_speed 字段存在且为默认值
1983        let state = ctx.joint_driver_low_speed.load();
1984        assert_eq!(state.hardware_timestamp_us, 0);
1985        assert_eq!(state.motor_temps, [0.0; 6]);
1986        assert_eq!(state.driver_voltage_low_mask, 0);
1987        assert_eq!(state.valid_mask, 0);
1988    }
1989
1990    // ============================================================
1991    // 测试新状态结构:CollisionProtectionState
1992    // ============================================================
1993
1994    #[test]
1995    fn test_collision_protection_state_default() {
1996        let state = CollisionProtectionState::default();
1997        assert_eq!(state.hardware_timestamp_us, 0);
1998        assert_eq!(state.system_timestamp_us, 0);
1999        assert_eq!(state.protection_levels, [0; 6]);
2000    }
2001
2002    #[test]
2003    fn test_collision_protection_state_clone() {
2004        let state = CollisionProtectionState {
2005            hardware_timestamp_us: 1000,
2006            system_timestamp_us: 2000,
2007            protection_levels: [5, 5, 5, 4, 4, 4],
2008        };
2009        let cloned = state.clone();
2010        assert_eq!(state.hardware_timestamp_us, cloned.hardware_timestamp_us);
2011        assert_eq!(state.system_timestamp_us, cloned.system_timestamp_us);
2012        assert_eq!(state.protection_levels, cloned.protection_levels);
2013    }
2014
2015    #[test]
2016    fn test_collision_protection_state_protection_levels() {
2017        // 测试不同保护等级
2018        let state_all_zero = CollisionProtectionState {
2019            protection_levels: [0; 6], // 所有关节不检测碰撞
2020            ..Default::default()
2021        };
2022        assert_eq!(state_all_zero.protection_levels, [0; 6]);
2023
2024        let state_mixed = CollisionProtectionState {
2025            protection_levels: [8, 7, 6, 5, 4, 3], // 不同等级
2026            ..Default::default()
2027        };
2028        assert_eq!(state_mixed.protection_levels[0], 8);
2029        assert_eq!(state_mixed.protection_levels[5], 3);
2030    }
2031
2032    #[test]
2033    fn test_piper_context_collision_protection() {
2034        let ctx = PiperContext::new();
2035
2036        // 验证 collision_protection 字段存在且为默认值
2037        let state = ctx.collision_protection.read().unwrap();
2038        assert_eq!(state.hardware_timestamp_us, 0);
2039        assert_eq!(state.system_timestamp_us, 0);
2040        assert_eq!(state.protection_levels, [0; 6]);
2041    }
2042
2043    // ============================================================
2044    // 测试新状态结构:JointLimitConfigState
2045    // ============================================================
2046
2047    #[test]
2048    fn test_joint_limit_config_state_default() {
2049        let state = JointLimitConfigState::default();
2050        assert_eq!(state.last_update_hardware_timestamp_us, 0);
2051        assert_eq!(state.last_update_system_timestamp_us, 0);
2052        assert_eq!(state.joint_limits_max, [0.0; 6]);
2053        assert_eq!(state.joint_limits_min, [0.0; 6]);
2054        assert_eq!(state.joint_max_velocity, [0.0; 6]);
2055        assert_eq!(state.joint_update_hardware_timestamps, [0; 6]);
2056        assert_eq!(state.joint_update_system_timestamps, [0; 6]);
2057        assert_eq!(state.valid_mask, 0);
2058    }
2059
2060    #[test]
2061    fn test_joint_limit_config_state_is_fully_valid() {
2062        // 完整状态(所有6个关节都已更新)
2063        let state_complete = JointLimitConfigState {
2064            valid_mask: 0b111111, // Bit 0-5 全部为 1
2065            ..Default::default()
2066        };
2067        assert!(state_complete.is_fully_valid());
2068
2069        // 不完整状态(只有部分关节更新)
2070        let state_incomplete = JointLimitConfigState {
2071            valid_mask: 0b001111, // 只有 Bit 0-3
2072            ..Default::default()
2073        };
2074        assert!(!state_incomplete.is_fully_valid());
2075    }
2076
2077    #[test]
2078    fn test_joint_limit_config_state_missing_joints() {
2079        // 完整状态
2080        let state_complete = JointLimitConfigState {
2081            valid_mask: 0b111111,
2082            ..Default::default()
2083        };
2084        assert_eq!(state_complete.missing_joints(), Vec::<usize>::new());
2085
2086        // 缺少 J1 和 J6
2087        let state_missing = JointLimitConfigState {
2088            valid_mask: 0b0011110, // Bit 1-4 有,Bit 0 和 5 没有
2089            ..Default::default()
2090        };
2091        let missing = state_missing.missing_joints();
2092        assert_eq!(missing.len(), 2);
2093        assert!(missing.contains(&0));
2094        assert!(missing.contains(&5));
2095    }
2096
2097    #[test]
2098    fn test_joint_limit_config_state_clone() {
2099        let state = JointLimitConfigState {
2100            last_update_hardware_timestamp_us: 1000,
2101            last_update_system_timestamp_us: 2000,
2102            joint_limits_max: [1.57, 1.57, 1.57, 1.57, 1.57, 1.57], // 90度 = π/2 弧度
2103            joint_limits_min: [-1.57, -1.57, -1.57, -1.57, -1.57, -1.57], // -90度
2104            joint_max_velocity: [PI, PI, PI, PI, PI, PI],           // 180度/s = π rad/s
2105            joint_update_hardware_timestamps: [100, 200, 300, 400, 500, 600],
2106            joint_update_system_timestamps: [1100, 1200, 1300, 1400, 1500, 1600],
2107            valid_mask: 0b111111,
2108        };
2109        let cloned = state.clone();
2110        assert_eq!(
2111            state.last_update_hardware_timestamp_us,
2112            cloned.last_update_hardware_timestamp_us
2113        );
2114        assert_eq!(state.joint_limits_max, cloned.joint_limits_max);
2115        assert_eq!(state.joint_limits_min, cloned.joint_limits_min);
2116        assert_eq!(state.joint_max_velocity, cloned.joint_max_velocity);
2117        assert_eq!(state.valid_mask, cloned.valid_mask);
2118        assert_eq!(state.is_fully_valid(), cloned.is_fully_valid());
2119    }
2120
2121    #[test]
2122    fn test_piper_context_joint_limit_config() {
2123        let ctx = PiperContext::new();
2124
2125        // 验证 joint_limit_config 字段存在且为默认值
2126        let state = ctx.joint_limit_config.read().unwrap();
2127        assert_eq!(state.last_update_hardware_timestamp_us, 0);
2128        assert_eq!(state.joint_limits_max, [0.0; 6]);
2129        assert_eq!(state.joint_limits_min, [0.0; 6]);
2130        assert_eq!(state.joint_max_velocity, [0.0; 6]);
2131        assert_eq!(state.valid_mask, 0);
2132    }
2133
2134    // ============================================================
2135    // 测试新状态结构:JointAccelConfigState
2136    // ============================================================
2137
2138    #[test]
2139    fn test_joint_accel_config_state_default() {
2140        let state = JointAccelConfigState::default();
2141        assert_eq!(state.last_update_hardware_timestamp_us, 0);
2142        assert_eq!(state.last_update_system_timestamp_us, 0);
2143        assert_eq!(state.max_acc_limits, [0.0; 6]);
2144        assert_eq!(state.joint_update_hardware_timestamps, [0; 6]);
2145        assert_eq!(state.joint_update_system_timestamps, [0; 6]);
2146        assert_eq!(state.valid_mask, 0);
2147    }
2148
2149    #[test]
2150    fn test_joint_accel_config_state_is_fully_valid() {
2151        // 完整状态(所有6个关节都已更新)
2152        let state_complete = JointAccelConfigState {
2153            valid_mask: 0b111111, // Bit 0-5 全部为 1
2154            ..Default::default()
2155        };
2156        assert!(state_complete.is_fully_valid());
2157
2158        // 不完整状态(只有部分关节更新)
2159        let state_incomplete = JointAccelConfigState {
2160            valid_mask: 0b001111, // 只有 Bit 0-3
2161            ..Default::default()
2162        };
2163        assert!(!state_incomplete.is_fully_valid());
2164    }
2165
2166    #[test]
2167    fn test_joint_accel_config_state_missing_joints() {
2168        // 完整状态
2169        let state_complete = JointAccelConfigState {
2170            valid_mask: 0b111111,
2171            ..Default::default()
2172        };
2173        assert_eq!(state_complete.missing_joints(), Vec::<usize>::new());
2174
2175        // 缺少 J1 和 J6
2176        let state_missing = JointAccelConfigState {
2177            valid_mask: 0b0011110, // Bit 1-4 有,Bit 0 和 5 没有
2178            ..Default::default()
2179        };
2180        let missing = state_missing.missing_joints();
2181        assert_eq!(missing.len(), 2);
2182        assert!(missing.contains(&0));
2183        assert!(missing.contains(&5));
2184    }
2185
2186    #[test]
2187    fn test_joint_accel_config_state_clone() {
2188        let state = JointAccelConfigState {
2189            last_update_hardware_timestamp_us: 1000,
2190            last_update_system_timestamp_us: 2000,
2191            max_acc_limits: [10.0, 10.0, 10.0, 10.0, 10.0, 10.0], // 10 rad/s²
2192            joint_update_hardware_timestamps: [100, 200, 300, 400, 500, 600],
2193            joint_update_system_timestamps: [1100, 1200, 1300, 1400, 1500, 1600],
2194            valid_mask: 0b111111,
2195        };
2196        let cloned = state.clone();
2197        assert_eq!(
2198            state.last_update_hardware_timestamp_us,
2199            cloned.last_update_hardware_timestamp_us
2200        );
2201        assert_eq!(state.max_acc_limits, cloned.max_acc_limits);
2202        assert_eq!(state.valid_mask, cloned.valid_mask);
2203        assert_eq!(state.is_fully_valid(), cloned.is_fully_valid());
2204    }
2205
2206    #[test]
2207    fn test_piper_context_joint_accel_config() {
2208        let ctx = PiperContext::new();
2209
2210        // 验证 joint_accel_config 字段存在且为默认值
2211        let state = ctx.joint_accel_config.read().unwrap();
2212        assert_eq!(state.last_update_hardware_timestamp_us, 0);
2213        assert_eq!(state.max_acc_limits, [0.0; 6]);
2214        assert_eq!(state.valid_mask, 0);
2215    }
2216
2217    // ============================================================
2218    // 测试新状态结构:EndLimitConfigState
2219    // ============================================================
2220
2221    #[test]
2222    fn test_end_limit_config_state_default() {
2223        let state = EndLimitConfigState::default();
2224        assert_eq!(state.last_update_hardware_timestamp_us, 0);
2225        assert_eq!(state.last_update_system_timestamp_us, 0);
2226        assert_eq!(state.max_end_linear_velocity, 0.0);
2227        assert_eq!(state.max_end_angular_velocity, 0.0);
2228        assert_eq!(state.max_end_linear_accel, 0.0);
2229        assert_eq!(state.max_end_angular_accel, 0.0);
2230        assert!(!state.is_valid);
2231    }
2232
2233    #[test]
2234    fn test_end_limit_config_state_clone() {
2235        let state = EndLimitConfigState {
2236            last_update_hardware_timestamp_us: 1000,
2237            last_update_system_timestamp_us: 2000,
2238            max_end_linear_velocity: 1.0,  // 1 m/s
2239            max_end_angular_velocity: 2.0, // 2 rad/s
2240            max_end_linear_accel: 0.5,     // 0.5 m/s²
2241            max_end_angular_accel: 1.5,    // 1.5 rad/s²
2242            is_valid: true,
2243        };
2244        let cloned = state.clone();
2245        assert_eq!(
2246            state.last_update_hardware_timestamp_us,
2247            cloned.last_update_hardware_timestamp_us
2248        );
2249        assert_eq!(
2250            state.max_end_linear_velocity,
2251            cloned.max_end_linear_velocity
2252        );
2253        assert_eq!(
2254            state.max_end_angular_velocity,
2255            cloned.max_end_angular_velocity
2256        );
2257        assert_eq!(state.max_end_linear_accel, cloned.max_end_linear_accel);
2258        assert_eq!(state.max_end_angular_accel, cloned.max_end_angular_accel);
2259        assert_eq!(state.is_valid, cloned.is_valid);
2260    }
2261
2262    #[test]
2263    fn test_piper_context_end_limit_config() {
2264        let ctx = PiperContext::new();
2265
2266        // 验证 end_limit_config 字段存在且为默认值
2267        let state = ctx.end_limit_config.read().unwrap();
2268        assert_eq!(state.last_update_hardware_timestamp_us, 0);
2269        assert_eq!(state.max_end_linear_velocity, 0.0);
2270        assert_eq!(state.max_end_angular_velocity, 0.0);
2271        assert_eq!(state.max_end_linear_accel, 0.0);
2272        assert_eq!(state.max_end_angular_accel, 0.0);
2273        assert!(!state.is_valid);
2274    }
2275
2276    // ============================================================
2277    // 测试固件版本状态:FirmwareVersionState
2278    // ============================================================
2279
2280    #[test]
2281    fn test_firmware_version_state_default() {
2282        let state = FirmwareVersionState::default();
2283        assert_eq!(state.hardware_timestamp_us, 0);
2284        assert_eq!(state.system_timestamp_us, 0);
2285        assert!(state.firmware_data.is_empty());
2286        assert!(!state.is_complete);
2287        assert!(state.version_string.is_none());
2288    }
2289
2290    #[test]
2291    fn test_firmware_version_state_clear() {
2292        let mut state = FirmwareVersionState {
2293            hardware_timestamp_us: 1000,
2294            system_timestamp_us: 2000,
2295            firmware_data: vec![b'S', b'-', b'V', b'1', b'.', b'6', b'-', b'3'],
2296            is_complete: true,
2297            version_string: Some("S-V1.6-3".to_string()),
2298        };
2299
2300        state.clear();
2301
2302        assert_eq!(state.hardware_timestamp_us, 0);
2303        assert_eq!(state.system_timestamp_us, 0);
2304        assert!(state.firmware_data.is_empty());
2305        assert!(!state.is_complete);
2306        assert!(state.version_string.is_none());
2307    }
2308
2309    #[test]
2310    fn test_firmware_version_state_check_completeness() {
2311        // 测试:没有 S-V 标记
2312        let mut state = FirmwareVersionState {
2313            firmware_data: b"Some data".to_vec(),
2314            ..Default::default()
2315        };
2316        assert!(!state.check_completeness());
2317        assert!(!state.is_complete);
2318
2319        // 测试:有 S-V 标记但数据不足 8 字节
2320        state.firmware_data = b"S-V1.6".to_vec();
2321        assert!(!state.check_completeness());
2322        assert!(!state.is_complete);
2323
2324        // 测试:有 S-V 标记且数据足够(正好 8 字节)
2325        state.firmware_data = b"S-V1.6-3".to_vec();
2326        assert!(state.check_completeness());
2327        assert!(state.is_complete);
2328
2329        // 测试:有 S-V 标记且数据足够(超过 8 字节)
2330        state.firmware_data = b"Prefix S-V1.6-3\nSuffix".to_vec();
2331        assert!(state.check_completeness());
2332        assert!(state.is_complete);
2333    }
2334
2335    #[test]
2336    fn test_firmware_version_state_parse_version() {
2337        // 测试:成功解析版本
2338        let mut state = FirmwareVersionState {
2339            firmware_data: b"Some prefix S-V1.6-3\nOther data".to_vec(),
2340            ..Default::default()
2341        };
2342        let version = state.parse_version();
2343        assert_eq!(version, Some("S-V1.6-3".to_string()));
2344        assert_eq!(state.version_string, Some("S-V1.6-3".to_string()));
2345        assert!(state.is_complete);
2346
2347        // 测试:未找到版本
2348        state.firmware_data = b"Some data without version".to_vec();
2349        let version = state.parse_version();
2350        assert_eq!(version, None);
2351        assert!(state.version_string.is_none());
2352        assert!(!state.is_complete);
2353    }
2354
2355    #[test]
2356    fn test_firmware_version_state_version_string() {
2357        let mut state = FirmwareVersionState::default();
2358
2359        // 测试:未解析时返回 None
2360        assert!(state.version_string().is_none());
2361
2362        // 测试:解析后可以获取版本字符串
2363        state.firmware_data = b"S-V1.6-3".to_vec();
2364        state.parse_version();
2365        assert_eq!(state.version_string(), Some(&"S-V1.6-3".to_string()));
2366    }
2367
2368    #[test]
2369    fn test_piper_context_firmware_version() {
2370        let ctx = PiperContext::new();
2371
2372        // 验证 firmware_version 字段存在且为默认值
2373        let state = ctx.firmware_version.read().unwrap();
2374        assert_eq!(state.hardware_timestamp_us, 0);
2375        assert_eq!(state.system_timestamp_us, 0);
2376        assert!(state.firmware_data.is_empty());
2377        assert!(!state.is_complete);
2378        assert!(state.version_string.is_none());
2379    }
2380}