-
Notifications
You must be signed in to change notification settings - Fork 143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fast segment display update hz #1638
Merged
toomanybrians
merged 16 commits into
missionpinball:dev
from
toomanybrians:fast-segment-throttling
May 23, 2022
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
c1259ae
Don't wait for responses on SEG processor
toomanybrians b464ba3
typos & version bump
toomanybrians dde149f
Merge branch 'avanwinkle:fast-retro' into fast-retro
toomanybrians b2bba1f
dirty path for fast segment throttling
toomanybrians 8609cc4
bug fix for segment color
toomanybrians db48d6a
FAST Segment fixes
toomanybrians 09d84fc
seg task little cleanup
toomanybrians 47cfd15
initial commit for FAST Platform v2 branch
toomanybrians 94bbd24
Merge branch 'dev' into fast-platform-v2
toomanybrians ad26712
updated version number to be PEP 400 compliant
toomanybrians ff868ed
replaced deprecated distutils
toomanybrians 8de2559
version bump to dev.20
toomanybrians 94dae93
Merge pull request #2 from missionpinball/dev
toomanybrians 1d05184
Merge branch 'fast-segment-throttling' into dev
toomanybrians 704460c
Merge pull request #3 from toomanybrians/dev
toomanybrians 1275490
add packaging module to setup requirements
toomanybrians File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
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 |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
import asyncio | ||
import os | ||
from copy import deepcopy | ||
from distutils.version import StrictVersion | ||
from packaging import version | ||
from typing import Dict, Set, Optional | ||
from serial import SerialException | ||
|
||
|
@@ -43,7 +43,8 @@ class FastHardwarePlatform(ServoPlatform, LightsPlatform, DmdPlatform, | |
|
||
__slots__ = ["dmd_connection", "net_connection", "rgb_connection", "seg_connection", "is_retro", | ||
"serial_connections", "fast_leds", "fast_commands", "config", "machine_type", "hw_switch_data", | ||
"io_boards", "flag_led_tick_registered", "_watchdog_task", "_led_task"] | ||
"io_boards", "flag_led_tick_registered", "_watchdog_task", "_led_task", "_seg_task", | ||
"fast_segs"] | ||
|
||
def __init__(self, machine): | ||
"""Initialise fast hardware platform. | ||
|
@@ -84,7 +85,9 @@ def __init__(self, machine): | |
self._led_task = None | ||
self.serial_connections = set() # type: Set[FastSerialCommunicator] | ||
self.fast_leds = {} | ||
self.fast_segs = list() | ||
self.flag_led_tick_registered = False | ||
self._seg_task = None | ||
self.hw_switch_data = None | ||
self.io_boards = {} # type: Dict[int, FastIoBoard] | ||
|
||
|
@@ -155,7 +158,7 @@ def _update_net(self) -> str: | |
max_firmware = self.net_connection.remote_firmware | ||
update_config = None | ||
for update in self.config['firmware_updates']: | ||
if StrictVersion(update['version']) > StrictVersion(max_firmware) and update['type'] == "net": | ||
if version.parse(update['version']) > version.parse(max_firmware) and update['type'] == "net": | ||
update_config = update | ||
|
||
if not update_config: | ||
|
@@ -187,6 +190,9 @@ def stop(self): | |
if self._led_task: | ||
self._led_task.cancel() | ||
self._led_task = None | ||
if self._seg_task: | ||
self._seg_task.cancel() | ||
self._seg_task = None | ||
if self._watchdog_task: | ||
self._watchdog_task.cancel() | ||
self._watchdog_task = None | ||
|
@@ -244,8 +250,10 @@ def register_io_board(self, board): | |
|
||
def _update_watchdog(self): | ||
"""Send Watchdog command.""" | ||
if self.net_connection: | ||
try: | ||
self.net_connection.send('WD:' + str(hex(self.config['watchdog']))[2:]) | ||
except: | ||
pass | ||
|
||
def process_received_message(self, msg: str, remote_processor: str): | ||
"""Send an incoming message from the FAST controller to the proper method for servicing. | ||
|
@@ -268,7 +276,7 @@ def process_received_message(self, msg: str, remote_processor: str): | |
self.log.warning("Received malformed message: %s from %s", msg, remote_processor) | ||
return | ||
|
||
# Can't use try since it swallows too many errors for now | ||
# Can't use try since it swallows too many errors for now #TODO | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Double comment |
||
if cmd in self.fast_commands: | ||
self.fast_commands[cmd](payload, remote_processor) | ||
else: # pragma: no cover | ||
|
@@ -335,22 +343,48 @@ def register_processor_connection(self, name: str, communicator): | |
self.net_connection = communicator | ||
elif name == 'SEG': | ||
self.seg_connection = communicator | ||
|
||
if not self._seg_task: | ||
# Need to wait until the segs are all set up | ||
self.machine.events.add_handler('machine_reset_phase_3', self._start_seg_updates) | ||
|
||
elif name == 'RGB': | ||
self.rgb_connection = communicator | ||
self.rgb_connection.send('RF:0') | ||
self.rgb_connection.send('RA:000000') # turn off all LEDs | ||
self.rgb_connection.send('RF:{}'.format( | ||
Util.int_to_hex_string(self.config['hardware_led_fade_time']))) | ||
|
||
def _start_seg_updates(self, **kwargs): | ||
|
||
for s in self.machine.device_manager.collections["segment_displays"]: | ||
self.fast_segs.append(s.hw_display) | ||
|
||
self.fast_segs.sort(key=lambda x: x.number) | ||
|
||
if self.fast_segs: | ||
self._seg_task = self.machine.clock.schedule_interval(self._update_segs, | ||
1 / self.machine.config['fast'][ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Invalid indent. Please run a linter. |
||
'segment_display_update_hz']) | ||
|
||
def _update_segs(self, **kwargs): | ||
|
||
for s in self.fast_segs: | ||
|
||
if s.next_text: | ||
self.seg_connection.send(f'PA:{s.hex_id},{s.next_text.convert_to_str()[0:7]}') | ||
s.next_text = None | ||
|
||
if s.next_color: | ||
self.seg_connection.send(('PC:{},{}').format(s.hex_id, s.next_color)) | ||
s.next_color = None | ||
|
||
def update_leds(self): | ||
"""Update all the LEDs connected to a FAST controller. | ||
|
||
This is done once per game loop for efficiency (i.e. all LEDs are sent as a single | ||
update rather than lots of individual ones). | ||
|
||
Also, every LED is updated every loop, even if it doesn't change. This | ||
is in case some interference causes a LED to change color. Since we | ||
update every loop, it will only be the wrong color for one tick. | ||
""" | ||
dirty_leds = [led for led in self.fast_leds.values() if led.dirty] | ||
|
||
|
@@ -774,7 +808,6 @@ async def configure_segment_display(self, number: str, display_size: int, platfo | |
"""Configure a segment display.""" | ||
self.debug_log("Configuring FAST segment display.") | ||
del platform_settings | ||
del display_size | ||
if not self.seg_connection: | ||
raise AssertionError("A request was made to configure a FAST " | ||
"Segment Display but no connection is " | ||
|
@@ -793,7 +826,7 @@ def get_switch_config_section(cls): | |
"""Return switch config section.""" | ||
return "fast_switches" | ||
|
||
def _check_switch_coil_combincation(self, switch, coil): | ||
def _check_switch_coil_combination(self, switch, coil): | ||
# V2 hardware can write rules across node boards | ||
if not self.net_connection.is_legacy: | ||
return | ||
|
@@ -824,7 +857,7 @@ def set_pulse_on_hit_and_release_rule(self, enable_switch, coil): | |
"Driver: %s", enable_switch.hw_switch.number, | ||
coil.hw_driver.number) | ||
|
||
self._check_switch_coil_combincation(enable_switch, coil) | ||
self._check_switch_coil_combination(enable_switch, coil) | ||
|
||
driver = coil.hw_driver | ||
|
||
|
@@ -857,8 +890,8 @@ def set_pulse_on_hit_and_release_and_disable_rule(self, enable_switch: SwitchSet | |
"%s, Driver: %s", enable_switch.hw_switch.number, | ||
coil.hw_driver.number) | ||
|
||
self._check_switch_coil_combincation(enable_switch, coil) | ||
self._check_switch_coil_combincation(eos_switch, coil) | ||
self._check_switch_coil_combination(enable_switch, coil) | ||
self._check_switch_coil_combination(eos_switch, coil) | ||
|
||
driver = coil.hw_driver | ||
|
||
|
@@ -890,7 +923,7 @@ def set_pulse_on_hit_rule(self, enable_switch: SwitchSettings, coil: DriverSetti | |
"Driver: %s", enable_switch.hw_switch.number, | ||
coil.hw_driver.number) | ||
|
||
self._check_switch_coil_combincation(enable_switch, coil) | ||
self._check_switch_coil_combination(enable_switch, coil) | ||
|
||
driver = coil.hw_driver | ||
|
||
|
@@ -912,7 +945,7 @@ def set_pulse_on_hit_and_enable_and_release_rule(self, enable_switch: SwitchSett | |
"Switch: %s, Driver: %s", | ||
enable_switch.hw_switch.number, coil.hw_driver.number) | ||
|
||
self._check_switch_coil_combincation(enable_switch, coil) | ||
self._check_switch_coil_combination(enable_switch, coil) | ||
|
||
driver = coil.hw_driver | ||
|
||
|
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
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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we ignore all errors here? I am certain that this breaks the linter (which is not currently running in CI).