use piper_sdk::can::{CanAdapter, CanError, PiperFrame};
use piper_sdk::driver::*;
use std::time::Instant;
fn is_ci_env() -> bool {
std::env::var("CI").is_ok()
|| std::env::var("GITHUB_ACTIONS").is_ok()
|| std::env::var("GITLAB_CI").is_ok()
|| std::env::var("CIRCLECI").is_ok()
|| std::env::var("TRAVIS").is_ok()
|| std::env::var("APPVEYOR").is_ok()
}
struct MockCanAdapter;
impl CanAdapter for MockCanAdapter {
fn send(&mut self, _frame: PiperFrame) -> Result<(), CanError> {
Ok(())
}
fn receive(&mut self) -> Result<PiperFrame, CanError> {
Err(CanError::Timeout)
}
}
#[test]
fn test_high_frequency_read_performance() {
let mock_can = MockCanAdapter;
let piper = Piper::new(mock_can, None).unwrap();
let start = Instant::now();
let mut count = 0;
while start.elapsed().as_millis() < 1000 {
let _state = piper.get_motion_state();
count += 1;
}
let elapsed = start.elapsed();
let hz = count as f64 / elapsed.as_secs_f64();
println!(
"High frequency read: {} calls in {:?} ({:.1} Hz)",
count, elapsed, hz
);
assert!(hz >= 450.0, "Failed to achieve 450 Hz: {:.1} Hz", hz);
let avg_latency_us = elapsed.as_micros() as f64 / count as f64;
let threshold_us = if is_ci_env() { 2500.0 * 5.0 } else { 2500.0 };
assert!(
avg_latency_us < threshold_us,
"Average latency too high: {:.1} μs (threshold: {:.1} μs, CI环境已放宽)",
avg_latency_us,
threshold_us
);
}
#[test]
fn test_lock_free_read_performance() {
let mock_can = MockCanAdapter;
let piper = Piper::new(mock_can, None).unwrap();
let start = Instant::now();
let mut count = 0;
while start.elapsed().as_millis() < 100 {
let _joint_pos = piper.get_joint_position();
let _end_pose = piper.get_end_pose();
let _joint = piper.get_joint_dynamic();
let _control = piper.get_robot_control();
let _gripper = piper.get_gripper();
count += 1;
}
let elapsed = start.elapsed();
let ops_per_sec = (count as f64) / elapsed.as_secs_f64();
println!(
"Lock-free read: {} operations in {:?} ({:.0} ops/s)",
count * 3,
elapsed,
ops_per_sec * 3.0
);
assert!(
ops_per_sec >= 10000.0,
"Lock-free read too slow: {:.0} ops/s",
ops_per_sec
);
}