Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor ejectors out of ball_device
- Loading branch information
Showing
6 changed files
with
171 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""Ball device and ejectors.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
"""Baseclass for ball device ejectors.""" | ||
|
||
|
||
class BallDeviceEjector: | ||
|
||
"""Ejector for a ball device. It has to implement at least one of eject_one_ball or eject_all_balls.""" | ||
|
||
def __init__(self, ball_device): | ||
"""Initialise ejector.""" | ||
self.ball_device = ball_device | ||
|
||
def eject_one_ball(self): | ||
"""Eject one ball.""" | ||
raise NotImplementedError() | ||
|
||
def eject_all_balls(self): | ||
"""Eject all balls.""" | ||
raise NotImplementedError() | ||
|
||
def ball_search(self, phase, iteration): | ||
"""Search ball in device.""" | ||
raise NotImplementedError() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
"""Hold coil ejector.""" | ||
from mpf.devices.ball_device.ball_device_ejector import BallDeviceEjector | ||
|
||
|
||
class HoldCoilEjector(BallDeviceEjector): | ||
|
||
"""Hold balls by enabling and releases by disabling a coil.""" | ||
|
||
def __init__(self, ball_device): | ||
"""Initialise hold coil ejector.""" | ||
super().__init__(ball_device) | ||
self.hold_release_in_progress = False | ||
|
||
# handle hold_coil activation when a ball hits a switch | ||
for switch in self.ball_device.config['hold_switches']: | ||
self.ball_device.machine.switch_controller.add_switch_handler( | ||
switch_name=switch.name, state=1, | ||
ms=0, | ||
callback=self.hold) | ||
|
||
def eject_one_ball(self): | ||
"""Eject one ball by disabling hold coil.""" | ||
# TODO: wait for some time to allow balls to settle for | ||
# both entrance and after a release | ||
|
||
self._disable_hold_coil() | ||
self.hold_release_in_progress = True | ||
|
||
# allow timed release of single balls and reenable coil after | ||
# release. Disable coil when device is empty | ||
self.ball_device.delay.add(name='hold_coil_release', | ||
ms=self.ball_device.config['hold_coil_release_time'], | ||
callback=self._hold_release_done) | ||
|
||
def _disable_hold_coil(self): | ||
self.ball_device.config['hold_coil'].disable() | ||
if self.ball_device.debug: | ||
self.ball_device.log.debug("Disabling hold coil. New " | ||
"balls: %s.", self.ball_device.balls) | ||
|
||
def hold(self, **kwargs): | ||
"""Event handler for hold event.""" | ||
del kwargs | ||
# do not enable coil when we are ejecting | ||
if self.hold_release_in_progress: | ||
return | ||
|
||
self._enable_hold_coil() | ||
|
||
def _enable_hold_coil(self): | ||
self.ball_device.config['hold_coil'].enable() | ||
if self.ball_device.debug: | ||
self.ball_device.log.debug("Enabling hold coil. New " | ||
"balls: %s.", self.ball_device.balls) | ||
|
||
def _hold_release_done(self): | ||
self.hold_release_in_progress = False | ||
|
||
# reenable hold coil if there are balls left | ||
if self.ball_device.balls > 0: | ||
self._enable_hold_coil() | ||
|
||
def ball_search(self, phase, iteration): | ||
"""Run ball search.""" | ||
self.ball_device.config['hold_coil'].pulse() | ||
return True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
"""Standard pulse ejector.""" | ||
from mpf.devices.ball_device.ball_device_ejector import BallDeviceEjector | ||
|
||
|
||
class PulseCoilEjector(BallDeviceEjector): | ||
|
||
"""Pulse a coil to eject one ball.""" | ||
|
||
def eject_one_ball(self): | ||
"""Pulse eject coil.""" | ||
if (self.ball_device.num_eject_attempts <= 2 and | ||
self.ball_device.config['eject_coil_jam_pulse'] and | ||
self.ball_device.config['jam_switch'] and | ||
self.ball_device.machine.switch_controller.is_active( | ||
self.ball_device.config['jam_switch'].name, | ||
ms=self.ball_device.config['entrance_count_delay'])): | ||
self.ball_device.config['eject_coil'].pulse( | ||
self.ball_device.config['eject_coil_jam_pulse']) | ||
|
||
elif self.ball_device.num_eject_attempts >= 4 and self.ball_device.config['eject_coil_retry_pulse']: | ||
self.ball_device.config['eject_coil'].pulse(self.ball_device.config['eject_coil_retry_pulse']) | ||
|
||
else: | ||
self.ball_device.config['eject_coil'].pulse() | ||
|
||
if self.ball_device.debug: | ||
self.ball_device.log.debug("Firing eject coil. New balls: %s.", self.ball_device.balls) | ||
|
||
def eject_all_balls(self): | ||
"""Cannot eject all balls.""" | ||
raise NotImplementedError() | ||
|
||
def ball_search(self, phase, iteration): | ||
"""Run ball search.""" | ||
del iteration | ||
if phase == 1: | ||
# round 1: only idle + no ball | ||
# only run ball search when the device is idle and contains no balls | ||
if self.ball_device.state == "idle" and self.ball_device.balls == 0: | ||
return self._fire_coil_for_search(True) | ||
elif phase == 2: | ||
# round 2: all devices except trough. small pulse | ||
if 'trough' not in self.ball_device.config['tags']: | ||
return self._fire_coil_for_search(False) | ||
else: | ||
# round 3: all devices except trough. normal pulse | ||
if 'trough' not in self.ball_device.config['tags']: | ||
return self._fire_coil_for_search(True) | ||
|
||
def _fire_coil_for_search(self, full_power): | ||
if not full_power and self.ball_device.config['eject_coil_jam_pulse']: | ||
self.ball_device.config['eject_coil'].pulse(self.ball_device.config['eject_coil_jam_pulse']) | ||
else: | ||
self.ball_device.config['eject_coil'].pulse() | ||
return True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters