diff options
author | Tircown <74233386+Tircown@users.noreply.github.com> | 2021-05-03 20:31:23 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-03 14:31:23 -0400 |
commit | f2c74ec0239ca9fe4b6c84d05337e86fa093b492 (patch) | |
tree | 3c1c71a52b298fc8602a2518082a7d0ae4494dfa /klippy/kinematics/hybrid_corexz.py | |
parent | f10247a498f2a73f5b2ffab931ff427951bf5342 (diff) | |
download | kutter-f2c74ec0239ca9fe4b6c84d05337e86fa093b492.tar.gz kutter-f2c74ec0239ca9fe4b6c84d05337e86fa093b492.tar.xz kutter-f2c74ec0239ca9fe4b6c84d05337e86fa093b492.zip |
kinematics: Add hybrid-corexy and hybrid-corexz (#4229)
Signed-off-by: Fabrice GALLET <tircown@gmail.com>
Diffstat (limited to 'klippy/kinematics/hybrid_corexz.py')
-rw-r--r-- | klippy/kinematics/hybrid_corexz.py | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/klippy/kinematics/hybrid_corexz.py b/klippy/kinematics/hybrid_corexz.py new file mode 100644 index 00000000..85f81ce9 --- /dev/null +++ b/klippy/kinematics/hybrid_corexz.py @@ -0,0 +1,100 @@ +# Code for handling the kinematics of hybrid-corexz robots +# +# Copyright (C) 2021 Fabrice Gallet <tircown@gmail.com> +# +# This file may be distributed under the terms of the GNU GPLv3 license. +import logging +import stepper + +# The hybrid-corexz kinematic is also known as Markforged kinematics +class HybridCoreXZKinematics: + def __init__(self, toolhead, config): + self.printer = config.get_printer() + printer_config = config.getsection('printer') + # itersolve parameters + self.rails = [ stepper.PrinterRail(config.getsection('stepper_x')), + stepper.LookupMultiRail(config.getsection('stepper_y')), + stepper.LookupMultiRail(config.getsection('stepper_z'))] + self.rails[2].get_endstops()[0][0].add_stepper( + self.rails[0].get_steppers()[0]) + self.rails[0].setup_itersolve('corexz_stepper_alloc', '-') + self.rails[1].setup_itersolve('cartesian_stepper_alloc', 'y') + self.rails[2].setup_itersolve('cartesian_stepper_alloc', 'z') + ranges = [r.get_range() for r in self.rails] + self.axes_min = toolhead.Coord(*[r[0] for r in ranges], e=0.) + self.axes_max = toolhead.Coord(*[r[1] for r in ranges], e=0.) + for s in self.get_steppers(): + s.set_trapq(toolhead.get_trapq()) + toolhead.register_step_generator(s.generate_steps) + self.printer.register_event_handler("stepper_enable:motor_off", + self._motor_off) + # Setup boundary checks + max_velocity, max_accel = toolhead.get_max_velocity() + self.max_z_velocity = config.getfloat( + 'max_z_velocity', max_velocity, above=0., maxval=max_velocity) + self.max_z_accel = config.getfloat( + 'max_z_accel', max_accel, above=0., maxval=max_accel) + self.limits = [(1.0, -1.0)] * 3 + def get_steppers(self): + return [s for rail in self.rails for s in rail.get_steppers()] + def calc_tag_position(self): + pos = [rail.get_tag_position() for rail in self.rails] + return [pos[0] + pos[2], pos[1], pos[2]] + def set_position(self, newpos, homing_axes): + for i, rail in enumerate(self.rails): + rail.set_position(newpos) + if i in homing_axes: + self.limits[i] = rail.get_range() + def note_z_not_homed(self): + # Helper for Safe Z Home + self.limits[2] = (1.0, -1.0) + def _home_axis(self, homing_state, axis, rail): + position_min, position_max = rail.get_range() + hi = rail.get_homing_info() + homepos = [None, None, None, None] + homepos[axis] = hi.position_endstop + forcepos = list(homepos) + if hi.positive_dir: + forcepos[axis] -= 1.5 * (hi.position_endstop - position_min) + else: + forcepos[axis] += 1.5 * (position_max - hi.position_endstop) + # Perform homing + homing_state.home_rails([rail], forcepos, homepos) + def home(self, homing_state): + for axis in homing_state.get_axes(): + self._home_axis(homing_state, axis, self.rails[axis]) + def _motor_off(self, print_time): + self.limits = [(1.0, -1.0)] * 3 + def _check_endstops(self, move): + end_pos = move.end_pos + for i in (0, 1, 2): + if (move.axes_d[i] + and (end_pos[i] < self.limits[i][0] + or end_pos[i] > self.limits[i][1])): + if self.limits[i][0] > self.limits[i][1]: + raise move.move_error("Must home axis first") + raise move.move_error() + def check_move(self, move): + limits = self.limits + xpos, ypos = move.end_pos[:2] + if (xpos < limits[0][0] or xpos > limits[0][1] + or ypos < limits[1][0] or ypos > limits[1][1]): + self._check_endstops(move) + if not move.axes_d[2]: + # Normal XY move - use defaults + return + # Move with Z - update velocity and accel for slower Z axis + self._check_endstops(move) + z_ratio = move.move_d / abs(move.axes_d[2]) + move.limit_speed( + self.max_z_velocity * z_ratio, self.max_z_accel * z_ratio) + def get_status(self, eventtime): + axes = [a for a, (l, h) in zip("xyz", self.limits) if l <= h] + return { + 'homed_axes': "".join(axes), + 'axis_minimum': self.axes_min, + 'axis_maximum': self.axes_max, + } + +def load_kinematics(toolhead, config): + return HybridCoreXZKinematics(toolhead, config) |