Skip to content
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

UI bug fixes and improvements #1045

Merged
merged 1 commit into from
Oct 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 40 additions & 13 deletions donkeycar/management/kivy_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,16 +257,17 @@ def update_tub(self, event=None):
tub_screen().status(f'Failed loading tub: {str(e)}')
return False
# Check if filter is set in tub screen
expression = tub_screen().ids.tub_filter.filter_expression
# expression = tub_screen().ids.tub_filter.filter_expression
train_filter = getattr(cfg, 'TRAIN_FILTER', None)

# Use filter, this defines the function
def select(underlying):
if not expression:
if not train_filter:
return True
else:
try:
record = TubRecord(cfg, self.tub.base_path, underlying)
res = eval(expression)
res = train_filter(record)
return res
except KeyError as err:
Logger.error(f'Filter: {err}')
Expand All @@ -281,8 +282,6 @@ def select(underlying):
msg = f'Loaded tub {self.file_path} with {self.len} records'
else:
msg = f'No records in tub {self.file_path}'
if expression:
msg += f' using filter {tub_screen().ids.tub_filter.record_filter}'
tub_screen().status(msg)
return True

Expand Down Expand Up @@ -399,9 +398,9 @@ def update(self, record):
self.core_image = CoreImage(bytes_io, ext='png')
self.texture = self.core_image.texture
except KeyError as e:
Logger.error('Record: Missing key:', e)
Logger.error(f'Record: Missing key: {e}')
except Exception as e:
Logger.error('Record: Bad record:', str(e))
Logger.error(f'Record: Bad record: {e}')

def get_image(self, record):
return record.image(cached=False)
Expand All @@ -423,11 +422,15 @@ def start(self, fwd=True, continuous=False):
:param continuous: If we do <<, >> or <, >
:return: None
"""
# this widget it used in two screens, so reference the original location
# of the config which is the config manager in the tub screen
cfg = tub_screen().ids.config_manager.config
hz = cfg.DRIVE_LOOP_HZ if cfg else 20
time.sleep(0.1)
call = partial(self.step, fwd, continuous)
if continuous:
self.fwd = fwd
s = float(self.speed) * tub_screen().ids.config_manager.config.DRIVE_LOOP_HZ
s = float(self.speed) * hz
cycle_time = 1.0 / s
else:
cycle_time = 0.08
Expand All @@ -441,6 +444,9 @@ def step(self, fwd=True, continuous=False, *largs):
:param largs: dummy
:return: None
"""
if self.screen.index is None:
self.screen.status("No tub loaded")
return
new_index = self.screen.index + (1 if fwd else -1)
if new_index >= tub_screen().ids.tub_loader.len:
new_index = 0
Expand Down Expand Up @@ -533,22 +539,33 @@ class TubFilter(PaddedBoxLayout):

def update_filter(self):
filter_text = self.ids.record_filter.text
config = tub_screen().ids.config_manager.config
# empty string resets the filter
if filter_text == '':
self.record_filter = ''
self.filter_expression = ''
rc_handler.data['record_filter'] = self.record_filter
if hasattr(config, 'TRAIN_FILTER'):
delattr(config, 'TRAIN_FILTER')
tub_screen().status(f'Filter cleared')
return
filter_expression = self.create_filter_string(filter_text)
try:
record = tub_screen().current_record
res = eval(filter_expression)
filter_func_text = f"""def filter_func(record):
return {filter_expression}
"""
# creates the function 'filter_func'
ldict = {}
exec(filter_func_text, globals(), ldict)
filter_func = ldict['filter_func']
res = filter_func(record)
status = f'Filter result on current record: {res}'
if isinstance(res, bool):
self.record_filter = filter_text
self.filter_expression = filter_expression
rc_handler.data['record_filter'] = self.record_filter
setattr(config, 'TRAIN_FILTER', filter_func)
else:
status += ' - non bool expression can\'t be applied'
status += ' - press <Reload tub> to see effect'
Expand Down Expand Up @@ -649,8 +666,9 @@ def initialise(self, e):

def on_index(self, obj, index):
""" Kivy method that is called if self.index changes"""
self.current_record = self.ids.tub_loader.records[index]
self.ids.slider.value = index
if index >= 0:
self.current_record = self.ids.tub_loader.records[index]
self.ids.slider.value = index

def on_current_record(self, obj, record):
""" Kivy method that is called if self.current_record changes."""
Expand Down Expand Up @@ -747,7 +765,7 @@ def get_image(self, record):

rgb = (0, 0, 255)
MakeMovie.draw_line_into_image(output[0], output[1], True, img_arr, rgb)
out_record = deepcopy(record)
out_record = copy(record)
out_record.underlying['pilot/angle'] = output[0]
# rename and denormalise the throttle output
pilot_throttle_field \
Expand Down Expand Up @@ -781,6 +799,8 @@ def on_index(self, obj, index):
def on_current_record(self, obj, record):
""" Kivy method that is called when self.current_index changes. Here
we update the images and the control panel entry."""
if not record:
return
i = record.underlying['_index']
self.ids.pilot_control.record_display = f"Record {i:06}"
self.ids.img_1.update(record)
Expand All @@ -806,6 +826,8 @@ def map_pilot_field(self, text):
return rc_handler.data['user_pilot_map'][text]

def set_brightness(self, val=None):
if not self.config:
return
if self.ids.button_bright.state == 'down':
self.config.AUG_MULTIPLY_RANGE = (val, val)
if 'MULTIPLY' not in self.aug_list:
Expand All @@ -816,6 +838,8 @@ def set_brightness(self, val=None):
self.on_aug_list(None, None)

def set_blur(self, val=None):
if not self.config:
return
if self.ids.button_blur.state == 'down':
self.config.AUG_BLUR_RANGE = (val, val)
if 'BLUR' not in self.aug_list:
Expand All @@ -826,11 +850,15 @@ def set_blur(self, val=None):
self.on_aug_list(None, None)

def on_aug_list(self, obj, aug_list):
if not self.config:
return
self.config.AUGMENTATIONS = self.aug_list
self.augmentation = ImageAugmentation(self.config, 'AUGMENTATIONS')
self.on_current_record(None, self.current_record)

def on_trans_list(self, obj, trans_list):
if not self.config:
return
self.config.TRANSFORMATIONS = self.trans_list
self.transformation = ImageAugmentation(self.config, 'TRANSFORMATIONS')
self.on_current_record(None, self.current_record)
Expand Down Expand Up @@ -1088,7 +1116,6 @@ def connected(self, event):
'-o ConnectTimeout=3',
f'{self.config.PI_USERNAME}@{self.config.PI_HOSTNAME}',
'date']
# Logger.info('car check: ' + ' '.join(cmd))
self.connection = Popen(cmd, shell=False, stdout=PIPE,
stderr=STDOUT, text=True,
encoding='utf-8', universal_newlines=True)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def package_files(directory, strip_leading):
long_description = fh.read()

setup(name='donkeycar',
version="4.3.22",
version="4.3.23",
long_description=long_description,
description='Self driving library for python.',
url='https://github.com/autorope/donkeycar',
Expand Down