From 2c49ccbcbc2c731010742549c80886d4943b4ac9 Mon Sep 17 00:00:00 2001 From: Ezward Date: Sun, 26 Feb 2023 12:43:58 -0800 Subject: [PATCH 1/3] fix user/angle in complete.py - that had been renamed user/steering in the PR that merged the computer vision template. - Much code in the deep learning pipeline explicitly hard-codes the literal `user/angle` so the deep learning code needs to continue to use that label. - This fix uses the Pipe() part to rename 'user/steering' to 'user/angle' immediately after it is emitted by the controller part. --- donkeycar/templates/complete.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/donkeycar/templates/complete.py b/donkeycar/templates/complete.py index c8ba81b95..4ba7c5cc7 100644 --- a/donkeycar/templates/complete.py +++ b/donkeycar/templates/complete.py @@ -41,6 +41,7 @@ from donkeycar.parts.explode import ExplodeDict from donkeycar.parts.transform import Lambda from donkeycar.parts.logger import LoggerPart +from donkeycar.parts.pipe import Pipe from donkeycar.utils import * logger = logging.getLogger(__name__) @@ -132,6 +133,11 @@ def drive(cfg, model_path=None, use_joystick=False, model_type=None, has_input_controller = hasattr(cfg, "CONTROLLER_TYPE") and cfg.CONTROLLER_TYPE != "mock" ctr = add_user_controller(V, cfg, use_joystick) + # + # convert 'user/steering' to 'user/angle' to be backward compatible with deep learning data + # + V.add(Pipe(inputs='user/steering', outputs='user/angle')) + # # explode the buttons input map into individual output key/values in memory # @@ -437,7 +443,7 @@ def run(self, *components): # based on the choice of user or autopilot drive mode # V.add(DriveMode(cfg.AI_THROTTLE_MULT), - inputs=['user/mode', 'user/steering', 'user/throttle', + inputs=['user/mode', 'user/angle', 'user/throttle', 'pilot/steering', 'pilot/throttle'], outputs=['steering', 'throttle']) @@ -471,10 +477,10 @@ def run(self, *components): # add tub to save data # if cfg.USE_LIDAR: - inputs = ['cam/image_array', 'lidar/dist_array', 'user/steering', 'user/throttle', 'user/mode'] + inputs = ['cam/image_array', 'lidar/dist_array', 'user/angle', 'user/throttle', 'user/mode'] types = ['image_array', 'nparray','float', 'float', 'str'] else: - inputs=['cam/image_array','user/steering', 'user/throttle', 'user/mode'] + inputs=['cam/image_array','user/angle', 'user/throttle', 'user/mode'] types=['image_array','float', 'float','str'] if cfg.HAVE_ODOM: From e41723a8e3a502b41ce88c084bbf39965477f37c Mon Sep 17 00:00:00 2001 From: Ezward Date: Sun, 26 Feb 2023 13:05:53 -0800 Subject: [PATCH 2/3] pilot/steering -> pilot/angle --- donkeycar/templates/complete.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/donkeycar/templates/complete.py b/donkeycar/templates/complete.py index 4ba7c5cc7..ee84bd944 100644 --- a/donkeycar/templates/complete.py +++ b/donkeycar/templates/complete.py @@ -393,7 +393,7 @@ def run(self, *components): # # collect model inference outputs # - outputs = ['pilot/steering', 'pilot/throttle'] + outputs = ['pilot/angle', 'pilot/throttle'] if cfg.TRAIN_LOCALIZER: outputs.append("pilot/loc") @@ -444,7 +444,7 @@ def run(self, *components): # V.add(DriveMode(cfg.AI_THROTTLE_MULT), inputs=['user/mode', 'user/angle', 'user/throttle', - 'pilot/steering', 'pilot/throttle'], + 'pilot/angle', 'pilot/throttle'], outputs=['steering', 'throttle']) V.add(LoggerPart(['steering', 'throttle']), inputs=['steering', 'throttle']) @@ -518,7 +518,7 @@ def run(self, *components): types += ['nparray'] if cfg.RECORD_DURING_AI: - inputs += ['pilot/steering', 'pilot/throttle'] + inputs += ['pilot/angle', 'pilot/throttle'] types += ['float', 'float'] if cfg.HAVE_PERFMON: From 6ebb712e834a6a0c52224c0f9826f9f002b28849 Mon Sep 17 00:00:00 2001 From: Ezward Date: Sun, 26 Feb 2023 13:55:43 -0800 Subject: [PATCH 3/3] Fix pipe.py and complete.py - Pipe.py would output a bad tuple if only one argument was being passed throught. Now it explictly checks. - This caused complete.py to have invalid 'user/angle' values. --- donkeycar/parts/pipe.py | 11 +++-------- donkeycar/templates/complete.py | 4 +--- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/donkeycar/parts/pipe.py b/donkeycar/parts/pipe.py index 8bd0167f5..a8c618713 100644 --- a/donkeycar/parts/pipe.py +++ b/donkeycar/parts/pipe.py @@ -2,12 +2,7 @@ class Pipe: """ Just pipe all inputs to the output, so they can be renamed. """ - def __init__(self): - self.running = True - def run(self, *args): - if self.running: - return args - - def shutdown(self): - self.running = False + # seems to be a python bug that takes a single argument + # return makes it into two element tuple with empty last element. + return args if len(args) > 1 else args[0] diff --git a/donkeycar/templates/complete.py b/donkeycar/templates/complete.py index ee84bd944..551821cd1 100644 --- a/donkeycar/templates/complete.py +++ b/donkeycar/templates/complete.py @@ -40,7 +40,6 @@ from donkeycar.parts.kinematics import Bicycle, InverseBicycle, BicycleUnnormalizeAngularVelocity from donkeycar.parts.explode import ExplodeDict from donkeycar.parts.transform import Lambda -from donkeycar.parts.logger import LoggerPart from donkeycar.parts.pipe import Pipe from donkeycar.utils import * @@ -136,7 +135,7 @@ def drive(cfg, model_path=None, use_joystick=False, model_type=None, # # convert 'user/steering' to 'user/angle' to be backward compatible with deep learning data # - V.add(Pipe(inputs='user/steering', outputs='user/angle')) + V.add(Pipe(), inputs=['user/steering'], outputs=['user/angle']) # # explode the buttons input map into individual output key/values in memory @@ -447,7 +446,6 @@ def run(self, *components): 'pilot/angle', 'pilot/throttle'], outputs=['steering', 'throttle']) - V.add(LoggerPart(['steering', 'throttle']), inputs=['steering', 'throttle']) if (cfg.CONTROLLER_TYPE != "pigpio_rc") and (cfg.CONTROLLER_TYPE != "MM1"): if isinstance(ctr, JoystickController):