def __init__(self, reactor, serialport, baud, logger=None): if logger is not None: self.logger = logger else: self.logger = logging.getLogger('serial') self.reactor = reactor self.serialport = serialport self.baud = baud # Serial port self.ser = None self.msgparser = msgproto.MessageParser() # C interface self.ffi_main, self.ffi_lib = chelper.get_ffi() self.serialqueue = None self.default_cmd_queue = self.alloc_command_queue() self.stats_buf = self.ffi_main.new('char[4096]') # Threading self.lock = threading.Lock() self.background_thread = None # Message handlers handlers = { '#unknown': self.handle_unknown, '#output': self.handle_output, 'shutdown': self.handle_output, 'is_shutdown': self.handle_output } self.handlers = {(k, None): v for k, v in handlers.items()}
def build_config(self): max_error = self._mcu.get_max_stepper_error() min_stop_interval = max(0., self._min_stop_interval - max_error) self._mcu.add_config_cmd( "config_stepper oid=%d step_pin=%s dir_pin=%s" " min_stop_interval=%d invert_step=%d" % ( self._oid, self._step_pin, self._dir_pin, self._mcu.seconds_to_clock(min_stop_interval), self._invert_step)) self._mcu.add_config_cmd( "reset_step_clock oid=%d clock=0" % (self._oid,), is_init=True) step_cmd = self._mcu.lookup_command( "queue_step oid=%c interval=%u count=%hu add=%hi") dir_cmd = self._mcu.lookup_command( "set_next_step_dir oid=%c dir=%c") self._reset_cmd = self._mcu.lookup_command( "reset_step_clock oid=%c clock=%u") self._get_position_cmd = self._mcu.lookup_command( "stepper_get_position oid=%c") ffi_main, self._ffi_lib = chelper.get_ffi() self._stepqueue = ffi_main.gc(self._ffi_lib.stepcompress_alloc( self._mcu.seconds_to_clock(max_error), step_cmd.msgid, dir_cmd.msgid, self._invert_dir, self._oid), self._ffi_lib.stepcompress_free) self._mcu.register_stepqueue(self._stepqueue)
def install(self, toolhead): self.toolhead = toolhead # setup extruding speed max_velocity, max_accel = self.toolhead.get_max_velocity() if self._max_extrude_only_velocity: self.max_e_velocity = self._max_extrude_only_velocity else: self.max_e_velocity = max_velocity * self.max_extrude_ratio if self._max_extrude_only_accel: self.max_e_accel = self._max_extrude_only_accel else: self.max_e_accel = max_accel * self.max_extrude_ratio # setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.trapq = ffi_main.gc(ffi_lib.trapq_alloc(), ffi_lib.trapq_free) self.trapq_append = ffi_lib.trapq_append self.trapq_free_moves = ffi_lib.trapq_free_moves self.sk_extruder = ffi_main.gc(ffi_lib.extruder_stepper_alloc(), ffi_lib.free) # dual-stepper support for s in self.stepper: s.actuator.set_max_jerk(9999999.9, 9999999.9) s.actuator.set_stepper_kinematics(self.sk_extruder) s.actuator.set_trapq(self.trapq) self.toolhead.register_step_generator(s.actuator.generate_steps) # setup pressure advance self.extruder_set_smooth_time = ffi_lib.extruder_set_smooth_time
def __init__(self, config): self.printer = config.get_printer() if config.get('endstop_pin', None) is not None: self.can_home = True self.rail = stepper.PrinterRail(config, need_position_minmax=False, default_position_endstop=0.) self.steppers = self.rail.get_steppers() else: self.can_home = False self.rail = stepper.PrinterStepper(config) self.steppers = [self.rail] self.velocity = config.getfloat('velocity', 5., above=0.) self.accel = config.getfloat('accel', 0., minval=0.) self.next_cmd_time = 0. # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.trapq = ffi_main.gc(ffi_lib.trapq_alloc(), ffi_lib.trapq_free) self.trapq_append = ffi_lib.trapq_append self.trapq_free_moves = ffi_lib.trapq_free_moves self.rail.setup_itersolve('cartesian_stepper_alloc', 'x') self.rail.set_trapq(self.trapq) self.rail.set_max_jerk(9999999.9, 9999999.9) # Register commands stepper_name = config.get_name().split()[1] self.gcode = self.printer.lookup_object('gcode') self.gcode.register_mux_command('MANUAL_STEPPER', "STEPPER", stepper_name, self.cmd_MANUAL_STEPPER, desc=self.cmd_MANUAL_STEPPER_help)
def __init__(self, name, step_pin_params, dir_pin_params, step_dist, units_in_radians=False): self._name = name self._step_dist = step_dist self._units_in_radians = units_in_radians self._mcu = step_pin_params['chip'] self._oid = oid = self._mcu.create_oid() self._mcu.register_config_callback(self._build_config) self._step_pin = step_pin_params['pin'] self._invert_step = step_pin_params['invert'] if dir_pin_params['chip'] is not self._mcu: raise self._mcu.get_printer().config_error( "Stepper dir pin must be on same mcu as step pin") self._dir_pin = dir_pin_params['pin'] self._invert_dir = dir_pin_params['invert'] self._mcu_position_offset = self._tag_position = 0. self._min_stop_interval = 0. self._reset_cmd_id = self._get_position_cmd = None self._active_callbacks = [] ffi_main, self._ffi_lib = chelper.get_ffi() self._stepqueue = ffi_main.gc(self._ffi_lib.stepcompress_alloc(oid), self._ffi_lib.stepcompress_free) self._mcu.register_stepqueue(self._stepqueue) self._stepper_kinematics = None self._itersolve_generate_steps = self._ffi_lib.itersolve_generate_steps self._itersolve_check_active = self._ffi_lib.itersolve_check_active self._trapq = ffi_main.NULL
def build_config(self): self._mcu_freq = self._mcu.get_mcu_freq() self._velocity_factor = 1. / (self._mcu_freq * self._step_dist) self._accel_factor = 1. / (self._mcu_freq**2 * self._step_dist) max_error = self._mcu.get_max_stepper_error() min_stop_interval = max(0., self._min_stop_interval - max_error) self._mcu.add_config_cmd( "config_stepper oid=%d step_pin=%s dir_pin=%s" " min_stop_interval=TICKS(%.9f) invert_step=%d" % (self._oid, self._step_pin, self._dir_pin, min_stop_interval, self._invert_step)) self._mcu.register_stepper(self) step_cmd = self._mcu.lookup_command( "queue_step oid=%c interval=%u count=%hu add=%hi") dir_cmd = self._mcu.lookup_command("set_next_step_dir oid=%c dir=%c") self._reset_cmd = self._mcu.lookup_command( "reset_step_clock oid=%c clock=%u") self._get_position_cmd = self._mcu.lookup_command( "stepper_get_position oid=%c") ffi_main, self._ffi_lib = chelper.get_ffi() max_error = int(max_error * self._mcu_freq) self._stepqueue = ffi_main.gc( self._ffi_lib.stepcompress_alloc(max_error, step_cmd.msgid, dir_cmd.msgid, self._invert_dir, self._oid), self._ffi_lib.stepcompress_free)
def __init__(self, config): self.printer = config.get_printer() if config.get('endstop_pin', None) is not None: self.can_home = True self.stepper = stepper.PrinterRail(config, need_position_minmax=False, default_position_endstop=0.) else: self.can_home = False self.stepper = stepper.PrinterStepper(config) self.next_cmd_time = 0. # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free) self.move_fill = ffi_lib.move_fill self.stepper.setup_itersolve('cartesian_stepper_alloc', 'x') self.stepper.set_max_jerk(9999999.9, 9999999.9) # Register commands stepper_name = config.get_name().split()[1] self.gcode = self.printer.lookup_object('gcode') self.gcode.register_mux_command('MANUAL_STEPPER', "STEPPER", stepper_name, self.cmd_MANUAL_STEPPER, desc=self.cmd_MANUAL_STEPPER_help) self.printer.register_event_handler("toolhead:motor_off", self.handle_motor_off)
def __init__(self, name, step_pin_params, dir_pin_params, rotation_dist, steps_per_rotation, step_pulse_duration=None, units_in_radians=False): self._name = name self._rotation_dist = rotation_dist self._steps_per_rotation = steps_per_rotation self._step_pulse_duration = step_pulse_duration self._units_in_radians = units_in_radians self._step_dist = rotation_dist / steps_per_rotation self._mcu = step_pin_params['chip'] self._oid = oid = self._mcu.create_oid() self._mcu.register_config_callback(self._build_config) self._step_pin = step_pin_params['pin'] self._invert_step = step_pin_params['invert'] if dir_pin_params['chip'] is not self._mcu: raise self._mcu.get_printer().config_error( "Stepper dir pin must be on same mcu as step pin") self._dir_pin = dir_pin_params['pin'] self._invert_dir = self._orig_invert_dir = dir_pin_params['invert'] self._step_both_edge = self._req_step_both_edge = False self._mcu_position_offset = 0. self._reset_cmd_tag = self._get_position_cmd = None self._active_callbacks = [] ffi_main, ffi_lib = chelper.get_ffi() self._stepqueue = ffi_main.gc(ffi_lib.stepcompress_alloc(oid), ffi_lib.stepcompress_free) ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, self._invert_dir) self._mcu.register_stepqueue(self._stepqueue) self._stepper_kinematics = None self._itersolve_generate_steps = ffi_lib.itersolve_generate_steps self._itersolve_check_active = ffi_lib.itersolve_check_active self._trapq = ffi_main.NULL self._mcu.get_printer().register_event_handler('klippy:connect', self._query_mcu_position)
def __init__(self, config, clocksync): self._printer = config.get_printer() self._clocksync = clocksync self._reactor = self._printer.get_reactor() self._name = config.get_name() if self._name.startswith('mcu '): self._name = self._name[4:] self._printer.register_event_handler("klippy:connect", self._connect) self._printer.register_event_handler("klippy:mcu_identify", self._mcu_identify) self._printer.register_event_handler("klippy:shutdown", self._shutdown) self._printer.register_event_handler("klippy:disconnect", self._disconnect) # Serial port self._serialport = config.get('serial', '/dev/ttyS0') serial_rts = True if config.get('restart_method', None) == "cheetah": # Special case: Cheetah boards require RTS to be deasserted, else # a reset will trigger the built-in bootloader. serial_rts = False baud = 0 if not (self._serialport.startswith("/dev/rpmsg_") or self._serialport.startswith("/tmp/klipper_host_")): baud = config.getint('baud', 250000, minval=2400) self._serial = serialhdl.SerialReader(self._reactor, self._serialport, baud, serial_rts) # Restarts self._restart_method = 'command' if baud: rmethods = { m: m for m in [None, 'arduino', 'cheetah', 'command', 'rpi_usb'] } self._restart_method = config.getchoice('restart_method', rmethods, None) self._reset_cmd = self._config_reset_cmd = None self._emergency_stop_cmd = None self._is_shutdown = self._is_timeout = False self._shutdown_msg = "" # Config building self._printer.lookup_object('pins').register_chip(self._name, self) self._oid_count = 0 self._config_callbacks = [] self._config_cmds = [] self._restart_cmds = [] self._init_cmds = [] self._pin_map = config.get('pin_map', None) self._mcu_freq = 0. # Move command queuing ffi_main, self._ffi_lib = chelper.get_ffi() self._max_stepper_error = config.getfloat('max_stepper_error', 0.000025, minval=0.) self._stepqueues = [] self._steppersync = None # Stats self._stats_sumsq_base = 0. self._mcu_tick_avg = 0. self._mcu_tick_stddev = 0. self._mcu_tick_awake = 0.
def __init__(self, config): self.printer = config.get_printer() if config.get('endstop_pin', None) is not None: self.can_home = True self.stepper = stepper.PrinterRail( config, need_position_minmax=False, default_position_endstop=0.) else: self.can_home = False self.stepper = stepper.PrinterStepper(config) self.velocity = config.getfloat('velocity', 5., above=0.) self.accel = config.getfloat('accel', 0., minval=0.) self.next_cmd_time = 0. # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free) self.move_fill = ffi_lib.move_fill self.stepper.setup_itersolve('cartesian_stepper_alloc', 'x') self.stepper.set_max_jerk(9999999.9, 9999999.9) # Register commands stepper_name = config.get_name().split()[1] self.gcode = self.printer.lookup_object('gcode') self.gcode.register_mux_command('MANUAL_STEPPER', "STEPPER", stepper_name, self.cmd_MANUAL_STEPPER, desc=self.cmd_MANUAL_STEPPER_help) self.printer.register_event_handler( "toolhead:motor_off", self.handle_motor_off)
def __init__(self, config): self.printer = config.get_printer() self.name = config.get_name() shared_heater = config.get('shared_heater', None) pheater = self.printer.lookup_object('heater') if shared_heater is None: self.heater = pheater.setup_heater(config) else: self.heater = pheater.lookup_heater(shared_heater) self.stepper = stepper.PrinterStepper(config) self.nozzle_diameter = config.getfloat('nozzle_diameter', above=0.) filament_diameter = config.getfloat('filament_diameter', minval=self.nozzle_diameter) self.filament_area = math.pi * (filament_diameter * .5)**2 max_cross_section = config.getfloat('max_extrude_cross_section', 4. * self.nozzle_diameter**2, above=0.) self.max_extrude_ratio = max_cross_section / self.filament_area logging.info("Extruder max_extrude_ratio=%.6f", self.max_extrude_ratio) toolhead = self.printer.lookup_object('toolhead') max_velocity, max_accel = toolhead.get_max_velocity() self.max_e_velocity = config.getfloat('max_extrude_only_velocity', max_velocity * self.max_extrude_ratio, above=0.) self.max_e_accel = config.getfloat('max_extrude_only_accel', max_accel * self.max_extrude_ratio, above=0.) self.stepper.set_max_jerk(9999999.9, 9999999.9) self.max_e_dist = config.getfloat('max_extrude_only_distance', 50., minval=0.) self.activate_gcode = config.get('activate_gcode', '') self.deactivate_gcode = config.get('deactivate_gcode', '') self.pressure_advance = config.getfloat('pressure_advance', 0., minval=0.) self.pressure_advance_lookahead_time = config.getfloat( 'pressure_advance_lookahead_time', 0.010, minval=0.) self.need_motor_enable = True self.extrude_pos = 0. # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free) self.extruder_move_fill = ffi_lib.extruder_move_fill sk = ffi_main.gc(ffi_lib.extruder_stepper_alloc(), ffi_lib.free) self.stepper.setup_itersolve(sk) # Setup SET_PRESSURE_ADVANCE command gcode = self.printer.lookup_object('gcode') if self.name in ('extruder', 'extruder0'): gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", None, self.cmd_default_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help) gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", self.name, self.cmd_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help)
def __init__(self, gc_checking=False, process='printer'): # Main code self.event_handlers = {} self.root = None self._process = False self.monotonic = chelper.get_ffi()[1].get_monotonic self.process_name = process # Python garbage collection self._check_gc = gc_checking self._last_gc_times = [0., 0., 0.] # Timers self._timers = [] self._next_timer = self.NEVER # Callbacks self._async_pipe = None self._async_queue = queue.Queue() # Multiprocessing self.mp_queue = None self.mp_queues = {} self._mp_callback_handler = mp_callback self._mp_completions = {} # File descriptors self._fds = [] # Greenlets self._g_dispatch = None self._greenlets = [] self._all_greenlets = [] self.thread_id = threading.get_ident()
def __init__(self, reactor, serialport, baud): self.reactor = reactor self.serialport = serialport self.baud = baud # Serial port self.ser = None self.msgparser = msgproto.MessageParser() # C interface self.ffi_main, self.ffi_lib = chelper.get_ffi() self.serialqueue = None self.default_cmd_queue = self.alloc_command_queue() self.stats_buf = self.ffi_main.new('char[4096]') # MCU time/clock tracking self.last_ack_time = self.last_ack_rtt_time = 0. self.last_ack_clock = self.last_ack_rtt_clock = 0 self.est_clock = 0. # Threading self.lock = threading.Lock() self.background_thread = None # Message handlers self.status_timer = self.reactor.register_timer(self._status_event) self.status_cmd = None handlers = { '#unknown': self.handle_unknown, '#output': self.handle_output, 'status': self.handle_status, 'shutdown': self.handle_output, 'is_shutdown': self.handle_output } self.handlers = dict(((k, None), v) for k, v in handlers.items())
def __init__(self, mcu, step_pin, dir_pin, min_stop_interval, max_error): self._mcu = mcu self._oid = mcu.create_oid() step_pin, pullup, invert_step = parse_pin_extras(step_pin) dir_pin, pullup, self._invert_dir = parse_pin_extras(dir_pin) self._mcu_freq = mcu.get_mcu_freq() min_stop_interval = int(min_stop_interval * self._mcu_freq) max_error = int(max_error * self._mcu_freq) self.commanded_position = 0 self._mcu_position_offset = 0 mcu.add_config_cmd( "config_stepper oid=%d step_pin=%s dir_pin=%s" " min_stop_interval=%d invert_step=%d" % ( self._oid, step_pin, dir_pin, min_stop_interval, invert_step)) mcu.register_stepper(self) self._step_cmd = mcu.lookup_command( "queue_step oid=%c interval=%u count=%hu add=%hi") self._dir_cmd = mcu.lookup_command( "set_next_step_dir oid=%c dir=%c") self._reset_cmd = mcu.lookup_command( "reset_step_clock oid=%c clock=%u") ffi_main, self.ffi_lib = chelper.get_ffi() self._stepqueue = ffi_main.gc(self.ffi_lib.stepcompress_alloc( max_error, self._step_cmd.msgid , self._dir_cmd.msgid, self._invert_dir, self._oid), self.ffi_lib.stepcompress_free) self.print_to_mcu_time = mcu.print_to_mcu_time
def __init__(self, config): self.printer = config.get_printer() self.printer.register_event_handler("klippy:connect", self.connect) self.toolhead = None self.damping_ratio_x = config.getfloat( 'damping_ratio_x', 0.1, minval=0., maxval=1.) self.damping_ratio_y = config.getfloat( 'damping_ratio_y', 0.1, minval=0., maxval=1.) self.shaper_freq_x = config.getfloat('shaper_freq_x', 0., minval=0.) self.shaper_freq_y = config.getfloat('shaper_freq_y', 0., minval=0.) ffi_main, ffi_lib = chelper.get_ffi() self.shapers = {None: None , 'zv': ffi_lib.INPUT_SHAPER_ZV , 'zvd': ffi_lib.INPUT_SHAPER_ZVD , 'mzv': ffi_lib.INPUT_SHAPER_MZV , 'ei': ffi_lib.INPUT_SHAPER_EI , '2hump_ei': ffi_lib.INPUT_SHAPER_2HUMP_EI , '3hump_ei': ffi_lib.INPUT_SHAPER_3HUMP_EI} shaper_type = config.getchoice('shaper_type', self.shapers, None) if shaper_type is None: self.shaper_type_x = config.getchoice( 'shaper_type_x', self.shapers, 'mzv') self.shaper_type_y = config.getchoice( 'shaper_type_y', self.shapers, 'mzv') else: self.shaper_type_x = self.shaper_type_y = shaper_type self.stepper_kinematics = [] self.orig_stepper_kinematics = [] # Register gcode commands gcode = self.printer.lookup_object('gcode') gcode.register_command("SET_INPUT_SHAPER", self.cmd_SET_INPUT_SHAPER, desc=self.cmd_SET_INPUT_SHAPER_help)
def __init__(self, toolhead, config): self.rails = [ stepper.PrinterRail(config.getsection('stepper_x')), stepper.PrinterRail(config.getsection('stepper_y')), stepper.LookupMultiRail(config.getsection('stepper_z')) ] self.rails[0].add_to_endstop(self.rails[1].get_endstops()[0][0]) self.rails[1].add_to_endstop(self.rails[0].get_endstops()[0][0]) 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.need_motor_enable = True self.limits = [(1.0, -1.0)] * 3 # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free) self.move_fill = ffi_lib.move_fill self.rails[0].setup_itersolve( ffi_main.gc(ffi_lib.corexy_stepper_alloc('+'), ffi_lib.free)) self.rails[1].setup_itersolve( ffi_main.gc(ffi_lib.corexy_stepper_alloc('-'), ffi_lib.free)) self.rails[2].setup_cartesian_itersolve('z') # Setup stepper max halt velocity max_halt_velocity = toolhead.get_max_axis_halt() max_xy_halt_velocity = max_halt_velocity * math.sqrt(2.) self.rails[0].set_max_jerk(max_xy_halt_velocity, max_accel) self.rails[1].set_max_jerk(max_xy_halt_velocity, max_accel) self.rails[2].set_max_jerk(min(max_halt_velocity, self.max_z_velocity), self.max_z_accel)
def home_start(self, print_time, sample_time, sample_count, rest_time, triggered=True): clock = self._mcu.print_time_to_clock(print_time) rest_ticks = self._mcu.print_time_to_clock(print_time + rest_time) - clock self._rest_ticks = rest_ticks reactor = self._mcu.get_printer().get_reactor() self._trigger_completion = reactor.completion() expire_timeout = TRSYNC_TIMEOUT if len(self._trsyncs) == 1: expire_timeout = TRSYNC_SINGLE_MCU_TIMEOUT for trsync in self._trsyncs: trsync.start(print_time, self._trigger_completion, expire_timeout) etrsync = self._trsyncs[0] ffi_main, ffi_lib = chelper.get_ffi() ffi_lib.trdispatch_start(self._trdispatch, etrsync.REASON_HOST_REQUEST) self._home_cmd.send([ self._oid, clock, self._mcu.seconds_to_clock(sample_time), sample_count, rest_ticks, triggered ^ self._invert, etrsync.get_oid(), etrsync.REASON_ENDSTOP_HIT ], reqclock=clock) return self._trigger_completion
def __init__(self, config, extruder_num): self.printer = config.get_printer() self.name = config.get_name() shared_heater = config.get('shared_heater', None) pheater = self.printer.lookup_object('heater') gcode_id = 'T%d' % (extruder_num,) if shared_heater is None: self.heater = pheater.setup_heater(config, gcode_id) else: self.heater = pheater.lookup_heater(shared_heater) self.stepper = stepper.PrinterStepper(config) self.nozzle_diameter = config.getfloat('nozzle_diameter', above=0.) filament_diameter = config.getfloat( 'filament_diameter', minval=self.nozzle_diameter) self.filament_area = math.pi * (filament_diameter * .5)**2 def_max_cross_section = 4. * self.nozzle_diameter**2 def_max_extrude_ratio = def_max_cross_section / self.filament_area max_cross_section = config.getfloat( 'max_extrude_cross_section', def_max_cross_section, above=0.) self.max_extrude_ratio = max_cross_section / self.filament_area logging.info("Extruder max_extrude_ratio=%.6f", self.max_extrude_ratio) toolhead = self.printer.lookup_object('toolhead') max_velocity, max_accel = toolhead.get_max_velocity() self.max_e_velocity = config.getfloat( 'max_extrude_only_velocity', max_velocity * def_max_extrude_ratio , above=0.) self.max_e_accel = config.getfloat( 'max_extrude_only_accel', max_accel * def_max_extrude_ratio , above=0.) self.stepper.set_max_jerk(9999999.9, 9999999.9) self.max_e_dist = config.getfloat( 'max_extrude_only_distance', 50., minval=0.) gcode_macro = self.printer.try_load_module(config, 'gcode_macro') self.activate_gcode = gcode_macro.load_template( config, 'activate_gcode', '') self.deactivate_gcode = gcode_macro.load_template( config, 'deactivate_gcode', '') self.pressure_advance = config.getfloat( 'pressure_advance', 0., minval=0.) self.pressure_advance_lookahead_time = config.getfloat( 'pressure_advance_lookahead_time', 0.010, minval=0.) self.extrude_pos = 0. # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.extruder_add_move = ffi_lib.extruder_add_move self.trapq = ffi_main.gc(ffi_lib.trapq_alloc(), ffi_lib.trapq_free) self.trapq_free_moves = ffi_lib.trapq_free_moves self.stepper.setup_itersolve('extruder_stepper_alloc') self.stepper.set_trapq(self.trapq) toolhead.register_step_generator(self.stepper.generate_steps) toolhead.register_step_generator(self._free_moves) # Setup SET_PRESSURE_ADVANCE command gcode = self.printer.lookup_object('gcode') if self.name == 'extruder': gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", None, self.cmd_default_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help) gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", self.name, self.cmd_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help)
def _build_config(self): mcu = self._mcu # Setup config mcu.add_config_cmd("config_trsync oid=%d" % (self._oid,)) mcu.add_config_cmd( "trsync_start oid=%d report_clock=0 report_ticks=0 expire_reason=0" % (self._oid,), on_restart=True) # Lookup commands self._trsync_start_cmd = mcu.lookup_command( "trsync_start oid=%c report_clock=%u report_ticks=%u" " expire_reason=%c", cq=self._cmd_queue) self._trsync_set_timeout_cmd = mcu.lookup_command( "trsync_set_timeout oid=%c clock=%u", cq=self._cmd_queue) self._trsync_trigger_cmd = mcu.lookup_command( "trsync_trigger oid=%c reason=%c", cq=self._cmd_queue) self._trsync_query_cmd = mcu.lookup_query_command( "trsync_trigger oid=%c reason=%c", "trsync_state oid=%c can_trigger=%c trigger_reason=%c clock=%u", oid=self._oid, cq=self._cmd_queue) self._stepper_stop_cmd = mcu.lookup_command( "stepper_stop_on_trigger oid=%c trsync_oid=%c", cq=self._cmd_queue) # Create trdispatch_mcu object set_timeout_tag = mcu.lookup_command_tag( "trsync_set_timeout oid=%c clock=%u") trigger_tag = mcu.lookup_command_tag("trsync_trigger oid=%c reason=%c") state_tag = mcu.lookup_command_tag( "trsync_state oid=%c can_trigger=%c trigger_reason=%c clock=%u") ffi_main, ffi_lib = chelper.get_ffi() self._trdispatch_mcu = ffi_main.gc(ffi_lib.trdispatch_mcu_alloc( self._trdispatch, mcu._serial.serialqueue, # XXX self._cmd_queue, self._oid, set_timeout_tag, trigger_tag, state_tag), ffi_lib.free)
def _connect(self): config_params = self._send_get_config() if not config_params['is_config']: if self._restart_method == 'rpi_usb': # Only configure mcu after usb power reset self._check_restart("full reset before config") # Not configured - send config and issue get_config again self._send_config(None) config_params = self._send_get_config() if not config_params['is_config'] and not self.is_fileoutput(): raise error("Unable to configure MCU '%s'" % (self._name, )) else: start_reason = self._printer.get_start_args().get("start_reason") if start_reason == 'firmware_restart': raise error("Failed automated reset of MCU '%s'" % (self._name, )) # Already configured - send init commands self._send_config(config_params['crc']) # Setup steppersync with the move_count returned by get_config move_count = config_params['move_count'] if move_count < self._reserved_move_slots: raise error("Too few moves available on MCU '%s'" % (self._name, )) ffi_main, ffi_lib = chelper.get_ffi() self._steppersync = ffi_main.gc( ffi_lib.steppersync_alloc(self._serial.serialqueue, self._stepqueues, len(self._stepqueues), move_count - self._reserved_move_slots), ffi_lib.steppersync_free) ffi_lib.steppersync_set_time(self._steppersync, 0., self._mcu_freq) # Log config information move_msg = "Configured MCU '%s' (%d moves)" % (self._name, move_count) logging.info(move_msg) log_info = self._log_info() + "\n" + move_msg self._printer.set_rollover_info(self._name, log_info, log=False)
def __init__(self, printer, config): self._printer = printer self._config = config # Serial port baud = config.getint('baud', 250000) self._serialport = config.get('serial', '/dev/ttyS0') self.serial = serialhdl.SerialReader(printer.reactor, self._serialport, baud) self.is_shutdown = False self._shutdown_msg = "" self._is_fileoutput = False self._timeout_timer = printer.reactor.register_timer( self.timeout_handler) # Config building self._emergency_stop_cmd = self._clear_shutdown_cmd = None self._oids = [] self._config_cmds = [] self._config_crc = None self._init_callbacks = [] self._pin_map = config.get('pin_map', None) self._custom = config.get('custom', '') # Move command queuing ffi_main, self.ffi_lib = chelper.get_ffi() self._max_stepper_error = config.getfloat('max_stepper_error', 0.000025) self._steppers = [] self._steppersync = None # Print time to clock epoch calculations self._print_start_time = 0. self._mcu_freq = 0. # Stats self._stats_sumsq_base = 0. self._mcu_tick_avg = 0. self._mcu_tick_stddev = 0.
def __init__(self, config): self.printer = config.get_printer() self.name = config.get_name().split()[-1] self.pressure_advance = self.pressure_advance_smooth_time = 0. # Setup stepper self.stepper = stepper.PrinterStepper(config) ffi_main, ffi_lib = chelper.get_ffi() self.sk_extruder = ffi_main.gc(ffi_lib.extruder_stepper_alloc(), ffi_lib.free) self.stepper.set_stepper_kinematics(self.sk_extruder) # Register commands self.printer.register_event_handler("klippy:connect", self._handle_connect) gcode = self.printer.lookup_object('gcode') if self.name == 'extruder': gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", None, self.cmd_default_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help) gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", self.name, self.cmd_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help) gcode.register_mux_command("SET_EXTRUDER_STEP_DISTANCE", "EXTRUDER", self.name, self.cmd_SET_E_STEP_DISTANCE, desc=self.cmd_SET_E_STEP_DISTANCE_help) gcode.register_mux_command("SYNC_STEPPER_TO_EXTRUDER", "STEPPER", self.name, self.cmd_SYNC_STEPPER_TO_EXTRUDER, desc=self.cmd_SYNC_STEPPER_TO_EXTRUDER_help)
def _set_input_shaper(self, shaper_type_x, shaper_type_y , shaper_freq_x, shaper_freq_y , damping_ratio_x, damping_ratio_y): if (shaper_type_x != self.shaper_type_x or shaper_type_y != self.shaper_type_y): self.toolhead.flush_step_generation() ffi_main, ffi_lib = chelper.get_ffi() new_delay = max( ffi_lib.input_shaper_get_step_generation_window( shaper_type_x, shaper_freq_x, damping_ratio_x), ffi_lib.input_shaper_get_step_generation_window( shaper_type_y, shaper_freq_y, damping_ratio_y)) self.toolhead.note_step_generation_scan_time(new_delay, old_delay=self.old_delay) self.old_delay = new_delay self.shaper_type_x = shaper_type_x self.shaper_type_y = shaper_type_y self.shaper_freq_x = shaper_freq_x self.shaper_freq_y = shaper_freq_y self.damping_ratio_x = damping_ratio_x self.damping_ratio_y = damping_ratio_y for sk in self.stepper_kinematics: ffi_lib.input_shaper_set_shaper_params(sk , shaper_type_x, shaper_type_y , shaper_freq_x, shaper_freq_y , damping_ratio_x, damping_ratio_y)
def _build_config(self): max_error = self._mcu.get_max_stepper_error() min_stop_interval = max(0., self._min_stop_interval - max_error) self._mcu.add_config_cmd( "config_stepper oid=%d step_pin=%s dir_pin=%s" " min_stop_interval=%d invert_step=%d" % (self._oid, self._step_pin, self._dir_pin, self._mcu.seconds_to_clock(min_stop_interval), self._invert_step)) self._mcu.add_config_cmd("reset_step_clock oid=%d clock=0" % (self._oid, ), on_restart=True) step_cmd_tag = self._mcu.lookup_command_tag( "queue_step oid=%c interval=%u count=%hu add=%hi") dir_cmd_tag = self._mcu.lookup_command_tag( "set_next_step_dir oid=%c dir=%c") self._reset_cmd_tag = self._mcu.lookup_command_tag( "reset_step_clock oid=%c clock=%u") self._get_position_cmd = self._mcu.lookup_query_command( "stepper_get_position oid=%c", "stepper_position oid=%c pos=%i", oid=self._oid) ffi_main, ffi_lib = chelper.get_ffi() ffi_lib.stepcompress_fill(self._stepqueue, self._mcu.seconds_to_clock(max_error), self._invert_dir, step_cmd_tag, dir_cmd_tag)
def _build_config(self): if self._step_pulse_duration is None: self._step_pulse_duration = .000002 invert_step = self._invert_step sbe = int(self._mcu.get_constants().get('STEPPER_BOTH_EDGE', '0')) if (self._req_step_both_edge and sbe and self._step_pulse_duration <= MIN_BOTH_EDGE_DURATION): # Enable stepper optimized step on both edges self._step_both_edge = True self._step_pulse_duration = 0. invert_step = -1 step_pulse_ticks = self._mcu.seconds_to_clock(self._step_pulse_duration) self._mcu.add_config_cmd( "config_stepper oid=%d step_pin=%s dir_pin=%s invert_step=%d" " step_pulse_ticks=%u" % (self._oid, self._step_pin, self._dir_pin, invert_step, step_pulse_ticks)) self._mcu.add_config_cmd("reset_step_clock oid=%d clock=0" % (self._oid,), on_restart=True) step_cmd_tag = self._mcu.lookup_command_tag( "queue_step oid=%c interval=%u count=%hu add=%hi") dir_cmd_tag = self._mcu.lookup_command_tag( "set_next_step_dir oid=%c dir=%c") self._reset_cmd_tag = self._mcu.lookup_command_tag( "reset_step_clock oid=%c clock=%u") self._get_position_cmd = self._mcu.lookup_query_command( "stepper_get_position oid=%c", "stepper_position oid=%c pos=%i", oid=self._oid) max_error = self._mcu.get_max_stepper_error() max_error_ticks = self._mcu.seconds_to_clock(max_error) ffi_main, ffi_lib = chelper.get_ffi() ffi_lib.stepcompress_fill(self._stepqueue, max_error_ticks, step_cmd_tag, dir_cmd_tag)
def __init__(self, config): self.printer = printer = config.get_printer() self.name = config.get_name() self.logger = printer.logger.getChild(self.name) self.config = config self.index = int(self.name[8:]) self.heater = printer.lookup_object(config.get('heater')) self.heater.set_min_extrude_temp(config.getfloat('min_extrude_temp', 170.0)) self.stepper = stepper.PrinterStepper(config, self.logger) self.nozzle_diameter = config.getfloat('nozzle_diameter', above=0.) filament_diameter = config.getfloat( 'filament_diameter', minval=self.nozzle_diameter) self.filament_area = math.pi * (filament_diameter * .5)**2 max_cross_section = config.getfloat( 'max_extrude_cross_section', 4. * self.nozzle_diameter**2 , above=0.) self.max_extrude_ratio = max_cross_section / self.filament_area self.logger.info("Extruder max_extrude_ratio=%.6f", self.max_extrude_ratio) self.toolhead = toolhead = printer.lookup_object('toolhead') max_velocity, max_accel = toolhead.get_max_velocity() self.max_e_velocity = config.getfloat( 'max_extrude_only_velocity', max_velocity * self.max_extrude_ratio , above=0.) self.max_e_accel = config.getfloat( 'max_extrude_only_accel', max_accel * self.max_extrude_ratio , above=0.) self.stepper.set_max_jerk(9999999.9, 9999999.9) self.max_e_dist = config.getfloat( 'max_extrude_only_distance', 50., minval=0.) self.activate_gcode = config.get('activate_gcode', '') self.deactivate_gcode = config.get('deactivate_gcode', '') self.pressure_advance = config.getfloat( 'pressure_advance', 0., minval=0.) self.pressure_advance_lookahead_time = config.getfloat( 'pressure_advance_lookahead_time', 0.010, minval=0.) self.need_motor_enable = True self.extrude_pos = 0. self.raw_filament = 0. self.extrude_factor = config.getfloat( 'extrusion_factor', 1.0, minval=0.1) # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free) self.extruder_move_fill = ffi_lib.extruder_move_fill sk = ffi_main.gc(ffi_lib.extruder_stepper_alloc(), ffi_lib.free) self.stepper.setup_itersolve(sk) # Setup SET_PRESSURE_ADVANCE command gcode = self.printer.lookup_object('gcode') if self.name in ('extruder', 'extruder0'): gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", None, self.cmd_default_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help) for key in [self.name.upper(), str(self.index)]: gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", key, self.cmd_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help) self.logger.debug("index={}, heater={}". format(self.index, self.heater.name))
def __init__(self, config): self.printer = config.get_printer() self.reactor = self.printer.get_reactor() self.all_mcus = self.printer.lookup_module_objects('mcu') self.mcu = self.all_mcus[0] self.move_queue = MoveQueue() self.commanded_pos = [0., 0., 0., 0.] # Velocity and acceleration control self.max_velocity = config.getfloat('max_velocity', above=0.) self.max_accel = config.getfloat('max_accel', above=0.) self.requested_accel_to_decel = config.getfloat( 'max_accel_to_decel', self.max_accel * 0.5, above=0.) self.max_accel_to_decel = min(self.requested_accel_to_decel, self.max_accel) self.square_corner_velocity = config.getfloat( 'square_corner_velocity', 5., minval=0.) self.config_max_velocity = self.max_velocity self.config_max_accel = self.max_accel self.config_square_corner_velocity = self.square_corner_velocity self.junction_deviation = 0. self._calc_junction_deviation() # Print time tracking self.buffer_time_low = config.getfloat( 'buffer_time_low', 1.000, above=0.) self.buffer_time_high = config.getfloat( 'buffer_time_high', 2.000, above=self.buffer_time_low) self.buffer_time_start = config.getfloat( 'buffer_time_start', 0.250, above=0.) self.move_flush_time = config.getfloat( 'move_flush_time', 0.050, above=0.) self.print_time = 0. self.last_print_start_time = 0. self.need_check_stall = -1. self.print_stall = 0 self.sync_print_time = True self.idle_flush_print_time = 0. self.flush_timer = self.reactor.register_timer(self._flush_handler) self.move_queue.set_flush_time(self.buffer_time_high) self.printer.try_load_module(config, "idle_timeout") # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free) self.move_fill = ffi_lib.move_fill # Create kinematics class self.extruder = kinematics.extruder.DummyExtruder() self.move_queue.set_extruder(self.extruder) kin_name = config.get('kinematics') try: mod = importlib.import_module('kinematics.' + kin_name) self.kin = mod.load_kinematics(self, config) except: msg = "Error loading kinematics '%s'" % (kin_name,) logging.exception(msg) raise config.error(msg) # SET_VELOCITY_LIMIT command gcode = self.printer.lookup_object('gcode') gcode.register_command('SET_VELOCITY_LIMIT', self.cmd_SET_VELOCITY_LIMIT, desc=self.cmd_SET_VELOCITY_LIMIT_help) gcode.register_command('M204', self.cmd_M204)
def set_dir_inverted(self, invert_dir): invert_dir = not not invert_dir if invert_dir == self._invert_dir: return self._invert_dir = invert_dir ffi_main, ffi_lib = chelper.get_ffi() ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, invert_dir) self._mcu.get_printer().send_event("stepper:set_dir_inverted", self)
def set_trapq(self, tq): if tq is None: ffi_main, self._ffi_lib = chelper.get_ffi() tq = ffi_main.NULL self._ffi_lib.itersolve_set_trapq(self._stepper_kinematics, tq) old_tq = self._trapq self._trapq = tq return old_tq
def __init__(self): self._fds = [] self._timers = [] self._next_timer = self.NEVER self._process = False self._g_dispatch = None self._greenlets = [] self.monotonic = chelper.get_ffi()[1].get_monotonic
def setup_cartesian_itersolve(self, axis): ffi_main, ffi_lib = chelper.get_ffi() self.setup_itersolve( ffi_main.gc(ffi_lib.cartesian_stepper_alloc(axis), ffi_lib.free)) for extra in self.extras: extra.setup_itersolve( ffi_main.gc(ffi_lib.cartesian_stepper_alloc(axis), ffi_lib.free))
def __init__(self, name): self._name = name self._ps = None self._running = running # IPC self._pipe, self._subpipe = multiprocessing.Pipe() # system timer self.monotonic = chelper.get_ffi()[1].get_monotonic
def __init__(self, config, extruder_num): self.printer = config.get_printer() self.name = config.get_name() shared_heater = config.get('shared_heater', None) pheater = self.printer.lookup_object('heater') gcode_id = 'T%d' % (extruder_num,) if shared_heater is None: self.heater = pheater.setup_heater(config, gcode_id) else: self.heater = pheater.lookup_heater(shared_heater) self.stepper = stepper.PrinterStepper(config) self.nozzle_diameter = config.getfloat('nozzle_diameter', above=0.) filament_diameter = config.getfloat( 'filament_diameter', minval=self.nozzle_diameter) self.filament_area = math.pi * (filament_diameter * .5)**2 def_max_cross_section = 4. * self.nozzle_diameter**2 def_max_extrude_ratio = def_max_cross_section / self.filament_area max_cross_section = config.getfloat( 'max_extrude_cross_section', def_max_cross_section, above=0.) self.max_extrude_ratio = max_cross_section / self.filament_area logging.info("Extruder max_extrude_ratio=%.6f", self.max_extrude_ratio) toolhead = self.printer.lookup_object('toolhead') max_velocity, max_accel = toolhead.get_max_velocity() self.max_e_velocity = config.getfloat( 'max_extrude_only_velocity', max_velocity * def_max_extrude_ratio , above=0.) self.max_e_accel = config.getfloat( 'max_extrude_only_accel', max_accel * def_max_extrude_ratio , above=0.) self.stepper.set_max_jerk(9999999.9, 9999999.9) self.max_e_dist = config.getfloat( 'max_extrude_only_distance', 50., minval=0.) self.activate_gcode = config.get('activate_gcode', '') self.deactivate_gcode = config.get('deactivate_gcode', '') self.pressure_advance = config.getfloat( 'pressure_advance', 0., minval=0.) self.pressure_advance_lookahead_time = config.getfloat( 'pressure_advance_lookahead_time', 0.010, minval=0.) self.need_motor_enable = True self.extrude_pos = 0. # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free) self.extruder_move_fill = ffi_lib.extruder_move_fill self.stepper.setup_itersolve('extruder_stepper_alloc') # Setup SET_PRESSURE_ADVANCE command gcode = self.printer.lookup_object('gcode') if self.name in ('extruder', 'extruder0'): gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", None, self.cmd_default_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help) gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", self.name, self.cmd_SET_PRESSURE_ADVANCE, desc=self.cmd_SET_PRESSURE_ADVANCE_help)
def __init__(self, config, clocksync): self._printer = config.get_printer() self._clocksync = clocksync self._reactor = self._printer.get_reactor() self._name = config.get_name() if self._name.startswith('mcu '): self._name = self._name[4:] self._printer.register_event_handler("klippy:connect", self._connect) self._printer.register_event_handler("klippy:shutdown", self._shutdown) self._printer.register_event_handler("klippy:disconnect", self._disconnect) # Serial port self._serialport = config.get('serial', '/dev/ttyS0') baud = 0 if not (self._serialport.startswith("/dev/rpmsg_") or self._serialport.startswith("/tmp/klipper_host_")): baud = config.getint('baud', 250000, minval=2400) self._serial = serialhdl.SerialReader( self._reactor, self._serialport, baud) # Restarts self._restart_method = 'command' if baud: rmethods = {m: m for m in [None, 'arduino', 'command', 'rpi_usb']} self._restart_method = config.getchoice( 'restart_method', rmethods, None) self._reset_cmd = self._config_reset_cmd = None self._emergency_stop_cmd = None self._is_shutdown = self._is_timeout = False self._shutdown_msg = "" # Config building self._printer.lookup_object('pins').register_chip(self._name, self) self._oid_count = 0 self._config_callbacks = [] self._init_cmds = [] self._config_cmds = [] self._pin_map = config.get('pin_map', None) self._custom = config.get('custom', '') self._mcu_freq = 0. # Move command queuing ffi_main, self._ffi_lib = chelper.get_ffi() self._max_stepper_error = config.getfloat( 'max_stepper_error', 0.000025, minval=0.) self._move_count = 0 self._stepqueues = [] self._steppersync = None # Stats self._stats_sumsq_base = 0. self._mcu_tick_avg = 0. self._mcu_tick_stddev = 0. self._mcu_tick_awake = 0.
def __init__(self): # Main code self._process = False self.monotonic = chelper.get_ffi()[1].get_monotonic # Timers self._timers = [] self._next_timer = self.NEVER # Callbacks self._pipe_fds = None self._async_queue = Queue.Queue() # File descriptors self._fds = [] # Greenlets self._g_dispatch = None self._greenlets = []
def __init__(self, mcu, pin_params): self._mcu = mcu self._oid = oid = self._mcu.create_oid() self._step_pin = pin_params['pin'] self._invert_step = pin_params['invert'] self._dir_pin = self._invert_dir = None self._mcu_position_offset = 0. self._step_dist = 0. self._min_stop_interval = 0. self._reset_cmd_id = self._get_position_cmd = None ffi_main, self._ffi_lib = chelper.get_ffi() self._stepqueue = ffi_main.gc(self._ffi_lib.stepcompress_alloc(oid), self._ffi_lib.stepcompress_free) self._mcu.register_stepqueue(self._stepqueue) self._stepper_kinematics = self._itersolve_gen_steps = None self.set_ignore_move(False)
def __init__(self, config): self.printer = config.get_printer() self.steppers = {} # Setup iterative solver ffi_main, ffi_lib = chelper.get_ffi() self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free) self.move_fill = ffi_lib.move_fill self.stepper_kinematics = ffi_main.gc( ffi_lib.cartesian_stepper_alloc('x'), ffi_lib.free) # Register commands self.gcode = self.printer.lookup_object('gcode') self.gcode.register_command('STEPPER_BUZZ', self.cmd_STEPPER_BUZZ, desc=self.cmd_STEPPER_BUZZ_help) if config.getboolean("enable_force_move", False): self.gcode.register_command('FORCE_MOVE', self.cmd_FORCE_MOVE, desc=self.cmd_FORCE_MOVE_help) self.gcode.register_command( 'SET_KINEMATIC_POSITION', self.cmd_SET_KINEMATIC_POSITION, desc=self.cmd_SET_KINEMATIC_POSITION_help)
def __init__(self, reactor, serialport, baud): self.reactor = reactor self.serialport = serialport self.baud = baud # Serial port self.ser = None self.msgparser = msgproto.MessageParser() # C interface self.ffi_main, self.ffi_lib = chelper.get_ffi() self.serialqueue = None self.default_cmd_queue = self.alloc_command_queue() self.stats_buf = self.ffi_main.new('char[4096]') # Threading self.lock = threading.Lock() self.background_thread = None # Message handlers handlers = { '#unknown': self.handle_unknown, '#output': self.handle_output, } self.handlers = { (k, None): v for k, v in handlers.items() }
def setup_itersolve(self, alloc_func, *params): ffi_main, ffi_lib = chelper.get_ffi() sk = ffi_main.gc(getattr(ffi_lib, alloc_func)(*params), ffi_lib.free) self.set_stepper_kinematics(sk)