parameters: (self, axes: str)
docstring: Handle split moves for unsticking axes before home.
  
          This is particularly ugly bit of code that flips the motor controller
          into relative mode since we don't necessarily know where we are.
  
          It will induce a movement. It should really only be called before a
          home because it doesn't update the position cache.
  
          :param axes: A string that is a sequence of plunger axis names.
docstring_summary: Handle split moves for unsticking axes before home.
docstring_tokens: Handle split moves for unsticking axes before home .
function: async def _do_relative_splits_during_home_for(self, axes: str) -> None:
          """Handle split moves for unsticking axes before home.
  
          This is particularly ugly bit of code that flips the motor controller
          into relative mode since we don't necessarily know where we are.
  
          It will induce a movement. It should really only be called before a
          home because it doesn't update the position cache.
  
          :param axes: A string that is a sequence of plunger axis names.
          """
          assert all(
              ax.lower() in "bc" for ax in axes
          ), "only plunger axes may be unstuck"
          since_moved = self._axes_moved_at.time_since_moved()
          split_currents = _command_builder().add_gcode(gcode=GCODE.SET_CURRENT)
          split_moves = _command_builder().add_gcode(gcode=GCODE.MOVE)
          applicable_speeds: List[float] = []
          log.debug(f"Finding splits for {axes} with since moved {since_moved}")
          to_unstick = [
              ax
              for ax in axes
              if (
                  since_moved.get(ax) is None
                  or (
                      self._move_split_config.get(ax)
                      and since_moved[ax]  # type: ignore[operator]
                      > self._move_split_config[ax].after_time
                  )
              )
          ]
          for axis in axes:
              msc = self._move_split_config.get(axis)
              log.debug(f"axis {axis}: msc {msc}")
              if not msc:
                  continue
              if axis in to_unstick:
                  log.debug(f"adding unstick for {axis}")
                  split_currents.add_float(
                      prefix=axis, value=msc.split_current, precision=None
                  )
                  split_moves.add_float(
                      prefix=axis, value=-msc.split_distance, precision=None
                  )
                  applicable_speeds.append(msc.split_speed)
          if not applicable_speeds:
              log.debug("no unstick needed")
              # nothing to do
              return
  
          fullstep_prefix, fullstep_postfix = self._build_fullstep_configurations(
              "".join(to_unstick)
          )
  
          command_sequence = [
              fullstep_prefix.add_builder(builder=split_currents)
              .add_gcode(gcode=GCODE.DWELL)
              .add_float(prefix="P", value=CURRENT_CHANGE_DELAY, precision=None)
              .add_builder(builder=self._build_speed_command(min(applicable_speeds)))
              .add_gcode(gcode=GCODE.RELATIVE_COORDS),
              split_moves,
          ]
          try:
              for command_string in command_sequence:
                  await self._send_command(
                      command_string,
                      timeout=DEFAULT_EXECUTE_TIMEOUT,
                      suppress_home_after_error=True,
                  )
          except SmoothieError:
              pass
          finally:
              await self._send_command(
                  _command_builder()
                  .add_gcode(gcode=GCODE.ABSOLUTE_COORDS)
                  .add_builder(builder=fullstep_postfix)
                  .add_builder(builder=self._build_speed_command(self._combined_speed))
              )
function_tokens: async def _do_relative_splits_during_home_for ( self , axes : str ) -> None : assert all ( ax . lower ( ) in "bc" for ax in axes ) , "only plunger axes may be unstuck" since_moved = self . _axes_moved_at . time_since_moved ( ) split_currents = _command_builder ( ) . add_gcode ( gcode = GCODE . SET_CURRENT ) split_moves = _command_builder ( ) . add_gcode ( gcode = GCODE . MOVE ) applicable_speeds : List [ float ] = [ ] log . debug ( f"Finding splits for {axes} with since moved {since_moved}" ) to_unstick = [ ax for ax in axes if ( since_moved . get ( ax ) is None or ( self . _move_split_config . get ( ax ) and since_moved [ ax ] # type: ignore[operator] > self . _move_split_config [ ax ] . after_time ) ) ] for axis in axes : msc = self . _move_split_config . get ( axis ) log . debug ( f"axis {axis}: msc {msc}" ) if not msc : continue if axis in to_unstick : log . debug ( f"adding unstick for {axis}" ) split_currents . add_float ( prefix = axis , value = msc . split_current , precision = None ) split_moves . add_float ( prefix = axis , value = - msc . split_distance , precision = None ) applicable_speeds . append ( msc . split_speed ) if not applicable_speeds : log . debug ( "no unstick needed" ) # nothing to do return fullstep_prefix , fullstep_postfix = self . _build_fullstep_configurations ( "" . join ( to_unstick ) ) command_sequence = [ fullstep_prefix . add_builder ( builder = split_currents ) . add_gcode ( gcode = GCODE . DWELL ) . add_float ( prefix = "P" , value = CURRENT_CHANGE_DELAY , precision = None ) . add_builder ( builder = self . _build_speed_command ( min ( applicable_speeds ) ) ) . add_gcode ( gcode = GCODE . RELATIVE_COORDS ) , split_moves , ] try : for command_string in command_sequence : await self . _send_command ( command_string , timeout = DEFAULT_EXECUTE_TIMEOUT , suppress_home_after_error = True , ) except SmoothieError : pass finally : await self . _send_command ( _command_builder ( ) . add_gcode ( gcode = GCODE . ABSOLUTE_COORDS ) . add_builder ( builder = fullstep_postfix ) . add_builder ( builder = self . _build_speed_command ( self . _combined_speed ) ) )