using Klipper reactor for file write process handling

This commit is contained in:
Félix Boisselier
2024-06-20 11:59:19 +02:00
parent 90ed7aca3c
commit 50ed13ca59
6 changed files with 62 additions and 32 deletions

View File

@@ -13,10 +13,13 @@ import os
import time import time
from multiprocessing import Process, Queue from multiprocessing import Process, Queue
FILE_WRITE_TIMEOUT = 10 # seconds
class Accelerometer: class Accelerometer:
def __init__(self, klipper_accelerometer): def __init__(self, reactor, klipper_accelerometer):
self._k_accelerometer = klipper_accelerometer self._k_accelerometer = klipper_accelerometer
self._reactor = reactor
self._bg_client = None self._bg_client = None
self._write_queue = Queue() self._write_queue = Queue()
@@ -70,16 +73,35 @@ class Accelerometer:
os.nice(20) os.nice(20)
except Exception: except Exception:
pass pass
with open(filename, 'w') as f: with open(filename, 'w') as f:
f.write('#time,accel_x,accel_y,accel_z\n') f.write('#time,accel_x,accel_y,accel_z\n')
samples = bg_client.samples or bg_client.get_samples() samples = bg_client.samples or bg_client.get_samples()
for t, accel_x, accel_y, accel_z in 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') f.write(f'{t:.6f},{accel_x:.6f},{accel_y:.6f},{accel_z:.6f}\n')
self._write_queue.get() self._write_queue.get()
def wait_for_file_writes(self): def wait_for_file_writes(self):
while not self._write_queue.empty(): while not self._write_queue.empty():
time.sleep(0.1) eventtime = self._reactor.monotonic()
self._reactor.pause(eventtime + 0.1)
for proc in self._write_processes: for proc in self._write_processes:
proc.join() if proc is None:
continue
eventtime = self._reactor.monotonic()
endtime = eventtime + FILE_WRITE_TIMEOUT
complete = False
while eventtime < endtime:
eventtime = self._reactor.pause(eventtime + 0.05)
if not proc.is_alive():
complete = True
break
if not complete:
raise TimeoutError(
'Shake&Tune was not able to write the accelerometer data into the CSV file. '
'This might be due to a slow SD card or a busy or full filesystem.'
)
self._write_processes = [] self._write_processes = []

View File

@@ -37,7 +37,7 @@ def axes_map_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None:
raise gcmd.error( raise gcmd.error(
f'The parameter axes_map is already set in your {accel_chip} configuration! Please remove it (or set it to "x,y,z")!' f'The parameter axes_map is already set in your {accel_chip} configuration! Please remove it (or set it to "x,y,z")!'
) )
accelerometer = Accelerometer(k_accelerometer) accelerometer = Accelerometer(printer.get_reactor(), k_accelerometer)
toolhead_info = toolhead.get_status(systime) toolhead_info = toolhead.get_status(systime)
old_accel = toolhead_info['max_accel'] old_accel = toolhead_info['max_accel']
@@ -46,7 +46,9 @@ def axes_map_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None:
# set the wanted acceleration values # set the wanted acceleration values
if 'minimum_cruise_ratio' in toolhead_info: if 'minimum_cruise_ratio' in toolhead_info:
old_mcr = toolhead_info['minimum_cruise_ratio'] # minimum_cruise_ratio found: Klipper >= v0.12.0-239 old_mcr = toolhead_info['minimum_cruise_ratio'] # minimum_cruise_ratio found: Klipper >= v0.12.0-239
gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={accel} MINIMUM_CRUISE_RATIO=0 SQUARE_CORNER_VELOCITY=5.0') gcode.run_script_from_command(
f'SET_VELOCITY_LIMIT ACCEL={accel} MINIMUM_CRUISE_RATIO=0 SQUARE_CORNER_VELOCITY=5.0'
)
else: # minimum_cruise_ratio not found: Klipper < v0.12.0-239 else: # minimum_cruise_ratio not found: Klipper < v0.12.0-239
old_mcr = None old_mcr = None
gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={accel} SQUARE_CORNER_VELOCITY=5.0') gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={accel} SQUARE_CORNER_VELOCITY=5.0')
@@ -94,7 +96,9 @@ def axes_map_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None:
# Restore the previous acceleration values # Restore the previous acceleration values
if old_mcr is not None: # minimum_cruise_ratio found: Klipper >= v0.12.0-239 if old_mcr is not None: # minimum_cruise_ratio found: Klipper >= v0.12.0-239
gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={old_accel} MINIMUM_CRUISE_RATIO={old_mcr} SQUARE_CORNER_VELOCITY={old_sqv}') gcode.run_script_from_command(
f'SET_VELOCITY_LIMIT ACCEL={old_accel} MINIMUM_CRUISE_RATIO={old_mcr} SQUARE_CORNER_VELOCITY={old_sqv}'
)
else: # minimum_cruise_ratio not found: Klipper < v0.12.0-239 else: # minimum_cruise_ratio not found: Klipper < v0.12.0-239
gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={old_accel} SQUARE_CORNER_VELOCITY={old_sqv}') gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={old_accel} SQUARE_CORNER_VELOCITY={old_sqv}')

View File

