Crate openigtlink_rust

Crate openigtlink_rust 

Source
Expand description

OpenIGTLink Protocol Implementation in Rust

This library provides a Rust implementation of the OpenIGTLink protocol, which is an open network protocol for image-guided therapy environments.

§Features

  • Type-safe message handling - Leverages Rust’s type system for protocol correctness
  • Comprehensive message types - 21 message types fully implemented
  • Synchronous and asynchronous I/O - Works with both sync and async Rust
  • Full protocol compliance - OpenIGTLink Version 2 and 3
  • Memory safe - No buffer overflows or memory leaks
  • Zero-copy parsing - Efficient deserialization where possible

§Quick Start

§Basic Client-Server Example

Server:

use openigtlink_rust::io::IgtlServer;
use openigtlink_rust::protocol::types::StatusMessage;

let server = IgtlServer::bind("127.0.0.1:18944")?;
let mut client_conn = server.accept()?;

let status = StatusMessage::ok("Server ready");
client_conn.send(&status)?;

Client:

use openigtlink_rust::io::IgtlClient;
use openigtlink_rust::protocol::types::TransformMessage;

let mut client = IgtlClient::connect("127.0.0.1:18944")?;

let transform = TransformMessage::identity();
client.send(&transform)?;

let response = client.receive()?;

§Sending Medical Images

use openigtlink_rust::protocol::types::{ImageMessage, ScalarType};
use openigtlink_rust::io::IgtlClient;

let mut client = IgtlClient::connect("127.0.0.1:18944")?;

let mut image = ImageMessage::new();
image.set_dimensions([512, 512, 1]);
image.set_scalar_type(ScalarType::Uint8);
image.set_image_data(vec![0u8; 512 * 512]);

client.send(&image)?;

§Architecture

The library is organized into three main modules:

§Module Structure

  • protocol - Core protocol implementation

    • header - OpenIGTLink message header (58 bytes)
    • types - All 21 message type implementations
    • crc - CRC-64 checksum validation
  • io - Network I/O layer

    • IgtlClient - TCP client for sending/receiving messages
    • IgtlServer - TCP server for accepting connections
  • error - Error handling

    • IgtlError - Unified error type for all operations
    • Result<T> - Type alias for Result<T, IgtlError>

§Design Principles

  1. Type Safety: Each message type is a distinct Rust type
  2. Zero-cost Abstractions: Minimal runtime overhead
  3. Explicit Error Handling: All network and parsing errors are explicit
  4. Protocol Compliance: Strict adherence to OpenIGTLink specification

§Supported Message Types

This implementation includes all major OpenIGTLink message types:

  • Transform & Tracking: TRANSFORM, POSITION, QTDATA, TDATA
  • Medical Imaging: IMAGE, IMGMETA, LBMETA, COLORTABLE
  • Geometric Data: POINT, POLYDATA, TRAJECTORY
  • Sensor Data: SENSOR, NDARRAY
  • Communication: STATUS, CAPABILITY, STRING, COMMAND, BIND
  • Video Streaming: VIDEO, VIDEOMETA

§Choosing Message Types

§Transform & Tracking

  • TRANSFORM - Single 4x4 homogeneous transformation matrix

    • Use for: Robot end-effector pose, single tool tracking
    • Example: Surgical instrument position
  • TDATA - Array of transformation matrices with names

    • Use for: Multiple tracking tools simultaneously
    • Example: Tracking 5 surgical instruments at once
  • POSITION - 3D position only (no orientation)

    • Use for: Point cloud data, simplified tracking
    • Example: Marker positions without rotation
  • QTDATA - Position + Quaternion (alternative to TRANSFORM)

    • Use for: More compact rotation representation
    • Example: IMU sensor orientation

§Medical Imaging

  • IMAGE - 2D/3D medical image with metadata

    • Use for: CT, MRI, ultrasound images
    • Supports: 8/16-bit grayscale, RGB, RGBA
    • Example: Real-time ultrasound streaming
  • VIDEO - Real-time video frames

    • Use for: Endoscopic video, webcam feeds
    • Supports: MJPEG, H.264, raw formats
    • Example: Laparoscopic camera feed
  • IMGMETA - Metadata for multiple images

    • Use for: Image catalog, DICOM series info
    • Example: List of available CT slices

§Sensor Data

  • SENSOR - Multi-channel sensor readings

    • Use for: Force sensors, temperature arrays
    • Example: 6-axis force/torque sensor
  • NDARRAY - N-dimensional array data

    • Use for: Generic numerical data
    • Example: Spectrogram, multi-dimensional measurements

§Geometric Data

  • POINT - Collection of 3D points with attributes

    • Use for: Fiducial markers, anatomical landmarks
    • Example: Registration points for navigation
  • POLYDATA - 3D mesh with vertices and polygons

    • Use for: Organ surfaces, tumor boundaries
    • Example: Liver segmentation mesh
  • TRAJECTORY - Planned surgical paths

    • Use for: Needle insertion paths, biopsy planning
    • Example: Brain biopsy trajectory

