1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// P8: Time step bounds check
use crate::models::verdict::CheckResult;
/// Check that `delta_time` satisfies `0 < delta_time <= max_delta_time`.
///
/// A zero or negative time step is physically meaningless and indicates a
/// clock error or command replay. A step exceeding `max_delta_time` may cause
/// the controller to integrate beyond its stability margin.
pub fn check_delta_time(delta_time: f64, max_delta_time: f64) -> CheckResult {
if !delta_time.is_finite() || delta_time <= 0.0 {
return CheckResult {
name: "delta_time".to_string(),
category: "physics".to_string(),
passed: false,
details: format!(
"delta_time {} is not finite and positive (must be > 0)",
delta_time
),
};
}
// Guard against a misconfigured profile where max_delta_time is NaN or
// infinite — this is a profile error, not a command error. Report it
// distinctly so operators can identify and correct the profile.
if !max_delta_time.is_finite() {
return CheckResult {
name: "delta_time".to_string(),
category: "physics".to_string(),
passed: false,
details: format!(
"max_delta_time {} is not finite; profile configuration is invalid",
max_delta_time
),
};
}
if delta_time > max_delta_time {
return CheckResult {
name: "delta_time".to_string(),
category: "physics".to_string(),
passed: false,
details: format!(
"delta_time {:.9} s exceeds max_delta_time {:.9} s",
delta_time, max_delta_time
),
};
}
CheckResult {
name: "delta_time".to_string(),
category: "physics".to_string(),
passed: true,
details: format!("delta_time {:.9} s within bounds", delta_time),
}
}