use haply::{ compute_total_force, device_model::*, Cube, HaplyDevice, Sphere };
use std::io::Write;
const USE_HTTP: bool = false;
const HTTP_BASE: &str = "http://localhost:10001";
const WS_URL: &str = "ws://localhost:10001/";
#[tokio::main]
async fn main() {
let mut device = HaplyDevice::new(HTTP_BASE, WS_URL).await.unwrap();
let configs = device.list_devices().await.unwrap_or_default();
if configs.is_empty() {
println!("No devices found. Exiting.");
return;
}
let first_id = configs[0].id().to_string();
println!("Using device: {}", first_id);
if !USE_HTTP {
let _ = device.configure_session(
SessionConfigure {
profile: Some(ProfileConfig {
name: "haptic_sample".to_string(),
required_version: Some(">=3.5".to_string()),
}),
basis: None,
serialization: None,
sdf: None,
},
Some(true)
).await;
}
let sphere = Sphere {
center: [0.0, -0.1, 0.18],
radius: 0.05,
stiffness: 500.0,
magnetism: 0.0,
damping: 0.1,
};
let _ = device.update_force(
vec![ForceInput { device_id: first_id.clone(), forces: Force { x: 0.0, y: 0.0, z: 0.0 } }],
Some(false),
Some(true)
).await;
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
let objects: Vec<Box<dyn haply::physics_model::PhysicalObject>> = vec![Box::new(sphere)];
println!("Running haptic loop (Ctrl+C to stop)...");
loop {
let state = device.read_state().await.unwrap();
let pos = state.inverse3
.first()
.and_then(|d| d.state.cursor_position)
.unwrap_or_default();
let total_force = compute_total_force(pos.into(), &objects);
print!(
"\rPos: ({:.4},{:.4},{:.4}) Force: ({:.4},{:.4},{:.4}) ",
pos.x,
pos.y,
pos.z,
total_force[0],
total_force[1],
total_force[2]
);
std::io::stdout().flush().unwrap();
let force = Force { x: total_force[0], y: total_force[1], z: total_force[2] };
let id = state.inverse3
.first()
.map(|d| d.device_id.clone())
.unwrap_or(first_id.clone());
let _ = device.update_force(
vec![ForceInput { device_id: id, forces: force }],
Some(true),
Some(true)
).await;
tokio::time::sleep(std::time::Duration::from_millis(1)).await;
}
}