def __init__(self, racecar_name, racecar_info, race_type):
        """ To capture the video of evaluation done during the training phase
        Args:
            racecar_info (dict): Information of the agent
        """
        self.racecar_info = racecar_info
        racecar_index = get_racecar_idx(racecar_name)
        self.racecar_index = racecar_index if racecar_index else 0
        # Store the font which we will use to write the phase with
        self.training_phase_font = utils.get_font('Amazon_Ember_RgIt', 35)

        # The track image as iconography
        self.track_icongraphy_img = utils.get_track_iconography_image()

        # Track image offset
        self.track_loc_offset = XYPixelLoc.TRACK_IMG_WITHOUT_OFFSET_LOC.value

        # Gradient overlay image
        width, height = IconographicImageSize.FULL_IMAGE_SIZE.value
        image = np.zeros(height * width * 4)
        image.resize(height, width, 4)
        self.gradient_img = self._plot_track_on_gradient(image)
        self.gradient_alpha_rgb_mul, self.one_minus_gradient_alpha = utils.get_gradient_values(
            self.gradient_img)

        # Top camera information
        top_camera_info = utils.get_top_camera_info()
        self.top_view_graphics = TopViewGraphics(
            top_camera_info.horizontal_fov, top_camera_info.padding_pct,
            top_camera_info.image_width, top_camera_info.image_height,
            racecar_info)
def test_get_racecar_idx(racecar_name, racecar_num):
    """This function checks the functionality of get_racecar_idx function
    in markov/utils.py

    Args:
        racecar_name (String): The name of racecar
        racecar_num: If single car race, returns None else returns the racecar number
    """
    assert utils.get_racecar_idx(racecar_name) == racecar_num
    def start_race(self):
        """
        Start the race (evaluation) for the current racer.
        """
        LOG.info(
            "[virtual event manager] Starting race for racer %s", self._current_racer.racerAlias
        )
        # update the car on current model if does not use f1 or tron type of shell
        if const.F1 not in self._body_shell_type.lower():
            self._model_updater.update_model_color(
                self._current_car_model_state.model_name, self._current_racer.carConfig.carColor
            )
        # send request
        if self._is_save_mp4_enabled:
            self._subscribe_to_save_mp4(
                VirtualEventVideoEditSrvRequest(
                    display_name=self._current_racer.racerAlias,
                    racecar_color=self._current_racer.carConfig.carColor,
                )
            )

        # Update CameraManager by adding cameras into the current namespace. By doing so
        # a single follow car camera will follow the current active racecar.
        self._camera_manager.add(
            self._main_cameras[VIRTUAL_EVENT], self._current_car_model_state.model_name
        )
        self._camera_manager.add(self._sub_camera, self._current_car_model_state.model_name)

        configure_environment_randomizer()
        # strip index for park position
        self._park_position_idx = get_racecar_idx(self._current_car_model_state.model_name)
        # set the park position in track and do evaluation
        # Before each evaluation episode (single lap for non-continuous race and complete race for
        # continuous race), a new copy of park_positions needs to be loaded into track_data because
        # a park position will be pop from park_positions when a racer car need to be parked.
        # unpause the physics in current world
        self._model_updater.unpause_physics()
        LOG.info("[virtual event manager] Unpaused physics in current world.")
        if (
            self._prev_model_name is not None
            and self._prev_model_name != self._current_car_model_state.model_name
        ):
            # disable the links on the prev car
            # we are doing it here because we don't want the car to float around
            # after the link is disabled
            prev_car_model_state = ModelState()
            prev_car_model_state.model_name = self._prev_model_name
        LOG.info("[virtual event manager] Unpaused model for current car.")
        if self._is_continuous:
            self._track_data.park_positions = [self._park_positions[self._park_position_idx]]
            self._current_graph_manager.evaluate(EnvironmentSteps(1))
        else:
            for _ in range(self._number_of_trials):
                self._track_data.park_positions = [self._park_positions[self._park_position_idx]]
                self._current_graph_manager.evaluate(EnvironmentSteps(1))
