Skip to content

Commit

Permalink
pid_calibrate: apply tolerance logic
Browse files Browse the repository at this point in the history
Apply the tolerance logic for the primary controller calibration

Signed-off-by: Rodrigo Andrade <[email protected]>
  • Loading branch information
rodrigo2019 authored and rogerlz committed Feb 13, 2024
1 parent a9f0dd8 commit 6784959
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 15 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Our goal is to support features and behavior that could be "risky" if used incor
If I want my printer to light itself on fire, I should be able to make my printer light itself on fire.

## Features merged into the master branch:
- [heater: Dual Loop PID](https://github.com/DangerKlippers/danger-klipper/issues/58) ([klipper#5972](https://github.com/Klipper3d/klipper/pull/5972))

- [core: no Python2 tests; no PRU boards](https://github.com/DangerKlippers/danger-klipper/pull/39)

Expand All @@ -23,6 +22,8 @@ If I want my printer to light itself on fire, I should be able to make my printe

- [heater: velocity PID](https://github.com/DangerKlippers/danger-klipper/pull/47) ([klipper#6272](https://github.com/Klipper3d/klipper/pull/6272))

- [heater: Dual Loop PID](https://github.com/DangerKlippers/danger-klipper/issues/58) ([klipper#5972](https://github.com/Klipper3d/klipper/pull/5972))

- [gcode: jinja2.ext.do extension](https://github.com/DangerKlippers/danger-klipper/pull/26) ([klipper#5149](https://github.com/Klipper3d/klipper/pull/5149))

- [gcode: gcode_shell_command](https://github.com/DangerKlippers/danger-klipper/pull/26) ([klipper#2173](https://github.com/Klipper3d/klipper/pull/2173) / [kiuah](https://github.com/dw-0/kiauh/blob/master/resources/gcode_shell_command.py) )
Expand Down
60 changes: 46 additions & 14 deletions klippy/extras/pid_calibrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ def __init__(self, config):
cmd_PID_CALIBRATE_help = "Run PID calibration test"

def _calibrate(
self, pheaters, heater, target, tolerance, fname, gcmd,
calibrate_secondary
self,
pheaters,
heater,
target,
tolerance,
fname,
gcmd,
calibrate_secondary,
):
if (
isinstance(heater.control, heaters.ControlDualLoopPID)
Expand All @@ -48,9 +54,7 @@ def _calibrate(
calibrate_secondary=calibrate_secondary,
)
else:
calibrate = ControlAutoTune(heater,
target,
tolerance)
calibrate = ControlAutoTune(heater, target, tolerance)

old_control = heater.set_control(calibrate)
try:
Expand Down Expand Up @@ -84,7 +88,13 @@ def cmd_PID_CALIBRATE(self, gcmd):
if isinstance(heater.control, heaters.ControlDualLoopPID):
fname = "/tmp/heattest_secondary.txt" if write_file else None
kp_s, ki_s, kd_s, _ = self._calibrate(
pheaters, heater, target, tolerance, fname, gcmd, calibrate_secondary=True
pheaters,
heater,
target,
tolerance,
fname,
gcmd,
calibrate_secondary=True,
)
old_kp = heater.control.secondary_pid.Kp
old_ki = heater.control.secondary_pid.Ki
Expand All @@ -95,7 +105,13 @@ def cmd_PID_CALIBRATE(self, gcmd):
fname = "/tmp/heattest_primary.txt" if write_file else None

kp_p, ki_p, kd_p, _ = self._calibrate(
pheaters, heater, target, tolerance, fname, gcmd, calibrate_secondary=False
pheaters,
heater,
target,
tolerance,
fname,
gcmd,
calibrate_secondary=False,
)

heater.control.secondary_pid.kp = old_kp
Expand All @@ -122,7 +138,13 @@ def cmd_PID_CALIBRATE(self, gcmd):
else:
fname = "/tmp/heattest.txt" if write_file else None
Kp, Ki, Kd, old_control = self._calibrate(
pheaters, heater, target, tolerance, fname, gcmd, calibrate_secondary=False
pheaters,
heater,
target,
tolerance,
fname,
gcmd,
calibrate_secondary=False,
)
logging.info("Autotune: final: Kp=%f Ki=%f Kd=%f", Kp, Ki, Kd)
gcmd.respond_info(
Expand All @@ -138,14 +160,17 @@ def cmd_PID_CALIBRATE(self, gcmd):
configfile.set(heater_name, "pid_Ki", "%.3f" % (Ki,))
configfile.set(heater_name, "pid_Kd", "%.3f" % (Kd,))


TUNE_PID_DELTA = 5.0
TUNE_PID_TOL = 0.02
TUNE_PID_SAMPLES = 3
TUNE_PID_MAX_PEAKS = 60


class ControlAutoTune:
def __init__(self, heater, target, tolerance, control=None, calibrate_secondary=False):
def __init__(
self, heater, target, tolerance, control=None, calibrate_secondary=False
):
self.heater = heater
self.heater_max_power = heater.get_max_power()
# store the reference so we can push messages if needed
Expand Down Expand Up @@ -185,8 +210,9 @@ def __init__(self, heater, target, tolerance, control=None, calibrate_secondary=
self._control = control
self._calibrate_secondary = calibrate_secondary

def temperature_update(self, read_time, primary_temp, target_temp,
secondary_temp=None):
def temperature_update(
self, read_time, primary_temp, target_temp, secondary_temp=None
):

if self._calibrate_secondary:
ref_temp = secondary_temp
Expand All @@ -201,7 +227,11 @@ def temperature_update(self, read_time, primary_temp, target_temp,
(read_time, ref_temp, self.heater.last_pwm_value, self.target)
)
# ensure the starting temp is low enough to run the test.
if not self.started and ref_temp >= self.temp_low and self._control is None:
if (
not self.started
and ref_temp >= self.temp_low
and self._control is None
):
self.errored = True
self.finish(read_time)
self.gcode.respond_info("temperature to high to start calibration")
Expand Down Expand Up @@ -253,8 +283,10 @@ def temperature_update(self, read_time, primary_temp, target_temp,
if self._control is not None and not self._calibrate_secondary:
pid = self._control.secondary_pid
sec_target = self._control.sec_max_temp_target
_, bounded_co = pid.calculate_output(read_time, secondary_temp,
sec_target)
_, bounded_co = pid.calculate_output(
read_time, secondary_temp, sec_target
)
bounded_co = min(bounded_co, self.powers[-1])
self.heater.set_pwm(read_time, bounded_co)
else:
self.heater.set_pwm(read_time, self.powers[-1])
Expand Down
80 changes: 80 additions & 0 deletions test/klippy/dual_loop_pid.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Config for extruder testing
[stepper_x]
step_pin: PF0
dir_pin: PF1
enable_pin: !PD7
microsteps: 16
rotation_distance: 40
endstop_pin: ^PE5
position_endstop: 0
position_max: 200
homing_speed: 50

[stepper_y]
step_pin: PF6
dir_pin: !PF7
enable_pin: !PF2
microsteps: 16
rotation_distance: 40
endstop_pin: ^PJ1
position_endstop: 0
position_max: 200
homing_speed: 50

[stepper_z]
step_pin: PL3
dir_pin: PL1
enable_pin: !PK0
microsteps: 16
rotation_distance: 8
endstop_pin: ^PD3
position_endstop: 0.5
position_max: 200

[temperature_sensor myExtraSensor]
sensor_type: Generic 3950
sensor_pin: PF4
min_temp: 0
max_temp: 80

[extruder]
step_pin: PA4
dir_pin: PA6
enable_pin: !PA2
microsteps: 16
rotation_distance: 33.5
nozzle_diameter: 0.500
filament_diameter: 3.500
heater_pin: PB4
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PK5
min_temp: 0
max_temp: 400

secondary_sensor_name: myExtraSensor
secondary_max_temp_target: 280
control: dual_loop_pid
primary_pid_kp: 22.2
primary_pid_ki: 1.08
primary_pid_kd: 114
secondary_pid_kp: 22.2
secondary_pid_ki: 1.08
secondary_pid_kd: 114

[extruder_stepper my_extra_stepper]
extruder: extruder
step_pin: PH5
dir_pin: PH6
enable_pin: !PB5
microsteps: 16
rotation_distance: 28.2

[mcu]
serial: /dev/ttyACM0

[printer]
kinematics: cartesian
max_velocity: 300
max_accel: 3000
max_z_velocity: 5
max_z_accel: 100
13 changes: 13 additions & 0 deletions test/klippy/dual_loop_pid.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Pid hot modify tests
DICTIONARY atmega2560.dict
CONFIG dual_loop_pid.cfg

# Extrude only
G1 E5
G1 E-2
G1 E7

# Home and extrusion moves
G28
G1 X20 Y20 Z1
G1 X25 Y25 E7.5

0 comments on commit 6784959

Please sign in to comment.