use haply::{ device_model::{ DampingConfig, Force, ForceInput }, HaplyDevice };
use std::io::Write;
use std::time::{ Duration, Instant };
use tokio::time::interval;
const HTTP_BASE: &str = "http://localhost:10001";
const WS_URL: &str = "ws://localhost:10001/";
const DAMPING_BASE: f32 = 6.0;
const DAMPING_AMPLITUDE: f32 = 4.0;
const DAMPING_FREQ_HZ: f64 = 0.5;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let mut device = HaplyDevice::new(HTTP_BASE, WS_URL).await?;
tokio::time::sleep(Duration::from_millis(300)).await;
let state = device.read_state().await?;
let inv = state.inverse3.first().ok_or("No Inverse3 device connected")?;
let id = inv.device_id.clone();
println!("Using Inverse3 device: {}", id);
println!(
"Damping oscillates {:.1}–{:.1} N·s/m at {:.1} Hz (Ctrl+C to stop)",
DAMPING_BASE - DAMPING_AMPLITUDE,
DAMPING_BASE + DAMPING_AMPLITUDE,
DAMPING_FREQ_HZ
);
device.update_force(
vec![ForceInput { device_id: id.clone(), forces: Force { x: 0.0, y: 0.0, z: 0.0 } }],
Some(true),
Some(true)
).await?;
let start = Instant::now();
let mut ticker = interval(Duration::from_millis(1)); let mut print_counter: u32 = 0;
loop {
ticker.tick().await;
let t = start.elapsed().as_secs_f64();
let scalar =
DAMPING_BASE +
DAMPING_AMPLITUDE * ((2.0 * std::f64::consts::PI * DAMPING_FREQ_HZ * t).sin() as f32);
device.set_damping(&id, DampingConfig { scalar: Some(scalar), vector: None }, None).await?;
device.update_force(
vec![ForceInput { device_id: id.clone(), forces: Force { x: 0.0, y: 0.0, z: 0.0 } }],
Some(true),
None
).await?;
device.send_command().await?;
print_counter += 1;
if print_counter >= 100 {
print_counter = 0;
let state = device.read_state().await?;
if let Some(inv) = state.inverse3.first() {
let vel = inv.state.cursor_velocity.unwrap_or_default();
let speed = (vel.x * vel.x + vel.y * vel.y + vel.z * vel.z).sqrt();
print!("\rdamping={:.3} N·s/m speed={:.4} m/s t={:.2}s ", scalar, speed, t);
std::io::stdout().flush().unwrap();
}
}
}
}