cu-transform 0.9.1

A coordinate frame transformation library for copper-rs, similar to tf2 in ROS2
Documentation
# cu_transform

This library provides spatial transformation functionality for the Copper framework, including both pose (position and
orientation) transformations and velocity transformations.

## Features

- Efficient representation of 3D transformations using homogeneous matrices
- Time-stamped transforms for tracking movements through time
- Transform tree for managing parent-child relationships between coordinate frames
- Velocity transformations for motion planning and control
- High-performance caching for both transforms and velocity transforms
- Interpolation between transforms
- allocation free for real time operations

## Usage

### Transform Tree

The transform tree maintains a hierarchical relationship between coordinate frames:

```rust
use cu_transform::{StampedTransform, TransformTree, Transform3D};
use cu29::clock::CuDuration;

fn tree_lookup() {
    // Create a transform tree
    let mut tree = TransformTree::<f32>::new();

    // Add a transform from "world" to "robot"
    let world_to_robot = StampedTransform {
        transform: Transform3D::default(), // Identity transform
        stamp: CuDuration(1000),
        parent_frame: "world".try_into().expect("invalid name"),
        child_frame: "robot".try_into().expect("invalid name"),
    };
    tree.add_transform(world_to_robot).unwrap();

    // Look up transform
    let transform = tree.lookup_transform("world", "robot", CuDuration(1000)).unwrap();
}
```

### Velocity Transforms

The cu_transform library also supports calculating and transforming velocities:

```rust
use cu_transform::{VelocityTransform, TransformTree};
use cu29::clock::CuDuration;


fn velocity_lookup() {
    // Create and set up a transform tree with moving frames
    // ...

    // Look up velocity between frames at a specific time
    // This uses caching to speed up repeated lookups
    let velocity = tree.lookup_velocity("world", "robot", CuDuration(1500)).unwrap();

    // Access linear and angular components
    let linear_x = velocity.linear[0]; // Linear velocity in x direction (m/s)
    let angular_z = velocity.angular[2]; // Angular velocity around z axis (rad/s)

    // For unit-aware applications, use the unit methods
    let linear_vel = velocity.linear_velocity(); // Returns velocities with proper units
}
```

## Velocity Transformation

### Computing Velocity

Velocity is computed by differentiating transformations over time:

```rust
fn compute_velocity() {
    // Assuming we have two transforms at different times
    let velocity = transform2.compute_velocity(&transform1);
}
```

### Frame Transformation

Velocities can be transformed between coordinate frames:

```rust
use cu_transform::{transform_velocity, VelocityTransform, Transform3D};


fn frame_transformation() {
    // Velocity in frame A
    let velocity_a = VelocityTransform {
        linear: [1.0, 0.0, 0.0],  // 1 m/s in x direction
        angular: [0.0, 0.0, 0.5],  // 0.5 rad/s around z axis
    };

    // Transform from frame A to frame B
    let transform_a_to_b = Transform3D { /* ... */ };

    // Position where the velocity is measured
    let position = [0.0, 0.0, 0.0];

    // Transform velocity from frame A to frame B
    let velocity_b = transform_velocity(&velocity_a, &transform_a_to_b, &position);
}
```

## Technical Details

### Velocity Transform Implementation

The velocity transformation follows the standard rigid body motion equations:

1. Linear velocity transformation: v_b = R * v_a + ω × (R * p)
2. Angular velocity transformation: ω_b = R * ω_a

Where:

- v_a is the linear velocity in frame A
- ω_a is the angular velocity in frame A
- R is the rotation matrix from A to B
- p is the position vector where velocity is measured
- × is the cross product

### Transform Chain

When looking up velocity across multiple frames, the transform tree handles the chain of transformations properly,
accumulating both linear and angular velocities correctly.

### Caching Mechanism

Both transforms and velocity transforms utilize a high-performance caching system to accelerate repeated lookups:

```rust

fn caching_tree() {
    // Create a transform tree with custom cache settings
    let tree = TransformTree::<f32>::with_cache_settings(
        200,                   // Cache size (max number of entries)
        Duration::from_secs(5) // Cache entry lifetime
    );

    // Lookup operations use the cache automatically
    let velocity = tree.lookup_velocity("world", "robot", time);

    // Cache is automatically invalidated when:
    // - New transforms are added to the tree
    // - Cache entries exceed their age limit
    // - The cache reaches capacity (uses LRU eviction)

    // Clear the cache manually if needed
    tree.clear_cache();

    // The cache is cleaned automatically at regular intervals,
    // but you can trigger cleanup explicitly if needed
    tree.cleanup_cache();
}

```

The velocity cache significantly improves performance for:

- Real-time applications with frequent velocity lookups
- Applications with many coordinate frames
- Complex transform chains that would otherwise require expensive recalculation

The cache keys include frame IDs, timestamp, and a hash of the transform path, ensuring correctness when the transform
tree structure changes.