From 978c294741bafac136081f40d066ad2884b1ffce Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sat, 16 Dec 2023 11:15:23 -0500 Subject: bulk_sensor: New file with helper code for reading bulk sensors Move the ClockSyncRegression class from adxl345.py to a new bulk_sensors.py file. Signed-off-by: Kevin O'Connor --- klippy/extras/bulk_sensor.py | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 klippy/extras/bulk_sensor.py (limited to 'klippy/extras/bulk_sensor.py') diff --git a/klippy/extras/bulk_sensor.py b/klippy/extras/bulk_sensor.py new file mode 100644 index 00000000..3d76eb6f --- /dev/null +++ b/klippy/extras/bulk_sensor.py @@ -0,0 +1,53 @@ +# Tools for reading bulk sensor data from the mcu +# +# Copyright (C) 2020-2023 Kevin O'Connor +# +# This file may be distributed under the terms of the GNU GPLv3 license. + +# Helper class for chip clock synchronization via linear regression +class ClockSyncRegression: + def __init__(self, mcu, chip_clock_smooth, decay = 1. / 20.): + self.mcu = mcu + self.chip_clock_smooth = chip_clock_smooth + self.decay = decay + self.last_chip_clock = self.last_exp_mcu_clock = 0. + self.mcu_clock_avg = self.mcu_clock_variance = 0. + self.chip_clock_avg = self.chip_clock_covariance = 0. + def reset(self, mcu_clock, chip_clock): + self.mcu_clock_avg = self.last_mcu_clock = mcu_clock + self.chip_clock_avg = chip_clock + self.mcu_clock_variance = self.chip_clock_covariance = 0. + self.last_chip_clock = self.last_exp_mcu_clock = 0. + def update(self, mcu_clock, chip_clock): + # Update linear regression + decay = self.decay + diff_mcu_clock = mcu_clock - self.mcu_clock_avg + self.mcu_clock_avg += decay * diff_mcu_clock + self.mcu_clock_variance = (1. - decay) * ( + self.mcu_clock_variance + diff_mcu_clock**2 * decay) + diff_chip_clock = chip_clock - self.chip_clock_avg + self.chip_clock_avg += decay * diff_chip_clock + self.chip_clock_covariance = (1. - decay) * ( + self.chip_clock_covariance + diff_mcu_clock*diff_chip_clock*decay) + def set_last_chip_clock(self, chip_clock): + base_mcu, base_chip, inv_cfreq = self.get_clock_translation() + self.last_chip_clock = chip_clock + self.last_exp_mcu_clock = base_mcu + (chip_clock-base_chip) * inv_cfreq + def get_clock_translation(self): + inv_chip_freq = self.mcu_clock_variance / self.chip_clock_covariance + if not self.last_chip_clock: + return self.mcu_clock_avg, self.chip_clock_avg, inv_chip_freq + # Find mcu clock associated with future chip_clock + s_chip_clock = self.last_chip_clock + self.chip_clock_smooth + scdiff = s_chip_clock - self.chip_clock_avg + s_mcu_clock = self.mcu_clock_avg + scdiff * inv_chip_freq + # Calculate frequency to converge at future point + mdiff = s_mcu_clock - self.last_exp_mcu_clock + s_inv_chip_freq = mdiff / self.chip_clock_smooth + return self.last_exp_mcu_clock, self.last_chip_clock, s_inv_chip_freq + def get_time_translation(self): + base_mcu, base_chip, inv_cfreq = self.get_clock_translation() + clock_to_print_time = self.mcu.clock_to_print_time + base_time = clock_to_print_time(base_mcu) + inv_freq = clock_to_print_time(base_mcu + inv_cfreq) - base_time + return base_time, base_chip, inv_freq -- cgit v1.2.3-70-g09d2