A debug component for stress-testing the Proprioception segment of RobotStateMemory with high-frequency read and write operations.
Purpose
This component is designed to:
- Test the performance and concurrency handling of the RobotStateMemory Proprioception segment
- Generate mock joint data at configurable frequencies with extraFloats and extraLongs fields
- Perform high-frequency read and write operations with parallel threads
- Track and report statistics about operation success rates and throughput
- Validate mutex refactoring with concurrent read/write access patterns
Properties
| Property | Type | Default | Description |
p.robotName | string | "Armar6" | Name of the robot to test with |
p.numJoints | int | 30 | Number of mock joints to generate |
p.writeFrequencyHz | float | 100.0 | Frequency of write operations in Hz (0 = disabled) |
p.readFrequencyHz | float | 100.0 | Frequency of read operations in Hz (0 = disabled) |
p.numParallelReads | int | 1 | Number of parallel read threads (for testing shared mutexes) |
p.numParallelWrites | int | 1 | Number of parallel write threads (for testing concurrent writes) |
p.numExtraFloats | int | 10 | Number of extra float values to write per snapshot |
p.numExtraLongs | int | 10 | Number of extra long values to write per snapshot |
p.statisticsIntervalSec | float | 1.0 | How often to print statistics (in seconds) |
p.verboseLogging | bool | false | Enable verbose logging of each operation |
Usage
Starting the component
# Start with default settings (100 Hz read/write on Armar6)
./bin/ProprioceptionStressTest
# Custom robot and frequencies
./bin/ProprioceptionStressTest \
--p.robotName=Armar7 \
--p.writeFrequencyHz=500 \
--p.readFrequencyHz=500 \
--p.numJoints=50
# High-frequency stress test (1000 Hz)
./bin/ProprioceptionStressTest \
--p.writeFrequencyHz=1000 \
--p.readFrequencyHz=1000 \
--p.verboseLogging=false
# Write-only test (no reads)
./bin/ProprioceptionStressTest \
--p.writeFrequencyHz=200 \
--p.readFrequencyHz=0
# Read-only test (no writes)
./bin/ProprioceptionStressTest \
--p.writeFrequencyHz=0 \
--p.readFrequencyHz=500
# Parallel reads test (5 threads reading at 200 Hz each = 1000 reads/sec total)
./bin/ProprioceptionStressTest \
--p.readFrequencyHz=200 \
--p.numParallelReads=5 \
--p.writeFrequencyHz=100
# Parallel writes test (3 threads writing at 100 Hz each = 300 writes/sec total)
./bin/ProprioceptionStressTest \
--p.writeFrequencyHz=100 \
--p.numParallelWrites=3 \
--p.readFrequencyHz=0
# Maximum stress test (10 parallel readers + 5 parallel writers)
./bin/ProprioceptionStressTest \
--p.readFrequencyHz=100 \
--p.numParallelReads=10 \
--p.writeFrequencyHz=100 \
--p.numParallelWrites=5
# Test with many extra fields (stress test for larger data payloads)
./bin/ProprioceptionStressTestRun \
--p.numJoints=50 \
--p.numExtraFloats=100 \
--p.numExtraLongs=100 \
--p.writeFrequencyHz=100
# Minimal extra fields (testing baseline performance)
./bin/ProprioceptionStressTestRun \
--p.numExtraFloats=0 \
--p.numExtraLongs=0 \
--p.writeFrequencyHz=500
Example Output
========================================
ProprioceptionStressTest Statistics
========================================
Elapsed time: 5.03 s
Robot: Armar6
----------------------------------------
WRITE Operations:
Total writes: 503
Write errors: 0
Write rate: 100.00 ops/s
----------------------------------------
READ Operations:
Total reads: 503
Successful reads: 503
Failed reads: 0
Read rate: 100.00 ops/s
Success rate: 100.0 %
========================================
Requirements
- RobotStateMemory component must be running
- The component will automatically connect to the memory system
Testing Scenarios
Concurrency Testing
Single Instance with Parallel Threads (tests shared mutexes within one process):
# Test concurrent reads (perfect for shared mutex validation)
./bin/ProprioceptionStressTestRun \
--p.readFrequencyHz=200 \
--p.numParallelReads=10 \
--p.writeFrequencyHz=50
# Test concurrent writes (validates write locking)
./bin/ProprioceptionStressTestRun \
--p.writeFrequencyHz=100 \
--p.numParallelWrites=5 \
--p.readFrequencyHz=100
# Maximum stress: many readers + many writers simultaneously
./bin/ProprioceptionStressTestRun \
--p.readFrequencyHz=100 \
--p.numParallelReads=10 \
--p.writeFrequencyHz=50 \
--p.numParallelWrites=3
Multiple Instances (tests inter-process concurrency):
# Terminal 1: High-frequency writes
./bin/ProprioceptionStressTestRun \
--Ice.Config=config1.cfg \
--p.writeFrequencyHz=500 \
--p.readFrequencyHz=0
# Terminal 2: High-frequency parallel reads
./bin/ProprioceptionStressTestRun \
--Ice.Config=config2.cfg \
--p.writeFrequencyHz=0 \
--p.readFrequencyHz=200 \
--p.numParallelReads=5
# Terminal 3: Mixed operations with parallel threads
./bin/ProprioceptionStressTestRun \
--Ice.Config=config3.cfg \
--p.writeFrequencyHz=100 \
--p.numParallelWrites=2 \
--p.readFrequencyHz=100 \
--p.numParallelReads=3
Performance Testing
Test different frequency configurations to find bottlenecks:
# Low frequency baseline
./bin/ProprioceptionStressTest --p.writeFrequencyHz=10 --p.readFrequencyHz=10
# Medium frequency
./bin/ProprioceptionStressTest --p.writeFrequencyHz=100 --p.readFrequencyHz=100
# High frequency
./bin/ProprioceptionStressTest --p.writeFrequencyHz=500 --p.readFrequencyHz=500
# Very high frequency
./bin/ProprioceptionStressTest --p.writeFrequencyHz=1000 --p.readFrequencyHz=1000
Notes
- The component generates random joint angles between -π and +π
- Each write operation creates a new snapshot with all configured joints, extraFloats, and extraLongs
- Extra fields:
extraFloats: Dictionary of float values (e.g., "extraFloat_0", "extraFloat_1", ...)
extraLongs: Dictionary of long integer values (e.g., "extraLong_0", "extraLong_1", ...)
- These fields simulate additional sensor data beyond joint positions
- Read operations query the latest available data
- Statistics are printed at the configured interval
- All operations are thread-safe using atomic counters
- Parallel threads: Multiple read/write threads run within the same process, perfect for testing shared mutex behavior
- Total throughput: With N parallel threads at F Hz each, total throughput is N × F operations/sec
- Data payload size: Increase
numExtraFloats and numExtraLongs to test performance with larger payloads
- Verbose logging can impact performance - use sparingly at high frequencies
- Parallel reads are ideal for validating shared mutex implementations (multiple readers should not block each other)
- Parallel writes test the mutex's ability to serialize concurrent write operations correctly