Example #4
0
    def __init__(self, racecar_name, racecars_info, race_type):
        """ This class is used for head to head racing where there are more than one agent
        Args:
            racecar_name (str): The agent name with 45degree camera view
            racecars_info (dict): All the agents information
            race_type (str): The type of race. This is used to know if its race type or evaluation
        """
        self.racecar_name = racecar_name
        self.racecars_info = racecars_info
        racecar_index = get_racecar_idx(racecar_name)
        self.racecar_index = racecar_index if racecar_index else 0
        self.race_type = race_type

        # Store the font which we will use to write the phase with
        self.amazon_ember_regular_20px = utils.get_font(
            'AmazonEmber-Regular', 20)
        self.amazon_ember_regular_16px = utils.get_font(
            'AmazonEmber-Regular', 16)
        self.amazon_ember_heavy_30px = utils.get_font('AmazonEmber-Heavy', 30)
        self.amazon_ember_light_18px = utils.get_font('AmazonEmber-Light', 18)
        self.amazon_ember_light_20px = utils.get_font('AmazonEmber-Light', 20)
        self.amazon_ember_light_italic_20px = utils.get_font(
            'AmazonEmber-LightItalic', 20)

        self.is_racing = rospy.get_param("VIDEO_JOB_TYPE", "") == "RACING"
        self.is_league_leaderboard = rospy.get_param("LEADERBOARD_TYPE",
                                                     "") == "LEAGUE"
        self.leaderboard_name = rospy.get_param("LEADERBOARD_NAME", "")
        self._total_laps = int(rospy.get_param("NUMBER_OF_TRIALS", 0))

        # The track image as iconography
        self.track_icongraphy_img = utils.get_track_iconography_image()

        # Track image offset
        self.track_loc_offset = XYPixelLoc.TRACK_IMG_WITH_OFFSET_LOC.value if self.is_league_leaderboard \
            else XYPixelLoc.TRACK_IMG_WITHOUT_OFFSET_LOC.value

        gradient_img_path = TrackAssetsIconographicPngs.HEAD_TO_HEAD_OVERLAY_PNG_LEAGUE_LEADERBOARD.value \
            if self.is_league_leaderboard else TrackAssetsIconographicPngs.HEAD_TO_HEAD_OVERLAY_PNG.value
        self.gradient_img = self._plot_track_on_gradient(gradient_img_path)
        self.gradient_alpha_rgb_mul, self.one_minus_gradient_alpha = utils.get_gradient_values(
            self.gradient_img)

        # Top camera information
        top_camera_info = utils.get_top_camera_info()
        self.top_view_graphics = TopViewGraphics(
            top_camera_info.horizontal_fov, top_camera_info.padding_pct,
            top_camera_info.image_width, top_camera_info.image_height,
            racecars_info)
