High Performance Monotonic Clock for robotics
This crate provides a monotonic clock and a mockable clock for testing and replay. It has a wide range of support for robots running on OSes and bare metal.
It is no-std compatible with some limitations, see below.
Low level CPU counter implementations are provided for:
- x86-64
- arm64
- armv7
- risc-v
We also provide a TOV (Time Of Validity) enum for tagging sensor data.
It can fall back to the posix monotonic clock for other platforms (with std).
It has been created originally for the Copper runtime but can be perfectly used independently. See the main crate cu29 for more information about the overall Copper project.
Examples
Basic Clock Usage
use ;
// Create a new robot clock
let clock = new;
// Get the current time (returns CuTime, which is nanoseconds since clock start)
let now = clock.now;
println!; // Displays with appropriate units (ns, µs, ms, s, etc.)
// Get a less precise but faster time reading
let recent = clock.recent;
// Clock is cloneable and all clones share the same time reference
let clock_clone = clock.clone;
assert_eq!; // more or less :)
// Create a clock with a specific reference time
let ref_time_ns = 1_000_000_000; // 1 second
let clock_with_ref = from_ref_time;
Working with Time Durations
use ;
use Duration;
// Create durations
let duration1 = from;
let duration2 = from; // 500ms in nanoseconds
// Arithmetic operations
let sum = duration1 + duration2; // 600ms
let diff = duration2 - duration1; // 400ms
let scaled = duration1 * 2u32; // 200ms
let divided = duration2 / 5u32; // 100ms
// Display formatting automatically chooses appropriate units
println!; // "600.000 ms"
println!; // "1.000 h"
// Min/max operations
let min_duration = duration1.min;
let max_duration = duration1.max;
// Convert to standard Duration
let std_duration: Duration = duration1.into;
Mock Clock for Testing and Simulation
use ;
use Duration;
// Create a mock clock that you can control
let = mock;
// The clock starts at 0
assert_eq!;
// Advance the clock by specific amounts
mock_control.increment;
assert_eq!; // 100ms in nanoseconds
// Jump to absolute time values
mock_control.set_value; // 5 seconds
assert_eq!;
// You can also decrement (breaks monotonicity, use with caution)
mock_control.decrement;
assert_eq!; // 4 seconds
// Get current mock time directly from the mock controller
let current_mock_time = mock_control.now;
let current_raw_value = mock_control.value;
// All clones of the clock are synchronized with the mock
let clock_clone = clock.clone;
assert_eq!;
Time of Validity (Tov)
Tov represents when sensor data was actually valid, which is crucial for robotics applications:
use ;
use Duration;
let clock = new;
let current_time = clock.now;
// Single timestamp - most common case
let tov_single = Time;
// Time range - for sensors that collect data over time (e.g., lidar scans)
let tov_range = Range;
// No valid time - for error conditions or initialization
let tov_none = None;
// Converting from common types
let tov_from_option: Tov = Some.into;
let tov_from_duration: Tov = current_time.into;
// Pattern matching on Tov in algorithms
// Display Tov values with automatic formatting
println!; // "1.500 s"
println!; // "[1.500 s – 1.510 s]"
println!; // "None"
// Create time ranges from collections of timestamps
let timestamps = ;
let range_from_slice = from;
// range_from_slice.start = 100, range_from_slice.end = 150
Optional Time Values
use ;
// Efficient optional time representation (avoids 128-bit Option overhead)
let some_time = from;
let no_time = none;
// Check if time is present
if ! some_time.is_none
// Convert to/from standard Option
let std_option: = some_time.into;
let back_to_option_time: OptionCuTime = std_option.into;
// Display formatting
println!; // "1.000 µs"
println!; // "None"
Platform-Specific High-Performance Timing
The clock automatically uses the best available timing mechanism for your platform:
- x86-64: RDTSC instruction for sub-nanosecond precision
- ARM64: ARM generic timer counters
- ARM32: 64-bit ARM performance counters
- RISC-V: Cycle counter
- Other platforms: Falls back to system monotonic clock (std only)
use ;
// The clock automatically calibrates frequency at first use
let clock = new;
// For no-std environments, frequency calibration is simplified
// but still provides high precision timing suitable for robotics