§Communication

  • STATUS - Status/error messages

    • Use for: Operation success/failure notifications
    • Example: “Registration completed successfully”
  • STRING - Text messages

    • Use for: Logging, user messages
    • Example: “Patient positioned, ready to scan”
  • COMMAND - Remote procedure calls

    • Use for: Controlling remote devices
    • Example: “StartScanning”, “StopMotor”

§Examples

§Example 1: Sending Transform Data

use openigtlink_rust::io::IgtlClient;
use openigtlink_rust::protocol::types::TransformMessage;

let mut client = IgtlClient::connect("192.168.1.100:18944")?;

// Create transformation matrix (4x4)
let mut transform = TransformMessage::identity();
transform.set_device_name("RobotArm");

// Set translation (in mm)
transform.matrix[0][3] = 100.0; // X
transform.matrix[1][3] = 50.0;  // Y
transform.matrix[2][3] = 200.0; // Z

// Send to server
client.send(&transform)?;

§Example 2: Streaming Medical Images

use openigtlink_rust::io::IgtlClient;
use openigtlink_rust::protocol::types::{ImageMessage, ScalarType};

let mut client = IgtlClient::connect("localhost:18944")?;

// Simulate ultrasound image stream (640x480 grayscale)
for frame_num in 0..100 {
    let mut image = ImageMessage::new();
    image.set_device_name("UltrasoundProbe");
    image.set_dimensions([640, 480, 1]);
    image.set_scalar_type(ScalarType::Uint8);
    image.set_spacing([0.1, 0.1, 1.0]); // mm per pixel

    // Generate synthetic image data
    let image_data = vec![((frame_num % 256) as u8); 640 * 480];
    image.set_image_data(image_data);

    client.send(&image)?;
    std::thread::sleep(std::time::Duration::from_millis(33)); // ~30 fps
}

§Example 3: Multi-Channel Sensor Data

use openigtlink_rust::io::IgtlClient;
use openigtlink_rust::protocol::types::SensorMessage;

let mut client = IgtlClient::connect("localhost:18944")?;

// 6-axis force/torque sensor
let mut sensor = SensorMessage::new();
sensor.set_device_name("ForceSensor");

// Forces (Fx, Fy, Fz) and Torques (Tx, Ty, Tz)
let readings = vec![1.2, -0.5, 3.8, 0.1, 0.05, -0.2];
sensor.set_data(readings);
sensor.set_unit(0x0101); // Newton (force) + Newton-meter (torque)

client.send(&sensor)?;

§Example 4: Status Message Handling

use openigtlink_rust::io::IgtlServer;
use openigtlink_rust::protocol::types::StatusMessage;

let server = IgtlServer::bind("0.0.0.0:18944")?;
let mut client_conn = server.accept()?;

// Receive message
let message = client_conn.receive()?;

// Send acknowledgment
let status = StatusMessage::ok("Data received successfully");
client_conn.send(&status)?;

§Example 5: Error Handling and Recovery

use openigtlink_rust::io::IgtlClient;
use openigtlink_rust::protocol::types::TransformMessage;
use openigtlink_rust::IgtlError;

fn send_with_retry(addr: &str) -> Result<(), IgtlError> {
    let max_retries = 3;

    for attempt in 0..max_retries {
        match IgtlClient::connect(addr) {
            Ok(mut client) => {
                let transform = TransformMessage::identity();
                return client.send(&transform);
            }
            Err(e) if attempt < max_retries - 1 => {
                eprintln!("Connection failed (attempt {}): {}", attempt + 1, e);
                std::thread::sleep(std::time::Duration::from_secs(1));
                continue;
            }
            Err(e) => return Err(e),
        }
    }
    unreachable!()
}

§Error Handling

All operations return Result<T, IgtlError>. Common error types:

  • IoError - Network communication failures
  • InvalidHeader - Malformed message headers
  • CrcMismatch - Data corruption detected
  • UnsupportedMessage - Unknown message type
  • InvalidData - Invalid message body
use openigtlink_rust::io::IgtlClient;
use openigtlink_rust::IgtlError;

match IgtlClient::connect("localhost:18944") {
    Ok(client) => println!("Connected"),
    Err(IgtlError::IoError(e)) => eprintln!("Network error: {}", e),
    Err(e) => eprintln!("Other error: {}", e),
}

Re-exports§

pub use error::IgtlError;
pub use error::Result;

Modules§

compression
Message compression support for OpenIGTLink
error
Error types for OpenIGTLink protocol operations
io
Network I/O module for OpenIGTLink communication
protocol
OpenIGTLink protocol implementation module