Skip to main content

example/
example.rs

1//! Example: discover Enpose tracker devices on the local network, then
2//! stream live marker poses from the first one found and print them to the
3//! terminal.
4//!
5//! Run with: `cargo run --example example`
6//!
7//! The program first broadcasts a discovery request and lists every device
8//! that replies. It then opens a [`PoseStream`] to the first compatible
9//! device and prints each [`MarkerPose`] it receives for a few seconds
10//! before disconnecting (which happens automatically when the stream is
11//! dropped).
12
13use std::time::{Duration, Instant};
14
15use enpose_api::{DeviceDiscovery, PoseStream};
16
17/// How long to stream poses before exiting.
18const STREAM_DURATION: Duration = Duration::from_secs(10);
19
20fn main() -> std::io::Result<()> {
21    let devices = DeviceDiscovery::new().discover()?;
22
23    if devices.is_empty() {
24        println!("No Enpose devices found on the local network.");
25        return Ok(());
26    }
27
28    println!("Found {} device(s):", devices.len());
29    for device in &devices {
30        let status = if device.compatible {
31            "compatible"
32        } else {
33            "INCOMPATIBLE (protocol version mismatch)"
34        };
35        println!("  - {} (serial {}): {}", device.ip, device.serial, status);
36    }
37
38    // Pick the first compatible device to stream from.
39    let Some(device) = devices.iter().find(|d| d.compatible) else {
40        println!("No compatible device to stream poses from.");
41        return Ok(());
42    };
43
44    println!("\nStreaming poses from {} for {:?}...", device.ip, STREAM_DURATION);
45
46    // Threaded mode: a background thread receives and buffers poses, so none
47    // are missed regardless of how often we poll below.
48    let mut stream = PoseStream::from_device(device, true)?;
49
50    let start = Instant::now();
51    while start.elapsed() < STREAM_DURATION {
52        // Blocking receive: waits up to 3 s for a pose update, so no manual
53        // polling delay is needed.
54        for pose in stream.receive_pose_updates(true)? {
55            println!(
56                "  t={:>10}us marker {:>3}: pos=({:+.4}, {:+.4}, {:+.4}) rmse={:.4} sensors={}",
57                pose.timestamp,
58                pose.marker_id,
59                pose.x,
60                pose.y,
61                pose.z,
62                pose.position_rmse,
63                pose.sensors,
64            );
65        }
66    }
67
68    // `stream` is dropped here, which disconnects from the device.
69    Ok(())
70}