feat: Add oscillator sensor visualization and data export scripts

- demo_oscillator_simple.py: Visualizes oscillator waveforms in terminal
- oscillator_data_export.py: Exports oscillator data as JSON
- Supports all waveforms: sine, square, sawtooth, triangle, noise
- Real-time visualization with phase tracking
- Configurable frequency, sample rate, and duration
This commit is contained in:
2026-03-19 03:47:51 -07:00
parent 238bac1bb2
commit f2b4226173
2 changed files with 245 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
#!/usr/bin/env python3
"""
Oscillator Data Export
Exports oscillator sensor data in JSON format for external use.
Usage:
uv run python scripts/oscillator_data_export.py --waveform sine --frequency 1.0 --duration 5.0
"""
import argparse
import json
import time
import sys
from pathlib import Path
from datetime import datetime
# Add mainline to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from engine.sensors.oscillator import OscillatorSensor, register_oscillator_sensor
def export_oscillator_data(
waveform: str = "sine",
frequency: float = 1.0,
duration: float = 5.0,
sample_rate: float = 60.0,
output_file: str | None = None,
):
"""Export oscillator data to JSON."""
print(f"Exporting oscillator data: {waveform} wave at {frequency}Hz")
print(f"Duration: {duration}s, Sample rate: {sample_rate}Hz")
# Create oscillator sensor
register_oscillator_sensor(
name="export_osc", waveform=waveform, frequency=frequency
)
osc = OscillatorSensor(name="export_osc", waveform=waveform, frequency=frequency)
osc.start()
# Collect data
data = {
"waveform": waveform,
"frequency": frequency,
"duration": duration,
"sample_rate": sample_rate,
"timestamp": datetime.now().isoformat(),
"samples": [],
}
sample_interval = 1.0 / sample_rate
num_samples = int(duration * sample_rate)
print(f"Collecting {num_samples} samples...")
for i in range(num_samples):
reading = osc.read()
if reading:
data["samples"].append(
{
"index": i,
"timestamp": reading.timestamp,
"value": reading.value,
"phase": osc._phase,
}
)
time.sleep(sample_interval)
osc.stop()
# Export to JSON
if output_file:
with open(output_file, "w") as f:
json.dump(data, f, indent=2)
print(f"Data exported to {output_file}")
else:
print(json.dumps(data, indent=2))
return data
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Export oscillator sensor data")
parser.add_argument(
"--waveform",
choices=["sine", "square", "sawtooth", "triangle", "noise"],
default="sine",
help="Waveform type",
)
parser.add_argument(
"--frequency", type=float, default=1.0, help="Oscillator frequency in Hz"
)
parser.add_argument(
"--duration", type=float, default=5.0, help="Duration to record in seconds"
)
parser.add_argument(
"--sample-rate", type=float, default=60.0, help="Sample rate in Hz"
)
parser.add_argument(
"--output", "-o", type=str, help="Output JSON file (default: print to stdout)"
)
args = parser.parse_args()
export_oscillator_data(
waveform=args.waveform,
frequency=args.frequency,
duration=args.duration,
sample_rate=args.sample_rate,
output_file=args.output,
)