Motor info added to the vibration graphs (#93)
and reduced global vibration generation time by reducing segment lenghts
This commit is contained in:
@@ -122,7 +122,7 @@ gcode:
|
|||||||
# enough to collect enough data for vibration analysis, without doing unnecessary distance to save time. At higher speeds, the full
|
# enough to collect enough data for vibration analysis, without doing unnecessary distance to save time. At higher speeds, the full
|
||||||
# segments lengths are used because the head moves faster and travels more distance in the same amount of time and we want enough data
|
# segments lengths are used because the head moves faster and travels more distance in the same amount of time and we want enough data
|
||||||
{% if curr_speed < (100 * 60) %}
|
{% if curr_speed < (100 * 60) %}
|
||||||
{% set segment_length_multiplier = 1/3 + 2/3 * (curr_speed / 60) / 100 %}
|
{% set segment_length_multiplier = 1/5 + 4/5 * (curr_speed / 60) / 100 %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set segment_length_multiplier = 1 %}
|
{% set segment_length_multiplier = 1 %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -156,12 +156,59 @@ gcode:
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
RESPOND MSG="Machine vibrations profile generation..."
|
|
||||||
RESPOND MSG="This may take some time (3-5min)"
|
|
||||||
RUN_SHELL_COMMAND CMD=shaketune PARAMS="--type vibrations --accel {accel|int} --kinematics {kinematics} --chip_name {accel_chip} {% if keep_csv %}--keep_csv{% endif %} --keep_results {keep_results}"
|
|
||||||
|
|
||||||
# Restore the previous acceleration values
|
# Restore the previous acceleration values
|
||||||
SET_VELOCITY_LIMIT ACCEL={old_accel} MINIMUM_CRUISE_RATIO={old_cruise_ratio} SQUARE_CORNER_VELOCITY={old_sqv}
|
SET_VELOCITY_LIMIT ACCEL={old_accel} MINIMUM_CRUISE_RATIO={old_cruise_ratio} SQUARE_CORNER_VELOCITY={old_sqv}
|
||||||
|
|
||||||
|
# Extract the TMC names and configuration
|
||||||
|
{% set ns_x = namespace(path='') %}
|
||||||
|
{% set ns_y = namespace(path='') %}
|
||||||
|
|
||||||
|
{% for item in printer %}
|
||||||
|
{% set parts = item.split() %}
|
||||||
|
{% if parts|length == 2 and parts[0].startswith('tmc') and parts[0][3:].isdigit() %}
|
||||||
|
{% if parts[1] == 'stepper_x' %}
|
||||||
|
{% set ns_x.path = parts[0] %}
|
||||||
|
{% elif parts[1] == 'stepper_y' %}
|
||||||
|
{% set ns_y.path = parts[0] %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if ns_x.path and ns_y.path %}
|
||||||
|
{% set metadata =
|
||||||
|
"stepper_x_tmc:" ~ ns_x.path ~ "|"
|
||||||
|
"stepper_x_run_current:" ~ (printer[ns_x.path + ' stepper_x'].run_current | round(2) | string) ~ "|"
|
||||||
|
"stepper_x_hold_current:" ~ (printer[ns_x.path + ' stepper_x'].hold_current | round(2) | string) ~ "|"
|
||||||
|
"stepper_y_tmc:" ~ ns_y.path ~ "|"
|
||||||
|
"stepper_y_run_current:" ~ (printer[ns_y.path + ' stepper_y'].run_current | round(2) | string) ~ "|"
|
||||||
|
"stepper_y_hold_current:" ~ (printer[ns_y.path + ' stepper_y'].hold_current | round(2) | string) ~ "|"
|
||||||
|
%}
|
||||||
|
|
||||||
|
{% set autotune_x = printer.configfile.config['autotune_tmc stepper_x'] if 'autotune_tmc stepper_x' in printer.configfile.config else none %}
|
||||||
|
{% set autotune_y = printer.configfile.config['autotune_tmc stepper_y'] if 'autotune_tmc stepper_y' in printer.configfile.config else none %}
|
||||||
|
{% if autotune_x and autotune_y %}
|
||||||
|
{% set stepper_x_voltage = autotune_x.voltage if autotune_x.voltage else '24.0' %}
|
||||||
|
{% set stepper_y_voltage = autotune_y.voltage if autotune_y.voltage else '24.0' %}
|
||||||
|
{% set metadata = metadata ~
|
||||||
|
"autotune_enabled:True|"
|
||||||
|
"stepper_x_motor:" ~ autotune_x.motor ~ "|"
|
||||||
|
"stepper_x_voltage:" ~ stepper_x_voltage ~ "|"
|
||||||
|
"stepper_y_motor:" ~ autotune_y.motor ~ "|"
|
||||||
|
"stepper_y_voltage:" ~ stepper_y_voltage ~ "|"
|
||||||
|
%}
|
||||||
|
{% else %}
|
||||||
|
{% set metadata = metadata ~ "autotune_enabled:False|" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
DUMP_TMC STEPPER=stepper_x
|
||||||
|
DUMP_TMC STEPPER=stepper_y
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{ action_respond_info("No TMC drivers found for X and Y steppers") }
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
RESPOND MSG="Machine vibrations profile generation..."
|
||||||
|
RESPOND MSG="This may take some time (3-5min)"
|
||||||
|
RUN_SHELL_COMMAND CMD=shaketune PARAMS="--type vibrations --accel {accel|int} --kinematics {kinematics} {% if metadata %}--metadata {metadata}{% endif %} --chip_name {accel_chip} {% if keep_csv %}--keep_csv{% endif %} --keep_results {keep_results}"
|
||||||
|
|
||||||
RESTORE_GCODE_STATE NAME=CREATE_VIBRATIONS_PROFILE
|
RESTORE_GCODE_STATE NAME=CREATE_VIBRATIONS_PROFILE
|
||||||
|
|||||||
@@ -560,6 +560,57 @@ def plot_vibration_spectrogram(ax, angles, speeds, spectrogram_data, peaks):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def plot_motor_config_txt(fig, motors, differences):
|
||||||
|
motor_details = [(motors[0], 'X motor'), (motors[1], 'Y motor')]
|
||||||
|
|
||||||
|
distance = 0.12
|
||||||
|
if motors[0].get_property('autotune_enabled'):
|
||||||
|
distance = 0.24
|
||||||
|
config_blocks = [
|
||||||
|
f"| {lbl}: {mot.get_property('motor').upper()} on {mot.get_property('tmc').upper()} @ {mot.get_property('voltage')}V {mot.get_property('run_current')}A"
|
||||||
|
for mot, lbl in motor_details
|
||||||
|
]
|
||||||
|
config_blocks.append('| TMC Autotune enabled')
|
||||||
|
else:
|
||||||
|
config_blocks = [
|
||||||
|
f"| {lbl}: {mot.get_property('tmc').upper()} @ {mot.get_property('run_current')}A"
|
||||||
|
for mot, lbl in motor_details
|
||||||
|
]
|
||||||
|
config_blocks.append('| TMC Autotune not detected')
|
||||||
|
|
||||||
|
for idx, block in enumerate(config_blocks):
|
||||||
|
fig.text(
|
||||||
|
0.40, 0.990 - 0.015 * idx, block, ha='left', va='top', fontsize=10, color=KLIPPAIN_COLORS['dark_purple']
|
||||||
|
)
|
||||||
|
|
||||||
|
tmc_registers = motors[0].get_registers()
|
||||||
|
idx = -1
|
||||||
|
for idx, (register, settings) in enumerate(tmc_registers.items()):
|
||||||
|
settings_str = ' '.join(f'{k}={v}' for k, v in settings.items())
|
||||||
|
tmc_block = f'| {register.upper()}: {settings_str}'
|
||||||
|
fig.text(
|
||||||
|
0.40 + distance,
|
||||||
|
0.990 - 0.015 * idx,
|
||||||
|
tmc_block,
|
||||||
|
ha='left',
|
||||||
|
va='top',
|
||||||
|
fontsize=10,
|
||||||
|
color=KLIPPAIN_COLORS['dark_purple'],
|
||||||
|
)
|
||||||
|
|
||||||
|
if differences is not None:
|
||||||
|
differences_text = f'| Y motor diff: {differences}'
|
||||||
|
fig.text(
|
||||||
|
0.40 + distance,
|
||||||
|
0.990 - 0.015 * (idx + 1),
|
||||||
|
differences_text,
|
||||||
|
ha='left',
|
||||||
|
va='top',
|
||||||
|
fontsize=10,
|
||||||
|
color=KLIPPAIN_COLORS['dark_purple'],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Startup and main routines
|
# Startup and main routines
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -577,7 +628,7 @@ def extract_angle_and_speed(logname):
|
|||||||
|
|
||||||
|
|
||||||
def vibrations_profile(
|
def vibrations_profile(
|
||||||
lognames, klipperdir='~/klipper', kinematics='cartesian', accel=None, max_freq=1000.0, st_version=None
|
lognames, klipperdir='~/klipper', kinematics='cartesian', accel=None, max_freq=1000.0, st_version=None, motors=None
|
||||||
):
|
):
|
||||||
set_locale()
|
set_locale()
|
||||||
global shaper_calibrate
|
global shaper_calibrate
|
||||||
@@ -710,6 +761,13 @@ def vibrations_profile(
|
|||||||
title_line2 = lognames[0].split('/')[-1]
|
title_line2 = lognames[0].split('/')[-1]
|
||||||
fig.text(0.060, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple'])
|
fig.text(0.060, 0.957, title_line2, ha='left', va='top', fontsize=16, color=KLIPPAIN_COLORS['dark_purple'])
|
||||||
|
|
||||||
|
# Add the motors infos to the top of the graph
|
||||||
|
if motors is not None and len(motors) == 2:
|
||||||
|
differences = motors[0].compare_to(motors[1])
|
||||||
|
plot_motor_config_txt(fig, motors, differences)
|
||||||
|
if differences is not None and kinematics == 'corexy':
|
||||||
|
print_with_c_locale(f'Warning: motors have different TMC configurations!\n{differences}')
|
||||||
|
|
||||||
# Plot the graphs
|
# Plot the graphs
|
||||||
plot_angle_profile_polar(ax1, all_angles, all_angles_energy, good_angles, symmetry_factor)
|
plot_angle_profile_polar(ax1, all_angles, all_angles_energy, good_angles, symmetry_factor)
|
||||||
plot_vibration_spectrogram_polar(ax4, all_angles, all_speeds, spectrogram_data)
|
plot_vibration_spectrogram_polar(ax4, all_angles, all_speeds, spectrogram_data)
|
||||||
|
|||||||
205
src/helpers/motorlogparser.py
Normal file
205
src/helpers/motorlogparser.py
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Classes to parse the Klipper log and parse the TMC dump to extract the relevant information
|
||||||
|
# Written by Frix_x#0161 #
|
||||||
|
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any, Dict, List, Optional, Union
|
||||||
|
|
||||||
|
|
||||||
|
class Motor:
|
||||||
|
def __init__(self, name: str):
|
||||||
|
self._name: str = name
|
||||||
|
self._registers: Dict[str, Dict[str, Any]] = {}
|
||||||
|
self._properties: Dict[str, Any] = {}
|
||||||
|
|
||||||
|
def set_register(self, register: str, value: Any) -> None:
|
||||||
|
# Special parsing for CHOPCONF to extract meaningful values
|
||||||
|
if register == 'CHOPCONF':
|
||||||
|
# Add intpol=0 if missing from the register dump
|
||||||
|
if 'intpol=' not in value:
|
||||||
|
value += ' intpol=0'
|
||||||
|
# Simplify the microstep resolution format
|
||||||
|
mres_match = re.search(r'mres=\d+\((\d+)usteps\)', value)
|
||||||
|
if mres_match:
|
||||||
|
value = re.sub(r'mres=\d+\(\d+usteps\)', f'mres={mres_match.group(1)}', value)
|
||||||
|
|
||||||
|
# Special parsing for CHOPCONF to avoid pwm_ before each values
|
||||||
|
if register == 'PWMCONF':
|
||||||
|
parts = value.split()
|
||||||
|
new_parts = []
|
||||||
|
for part in parts:
|
||||||
|
key, val = part.split('=', 1)
|
||||||
|
if key.startswith('pwm_'):
|
||||||
|
key = key[4:]
|
||||||
|
new_parts.append(f'{key}={val}')
|
||||||
|
value = ' '.join(new_parts)
|
||||||
|
|
||||||
|
# General cleaning to remove extraneous labels and colons and parse the whole into Motor _registers
|
||||||
|
cleaned_values = re.sub(r'\b\w+:\s+\S+\s+', '', value)
|
||||||
|
|
||||||
|
# Then fill the registers while merging all the thresholds into the same THRS virtual register
|
||||||
|
if register in ['TPWMTHRS', 'TCOOLTHRS']:
|
||||||
|
existing_thrs = self._registers.get('THRS', {})
|
||||||
|
new_values = self._parse_register_values(cleaned_values)
|
||||||
|
merged_values = {**existing_thrs, **new_values}
|
||||||
|
self._registers['THRS'] = merged_values
|
||||||
|
else:
|
||||||
|
self._registers[register] = self._parse_register_values(cleaned_values)
|
||||||
|
|
||||||
|
def _parse_register_values(self, register_string: str) -> Dict[str, Any]:
|
||||||
|
parsed = {}
|
||||||
|
parts = register_string.split()
|
||||||
|
for part in parts:
|
||||||
|
if '=' in part:
|
||||||
|
k, v = part.split('=', 1)
|
||||||
|
parsed[k] = v
|
||||||
|
return parsed
|
||||||
|
|
||||||
|
def get_register(self, register: str) -> Optional[Dict[str, Any]]:
|
||||||
|
return self._registers.get(register)
|
||||||
|
|
||||||
|
def get_registers(self) -> Dict[str, Dict[str, Any]]:
|
||||||
|
return self._registers
|
||||||
|
|
||||||
|
def set_property(self, property: str, value: Any) -> None:
|
||||||
|
self._properties[property] = value
|
||||||
|
|
||||||
|
def get_property(self, property: str) -> Optional[Any]:
|
||||||
|
return self._properties.get(property)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'Stepper: {self._name}\nKlipper config: {self._properties}\nTMC Registers: {self._registers}'
|
||||||
|
|
||||||
|
# Return the other motor properties and registers that are different from the current motor
|
||||||
|
def compare_to(self, other: 'Motor') -> Optional[Dict[str, Dict[str, Any]]]:
|
||||||
|
differences = {'properties': {}, 'registers': {}}
|
||||||
|
|
||||||
|
# Compare properties
|
||||||
|
all_keys = self._properties.keys() | other._properties.keys()
|
||||||
|
for key in all_keys:
|
||||||
|
val1 = self._properties.get(key)
|
||||||
|
val2 = other._properties.get(key)
|
||||||
|
if val1 != val2:
|
||||||
|
differences['properties'][key] = val2
|
||||||
|
|
||||||
|
# Compare registers
|
||||||
|
all_keys = self._registers.keys() | other._registers.keys()
|
||||||
|
for key in all_keys:
|
||||||
|
reg1 = self._registers.get(key, {})
|
||||||
|
reg2 = other._registers.get(key, {})
|
||||||
|
if reg1 != reg2:
|
||||||
|
reg_diffs = {}
|
||||||
|
sub_keys = reg1.keys() | reg2.keys()
|
||||||
|
for sub_key in sub_keys:
|
||||||
|
reg_val1 = reg1.get(sub_key)
|
||||||
|
reg_val2 = reg2.get(sub_key)
|
||||||
|
if reg_val1 != reg_val2:
|
||||||
|
reg_diffs[sub_key] = reg_val2
|
||||||
|
if reg_diffs:
|
||||||
|
differences['registers'][key] = reg_diffs
|
||||||
|
|
||||||
|
# Clean up: remove empty sections if there are no differences
|
||||||
|
if not differences['properties']:
|
||||||
|
del differences['properties']
|
||||||
|
if not differences['registers']:
|
||||||
|
del differences['registers']
|
||||||
|
|
||||||
|
if not differences:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return differences
|
||||||
|
|
||||||
|
|
||||||
|
class MotorLogParser:
|
||||||
|
_section_pattern: str = r'DUMP_TMC stepper_(x|y)'
|
||||||
|
_register_patterns: Dict[str, str] = {
|
||||||
|
'CHOPCONF': r'CHOPCONF:\s+\S+\s+(.*)',
|
||||||
|
'PWMCONF': r'PWMCONF:\s+\S+\s+(.*)',
|
||||||
|
'COOLCONF': r'COOLCONF:\s+(.*)',
|
||||||
|
'TPWMTHRS': r'TPWMTHRS:\s+\S+\s+(.*)',
|
||||||
|
'TCOOLTHRS': r'TCOOLTHRS:\s+\S+\s+(.*)',
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, filepath: Path, config_string: Optional[str] = None):
|
||||||
|
self._filepath = filepath
|
||||||
|
|
||||||
|
self._motors: List[Motor] = []
|
||||||
|
self._config = self._parse_config(config_string) if config_string else {}
|
||||||
|
|
||||||
|
self._parse_registers()
|
||||||
|
|
||||||
|
def _parse_config(self, config_string: str) -> Dict[str, Any]:
|
||||||
|
config = {}
|
||||||
|
entries = config_string.split('|')
|
||||||
|
for entry in entries:
|
||||||
|
if entry:
|
||||||
|
key, value = entry.split(':')
|
||||||
|
config[key.strip()] = self._convert_value(value.strip())
|
||||||
|
return config
|
||||||
|
|
||||||
|
def _convert_value(self, value: str) -> Union[int, float, bool, str]:
|
||||||
|
if value.isdigit():
|
||||||
|
return int(value)
|
||||||
|
try:
|
||||||
|
return float(value)
|
||||||
|
except ValueError:
|
||||||
|
if value.lower() in ['true', 'false']:
|
||||||
|
return value.lower() == 'true'
|
||||||
|
return value
|
||||||
|
|
||||||
|
def _parse_registers(self) -> None:
|
||||||
|
with open(self._filepath, 'r') as file:
|
||||||
|
log_content = file.read()
|
||||||
|
|
||||||
|
sections = re.split(self._section_pattern, log_content)
|
||||||
|
|
||||||
|
# Detect only the latest dumps from the log (to ignore potential previous and outdated dumps)
|
||||||
|
last_sections: Dict[str, int] = {}
|
||||||
|
for i in range(1, len(sections), 2):
|
||||||
|
stepper_name = 'stepper_' + sections[i].strip()
|
||||||
|
last_sections[stepper_name] = i
|
||||||
|
|
||||||
|
for stepper_name, index in last_sections.items():
|
||||||
|
content = sections[index + 1]
|
||||||
|
motor = Motor(stepper_name)
|
||||||
|
|
||||||
|
# Apply general properties from config string
|
||||||
|
for key, value in self._config.items():
|
||||||
|
if stepper_name in key:
|
||||||
|
prop_key = key.replace(stepper_name + '_', '')
|
||||||
|
motor.set_property(prop_key, value)
|
||||||
|
elif 'autotune' in key:
|
||||||
|
motor.set_property(key, value)
|
||||||
|
|
||||||
|
# Parse TMC registers
|
||||||
|
for key, pattern in self._register_patterns.items():
|
||||||
|
match = re.search(pattern, content)
|
||||||
|
if match:
|
||||||
|
values = match.group(1).strip()
|
||||||
|
motor.set_register(key, values)
|
||||||
|
|
||||||
|
self._motors.append(motor)
|
||||||
|
|
||||||
|
# Find and return the motor by its name
|
||||||
|
def get_motor(self, motor_name: str) -> Optional[Motor]:
|
||||||
|
for motor in self._motors:
|
||||||
|
if motor._name == motor_name:
|
||||||
|
return motor
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Get all the motor list at once
|
||||||
|
def get_motors(self) -> List[Motor]:
|
||||||
|
return self._motors
|
||||||
|
|
||||||
|
|
||||||
|
# # Usage example:
|
||||||
|
# config_string = "stepper_x_tmc:tmc2240|stepper_x_run_current:0.9|stepper_x_hold_current:0.9|stepper_y_tmc:tmc2240|stepper_y_run_current:0.9|stepper_y_hold_current:0.9|autotune_enabled:True|stepper_x_motor:ldo-35sth48-1684ah|stepper_x_voltage:|stepper_y_motor:ldo-35sth48-1684ah|stepper_y_voltage:|"
|
||||||
|
# parser = MotorLogParser('/path/to/your/logfile.log', config_string)
|
||||||
|
|
||||||
|
# stepper_x = parser.get_motor('stepper_x')
|
||||||
|
# stepper_y = parser.get_motor('stepper_y')
|
||||||
|
|
||||||
|
# print(stepper_x)
|
||||||
|
# print(stepper_y)
|
||||||
@@ -26,10 +26,12 @@ from src.graph_creators.graph_belts import belts_calibration
|
|||||||
from src.graph_creators.graph_shaper import shaper_calibration
|
from src.graph_creators.graph_shaper import shaper_calibration
|
||||||
from src.graph_creators.graph_vibrations import vibrations_profile
|
from src.graph_creators.graph_vibrations import vibrations_profile
|
||||||
from src.helpers.locale_utils import print_with_c_locale
|
from src.helpers.locale_utils import print_with_c_locale
|
||||||
|
from src.helpers.motorlogparser import MotorLogParser
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
KLIPPER_FOLDER = Path.home() / 'klipper'
|
KLIPPER_FOLDER = Path.home() / 'klipper'
|
||||||
|
KLIPPER_LOG_FOLDER = Path.home() / 'printer_data/logs'
|
||||||
RESULTS_BASE_FOLDER = Path.home() / 'printer_data/config/K-ShakeTune_results'
|
RESULTS_BASE_FOLDER = Path.home() / 'printer_data/config/K-ShakeTune_results'
|
||||||
RESULTS_SUBFOLDERS = {'belts': 'belts', 'shaper': 'inputshaper', 'vibrations': 'vibrations'}
|
RESULTS_SUBFOLDERS = {'belts': 'belts', 'shaper': 'inputshaper', 'vibrations': 'vibrations'}
|
||||||
|
|
||||||
@@ -102,6 +104,13 @@ class Config:
|
|||||||
choices=['cartesian', 'corexy'],
|
choices=['cartesian', 'corexy'],
|
||||||
help='Machine kinematics configuration used for the vibrations profile creation',
|
help='Machine kinematics configuration used for the vibrations profile creation',
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--metadata',
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
dest='metadata',
|
||||||
|
help='Motor configuration metadata printed on the vibrations profiles',
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-c',
|
'-c',
|
||||||
'--keep_csv',
|
'--keep_csv',
|
||||||
@@ -279,14 +288,18 @@ class VibrationsGraphCreator(GraphCreator):
|
|||||||
self._kinematics = None
|
self._kinematics = None
|
||||||
self._accel = None
|
self._accel = None
|
||||||
self._chip_name = None
|
self._chip_name = None
|
||||||
|
self._motors = None
|
||||||
|
|
||||||
self._setup_folder('vibrations')
|
self._setup_folder('vibrations')
|
||||||
|
|
||||||
def configure(self, kinematics: str, accel: float, chip_name: str) -> None:
|
def configure(self, kinematics: str, accel: float, chip_name: str, metadata: str) -> None:
|
||||||
self._kinematics = kinematics
|
self._kinematics = kinematics
|
||||||
self._accel = accel
|
self._accel = accel
|
||||||
self._chip_name = chip_name
|
self._chip_name = chip_name
|
||||||
|
|
||||||
|
parser = MotorLogParser(Config.KLIPPER_LOG_FOLDER / 'klippy.log', metadata)
|
||||||
|
self._motors = parser.get_motors()
|
||||||
|
|
||||||
def _archive_files(self, lognames: list[Path]) -> None:
|
def _archive_files(self, lognames: list[Path]) -> None:
|
||||||
tar_path = self._folder / f'{self._type}_{self._graph_date}.tar.gz'
|
tar_path = self._folder / f'{self._type}_{self._graph_date}.tar.gz'
|
||||||
with tarfile.open(tar_path, 'w:gz') as tar:
|
with tarfile.open(tar_path, 'w:gz') as tar:
|
||||||
@@ -308,6 +321,7 @@ class VibrationsGraphCreator(GraphCreator):
|
|||||||
kinematics=self._kinematics,
|
kinematics=self._kinematics,
|
||||||
accel=self._accel,
|
accel=self._accel,
|
||||||
st_version=self._version,
|
st_version=self._version,
|
||||||
|
motors=self._motors,
|
||||||
)
|
)
|
||||||
self._save_figure_and_cleanup(fig, lognames)
|
self._save_figure_and_cleanup(fig, lognames)
|
||||||
|
|
||||||
@@ -369,7 +383,7 @@ def main():
|
|||||||
'shaper': (ShaperGraphCreator, lambda gc: gc.configure(options.scv, options.max_smoothing)),
|
'shaper': (ShaperGraphCreator, lambda gc: gc.configure(options.scv, options.max_smoothing)),
|
||||||
'vibrations': (
|
'vibrations': (
|
||||||
VibrationsGraphCreator,
|
VibrationsGraphCreator,
|
||||||
lambda gc: gc.configure(options.kinematics, options.accel_used, options.chip_name),
|
lambda gc: gc.configure(options.kinematics, options.accel_used, options.chip_name, options.metadata),
|
||||||
),
|
),
|
||||||
'axesmap': (AxesMapFinder, None),
|
'axesmap': (AxesMapFinder, None),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user