@@ -99,7 +99,7 @@ def axes_shaper_calibration(gcmd, config, st_process: ShakeTuneProcess) -> None:
accel_chip = Accelerometer.find_axis_accelerometer(printer, config['axis']) accel_chip = Accelerometer.find_axis_accelerometer(printer, config['axis'])
if accel_chip is None: if accel_chip is None:
raise gcmd.error('No suitable accelerometer found for measurement!') raise gcmd.error('No suitable accelerometer found for measurement!')
accelerometer = Accelerometer(printer.lookup_object(accel_chip)) accelerometer = Accelerometer(printer.get_reactor(), printer.lookup_object(accel_chip))
# Then do the actual measurements # Then do the actual measurements
accelerometer.start_measurement() accelerometer.start_measurement()

View File

@@ -60,7 +60,7 @@ def compare_belts_responses(gcmd, config, st_process: ShakeTuneProcess) -> None:
raise gcmd.error( raise gcmd.error(
'No suitable accelerometer found for measurement! Multi-accelerometer configurations are not supported for this macro.' 'No suitable accelerometer found for measurement! Multi-accelerometer configurations are not supported for this macro.'
) )
accelerometer = Accelerometer(printer.lookup_object(accel_chip)) accelerometer = Accelerometer(printer.get_reactor(), printer.lookup_object(accel_chip))
# Move to the starting point # Move to the starting point
test_points = res_tester.test.get_start_test_points() test_points = res_tester.test.get_start_test_points()

View File

@@ -64,7 +64,9 @@ def create_vibrations_profile(gcmd, config, st_process: ShakeTuneProcess) -> Non
# set the wanted acceleration values # set the wanted acceleration values
if 'minimum_cruise_ratio' in toolhead_info: # minimum_cruise_ratio found: Klipper >= v0.12.0-239 if 'minimum_cruise_ratio' in toolhead_info: # minimum_cruise_ratio found: Klipper >= v0.12.0-239
old_mcr = toolhead_info['minimum_cruise_ratio'] old_mcr = toolhead_info['minimum_cruise_ratio']
gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={accel} MINIMUM_CRUISE_RATIO=0 SQUARE_CORNER_VELOCITY=5.0') gcode.run_script_from_command(
f'SET_VELOCITY_LIMIT ACCEL={accel} MINIMUM_CRUISE_RATIO=0 SQUARE_CORNER_VELOCITY=5.0'
)
else: # minimum_cruise_ratio not found: Klipper < v0.12.0-239 else: # minimum_cruise_ratio not found: Klipper < v0.12.0-239
old_mcr = None old_mcr = None
gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={accel} SQUARE_CORNER_VELOCITY=5.0') gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={accel} SQUARE_CORNER_VELOCITY=5.0')
@@ -95,7 +97,7 @@ def create_vibrations_profile(gcmd, config, st_process: ShakeTuneProcess) -> Non
if k_accelerometer is None: if k_accelerometer is None:
raise gcmd.error(f'Accelerometer [{current_accel_chip}] not found!') raise gcmd.error(f'Accelerometer [{current_accel_chip}] not found!')
ConsoleOutput.print(f'Accelerometer chip used for this angle: [{current_accel_chip}]') ConsoleOutput.print(f'Accelerometer chip used for this angle: [{current_accel_chip}]')
accelerometer = Accelerometer(k_accelerometer) accelerometer = Accelerometer(printer.get_reactor(), k_accelerometer)
# Sweep the speed range to record the vibrations at different speeds # Sweep the speed range to record the vibrations at different speeds
for curr_speed_sample in range(nb_speed_samples): for curr_speed_sample in range(nb_speed_samples):
@@ -139,7 +141,9 @@ def create_vibrations_profile(gcmd, config, st_process: ShakeTuneProcess) -> Non
# Restore the previous acceleration values # Restore the previous acceleration values
if old_mcr is not None: # minimum_cruise_ratio found: Klipper >= v0.12.0-239 if old_mcr is not None: # minimum_cruise_ratio found: Klipper >= v0.12.0-239
gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={old_accel} MINIMUM_CRUISE_RATIO={old_mcr} SQUARE_CORNER_VELOCITY={old_sqv}') gcode.run_script_from_command(
f'SET_VELOCITY_LIMIT ACCEL={old_accel} MINIMUM_CRUISE_RATIO={old_mcr} SQUARE_CORNER_VELOCITY={old_sqv}'
)
else: # minimum_cruise_ratio not found: Klipper < v0.12.0-239 else: # minimum_cruise_ratio not found: Klipper < v0.12.0-239
gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={old_accel} SQUARE_CORNER_VELOCITY={old_sqv}') gcode.run_script_from_command(f'SET_VELOCITY_LIMIT ACCEL={old_accel} SQUARE_CORNER_VELOCITY={old_sqv}')
toolhead.wait_moves() toolhead.wait_moves()

View File

@@ -41,7 +41,7 @@ def excitate_axis_at_freq(gcmd, config, st_process: ShakeTuneProcess) -> None:
k_accelerometer = printer.lookup_object(accel_chip, None) k_accelerometer = printer.lookup_object(accel_chip, None)
if k_accelerometer is None: if k_accelerometer is None:
raise gcmd.error(f'Accelerometer chip [{accel_chip}] was not found!') raise gcmd.error(f'Accelerometer chip [{accel_chip}] was not found!')
accelerometer = Accelerometer(k_accelerometer) accelerometer = Accelerometer(printer.get_reactor(), k_accelerometer)
ConsoleOutput.print(f'Excitating {axis.upper()} axis at {freq}Hz for {duration} seconds') ConsoleOutput.print(f'Excitating {axis.upper()} axis at {freq}Hz for {duration} seconds')