Example #5
0
    def __init__(self, racecar_name, racecar_info, race_type):
        """ Initializing the required data for the head to bot, time-trail. This is used for single agent
        Arguments:
            racecars_info (list): list of dict having information of the agent
            race_type (str): Since this class is reused for all the different race_type
        """
        self.racecar_info = racecar_info
        self.race_type = race_type
        racecar_index = get_racecar_idx(racecar_name)
        self.racecar_index = racecar_index if racecar_index else 0
        # Store the font which we will use to write the phase with
        self.amazon_ember_regular_20px = utils.get_font(
            'AmazonEmber-Regular', 20)
        self.amazon_ember_regular_16px = utils.get_font(
            'AmazonEmber-Regular', 16)
        self.amazon_ember_heavy_30px = utils.get_font('AmazonEmber-Heavy', 30)
        self.amazon_ember_light_18px = utils.get_font('AmazonEmber-Light', 18)
        self.amazon_ember_light_20px = utils.get_font('AmazonEmber-Light', 20)
        self.amazon_ember_light_italic_20px = utils.get_font(
            'AmazonEmber-LightItalic', 20)

        self.is_racing = rospy.get_param("VIDEO_JOB_TYPE", "") == "RACING"
        self.is_league_leaderboard = rospy.get_param("LEADERBOARD_TYPE",
                                                     "") == "LEAGUE"
        self.leaderboard_name = rospy.get_param("LEADERBOARD_NAME", "")
        self._total_laps = int(rospy.get_param("NUMBER_OF_TRIALS", 0))

        # The track image as iconography
        self.track_icongraphy_img = utils.get_track_iconography_image()

        # Track image offset
        self.track_loc_offset = XYPixelLoc.TRACK_IMG_WITH_OFFSET_LOC.value if self.is_league_leaderboard \
            else XYPixelLoc.TRACK_IMG_WITHOUT_OFFSET_LOC.value

        # Gradient overlay image
        gradient_img_path = TrackAssetsIconographicPngs.OBSTACLE_OVERLAY_PNG_LEAGUE_LEADERBOARD.value \
            if self.is_league_leaderboard else TrackAssetsIconographicPngs.OBSTACLE_OVERLAY_PNG.value
        self.gradient_img = self._plot_track_on_gradient(gradient_img_path)
        self.gradient_alpha_rgb_mul, self.one_minus_gradient_alpha = utils.get_gradient_values(
            self.gradient_img)

        # Top camera information
        top_camera_info = utils.get_top_camera_info()
        self.top_view_graphics = TopViewGraphics(
            top_camera_info.horizontal_fov, top_camera_info.padding_pct,
            top_camera_info.image_width, top_camera_info.image_height,
            racecar_info)
    def __init__(self, config_dict, run_phase_sink, metrics):
        '''config_dict (dict): containing all the keys in ConfigParams
           run_phase_sink (RunPhaseSubject): Sink to receive notification of a change in run phase
           metrics (EvalMetrics/TrainingMetrics): Training or evaluation metrics
        '''
        # reset rules manager
        self._metrics = metrics
        self._is_continuous = config_dict[
            const.ConfigParams.IS_CONTINUOUS.value]
        self._reset_rules_manager = construct_reset_rules_manager(config_dict)
        self._ctrl_status = dict()
        self._ctrl_status[
            AgentCtrlStatus.AGENT_PHASE.value] = AgentPhase.RUN.value
        self._config_dict = config_dict
        self._done_condition = config_dict.get(
            const.ConfigParams.DONE_CONDITION.value, any)
        self._number_of_resets = config_dict[
            const.ConfigParams.NUMBER_OF_RESETS.value]
        self._off_track_penalty = config_dict[
            const.ConfigParams.OFF_TRACK_PENALTY.value]
        self._collision_penalty = config_dict[
            const.ConfigParams.COLLISION_PENALTY.value]
        self._pause_duration = 0.0
        self._reset_count = 0
        self._curr_crashed_object_name = ''
        # simapp_version speed scale
        self._speed_scale_factor_ = get_speed_factor(
            config_dict[const.ConfigParams.VERSION.value])
        # Store the name of the agent used to set agents position on the track
        self._agent_name_ = config_dict[const.ConfigParams.AGENT_NAME.value]
        # Set start lane. This only support for two agents H2H race
        self._agent_idx_ = get_racecar_idx(self._agent_name_)
        # Get track data
        self._track_data_ = TrackData.get_instance()
        if self._agent_idx_ is not None:
            self._start_lane_ = self._track_data_.inner_lane \
                if self._agent_idx_ % 2 else self._track_data_.outer_lane
        else:
            self._start_lane_ = self._track_data_.center_line
        # Store the name of the links in the agent, this should be const
        self._agent_link_name_list_ = config_dict[
            const.ConfigParams.LINK_NAME_LIST.value]
        # Store the reward function
        self._reward_ = config_dict[const.ConfigParams.REWARD.value]
        # Create publishers for controlling the car
        self._velocity_pub_dict_ = OrderedDict()
        self._steering_pub_dict_ = OrderedDict()
        for topic in config_dict[const.ConfigParams.VELOCITY_LIST.value]:
            self._velocity_pub_dict_[topic] = rospy.Publisher(topic,
                                                              Float64,
                                                              queue_size=1)
        for topic in config_dict[const.ConfigParams.STEERING_LIST.value]:
            self._steering_pub_dict_[topic] = rospy.Publisher(topic,
                                                              Float64,
                                                              queue_size=1)
        #Create default reward parameters
        self._reward_params_ = const.RewardParam.make_default_param()
        #Create the default metrics dictionary
        self._step_metrics_ = StepMetrics.make_default_metric()
        # Dictionary of bools indicating starting position behavior
        self._start_pos_behavior_ = \
            {'change_start' : config_dict[const.ConfigParams.CHANGE_START.value],
             'alternate_dir' : config_dict[const.ConfigParams.ALT_DIR.value]}
        # Dictionary to track the previous way points
        self._prev_waypoints_ = {
            'prev_point': Point(0, 0),
            'prev_point_2': Point(0, 0)
        }

        # Normalized distance of new start line from the original start line of the track.
        start_ndist = 0.0

        # Normalized start position offset w.r.t to start_ndist, which is the start line of the track.
        start_pos_offset = config_dict.get(
            const.ConfigParams.START_POSITION.value, 0.0)
        self._start_line_ndist_offset = start_pos_offset / self._track_data_.get_track_length(
        )

        # Dictionary containing some of the data for the agent
        # - During the reset call, every value except start_ndist will get wiped out by self._clear_data
        #   (reset happens prior to every episodes begin)
        # - If self._start_line_ndist_offset is not 0 (usually some minus value),
        #   then initial current_progress suppose to be non-zero (usually some minus value) as progress
        #   suppose to be based on start_ndist.
        # - This will be correctly calculated by first call of utils.compute_current_prog function.
        #   As prev_progress will be initially 0.0 and physical position is not at start_ndist,
        #   utils.compute_current_prog will return negative progress if self._start_line_ndist_offset is negative value
        #   (meaning behind start line) and will return positive progress if self._start_line_ndist_offset is
        #   positive value (meaning ahead of start line).
        self._data_dict_ = {
            'max_progress': 0.0,
            'current_progress': 0.0,
            'prev_progress': 0.0,
            'steps': 0.0,
            'start_ndist': start_ndist,
            'prev_car_pose': 0.0
        }

        #Load the action space
        self._action_space_, self._json_actions_ = \
            load_action_space(config_dict[const.ConfigParams.ACTION_SPACE_PATH.value])
        #! TODO evaluate if this is the best way to reset the car
        # Adding the reward data publisher
        self.reward_data_pub = RewardDataPublisher(self._agent_name_,
                                                   self._json_actions_)
        # subscriber to time to update camera position
        self.camera_manager = CameraManager.get_instance()
        # True if the agent is in the training phase
        self._is_training_ = False
        # Register to the phase sink
        run_phase_sink.register(self)
        # Make sure velocity and angle are set to 0
        send_action(self._velocity_pub_dict_, self._steering_pub_dict_, 0.0,
                    0.0)

        # start_dist should be hypothetical start line (start_ndist) plus
        # start position offset (start_line_ndist_offset).
        start_pose = self._start_lane_.interpolate_pose(
            (self._data_dict_['start_ndist'] + self._start_line_ndist_offset) *
            self._track_data_.get_track_length(),
            finite_difference=FiniteDifference.FORWARD_DIFFERENCE)
        self._track_data_.initialize_object(self._agent_name_, start_pose, \
                                            ObstacleDimensions.BOT_CAR_DIMENSION)

        self.make_link_points = lambda link_state: Point(
            link_state.pose.position.x, link_state.pose.position.y)
        self.reference_frames = ['' for _ in self._agent_link_name_list_]

        self._pause_car_model_pose = None
        self._park_position = DEFAULT_PARK_POSITION
        AbstractTracker.__init__(self, TrackerPriority.HIGH)
    def __init__(self, racecar_name, racecars_info, race_type):
        """ This class is used for head to head racing where there are more than one agent
        Args:
            racecar_name (str): The agent name with 45degree camera view
            racecars_info (dict): All the agents information
            race_type (str): The type of race. This is used to know if its race type or evaluation
        """
        self.racecar_name = racecar_name
        self.racecars_info = racecars_info
        racecar_index = get_racecar_idx(racecar_name)
        self.racecar_index = racecar_index if racecar_index else 0
        self.race_type = race_type

        # Store the font which we will use to write the phase with
        self.formula1_display_regular_12px = utils.get_font(
            'Formula1-Display-Regular', 12)
        self.formula1_display_regular_14px = utils.get_font(
            'Formula1-Display-Regular', 14)
        self.formula1_display_regular_16px = utils.get_font(
            'Formula1-Display-Regular', 16)
        self.formula1_display_wide_12px = utils.get_font(
            'Formula1-Display-Wide', 12)
        self.formula1_display_bold_16px = utils.get_font(
            'Formula1-Display-Bold', 16)

        self.total_laps = int(rospy.get_param("NUMBER_OF_TRIALS", 0))
        self.is_league_leaderboard = rospy.get_param("LEADERBOARD_TYPE",
                                                     "") == "LEAGUE"
        self.leaderboard_name = rospy.get_param("LEADERBOARD_NAME", "")

        # The track image as iconography
        self.track_icongraphy_img = utils.get_track_iconography_image()

        # Track image offset
        self.track_loc_offset = XYPixelLoc.TRACK_IMG_WITHOUT_OFFSET_LOC.value

        # Default image of top view
        gradient_default_img_path = TrackAssetsIconographicPngs.F1_OVERLAY_DEFAULT_PNG.value
        self.gradient_default_img = self._plot_track_on_gradient(
            gradient_default_img_path)
        self.gradient_default_alpha_rgb_mul, self.one_minus_gradient_default_alpha = utils.get_gradient_values(
            self.gradient_default_img)

        # Midway track gradient
        gradient_midway_img_path = TrackAssetsIconographicPngs.F1_OVERLAY_MIDWAY_PNG.value
        self.gradient_midway_img = self._plot_track_on_gradient(
            gradient_midway_img_path)
        self.gradient_midway_alpha_rgb_mul, self.one_minus_gradient_midway_alpha = utils.get_gradient_values(
            self.gradient_midway_img)

        # Finisher track gradient
        gradient_finisher_img_path = TrackAssetsIconographicPngs.F1_OVERLAY_FINISHERS_PNG.value
        self.gradient_finisher_img = self._plot_track_on_gradient(
            gradient_finisher_img_path)
        self.gradient_finisher_alpha_rgb_mul, self.one_minus_gradient_finisher_alpha = utils.get_gradient_values(
            self.gradient_finisher_img)

        # Top camera gradient
        num_racers = len(self.racecars_info)
        if num_racers <= 8:
            # TODO: Add one box image and use 1 box image if number of racers are <= 4.
            gradient_top_camera_img_path = TrackAssetsIconographicPngs.F1_OVERLAY_TOPVIEW_2BOX_PNG.value
        elif num_racers <= 12:
            gradient_top_camera_img_path = TrackAssetsIconographicPngs.F1_OVERLAY_TOPVIEW_3BOX_PNG.value
        else:
            raise Exception(
                "More than 12 racers are not supported for Grand Prix")

        gradient_top_camera_img = utils.get_image(
            gradient_top_camera_img_path,
            IconographicImageSize.FULL_IMAGE_SIZE.value)
        gradient_top_camera_img = cv2.cvtColor(gradient_top_camera_img,
                                               cv2.COLOR_RGBA2BGRA)
        self.gradient_top_camera_alpha_rgb_mul, self.one_minus_gradient_top_camera_alpha = utils.get_gradient_values(
            gradient_top_camera_img)

        # Top camera information
        top_camera_info = utils.get_top_camera_info()
        self.edited_topview_pub = rospy.Publisher('/deepracer/topview_stream',
                                                  ROSImg,
                                                  queue_size=1)
        self.top_view_graphics = TopViewGraphics(
            top_camera_info.horizontal_fov, top_camera_info.padding_pct,
            top_camera_info.image_width, top_camera_info.image_height,
            racecars_info, race_type)
        self.hex_car_colors = [
            val['racecar_color'].split('_')[-1] for val in racecars_info
        ]
        self._racer_color_code_rect_img = list()
        self._racer_color_code_slash_img = list()
        for car_color in self.hex_car_colors:
            # Rectangular png of racers
            racer_color_code_rect = "{}_{}".format(
                TrackAssetsIconographicPngs.F1_AGENTS_RECT_DISPLAY_ICON_PNG.
                value, car_color)
            self._racer_color_code_rect_img.append(
                utils.get_image(
                    racer_color_code_rect, IconographicImageSize.
                    F1_RACER_RECT_DISPLAY_ICON_SIZE.value))
            # Slash png of racers
            racer_color_code_slash = "{}_{}".format(
                TrackAssetsIconographicPngs.F1_AGENTS_SLASH_DISPLAY_ICON_PNG.
                value, car_color)
            racer_color_code_slash_img = utils.get_image(
                racer_color_code_slash,
                IconographicImageSize.F1_RACER_SLASH_DISPLAY_ICON_SIZE.value)
            self._racer_color_code_slash_img.append(
                cv2.cvtColor(racer_color_code_slash_img, cv2.COLOR_RGBA2BGRA))
