归位流程
toolhead 初始化的时候,会加载homing模块对象,并对其进行初始化操作。
def __init__ ( self, config) :
self. printer = config. get_printer( )
gcode = self. printer. lookup_object( 'gcode' )
gcode. register_command( 'G28' , self. cmd_G28)
归位代码解析
def homing_move ( self, movepos, speed, probe_pos= False ,
triggered= True , check_triggered= True ) :
self. printer. send_event( "homing:homing_move_begin" , self)
self. toolhead. flush_step_generation( )
kin = self. toolhead. get_kinematics( )
kin_spos = { s. get_name( ) : s. get_commanded_position( )
for s in kin. get_steppers( ) }
self. stepper_positions = [ StepperPosition( s, name)
for es, name in self. endstops
for s in es. get_steppers( ) ]
print_time = self. toolhead. get_last_move_time( )
endstop_triggers = [ ]
for mcu_endstop, name in self. endstops:
rest_time = self. _calc_endstop_rate( mcu_endstop, movepos, speed)
wait = mcu_endstop. home_start( print_time, ENDSTOP_SAMPLE_TIME,
ENDSTOP_SAMPLE_COUNT, rest_time,
triggered= triggered)
endstop_triggers. append( wait)
all_endstop_trigger = multi_complete( self. printer, endstop_triggers)
self. toolhead. dwell( HOMING_START_DELAY)
error = None
try :
self. toolhead. drip_move( movepos, speed, all_endstop_trigger)
except self. printer. command_error as e:
error = "Error during homing move: %s" % ( str ( e) , )
trigger_times = { }
move_end_print_time = self. toolhead. get_last_move_time( )
for mcu_endstop, name in self. endstops:
trigger_time = mcu_endstop. home_wait( move_end_print_time)
if trigger_time > 0 . :
trigger_times[ name] = trigger_time
elif trigger_time < 0 . and error is None :
error = "Communication timeout during homing %s" % ( name, )
elif check_triggered and error is None :
error = "No trigger on %s after full movement" % ( name, )
self. toolhead. flush_step_generation( )
for sp in self. stepper_positions:
tt = trigger_times. get( sp. endstop_name, move_end_print_time)
sp. note_home_end( tt)
if probe_pos:
halt_steps = { sp. stepper_name: sp. halt_pos - sp. start_pos
for sp in self. stepper_positions}
trig_steps = { sp. stepper_name: sp. trig_pos - sp. start_pos
for sp in self. stepper_positions}
haltpos = trigpos = self. calc_toolhead_pos( kin_spos, trig_steps)
if trig_steps != halt_steps:
haltpos = self. calc_toolhead_pos( kin_spos, halt_steps)
else :
haltpos = trigpos = movepos
over_steps = { sp. stepper_name: sp. halt_pos - sp. trig_pos
for sp in self. stepper_positions}
if any ( over_steps. values( ) ) :
self. toolhead. set_position( movepos)
halt_kin_spos = { s. get_name( ) : s. get_commanded_position( )
for s in kin. get_steppers( ) }
haltpos = self. calc_toolhead_pos( halt_kin_spos, over_steps)
self. toolhead. set_position( haltpos)
try :
self. printer. send_event( "homing:homing_move_end" , self)
except self. printer. command_error as e:
if error is None :
error = str ( e)
if error is not None :
raise self. printer. command_error( error)
return trigpos
发送归位操作开始事件
self. printer. send_event( "homing:homing_move_begin" , self)
通知打印机即将开始归位操作,触发事件 homing_move_begin
。
获取当前步进电机的位置
kin = self. toolhead. get_kinematics( )
kin_spos = { s. get_name( ) : s. get_commanded_position( ) for s in kin. get_steppers( ) }
kin.get_steppers()
返回系统中所有参与运动的步进电机。kin_spos
保存这些电机的当前命令位置。
记录限位开关的状态
self. stepper_positions = [ StepperPosition( s, name) for es, name in self. endstops for s in es. get_steppers( ) ]
为所有与限位开关(endstop)相关的步进电机创建一个 StepperPosition
对象,记录限位开关的相关信息。
计算限位开关的采样频率并开始监控
for mcu_endstop, name in self. endstops:
rest_time = self. _calc_endstop_rate( mcu_endstop, movepos, speed)
wait = mcu_endstop. home_start( print_time, ENDSTOP_SAMPLE_TIME, ENDSTOP_SAMPLE_COUNT, rest_time, triggered= triggered)
endstop_triggers. append( wait)
这里通过调用 home_start()
方法开始检测限位开关的状态,指定采样时间、频率等参数。并将每个限位开关的触发状态加入到 endstop_triggers
列表中。
移动工具头
self. toolhead. drip_move( movepos, speed, all_endstop_trigger)
通过 drip_move
方法移动工具头至目标位置 movepos
,并在移动过程中监控限位开关的触发状态 all_endstop_trigger
。
检测限位开关是否触发
for mcu_endstop, name in self. endstops:
trigger_time = mcu_endstop. home_wait( move_end_print_time)
if trigger_time > 0 . :
trigger_times[ name] = trigger_time
elif trigger_time < 0 . and error is None :
error = "Communication timeout during homing %s" % ( name, )
elif check_triggered and error is None :
error = "No trigger on %s after full movement" % ( name, )
使用 home_wait()
方法等待限位开关触发,判断各个限位开关是否在预期时间内触发。若未触发或通信超时,将会记录错误信息。
计算并设置停止位置
halt_steps = { sp. stepper_name: sp. halt_pos - sp. start_pos for sp in self. stepper_positions}
trig_steps = { sp. stepper_name: sp. trig_pos - sp. start_pos for sp in self. stepper_positions}
haltpos = trigpos = self. calc_toolhead_pos( kin_spos, trig_steps)
通过计算步进电机的位置,确定工具头的停止位置。calc_toolhead_pos()
方法将步进电机的位置转换为工具头的物理位置。
调整并设置工具头的最终位置
self. toolhead. set_position( haltpos)
设置工具头的最终位置为计算出的 haltpos
,该位置可能经过限位开关触发或过冲后的调整。
结束并发送归位操作结束事件
self. printer. send_event( "homing:homing_move_end" , self)
发送 homing_move_end
事件,通知打印机归位操作已完成。
错误处理
if error is not None :
raise self. printer. command_error( error)
如果在归位过程中出现错误,抛出异常并将错误信息传递给打印机。