From 8e02ead65a823991ae809f06eb23cba19500674a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Boisselier?= Date: Sun, 4 Aug 2024 20:11:51 +0200 Subject: [PATCH] buffered writes and waiting for file write everytime it's needed --- shaketune/commands/accelerometer.py | 12 ++++++++---- shaketune/commands/axes_map_calibration.py | 4 +++- shaketune/commands/axes_shaper_calibration.py | 4 ++-- shaketune/commands/compare_belts_responses.py | 5 +++-- shaketune/commands/create_vibrations_profile.py | 3 +-- shaketune/commands/excitate_axis_at_freq.py | 1 + 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/shaketune/commands/accelerometer.py b/shaketune/commands/accelerometer.py index d00c0d2..d5637ed 100644 --- a/shaketune/commands/accelerometer.py +++ b/shaketune/commands/accelerometer.py @@ -9,11 +9,14 @@ # accelerometer measurements and write the data to a file in a blocking manner. +import io import os import time from multiprocessing import Process, Queue -FILE_WRITE_TIMEOUT = 10 # seconds +FILE_WRITE_TIMEOUT = 20 # seconds max to write a whole CSV file +CHUNK_WRITE_SIZE = 1024 * 1024 # CSV is sliced into chunk of 1MB +CHUNK_WRITE_DELAY = 0.01 # 10ms between each chunk write class Accelerometer: @@ -70,13 +73,14 @@ def _queue_file_write(self, bg_client, filename): def _write_to_file(self, bg_client, filename): try: - os.nice(20) + os.nice(19) except Exception: pass - with open(filename, 'w') as f: + samples = bg_client.samples or bg_client.get_samples() + + with io.BufferedWriter(open(filename, 'w')) as f: f.write('#time,accel_x,accel_y,accel_z\n') - samples = bg_client.samples or bg_client.get_samples() for t, accel_x, accel_y, accel_z in samples: f.write(f'{t:.6f},{accel_x:.6f},{accel_y:.6f},{accel_z:.6f}\n') diff --git a/shaketune/commands/axes_map_calibration.py b/shaketune/commands/axes_map_calibration.py index 9c8e433..a23cf33 100644 --- a/shaketune/commands/axes_map_calibration.py +++ b/shaketune/commands/axes_map_calibration.py @@ -76,18 +76,20 @@ def axes_map_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None: toolhead.dwell(0.5) accelerometer.stop_measurement('axesmap_X', append_time=True) toolhead.dwell(0.5) + accelerometer.wait_for_file_writes() accelerometer.start_measurement() toolhead.dwell(0.5) toolhead.move([mid_x + SEGMENT_LENGTH / 2, mid_y + SEGMENT_LENGTH / 2, z_height, E], speed) toolhead.dwell(0.5) accelerometer.stop_measurement('axesmap_Y', append_time=True) toolhead.dwell(0.5) + accelerometer.wait_for_file_writes() accelerometer.start_measurement() toolhead.dwell(0.5) toolhead.move([mid_x + SEGMENT_LENGTH / 2, mid_y + SEGMENT_LENGTH / 2, z_height + SEGMENT_LENGTH, E], speed) toolhead.dwell(0.5) accelerometer.stop_measurement('axesmap_Z', append_time=True) - + toolhead.dwell(0.5) accelerometer.wait_for_file_writes() # Re-enable the input shaper if it was active diff --git a/shaketune/commands/axes_shaper_calibration.py b/shaketune/commands/axes_shaper_calibration.py index 8aab716..97360a3 100644 --- a/shaketune/commands/axes_shaper_calibration.py +++ b/shaketune/commands/axes_shaper_calibration.py @@ -105,7 +105,8 @@ def axes_shaper_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None: accelerometer.start_measurement() vibrate_axis(toolhead, gcode, config['direction'], min_freq, max_freq, hz_per_sec, accel_per_hz) accelerometer.stop_measurement(config['label'], append_time=True) - + toolhead.dwell(0.5) + toolhead.wait_moves() accelerometer.wait_for_file_writes() # And finally generate the graph for each measured axis @@ -114,7 +115,6 @@ def axes_shaper_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None: st_process.run() st_process.wait_for_completion() toolhead.dwell(1) - toolhead.wait_moves() # Re-enable the input shaper if it was active if input_shaper is not None: diff --git a/shaketune/commands/compare_belts_responses.py b/shaketune/commands/compare_belts_responses.py index c114e99..8092c13 100644 --- a/shaketune/commands/compare_belts_responses.py +++ b/shaketune/commands/compare_belts_responses.py @@ -108,8 +108,9 @@ def compare_belts_responses(gcmd, config, st_process: ShakeTuneProcess) -> None: accelerometer.start_measurement() vibrate_axis(toolhead, gcode, config['direction'], min_freq, max_freq, hz_per_sec, accel_per_hz) accelerometer.stop_measurement(config['label'], append_time=True) - - accelerometer.wait_for_file_writes() + toolhead.dwell(0.5) + toolhead.wait_moves() + accelerometer.wait_for_file_writes() # Re-enable the input shaper if it was active if input_shaper is not None: diff --git a/shaketune/commands/create_vibrations_profile.py b/shaketune/commands/create_vibrations_profile.py index 84cd04f..bdb3408 100644 --- a/shaketune/commands/create_vibrations_profile.py +++ b/shaketune/commands/create_vibrations_profile.py @@ -136,8 +136,7 @@ def create_vibrations_profile(gcmd, config, st_process: ShakeTuneProcess) -> Non toolhead.dwell(0.3) toolhead.wait_moves() - - accelerometer.wait_for_file_writes() + accelerometer.wait_for_file_writes() # Restore the previous acceleration values if old_mcr is not None: # minimum_cruise_ratio found: Klipper >= v0.12.0-239 diff --git a/shaketune/commands/excitate_axis_at_freq.py b/shaketune/commands/excitate_axis_at_freq.py index 6eae2d4..d2c5d10 100644 --- a/shaketune/commands/excitate_axis_at_freq.py +++ b/shaketune/commands/excitate_axis_at_freq.py @@ -100,6 +100,7 @@ def excitate_axis_at_freq(gcmd, config, st_process: ShakeTuneProcess) -> None: # If the user wanted to create a graph, we stop the recording and generate it if create_graph: accelerometer.stop_measurement(f'staticfreq_{axis.upper()}', append_time=True) + toolhead.dwell(0.5) accelerometer.wait_for_file_writes() creator = st_process.get_graph_creator()