Example #8
0
    def __init__(self, config_dict, run_phase_sink, metrics):
        '''agent_name - String containing the name of the agent
           config_dict - Dictionary containing all the keys in ConfigParams
           run_phase_sink - Sink to recieve notification of a change in run phase
        '''
        # reset rules manager
        self._metrics = metrics
        self._is_continuous = config_dict[
            const.ConfigParams.IS_CONTINUOUS.value]
        self._is_reset = False
        self._reset_rules_manager = construct_reset_rules_manager(config_dict)
        self._ctrl_status = dict()
        self._ctrl_status[
            AgentCtrlStatus.AGENT_PHASE.value] = AgentPhase.RUN.value
        self._config_dict = config_dict
        self._done_condition = config_dict.get(
            const.ConfigParams.DONE_CONDITION.value, any)
        self._number_of_resets = config_dict[
            const.ConfigParams.NUMBER_OF_RESETS.value]
        self._off_track_penalty = config_dict[
            const.ConfigParams.OFF_TRACK_PENALTY.value]
        self._collision_penalty = config_dict[
            const.ConfigParams.COLLISION_PENALTY.value]
        self._pause_duration = 0.0
        self._reset_count = 0
        self._curr_crashed_object_name = None
        self._last_crashed_object_name = None
        # simapp_version speed scale
        self._speed_scale_factor_ = get_speed_factor(
            config_dict[const.ConfigParams.VERSION.value])
        # Store the name of the agent used to set agents position on the track
        self._agent_name_ = config_dict[const.ConfigParams.AGENT_NAME.value]
        # Set start lane. This only support for two agents H2H race
        self._agent_idx_ = get_racecar_idx(self._agent_name_)
        # Get track data
        self._track_data_ = TrackData.get_instance()
        if self._agent_idx_ is not None:
            self._start_lane_ = self._track_data_.inner_lane \
                if self._agent_idx_ % 2 else self._track_data_.outer_lane
        else:
            self._start_lane_ = self._track_data_.center_line
        # Store the name of the links in the agent, this should be const
        self._agent_link_name_list_ = config_dict[
            const.ConfigParams.LINK_NAME_LIST.value]
        # Store the reward function
        self._reward_ = config_dict[const.ConfigParams.REWARD.value]
        # Create publishers for controlling the car
        self._velocity_pub_dict_ = OrderedDict()
        self._steering_pub_dict_ = OrderedDict()
        for topic in config_dict[const.ConfigParams.VELOCITY_LIST.value]:
            self._velocity_pub_dict_[topic] = rospy.Publisher(topic,
                                                              Float64,
                                                              queue_size=1)
        for topic in config_dict[const.ConfigParams.STEERING_LIST.value]:
            self._steering_pub_dict_[topic] = rospy.Publisher(topic,
                                                              Float64,
                                                              queue_size=1)
        #Create default reward parameters
        self._reward_params_ = const.RewardParam.make_default_param()
        #Creat the default metrics dictionary
        self._step_metrics_ = StepMetrics.make_default_metric()
        # Dictionary of bools indicating starting position behavior
        self._start_pos_behavior_ = \
            {'change_start' : config_dict[const.ConfigParams.CHANGE_START.value],
             'alternate_dir' : config_dict[const.ConfigParams.ALT_DIR.value]}
        # Dictionary to track the previous way points
        self._prev_waypoints_ = {
            'prev_point': Point(0, 0),
            'prev_point_2': Point(0, 0)
        }
        # Normalize start position in meter to normalized start_ndist in percentage
        start_ndist = config_dict.get(const.ConfigParams.START_POSITION.value, 0.0) / \
            self._track_data_.get_track_length()
        # Dictionary containing some of the data for the agent
        self._data_dict_ = {
            'max_progress': 0.0,
            'current_progress': 0.0,
            'prev_progress': 0.0,
            'steps': 0.0,
            'start_ndist': start_ndist
        }
        #Load the action space
        self._action_space_, self._json_actions_ = \
            load_action_space(config_dict[const.ConfigParams.ACTION_SPACE_PATH.value])
        #! TODO evaluate if this is the best way to reset the car
        # Adding the reward data publisher
        self.reward_data_pub = RewardDataPublisher(self._agent_name_,
                                                   self._json_actions_)
        # subscriber to time to update camera position
        self.camera_manager = CameraManager.get_instance()
        # True if the agent is in the training phase
        self._is_training_ = False
        # Register to the phase sink
        run_phase_sink.register(self)
        # Make sure velicty and angle are set to 0
        send_action(self._velocity_pub_dict_, self._steering_pub_dict_, 0.0,
                    0.0)
        start_pose = self._track_data_.center_line.interpolate_pose(
            self._data_dict_['start_ndist'] *
            self._track_data_.get_track_length(),
            finite_difference=FiniteDifference.FORWARD_DIFFERENCE)
        self._track_data_.initialize_object(self._agent_name_, start_pose, \
                                            ObstacleDimensions.BOT_CAR_DIMENSION)

        self.make_link_points = lambda link_state: Point(
            link_state.pose.position.x, link_state.pose.position.y)
        self.reference_frames = ['' for _ in self._agent_link_name_list_]

        self._pause_car_model_pose = None
        self._park_position = DEFAULT_PARK_POSITION
        AbstractTracker.__init__(self, TrackerPriority.HIGH)
    def __init__(self, racecar_name, racecars_info):
        #
        # We have no guarantees as to when gazebo will load the model, therefore we need
        # to wait until the model is loaded and markov packages has spawned all the models
        #
        rospy.wait_for_service('/robomaker_markov_package_ready')

        self._agents_metrics.append(DoubleBuffer(clear_data_on_get=False))

        self.racecar_name = racecar_name
        self.racecars_info = racecars_info
        racecar_index = get_racecar_idx(racecar_name)
        self.racecar_index = racecar_index if racecar_index else 0
        self.agent_name = utils.racecar_name_to_agent_name(racecars_info, racecar_name)

        # init cv bridge
        self.bridge = CvBridge()

        # This determines what kind of image editing should be done based on the race type
        self.is_training = rospy.get_param("JOB_TYPE") == 'TRAINING'
        self.job_type_image_edit = self._get_image_editing_job_type()
        if self.is_training:
            # String indicating the current phase
            self._current_training_phase = DoubleBuffer(clear_data_on_get=False)
            self._current_training_phase.put('Initializing')
            # Subscriber to get the phase of the training (Ideal, training, evaluation)
            rospy.Subscriber('/agent/training_phase', String, self._training_phase_cb)

        # Fetching main camera frames, start consumer thread and producer thread for main camera frame
        main_camera_topic = "/{}/{}/zed/rgb/image_rect_color".format(self.racecar_name, "main_camera")

        # All KVS related initialization
        self._kvs_frame_buffer = DoubleBuffer(clear_data_on_get=False)

        # Publish to KVS stream topic
        self.kvs_pub = rospy.Publisher('/{}/deepracer/kvs_stream'.format(self.racecar_name), ROSImg, queue_size=1)

        # All Mp4 related initialization
        self._mp4_queue.append(Queue())
        self._mp4_edited_frame_queue.append(Queue(MAX_FRAMES_IN_QUEUE))
        self._mp4_condition_lock.append(Condition())

        # Initialize save mp4 ROS service for the markov package to signal when to
        # start and stop collecting video frames
        camera_info = utils.get_cameratype_params(self.racecar_name, self.agent_name)
        self.save_to_mp4_obj = SaveToMp4(camera_infos=[camera_info[CameraTypeParams.CAMERA_PIP_PARAMS],
                                                       camera_info[CameraTypeParams.CAMERA_45DEGREE_PARAMS],
                                                       camera_info[CameraTypeParams.CAMERA_TOPVIEW_PARAMS]],
                                         fourcc=Mp4Parameter.FOURCC.value,
                                         fps=Mp4Parameter.FPS.value,
                                         frame_size=Mp4Parameter.FRAME_SIZE.value)
        rospy.Service('/{}/save_mp4/subscribe_to_save_mp4'.format(self.racecar_name),
                      Empty, self.subscribe_to_save_mp4)
        rospy.Service('/{}/save_mp4/unsubscribe_from_save_mp4'.format(self.racecar_name),
                      Empty, self.unsubscribe_to_save_mp4)

        # Publish to save mp4 topic
        self.mp4_main_camera_pub = rospy.Publisher('/{}/deepracer/main_camera_stream'.format(self.racecar_name), ROSImg,
                                                   queue_size=1)

        # ROS service to get video metrics
        rospy.wait_for_service("/{}/{}".format(self.agent_name, "mp4_video_metrics"))
        self.mp4_video_metrics_srv = ServiceProxyWrapper("/{}/{}".format(self.agent_name, "mp4_video_metrics"),
                                                         VideoMetricsSrv)
        self.is_save_mp4_enabled = False

        rospy.Subscriber(main_camera_topic, ROSImg, self._producer_frame_thread)
        Thread(target=self._consumer_mp4_frame_thread).start()
        Thread(target=self._kvs_publisher).start()
        Thread(target=self._mp4_publisher).start()
    def __init__(self, racecar_name, racecar_info, race_type):
        """ Initializing the required data for the head to bot, time-trail. This is used for single agent
        Arguments:
            racecar_name (str): racecar name in string
            racecars_info (list): list of dict having information of the agent
            race_type (str): Since this class is reused for all the different race_type
        """
        # race duration in milliseconds
        self._world_name = rospy.get_param("WORLD_NAME")
        self.num_sectors = int(rospy.get_param("NUM_SECTORS", "3"))
        self.race_duration = int(
            rospy.get_param("RACE_DURATION", DEFAULT_RACE_DURATION)) * 1000
        self.racecar_info = racecar_info
        self.race_type = race_type
        racecar_index = get_racecar_idx(racecar_name)
        self.racecar_index = racecar_index if racecar_index else 0
        # Store the font which we will use to write the phase with
        self.amazon_ember_regular_28px = utils.get_font(
            'AmazonEmber-Regular', 28)
        self.amazon_ember_regular_14px = utils.get_font(
            'AmazonEmber-Regular', 14)

        # The track image as iconography
        self.track_icongraphy_img = utils.get_track_iconography_image()

        # Track image offset
        self.track_loc_offset = VirtualEventXYPixelLoc.TRACK_IMG_VIRTUAL_EVENT_LOC.value
        self._track_x_min = None
        self._track_x_max = None
        self._track_y_min = None
        self._track_y_max = None

        # Gradient overlay image with track and virtual event mock
        gradient_img_path = VirtualEventIconographicPngs.OVERLAY_PNG.value
        self.gradient_img = self._plot_track_on_gradient(gradient_img_path)

        # Time remaining text
        loc_x, loc_y = VirtualEventXYPixelLoc.TIME_REMAINING_TEXT.value
        self.gradient_img = utils.write_text_on_image(
            image=self.gradient_img,
            text="TIME REMAINING",
            loc=(loc_x, loc_y),
            font=self.amazon_ember_regular_14px,
            font_color=RaceCarColorToRGB.White.value,
            font_shadow_color=RaceCarColorToRGB.Black.value)

        # Speed text
        loc_x, loc_y = VirtualEventXYPixelLoc.SPEED_TEXT.value
        self.gradient_img = utils.write_text_on_image(
            image=self.gradient_img,
            text="m/s",
            loc=(loc_x, loc_y),
            font=self.amazon_ember_regular_14px,
            font_color=RaceCarColorToRGB.White.value,
            font_shadow_color=RaceCarColorToRGB.Black.value)

        # Reset text
        loc_x, loc_y = VirtualEventXYPixelLoc.RESET_TEXT.value
        self.gradient_img = utils.write_text_on_image(
            image=self.gradient_img,
            text="RESET",
            loc=(loc_x, loc_y),
            font=self.amazon_ember_regular_14px,
            font_color=RaceCarColorToRGB.White.value,
            font_shadow_color=RaceCarColorToRGB.Black.value)

        # current lap time text
        loc_x, loc_y = VirtualEventXYPixelLoc.CURRENT_LAP_TIME_TEXT.value
        self.gradient_img = utils.write_text_on_image(
            image=self.gradient_img,
            text="CURRENT LAP TIME",
            loc=(loc_x, loc_y),
            font=self.amazon_ember_regular_14px,
            font_color=RaceCarColorToRGB.White.value,
            font_shadow_color=RaceCarColorToRGB.Black.value)

        # best lap time text
        loc_x, loc_y = VirtualEventXYPixelLoc.BEST_LAP_TIME_TEXT.value
        self.gradient_img = utils.write_text_on_image(
            image=self.gradient_img,
            text="BEST LAP TIME",
            loc=(loc_x, loc_y),
            font=self.amazon_ember_regular_14px,
            font_color=RaceCarColorToRGB.White.value,
            font_shadow_color=RaceCarColorToRGB.Black.value)

        # apply graident
        self.gradient_alpha_rgb_mul, self.one_minus_gradient_alpha = utils.get_gradient_values(
            self.gradient_img)

        # Top camera information
        top_camera_info = utils.get_top_camera_info()
        self.top_view_graphics = TopViewGraphics(
            top_camera_info.horizontal_fov,
            top_camera_info.padding_pct,
            top_camera_info.image_width,
            top_camera_info.image_height,
            racecar_info,
            is_virtual_event=True)

        # virtual event image editting state machine
        self._image_edit_fsm = FSM(initial_state=VirtualEventWaitState())
        # if best sector time download from s3 failed. Then, initialize best sector time as None
        # and not display sector color
        self._sector_times = {}

        # declare sector images
        self._sectors_img_dict = {}
        for idx in range(self.num_sectors):
            sector = SECTOR_X_FORMAT.format(idx + 1)
            sector_color_img_dict = utils.init_sector_img_dict(
                world_name=self._world_name, sector=sector)
            self._sectors_img_dict[sector] = sector_color_img_dict

        # use the s3 bucket and prefix for yaml file stored as environment variable because
        # here is SimApp use only. For virtual event there is no s3 bucket and prefix past
        # through yaml file. All are past through sqs. For simplicity, reuse the yaml s3 bucket
        # and prefix environment variable.
        self._virtual_event_best_sector_time = VirtualEventBestSectorTime(
            bucket=os.environ.get("YAML_S3_BUCKET", ''),
            s3_key=get_s3_key(os.environ.get("YAML_S3_PREFIX", ''),
                              SECTOR_TIME_S3_POSTFIX),
            region_name=os.environ.get("APP_REGION", "us-east-1"),
            local_path=SECTOR_TIME_LOCAL_PATH)
        self._sector_times.update(
            self._virtual_event_best_sector_time.get_sector_time(
                num_sectors=self.num_sectors))

        # declare default best personal and current persoanl time to inf
        for idx in range(self.num_sectors):
            sector = SECTOR_X_FORMAT.format(idx + 1)
            self._sector_times[SECTOR_TIME_FORMAT_DICT[
                TrackSectorTime.BEST_PERSONAL].format(sector)] = float("inf")
            self._sector_times[SECTOR_TIME_FORMAT_DICT[
                TrackSectorTime.CURRENT_PERSONAL].format(sector)] = float(
                    "inf")

        self._curr_lap_time = 0
        self._last_eval_time = 0
        self._curr_progress = 0
        self._last_progress = 0
        self._current_lap = 1

        # Initializing the fader behaviour to pre-compute the gradient values
        final_fading_image = utils.get_image(
            VirtualEventIconographicPngs.FINAL_FADING_IMAGE_50ALPHA.value,
            IconographicImageSize.FULL_IMAGE_SIZE.value)
        final_fading_image = cv2.cvtColor(final_fading_image,
                                          cv2.COLOR_RGBA2BGRA)
        self._fader_obj = Fader(
            final_fading_image,
            fading_min_percent=VirtualEventFader.FADING_MIN_PERCENT.value,
            fading_max_percent=VirtualEventFader.FADING_MAX_PERCENT.value,
            num_frames=VirtualEventFader.NUM_FRAMES.value)
