Advanced Usage Tutorial¶
This tutorial covers advanced features of SoftRealtimeLoop
Sensor Data Acquisition¶
Example of reading from a simulated sensor at precise intervals:
class SimpleSensorSimulator:
def __init__(self):
self.start_time = time.monotonic()
def read(self, t):
# Simulate a 0.5 Hz sine wave sensor reading
return 100 * sin(2 * pi * 0.5 * t)
def sensor_example():
# Create a 20Hz loop (0.05 second period)
rt_loop = SoftRealtimeLoop(dt=0.05)
# Initialize sensor and data storage
sensor = SimpleSensorSimulator()
readings = []
print("Recording simulated sensor data for 2 seconds...")
for t in rt_loop:
reading = sensor.read(t)
readings.append(reading)
print(f"Time: {t:.2f}s, Sensor value: {reading:.1f}")
if t > 2.0: # Stop after 2 seconds
rt_loop.stop()
print(f"\nCollected {len(readings)} samples at 20Hz")
print(f"Average sampling period: {2.0 / len(readings):.3f} seconds")
Graceful Shutdown with Fade-out¶
Demonstration of the fade-out feature for a smooth shutdown:
def fade_example():
# Create a 10Hz loop with 1-second fade-out
rt_loop = SoftRealtimeLoop(dt=0.1, fade=1.0)
print("Running loop with fade-out...")
print("Press Ctrl+C to test graceful shutdown!")
try:
for t in rt_loop:
fade_value = rt_loop.fade
print(f"Time: {t:.1f}s, Fade value: {fade_value:.2f}")
if t > 10.0: # Auto-stop after 10 seconds if no Ctrl+C
rt_loop.stop()
except KeyboardInterrupt:
print("\nCtrl+C detected - demonstrating fade-out...")
# The loop will automatically handle the fade-out
print("\nLoop completed with graceful shutdown!")
Understanding Performance Statistics¶
When a SoftRealtimeLoop completes (either through normal termination or interruption), it prints detailed timing statistics if reporting is enabled (default). Let's understand what these metrics mean and how to use them:
Available Statistics¶
The loop reports three key metrics:
# Example output:
In 1000 cycles at 100.00 Hz:
avg error: 0.123 milliseconds
stddev error: 0.045 milliseconds
percent of time sleeping: 85.2 %
-
Average Error: Shows how far off your timing is from the target on average
- Values under 1ms are typically good for most applications
- Higher values indicate your loop might be overloaded
-
Standard Deviation Error: Shows how consistent your timing is
- Lower values mean more consistent timing
- High variance might indicate interference from other processes
-
Percent Time Sleeping: Shows how much CPU headroom you have
- Higher values (>50%) indicate your loop has plenty of processing time
- Low values suggest your loop might be struggling to keep up
Improving Performance¶
If your statistics show timing issues, here are some general ways to improve your real-time performance:
- Reduce other system load
- Increase process priority
- Move computationally intensive operations outside the loop
Monitoring Performance¶
You can access timing statistics programmatically:
rt_loop = SoftRealtimeLoop(dt=0.001)
# ... run your loop ...
avg_error = rt_loop.sum_err / rt_loop.n if rt_loop.n > 0 else 0
sleep_percentage = (rt_loop.sleep_t_agg / rt_loop.time_since_start) * 100 if rt_loop.time_since_start > 0 else 0
By monitoring these statistics, you can ensure your real-time applications maintain precise timing and reliable performance. The statistics help identify when your loop needs tuning or when system resources are becoming constrained.
Best Practices¶
-
Choose Appropriate Time Steps:
- Faster loops (smaller dt) require more CPU resources
- Balance between control requirements and system capabilities
-
Monitor Resource Usage:
- Watch for sleep percentages below 20%
- Consider operating at a lower frequency if the system is struggling
-
Use Fade-out for Clean Graceful Shutdown:
-
Reset for Multiple Uses:
If you have any questions or need further assistance, please post on the Open Source Leg community forum.