Example #11
0
    def __init__(self, racecar_name, racecars_info, is_publish_to_kvs_stream):
        #
        # We have no guarantees as to when gazebo will load the model, therefore we need
        # to wait until the model is loaded and markov packages has spawned all the models
        #
        rospy.wait_for_service('/robomaker_markov_package_ready')

        self._agents_metrics.append(DoubleBuffer(clear_data_on_get=False))

        self.racecar_name = racecar_name
        self.racecars_info = racecars_info
        racecar_index = get_racecar_idx(racecar_name)
        self.racecar_index = racecar_index if racecar_index else 0
        self.agent_name = utils.racecar_name_to_agent_name(
            racecars_info, racecar_name)
        self._is_publish_to_kvs_stream = is_publish_to_kvs_stream

        # init cv bridge
        self.bridge = CvBridge()

        # This determines what kind of image editing should be done based on the race type
        self.is_training = rospy.get_param("JOB_TYPE") == 'TRAINING'
        self.race_type = rospy.get_param("RACE_TYPE",
                                         RaceType.TIME_TRIAL.value)
        self.is_f1_race_type = self.race_type == RaceType.F1.value
        #
        # Two job types are required because in the F1 editing we have static variables
        # to compute the gap and ranking. With Mp4 stacking frames, these values would be already updated by KVS.
        # If same class is used then during the finish phase you see all the racers information at once
        # and not updated real time when racers finish the lap.
        # %TODO seperate out the kvs and Mp4 functionality
        #
        self.job_type_image_edit_mp4 = self._get_image_editing_job_type()
        if self.is_training:
            # String indicating the current phase
            self._current_training_phase = DoubleBuffer(
                clear_data_on_get=False)
            self._current_training_phase.put('Initializing')
            # Subscriber to get the phase of the training (Ideal, training, evaluation)
            rospy.Subscriber('/agent/training_phase', String,
                             self._training_phase_cb)

        # Fetching main camera frames, start consumer thread and producer thread for main camera frame
        main_camera_topic = "/{}/{}/zed/rgb/image_rect_color".format(
            self.racecar_name, "main_camera")

        # All Mp4 related initialization
        self._mp4_queue.append(Queue.Queue())

        # Initialize save mp4 ROS service for the markov package to signal when to
        # start and stop collecting video frames
        camera_info = utils.get_cameratype_params(self.racecar_name,
                                                  self.agent_name,
                                                  self.is_f1_race_type)
        self.save_to_mp4_obj = SaveToMp4(
            camera_infos=[
                camera_info[CameraTypeParams.CAMERA_PIP_PARAMS],
                camera_info[CameraTypeParams.CAMERA_45DEGREE_PARAMS],
                camera_info[CameraTypeParams.CAMERA_TOPVIEW_PARAMS]
            ],
            fourcc=Mp4Parameter.FOURCC.value,
            fps=Mp4Parameter.FPS.value,
            frame_size=Mp4Parameter.FRAME_SIZE.value)
        rospy.Service(
            '/{}/save_mp4/subscribe_to_save_mp4'.format(self.racecar_name),
            Empty, self.subscribe_to_save_mp4)
        rospy.Service(
            '/{}/save_mp4/unsubscribe_from_save_mp4'.format(self.racecar_name),
            Empty, self.unsubscribe_to_save_mp4)

        # Publish to save mp4 topic
        self.mp4_main_camera_pub = rospy.Publisher(
            '/{}/deepracer/main_camera_stream'.format(self.racecar_name),
            ROSImg,
            queue_size=1)

        # ROS service to get video metrics
        rospy.wait_for_service("/{}/{}".format(self.agent_name,
                                               "mp4_video_metrics"))
        self.mp4_video_metrics_srv = ServiceProxyWrapper(
            "/{}/{}".format(self.agent_name, "mp4_video_metrics"),
            VideoMetricsSrv)
        self.is_save_mp4_enabled = False

        # Only F1 race requires top camera frames edited
        self.top_camera_mp4_pub = None
        if self.is_f1_race_type and self.racecar_index == 0:
            self._top_camera_frame_buffer = DoubleBuffer(
                clear_data_on_get=False)
            top_camera_topic = "/sub_camera/zed/rgb/image_rect_color"
            rospy.Subscriber(top_camera_topic, ROSImg, self._top_camera_cb)
            self.top_camera_mp4_pub = rospy.Publisher(
                '/{}/topcamera/deepracer/mp4_stream'.format(racecar_name),
                ROSImg,
                queue_size=1)

        self._main_camera_frame_buffer = DoubleBuffer(clear_data_on_get=False)
        rospy.Subscriber(main_camera_topic, ROSImg,
                         self._producer_frame_thread)
        Thread(target=self._consumer_mp4_frame_thread).start()

        # Leaderboard jobs do not require KVS streams
        if self._is_publish_to_kvs_stream:
            self.job_type_image_edit_kvs = self._get_image_editing_job_type()
            # Publish to KVS stream topic
            self.kvs_pub = rospy.Publisher('/{}/deepracer/kvs_stream'.format(
                self.racecar_name),
                                           ROSImg,
                                           queue_size=1)
            Thread(target=self._kvs_publisher).start()