Пример #1
0
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(BasicAgent, self).__init__(vehicle)

        self._state = AgentState.NAVIGATING
        args_lateral_dict = {
            'K_P': 0.75,
            'K_D': 0.001,
            'K_I': 1,
            'dt': 1.0 / 20.0
        }
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._grp = None
Пример #2
0
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(BasicAgent, self).__init__(vehicle)

        self.stopping_for_traffic_light = False
        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        args_lateral_dict = {
            'K_P': 0.75,
            'K_D': 0.001,
            'K_I': 1,
            'dt': 1.0 / 20.0
        }
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._grp = None
        self.drawn_lights = False
        self.is_affected_by_traffic_light = False
Пример #3
0
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(TryAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0  # meters
        self._state = _AgentState.NAVIGATING
        args_lateral_dict = {'K_P': 1, 'K_D': 0.02, 'K_I': 0, 'dt': 1.0 / 20.0}
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._grp = None
        self.speed = 60
        self.matrix_transform = None
        self.last = False
        self.walker = None
 def __init__(self, world):
     """
     :param vehicle: actor to apply to local planner logic onto
     """
     super(LearningAgent, self).__init__(world.player)
     self._world_obj = world
     # Learning Model
     self._model = Model()
     self._THW = None
     self._target_speed = None
     self._sin_param = None
     self._poly_param = None
     # Local plannar
     self._local_planner = LocalPlanner(world.player)
     self.update_parameters()
     # Global plannar
     self._proximity_threshold = 10.0  # meter
     self._state = AgentState.NAVIGATING
     self._hop_resolution = 0.2
     self._path_seperation_hop = 2
     self._path_seperation_threshold = 0.5
     self._grp = None  # global route planar
     # Behavior planning
     self._hazard_detected = False
     self._blocked_time = None
     self._perform_lane_change = False
     self._front_r = []
     self._left_front_r = []
     self._left_back_r = []
Пример #5
0
    def __init__(self, vehicle):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(RoamingAgent, self).__init__(vehicle)
        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        self._local_planner = LocalPlanner(self._vehicle)
Пример #6
0
  def __init__(self,
               environment: oatomobile.envs.CARLAEnv,
               *,
               proximity_tlight_threshold: float = 9.5,
               proximity_vehicle_threshold: float = 9.5,
               noise: float = 0.1) -> None:
    """Constructs an autopilot agent.

    Args:
      environment: The navigation environment to spawn the agent.
      proximity_tlight_threshold: The threshold (in metres) to
        the traffic light.
      proximity_vehicle_threshold: The threshold (in metres) to
        the front vehicle.
      noise: The percentage of random actions.
    """
    super(AutopilotAgent, self).__init__(environment=environment)

    # References to the CARLA objects.
    self._vehicle = self._environment.simulator.hero
    self._world = self._vehicle.get_world()
    self._map = self._world.get_map()
    self._road_map = imread(osp.join(osp.dirname(__file__), '%s.png' % self._map.name))
    # Agent hyperparametres.
    self._proximity_tlight_threshold = proximity_tlight_threshold
    self._proximity_vehicle_threshold = proximity_vehicle_threshold
    self._hop_resolution = 2.0
    self._path_seperation_hop = 2
    self._path_seperation_threshold = 0.5
    self._target_speed = defaults.TARGET_SPEED
    self._noise = noise

    # The internal state of the agent.
    self._last_traffic_light = None

    # Local planner, including the PID controllers.
    dt = self._vehicle.get_world().get_settings().fixed_delta_seconds
    # lateral_control_dict = defaults.LATERAL_PID_CONTROLLER_CONFIG.copy()
    # lateral_control_dict.update({"dt": dt})
    # TODO(filangel): tune the parameters for FPS != 20
    self._local_planner = LocalPlanner(
        self._vehicle,
        opt_dict=dict(
            target_speed=self._target_speed,
            dt=dt,
        ),
    )

    # Set agent's dsestination.
    if hasattr(self._environment.unwrapped.simulator, "destination"):
      self._set_destination(
          self._environment.unwrapped.simulator.destination.location)
Пример #7
0
    def __init__(self, vehicle):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(BasicAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        self._local_planner = LocalPlanner(self._vehicle)

        # setting up global router
        self._current_plan = None
Пример #8
0
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(BasicAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0 # meters
        self._state = AgentState.NAVIGATING
        self._local_planner = LocalPlanner(self._vehicle, opt_dict={'target_speed' : target_speed})
        self._hop_resolution = 2.0

        # setting up global router
        self._current_plan = None
Пример #9
0
    def __init__(self, vehicle):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(RoamingAgent, self).__init__(vehicle)
        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        args_lateral_dict = {
            'K_P': 1.5,
            'K_D': 0,
            'K_I': 0,
            'dt': 1.0 / 20.0}
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={'lateral_control_dict':args_lateral_dict})
Пример #10
0
class RoamingAgent(Agent):
    """
    RoamingAgent implements a basic agent that navigates scenes making random
    choices when facing an intersection.

    This agent respects traffic lights and other vehicles.
    """

    def __init__(self, vehicle):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(RoamingAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        self._local_planner = LocalPlanner(self._vehicle)

    def run_step(self, debug=False):
        """
        Execute one step of navigation.
        :return: carla.VehicleControl
        """

        # is there an obstacle in front of us?
        hazard_detected = False

        # retrieve relevant elements for safe navigation, i.e.: traffic lights
        # and other vehicles
        actor_list = self._world.get_actors()
        vehicle_list = actor_list.filter("*vehicle*")
        lights_list = actor_list.filter("*traffic_light*")

        # check possible obstacles
        vehicle_state, vehicle = self._is_vehicle_hazard(vehicle_list)
        if vehicle_state:
            if debug:
                print('!!! VEHICLE BLOCKING AHEAD [{}])'.format(vehicle.id))

            self._state = AgentState.BLOCKED_BY_VEHICLE
            hazard_detected = True

        # check for the state of the traffic lights
        light_state, traffic_light = self._is_light_red(lights_list)
        if light_state:
            if debug:
                print('=== RED LIGHT AHEAD [{}])'.format(traffic_light.id))

            self._state = AgentState.BLOCKED_RED_LIGHT
            hazard_detected = True

        if hazard_detected:
            control = self.emergency_stop()
        else:
            self._state = AgentState.NAVIGATING
            # standard local planner behavior
            control = self._local_planner.run_step()

        return control
Пример #11
0
    def __init__(self, vehicle):
        self._vehicle = vehicle
        self._map = vehicle.get_world().get_map()

        args_lateral_dict = {
            'K_P': 1,
            'K_D': 0.4,
            'K_I': 0,
            'dt': 1.0/20.0}
        self._local_planner = LocalPlanner(
            self._vehicle, opt_dict={
                'target_speed' : 0,
                'lateral_control_dict' :args_lateral_dict
            }
        )
        self._hop_resolution = 2.0
        self._grp = self._initialize_global_route_planner()
Пример #12
0
    def __init__(self, vehicle, target_speed=20, opt_dict={}):
        """
        Initialization the agent paramters, the local and the global planner.

            :param vehicle: actor to apply to agent logic onto
            :param target_speed: speed (in Km/h) at which the vehicle will move
            :param opt_dict: dictionary in case some of its parameters want to be changed.
                This also applies to parameters related to the LocalPlanner.
        """
        self._vehicle = vehicle
        self._world = self._vehicle.get_world()
        self._map = self._world.get_map()
        self._last_traffic_light = None

        # Base parameters
        self._ignore_traffic_lights = False
        self._ignore_stop_signs = False
        self._ignore_vehicles = False
        self._target_speed = target_speed
        self._sampling_resolution = 2.0
        self._base_tlight_threshold = 5.0  # meters
        self._base_vehicle_threshold = 5.0  # meters
        self._max_brake = 0.5

        # Change parameters according to the dictionary
        opt_dict['target_speed'] = target_speed
        if 'ignore_traffic_lights' in opt_dict:
            self._ignore_traffic_lights = opt_dict['ignore_traffic_lights']
        if 'ignore_stop_signs' in opt_dict:
            self._ignore_stop_signs = opt_dict['ignore_stop_signs']
        if 'ignore_vehicles' in opt_dict:
            self._ignore_vehicles = opt_dict['ignore_vehicles']
        if 'sampling_resolution' in opt_dict:
            self._sampling_resolution = opt_dict['sampling_resolution']
        if 'base_tlight_threshold' in opt_dict:
            self._base_tlight_threshold = opt_dict['base_tlight_threshold']
        if 'base_vehicle_threshold' in opt_dict:
            self._base_vehicle_threshold = opt_dict['base_vehicle_threshold']
        if 'max_brake' in opt_dict:
            self._max_steering = opt_dict['max_brake']

        # Initialize the planners
        self._local_planner = LocalPlanner(self._vehicle, opt_dict=opt_dict)
        self._global_planner = GlobalRoutePlanner(self._map,
                                                  self._sampling_resolution)
Пример #13
0
class Planner(object):
    def __init__(self, vehicle = None):

        self._vehicle = None
        self.global_planner = None
        self.local_planner = None
        self.resolution = 20.0
        self.route_trace = None

        if vehicle is not None:
            self.initialize(vehicle)

    def initialize(self, vehicle):
        self._vehicle = vehicle
        dao = GlobalRoutePlannerDAO(self._vehicle.get_world().get_map(), self.resolution)
        self.global_planner = GlobalRoutePlanner(dao)
        self.global_planner.setup()
        self.local_planner = LocalPlanner(self._vehicle)



    def set_destination(self, location):

        start_waypoint = self._vehicle.get_world().get_map().get_waypoint(self._vehicle.get_location())
        end_waypoint = self._vehicle.get_world().get_map().get_waypoint(carla.Location(location[0], location[1], location[2]))

        self.route_trace = self.global_planner.trace_route(start_waypoint.transform.location, end_waypoint.transform.location)

        #self.route_trace.pop(0)
        #assert self.route_trace

        self.local_planner.set_global_plan(self.route_trace)

    def run_step(self):
        return self.local_planner.run_step(False)

    def view_plan(self):
        for w in self.route_trace:
            self._vehicle.get_world().debug.draw_string(w[0].transform.location, 'o', draw_shadow=False,
                                       color=carla.Color(r=255, g=0, b=0), life_time=120.0,
                                       persistent_lines=True)

    def done(self):
        return self.local_planner.done()
Пример #14
0
    def _init(self):
        super()._init()


        self._proximity_tlight_threshold = 5.0  # meters
        self._proximity_vehicle_threshold = 10.0  # meters
        self._local_planner = None

        try:
            self._map = self._world.get_map()

        except RuntimeError as error:
            print('RuntimeError: {}'.format(error))
            print('  The server could not send the OpenDRIVE (.xodr) file:')
            print('  Make sure it exists, has the same name of your town, and is correct.')
            sys.exit(1)
        self._last_traffic_light = None



        self._proximity_tlight_threshold = 5.0  # meters
        self._proximity_vehicle_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING

        # TBD: subject to change
        self.target_speed = 7
        args_lateral_dict = {
            'K_P': 1,
            'K_D': 0.4,
            'K_I': 0,
            'dt': 1.0/20.0}
        self._local_planner = LocalPlanner(
            self._vehicle, opt_dict={'target_speed' : self.target_speed,
            'lateral_control_dict':args_lateral_dict})
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._grp = None

        self._map = CarlaDataProvider.get_map()
        route = [(self._map.get_waypoint(x[0].location), x[1]) for x in self._global_plan_world_coord]

        self._local_planner.set_global_plan(route)
Пример #15
0
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(BasicAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        args_lateral_dict = {"K_P": 1, "K_D": 0.02, "K_I": 0, "dt": 1.0 / 20.0}
        self._local_planner = LocalPlanner(
            self._vehicle,
            opt_dict={
                "target_speed": target_speed,
                "lateral_control_dict": args_lateral_dict
            },
        )
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._grp = None
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(RainDrivingAgent, self).__init__(vehicle)

        self._proximity_tlight_threshold = 5.0  # meters
        self._proximity_vehicle_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        args_lateral_dict = {'K_P': 1, 'K_D': 0.4, 'K_I': 0, 'dt': 1.0 / 20.0}
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._grp = None

        # create the camera
        camera_bp = self._world.get_blueprint_library().find(
            'sensor.camera.rgb')
        camera_bp.set_attribute('image_size_x', str(1920 // 2))
        camera_bp.set_attribute('image_size_y', str(1080 // 2))
        camera_bp.set_attribute('fov', str(90))
        camera_transform = carla.Transform(carla.Location(x=-5.5, z=2.8),
                                           carla.Rotation(pitch=-15))
        self._camera = self._world.spawn_actor(camera_bp,
                                               camera_transform,
                                               attach_to=self._vehicle)
        self._camera.listen(lambda image: self._process_image(image))
        self._curr_image = None
        self._save_count = 0
Пример #17
0
    def __init__(self, vehicle, target_speed=50):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(TestAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        args_lateral_dict = {'K_P': 1, 'K_D': 0.02, 'K_I': 0, 'dt': 1.0 / 20.0}
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._world = self._vehicle.get_world()
        self._map = self._vehicle.get_world().get_map()
    def __init__(self, world):
        """
        :param vehicle: actor to apply to local planner logic onto
        """
        super(AutonomousAgent, self).__init__(world.player)
        self._world_obj = world

        self._THW = 2
        self._target_speed = None

        # Local plannar
        self._local_planner = LocalPlanner(world.player)
        self.update_parameters()
        # Global plannar
        self._proximity_threshold = 10.0  # meter   # Distance between waypoints
        self._state = AgentState.NAVIGATING
        self._hop_resolution = 0.2
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._grp = None  # global route planar
        # Behavior planning
        self._hazard_detected = False
        self._blocked_time = None
        self._perform_lane_change = False
        self._front_r = []
        self._left_front_r = []
        self._left_back_r = []

        # Turns positions
        self.right_positions = None
        self.left_positions = None

        # Turn flags
        self.right_turn = False
        self.left_turn = False
        self.temp_flag = True
        self.left_positions = None
Пример #19
0
    def __init__(self, vehicle, world_map, route_list, target_speed=30):
        """
		:param vehicle: actor to apply to local planner logic onto
		"""
        super(NNAgent, self).__init__(vehicle)

        #Proximity threshold to other vehicles
        self.vehicle = vehicle
        self._proximity_threshold = 15.0  # meters
        self.route_list = route_list
        self.route_count = 0
        self.world_map = world_map
        #Threshold for vehicle blocking
        self._blocking_threshold = 20

        self.prev_target_diff = 200

        #Initializing Local Planner to traffict light and vehicle distance calculation
        #Required for detecting traffic lights
        self._local_planner = LocalPlanner(self._vehicle)

        #Initial agent state is always set to navigating
        self._state = AgentState.NAVIGATING
        #Load the trained DQN models
        self.straight_model = load_model('models/Straight_Model_DQN.h5')
        self.right_turn_model = load_model('models/Right_Turn_DQN.h5')
        self.left_turn_model = load_model('models/Left_Turn_DQN.h5')
        self.left_lane_static = load_model('models/Left_Lane_DQN.h5')
        self.right_lane_static = load_model('models/Right_Lane_DQN.h5')
        self.left_lane_model = tf.keras.models.load_model(
            'models/Left_Lane500.h5')
        #Variable for detecting junction
        self.vehicle_junction_hazard = False
        self.vehicle_crossing = None
        #Variables for going around static obstacles
        self.static_obstacle = False
        self.static_lane_change = False
        self.first_lane_reached = False
Пример #20
0
class NavigationAssistant:
    def __init__(self, vehicle):
        self._vehicle = vehicle
        self._map = vehicle.get_world().get_map()

        args_lateral_dict = {
            'K_P': 1,
            'K_D': 0.4,
            'K_I': 0,
            'dt': 1.0/20.0}
        self._local_planner = LocalPlanner(
            self._vehicle, opt_dict={
                'target_speed' : 0,
                'lateral_control_dict' :args_lateral_dict
            }
        )
        self._hop_resolution = 2.0
        self._grp = self._initialize_global_route_planner()

    # Initializes the global route planner.
    def _initialize_global_route_planner(self):
        dao = GlobalRoutePlannerDAO(self._vehicle.get_world().get_map(), self._hop_resolution)
        grp = GlobalRoutePlanner(dao)
        grp.setup()
        return grp

    # Sets vehicle's speed.
    def set_speed(self, target_speed):
        self._local_planner.set_speed(target_speed)

    # Sets vehicle's destination & computes the optimal route towards the destination.
    def set_destination(self, location):
        start_waypoint = self._map.get_waypoint( self._vehicle.get_location() )
        end_waypoint = self._map.get_waypoint(location)

        # Computes the optimal route for the starting location.
        route_trace = self._grp.trace_route(start_waypoint.transform.location, end_waypoint.transform.location)
        self._local_planner.set_global_plan(route_trace)

    # Executes one step of navigation.
    def run_step(self, hazard_detected, debug=False):
        if hazard_detected:
            control = self._emergency_stop()
        else:
            control = self._local_planner.run_step(debug=debug)

        return control

    # Checks whether the vehicle reached its destination.
    def done(self):
        return self._local_planner.done()

    # Returns a control that forces the vehicle to stop.
    @staticmethod
    def _emergency_stop():
        control = carla.VehicleControl()
        control.steer = 0.0
        control.throttle = 0.0
        control.brake = 1.0
        control.hand_brake = False

        return control
Пример #21
0
class AutopilotAgent(oatomobile.Agent):
  """An autopilot agent, based on the official implementation of
  `carla.PythonAPI.agents.navigation.basic_agent.BasicAgent`"""

  def __init__(self,
               environment: oatomobile.envs.CARLAEnv,
               *,
               proximity_tlight_threshold: float = 9.5,
               proximity_vehicle_threshold: float = 9.5,
               noise: float = 0.1) -> None:
    """Constructs an autopilot agent.

    Args:
      environment: The navigation environment to spawn the agent.
      proximity_tlight_threshold: The threshold (in metres) to
        the traffic light.
      proximity_vehicle_threshold: The threshold (in metres) to
        the front vehicle.
      noise: The percentage of random actions.
    """
    super(AutopilotAgent, self).__init__(environment=environment)

    # References to the CARLA objects.
    self._vehicle = self._environment.simulator.hero
    self._world = self._vehicle.get_world()
    self._map = self._world.get_map()
    self._road_map = imread(osp.join(osp.dirname(__file__), '%s.png' % self._map.name))
    # Agent hyperparametres.
    self._proximity_tlight_threshold = proximity_tlight_threshold
    self._proximity_vehicle_threshold = proximity_vehicle_threshold
    self._hop_resolution = 2.0
    self._path_seperation_hop = 2
    self._path_seperation_threshold = 0.5
    self._target_speed = defaults.TARGET_SPEED
    self._noise = noise

    # The internal state of the agent.
    self._last_traffic_light = None

    # Local planner, including the PID controllers.
    dt = self._vehicle.get_world().get_settings().fixed_delta_seconds
    # lateral_control_dict = defaults.LATERAL_PID_CONTROLLER_CONFIG.copy()
    # lateral_control_dict.update({"dt": dt})
    # TODO(filangel): tune the parameters for FPS != 20
    self._local_planner = LocalPlanner(
        self._vehicle,
        opt_dict=dict(
            target_speed=self._target_speed,
            dt=dt,
        ),
    )

    # Set agent's dsestination.
    if hasattr(self._environment.unwrapped.simulator, "destination"):
      self._set_destination(
          self._environment.unwrapped.simulator.destination.location)

  def act(
      self,
      observation: oatomobile.Observations,
  ) -> oatomobile.Action:
    """Takes in an observation, samples from agent's policy, returns an
    action."""
    # Remove unused arguments.
    del observation

    # Random action branch.
    if random.random() < self._noise:
      return carla.VehicleControl(  # pylint: disable=no-member
          **{
              k: float(v)
              for (k, v) in self._environment.action_space.sample().items()
          })
    # Normal autopilot action.
    else:
      return self._run_step()

  def _run_step(
      self,
      debug: bool = False,
  ) -> carla.VehicleControl:  # pylint: disable=no-member
    """Executes one step of navigation."""

    # is there an obstacle in front of us?
    hazard_detected = False

    # retrieve relevant elements for safe navigation, i.e.: traffic lights
    # and other vehicles
    actor_list = self._world.get_actors()
    vehicle_list = actor_list.filter("*vehicle*")
    lights_list = actor_list.filter("*traffic_light*")
    walkers_list = actor_list.filter('*walker*')
    # check possible obstacles
    vehicle_state, vehicle = self._is_vehicle_hazard(vehicle_list)
    if vehicle_state:
      if debug:
        logging.warning('!!! VEHICLE BLOCKING AHEAD [{}])'.format(vehicle.id))

      hazard_detected = True

    # check for the state of the traffic lights
    light_state, traffic_light = self._is_light_red(lights_list)
    if light_state:
      if debug:
        logging.warning('=== RED LIGHT AHEAD [{}])'.format(traffic_light.id))

      hazard_detected = True

    # check for the state of the walkers
    walker_state, walker = self._is_walker_hazard(walkers_list)
    if walker_state:
      if debug:
        logging.warning('=== WALKER AHEAD [{}])'.format(walker.id))

      hazard_detected = True

    if hazard_detected:
      control = carla.VehicleControl()  # pylint: disable=no-member
      control.steer = 0.0
      control.throttle = 0.0
      control.brake = 1.0
      control.hand_brake = False
    else:
      # standard local planner behavior
      control = self._local_planner.run_step(debug=debug)

    return control

  def _set_destination(
      self,
      destination: carla.Location,  # pylint: disable=no-member
  ) -> None:
    """Generates the global plan for the agent.

    Args:
      destination: The location of the new destination.
    """
    # Set vehicle's current location as start for the plan.
    origin = self._vehicle.get_location()
    start_waypoint = self._map.get_waypoint(origin).transform.location
    end_waypoint = self._map.get_waypoint(destination).transform.location
    # Calculate the plan.
    waypoints, roadoptions, _ = cutil.global_plan(
        world=self._world,
        origin=start_waypoint,
        destination=end_waypoint,
    )
    # Mutate the local planner's global plan.
    self._local_planner.set_global_plan(list(zip(waypoints, roadoptions)))

  def _is_walker_hazard(self, walkers_list):
    ego_vehicle_location = self._vehicle.get_location()
    ego_vehicle_waypoint = self._map.get_waypoint(ego_vehicle_location)

    for walker in walkers_list:
      loc = walker.get_location()
      dist = loc.distance(ego_vehicle_location)
      degree = 162 / (np.clip(dist, 1.5, 10.5)+0.3)
      if self._is_point_on_sidewalk(loc):
        continue

      if is_within_distance_ahead(loc, ego_vehicle_location,
                                  self._vehicle.get_transform().rotation.yaw,
                                  self._proximity_vehicle_threshold, degree=degree):
        return (True, walker)

    return (False, None)

  def _is_vehicle_hazard(
      self,
      vehicle_list,
  ) -> Tuple[bool, Optional[carla.Vehicle]]:  # pylint: disable=no-member
    """It detects if a vehicle in the scene can be dangerous for the ego
    vehicle's current plan.

    Args:
      vehicle_list: List of potential vehicles (obstancles) to check.

    Returns:
      vehicle_ahead: If True a vehicle ahead blocking us and False otherwise.
      vehicle: The blocker vehicle itself.
    """

    ego_vehicle_location = self._vehicle.get_location()
    ego_vehicle_orientation = self._vehicle.get_transform().rotation.yaw
    ego_vehicle_waypoint = self._map.get_waypoint(ego_vehicle_location)

    for target_vehicle in vehicle_list:
      # do not account for the ego vehicle.
      if target_vehicle.id == self._vehicle.id:
        continue

      # if the object is not in our lane it's not an obstacle.
      target_vehicle_waypoint = self._map.get_waypoint(
          target_vehicle.get_location())
      if target_vehicle_waypoint.road_id != ego_vehicle_waypoint.road_id or \
              target_vehicle_waypoint.lane_id != ego_vehicle_waypoint.lane_id:
        continue

      loc = target_vehicle.get_location()
      ori = target_vehicle.get_transform().rotation.yaw

      if is_within_distance_ahead(
          loc,
          ego_vehicle_location,
          self._vehicle.get_transform().rotation.yaw,
          self._proximity_vehicle_threshold,
      ) and compute_yaw_difference(ego_vehicle_orientation, ori) <= 150:
        return (True, target_vehicle)

    return (False, None)

  def _is_light_red(
      self,
      lights_list,
  ) -> Tuple[bool, Any]:  # pylint: disable=no-member
    """It detects if the light in the scene is red.

    Args:
      lights_list: The list containing TrafficLight objects.

    Returns:
      light_ahead: If True a traffic light ahead is read and False otherwise.
      traffic_light: The traffic light object ahead itself.
    """
    if self._map.name == 'Town01' or self._map.name == 'Town02':
      return self._is_light_red_europe_style(lights_list)
    else:
      return self._is_light_red_us_style(lights_list)

  def _is_light_red_europe_style(self, lights_list):
    """This method is specialized to check European style traffic lights."""
    ego_vehicle_location = self._vehicle.get_location()
    ego_vehicle_waypoint = self._map.get_waypoint(ego_vehicle_location)

    for traffic_light in lights_list:
      object_waypoint = self._map.get_waypoint(traffic_light.get_location())
      if object_waypoint.road_id != ego_vehicle_waypoint.road_id or \
              object_waypoint.lane_id != ego_vehicle_waypoint.lane_id:
        continue

      loc = traffic_light.get_location()
      if is_within_distance_ahead(
          loc,
          ego_vehicle_location,
          self._vehicle.get_transform().rotation.yaw,
          self._proximity_tlight_threshold,
      ):
        if traffic_light.state == carla.TrafficLightState.Red:  # pylint: disable=no-member
          return (True, traffic_light)

    return (False, None)

  def _is_light_red_us_style(self, lights_list, debug=False):
    """This method is specialized to check US style traffic lights."""
    ego_vehicle_location = self._vehicle.get_location()
    ego_vehicle_waypoint = self._map.get_waypoint(ego_vehicle_location)

    if ego_vehicle_waypoint.is_junction:
      # It is too late. Do not block the intersection! Keep going!
      return (False, None)

    if self._local_planner.target_waypoint is not None:
      if self._local_planner.target_waypoint.is_junction:
        min_angle = 180.0
        sel_magnitude = 0.0
        sel_traffic_light = None
        for traffic_light in lights_list:
          loc = traffic_light.get_location()
          magnitude, angle = compute_magnitude_angle(
              loc, ego_vehicle_location,
              self._vehicle.get_transform().rotation.yaw)
          if magnitude < 60.0 and angle < min(25.0, min_angle):
            sel_magnitude = magnitude
            sel_traffic_light = traffic_light
            min_angle = angle

        if sel_traffic_light is not None:
          if debug:
            logging.debug('=== Magnitude = {} | Angle = {} | ID = {}'.format(
                sel_magnitude, min_angle, sel_traffic_light.id))

          if self._last_traffic_light is None:
            self._last_traffic_light = sel_traffic_light

          if self._last_traffic_light.state == carla.TrafficLightState.Red:  # pylint: disable=no-member
            return (True, self._last_traffic_light)
        else:
          self._last_traffic_light = None

    return (False, None)

  def _get_trafficlight_trigger_location(
      self,
      traffic_light,
  ) -> carla.Location:  # pylint: disable=no-member
    """Calculates the yaw of the waypoint that represents the trigger volume of
    the traffic light."""

    def rotate_point(point, radians):
      """Rotates a given point by a given angle."""
      rotated_x = math.cos(radians) * point.x - math.sin(radians) * point.y
      rotated_y = math.sin(radians) * point.x - math.cos(radians) * point.y

      return carla.Vector3D(rotated_x, rotated_y, point.z)  # pylint: disable=no-member

    base_transform = traffic_light.get_transform()
    base_rot = base_transform.rotation.yaw
    area_loc = base_transform.transform(traffic_light.trigger_volume.location)
    area_ext = traffic_light.trigger_volume.extent

    point = rotate_point(
        carla.Vector3D(0, 0, area_ext.z),  # pylint: disable=no-member
        math.radians(base_rot),
    )
    point_location = area_loc + carla.Location(x=point.x, y=point.y)  # pylint: disable=no-member

    return carla.Location(point_location.x, point_location.y, point_location.z)  # pylint: disable=no-member

  def _world_to_pixel(self, location, offset=(0, 0)):
    world_offset = WORLD_OFFSETS[self._map.name]
    x = PIXELS_PER_METER * (location.x - world_offset[0])
    y = PIXELS_PER_METER * (location.y - world_offset[1])
    return [int(x - offset[0]), int(y - offset[1])]
    
  def _is_point_on_sidewalk(self, loc):
    # Convert to pixel coordinate
    pixel_x, pixel_y = self._world_to_pixel(loc)
    pixel_y = np.clip(pixel_y, 0, self._road_map.shape[0]-1)
    pixel_x = np.clip(pixel_x, 0, self._road_map.shape[1]-1)
    point = self._road_map[pixel_y, pixel_x, 0]

    return point == 0
Пример #22
0
class BasicAgent(Agent):
    """
    BasicAgent implements a basic agent that navigates scenes to reach a given
    target destination. This agent respects traffic lights and other vehicles.
    """
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(BasicAgent, self).__init__(vehicle)

        self.stopping_for_traffic_light = False
        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        args_lateral_dict = {
            'K_P': 0.75,
            'K_D': 0.001,
            'K_I': 1,
            'dt': 1.0 / 20.0
        }
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._grp = None
        self.drawn_lights = False
        self.is_affected_by_traffic_light = False

    def set_destination(self, location):
        """
        This method creates a list of waypoints from agent's position to destination location
        based on the route returned by the global router
        """

        start_waypoint = self._map.get_waypoint(self._vehicle.get_location())
        end_waypoint = self._map.get_waypoint(
            carla.Location(location[0], location[1], location[2]))

        route_trace = self._trace_route(start_waypoint, end_waypoint)
        assert route_trace

        self._local_planner.set_global_plan(route_trace)

    def _trace_route(self, start_waypoint, end_waypoint):
        """
        This method sets up a global router and returns the optimal route
        from start_waypoint to end_waypoint
        """

        # Setting up global router
        if self._grp is None:
            dao = GlobalRoutePlannerDAO(self._vehicle.get_world().get_map(),
                                        self._hop_resolution)
            grp = GlobalRoutePlanner(dao)
            grp.setup()
            self._grp = grp

        # Obtain route plan
        route = self._grp.trace_route(start_waypoint.transform.location,
                                      end_waypoint.transform.location)

        return route

    def run_step(self, debug=False):
        """
        Execute one step of navigation.
        :return: carla.VehicleControl
        """

        # is there an obstacle in front of us?
        hazard_detected = False

        # retrieve relevant elements for safe navigation, i.e.: traffic lights
        # and other vehicles
        actor_list = self._world.get_actors()  # type: ActorList
        vehicle_list = actor_list.filter("*vehicle*")  # type: List[Actor]
        pedestrians_list = actor_list.filter("*walker.pedestrian*")
        lights_list = actor_list.filter(
            "*traffic_light*")  # type: List[carla.TrafficLight]

        if not self.drawn_lights and debug:
            for light in lights_list:
                self._world.debug.draw_box(
                    carla.BoundingBox(
                        light.trigger_volume.location +
                        light.get_transform().location,
                        light.trigger_volume.extent * 2),
                    carla.Rotation(0, 0, 0), 0.05, carla.Color(255, 128, 0, 0),
                    0)
            self.drawn_lights = True

        # check possible obstacles
        vehicle_state, vehicle = self._is_vehicle_hazard(vehicle_list)
        if vehicle_state:
            if debug:
                print('!!! VEHICLE BLOCKING AHEAD [{}])'.format(vehicle.id))

            self._state = AgentState.BLOCKED_BY_VEHICLE
            hazard_detected = True

        # Check for pedestrians
        pedestrian_state, pedestrian = self._is_pedestrian_hazard(
            pedestrians_list)
        if pedestrian_state:
            if debug:
                print('!!! PEDESTRIAN BLOCKING AHEAD [{}])'.format(
                    pedestrian.id))

            self._state = AgentState.BLOCKED_BY_VEHICLE
            hazard_detected = True

        # check for the state of the traffic lights
        light_state, traffic_light = self._is_light_red(lights_list)
        if light_state:
            if debug:
                print('=== RED LIGHT AHEAD [{}])'.format(traffic_light.id))

            self._state = AgentState.BLOCKED_RED_LIGHT
            hazard_detected = True

        new_target_speed = self._update_target_speed(hazard_detected, debug)

        # if hazard_detected:
        #     control = self.emergency_stop()
        # else:
        #     self._state = AgentState.NAVIGATING
        #     self.braking_intial_speed = None
        #     # standard local planner behavior
        #     control = self._local_planner.run_step(debug=debug)
        #     if self.stopping_for_traffic_light:
        #         control.steer = 0.0

        self._state = AgentState.NAVIGATING
        self.braking_intial_speed = None
        # standard local planner behavior
        control = self._local_planner.run_step(debug=debug)
        if self.stopping_for_traffic_light:
            control.steer = 0.0
        # Prevent from steering randomly when stopped
        if math.fabs(get_speed(self._vehicle)) < 0.1:
            control.steer = 0

        return control

    def done(self):
        """
        Check whether the agent has reached its destination.
        :return bool
        """
        return self._local_planner.done()

    def _update_target_speed(self, hazard_detected, debug):
        if hazard_detected:
            self._set_target_speed(0)
            return 0

        MAX_PERCENTAGE_OF_SPEED_LIMIT = 0.75
        speed_limit = self._vehicle.get_speed_limit()  # km/h
        current_speed = get_speed(self._vehicle)
        new_target_speed = speed_limit * MAX_PERCENTAGE_OF_SPEED_LIMIT

        use_custom_traffic_light_speed = False
        if use_custom_traffic_light_speed:
            TRAFFIC_LIGHT_SECONDS_AWAY = 3
            METERS_TO_STOP_BEFORE_TRAFFIC_LIGHT = 8
            get_traffic_light = self._vehicle.get_traffic_light(
            )  # type: carla.TrafficLight
            nearest_traffic_light, distance = get_nearest_traffic_light(
                self._vehicle)  # type: carla.TrafficLight, float
            distance_to_light = distance
            distance -= METERS_TO_STOP_BEFORE_TRAFFIC_LIGHT

            if nearest_traffic_light is None:
                nearest_traffic_light = get_traffic_light

            # Draw debug info
            if debug and nearest_traffic_light is not None:
                self._world.debug.draw_point(
                    nearest_traffic_light.get_transform().location,
                    size=1,
                    life_time=0.1,
                    color=carla.Color(255, 15, 15))
            """
            if get_traffic_light is not None:
                print("get_traffic_light:     ", get_traffic_light.get_location() if get_traffic_light is not None else "None", " ", get_traffic_light.state if get_traffic_light is not None else "None")
    
            if nearest_traffic_light is not None:
                print("nearest_traffic_light: ",  nearest_traffic_light.get_location() if nearest_traffic_light is not None else "None", " ", nearest_traffic_light.state if nearest_traffic_light is not None else "None")
            """

            ego_vehicle_location = self._vehicle.get_location()
            ego_vehicle_waypoint = self._map.get_waypoint(ego_vehicle_location)

            self.is_affected_by_traffic_light = False
            self.stopping_for_traffic_light = False
            if ego_vehicle_waypoint.is_junction:
                # It is too late. Do not block the intersection! Keep going!
                pass

            # Check if we should start braking
            elif distance_to_light <= TRAFFIC_LIGHT_SECONDS_AWAY * new_target_speed / 3.6 and nearest_traffic_light is not None and nearest_traffic_light.state != carla.TrafficLightState.Green:
                self.is_affected_by_traffic_light = True
                brake_distance = current_speed / 3.6 * TRAFFIC_LIGHT_SECONDS_AWAY
                print("TL distance: ", distance_to_light,
                      ", distance (to stop): ", distance,
                      ", distance travel 4 secs: ", brake_distance)
                new_target_speed = self._target_speed
                if distance <= 0:
                    new_target_speed = 0
                    self.stopping_for_traffic_light = True
                    print("Stopping before traffic light, distance  ",
                          distance, "m")
                elif brake_distance >= distance and brake_distance != 0:
                    percent_before_light = (brake_distance -
                                            distance) / brake_distance
                    new_target_speed = speed_limit - max(
                        0, percent_before_light) * speed_limit
                    print("Slowing down before traffic light ",
                          percent_before_light * 100, "% ", new_target_speed,
                          " km/h")

        self._set_target_speed(max(0, new_target_speed))
        return new_target_speed

    def _set_target_speed(self, target_speed: int):
        """
        This function updates all the needed values required to actually set a new target speed
        """
        self._target_speed = target_speed
        self._local_planner.set_speed(target_speed)
Пример #23
0
class TryAgent(_Agent):
    """
    BasicAgent implements a basic agent that navigates scenes to reach a given
    target destination. This agent respects traffic lights and other vehicles.
    """
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(TryAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0  # meters
        self._state = _AgentState.NAVIGATING
        args_lateral_dict = {'K_P': 1, 'K_D': 0.02, 'K_I': 0, 'dt': 1.0 / 20.0}
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._grp = None
        self.speed = 60
        self.matrix_transform = None
        self.last = False
        self.walker = None

    def set_destination(self, location):
        """
        This method creates a list of waypoints from agent's position to destination location
        based on the route returned by the global router
        """

        start_waypoint = self._map.get_waypoint(self._vehicle.get_location())
        end_waypoint = self._map.get_waypoint(
            carla.Location(location[0], location[1], location[2]))

        route_trace = self._trace_route(start_waypoint, end_waypoint)
        assert route_trace

        self._local_planner.set_global_plan(route_trace)

    def _trace_route(self, start_waypoint, end_waypoint):
        """
        This method sets up a global router and returns the optimal route
        from start_waypoint to end_waypoint
        """

        # Setting up global router
        if self._grp is None:
            dao = GlobalRoutePlannerDAO(self._vehicle.get_world().get_map(),
                                        self._hop_resolution)
            grp = GlobalRoutePlanner(dao)
            grp.setup()
            self._grp = grp

        # Obtain route plan
        route = self._grp.trace_route(start_waypoint.transform.location,
                                      end_waypoint.transform.location)

        return route

    def run_step(self, debug=False):
        """
        Execute one step of navigation.
        :return: carla.VehicleControl
        """
        self.matrix_transform = self.get_matrix(self._vehicle.get_transform())
        # matrix = get_matrix(self._vehicle.get_transform())
        velocity = np.dot(np.array([1, 0, 0, 0]),
                          np.linalg.inv(self.matrix_transform))
        # is there an obstacle in front of us?
        hazard_detected = False

        # retrieve relevant elements for safe navigation, i.e.: traffic lights
        # and other vehicles
        actor_list = self._world.get_actors()
        vehicle_list = actor_list.filter("*vehicle*")
        lights_list = actor_list.filter("*traffic_light*")
        # pedestrian_list = actor_list.filter("*pedestrian*")
        walker_list = actor_list.filter("*walker*")
        angle = float(10 / 17)
        angles = np.array([0, 0, 0])
        for walker in walker_list:
            _distance = math.sqrt(
                (self._vehicle.get_location().x - walker.get_location().x)**2 +
                (self._vehicle.get_location().y - walker.get_location().y)**2)
            x = -(self._vehicle.get_location().x - walker.get_location().x)
            y = -(self._vehicle.get_location().y - walker.get_location().y)
            z = -(self._vehicle.get_location().z - walker.get_location().z)
            _angles = np.dot(np.array([x, y, z, 0]), self.matrix_transform)
            _angle = _angles[1] / _angles[0]
            if _distance < self.speed or _distance < 10:
                hazard_detected = True
                distance = _distance
                if abs(_angle) < abs(angle):
                    angle = _angle
                    angles = _angles
                    ped = np.dot(
                        np.linalg.inv(self.matrix_transform),
                        np.array([
                            walker.get_location().x,
                            walker.get_location().y,
                            walker.get_location().z, 1
                        ]))
                    self.walker = np.array([
                        walker.get_location().x,
                        walker.get_location().y,
                        walker.get_location().z, 1
                    ])
        """
        x = self.GlobaltoLocalVehicle(self._vehicle)[0]
        end1 = self.LocaltoGlobal(np.array([x[0] + 10 + self.speed, x[1] + (10+self.speed)*float(10/17), x[2]+2, 1]))
        end2 = self.LocaltoGlobal(np.array([x[0] + 10 + self.speed, x[1] - (10+self.speed)*float(10/17), x[2]+2, 1]))
        self._world.debug.draw_line(self._vehicle.get_location(), carla.Location(end1), life_time = 0.0001)
        self._world.debug.draw_line(self._vehicle.get_location(), carla.Location(end2), life_time = 0.0001)
        """
        # check possible obstacles
        vehicle_state, vehicle = self._is_vehicle_hazard(vehicle_list)
        if vehicle_state:
            if debug:
                print('!!! VEHICLE BLOCKING AHEAD [{}])'.format(vehicle.id))

            self._state = _AgentState.BLOCKED_BY_VEHICLE
            hazard_detected = True

        # check for the state of the traffic lights
        """
        light_state, traffic_light = self._is_light_red(lights_list)
        if light_state:
            if debug:
                print('=== RED LIGHT AHEAD [{}])'.format(traffic_light.id))

            self._state = _AgentState.BLOCKED_RED_LIGHT
            hazard_detected = True
        """
        if hazard_detected and abs(angle) < 0.5 and angles[0] > 0:
            if self.speed < 15 and ped[1] != 0:
                self.speed = self.speed
            else:
                self.speed = self.speed - self.get_break(self.speed, distance)
                if self.speed < 0:
                    self.speed = 0
            velocity = (velocity / norm(velocity)) * self.speed
            control = carla.Vector3D(velocity[0], velocity[1], velocity[2])
            self.last = hazard_detected
        else:
            if self.speed < 60:
                self.increase_speed()
            velocity = (velocity / norm(velocity)) * self.speed
            control = carla.Vector3D(velocity[0], velocity[1], velocity[2])
            self.last = hazard_detected
            self.walker = None
        """
        if hazard_detected and self.speed >= 10 and abs(angle) < 0.3 and angles[0]>0:
            # control = self.emergency_stop()
            # if self.speed > 10:
            self.speed = self.speed-self.get_break(self.speed,distance)
            if self.speed < 0:
                self.speed = 0
            velocity = (velocity/norm(velocity))*self.speed
            control = carla.Vector3D(velocity[0],velocity[1],velocity[2])

        elif hazard_detected and distance<30 and distance>10 and self.speed >= 5 and abs(angle) < 0.3 and angles[0]>0:
            # if self.speed > 5:
            control = self.emergency_stop()
            self.speed = self.speed-self.get_break(self.speed,distance)*0.1
            if self.speed < 0:
                self.speed = 0
            velocity = (velocity/norm(velocity))*self.speed
            control = carla.Vector3D(velocity[0],velocity[1],velocity[2])

        elif hazard_detected and distance<10 and self.speed > 0 and abs(angle) < 0.3 and angles[0]>0:
            return carla.Vector3D(0,0,0)

        elif hazard_detected:
            velocity = (velocity/norm(velocity))*self.speed
            control = carla.Vector3D(velocity[0],velocity[1],velocity[2])
            return control

        else:
            if self.speed<60:
                self.increase_speed()
            # self._state = _AgentState.NAVIGATING
            # standard local planner behavior
            # control = self._local_planner.run_step(debug=debug)
            velocity = (velocity/norm(velocity))*self.speed
            control = carla.Vector3D(velocity[0],velocity[1],velocity[2])
            # control = carla.Vector3D(0,0,0)
        # print(self.speed)"""
        return control

    def done(self):
        """
        Check whether the agent has reached its destination.
        :return bool
        """
        return self._local_planner.done()

    def get_location(self):
        return self._vehicle.get_location()

    def check_end(self, location):
        # matrix = self.get_matrix(self._vehicle.get_transform())
        x = np.dot(np.linalg.inv(self.matrix_transform),
                   np.array([location.x, location.y, location.z, 1]))
        if x[0] < 0:
            return True
        else:
            return False

    def get_break(self, c, distance):
        f = 2 * ((20 + c * 100 * 0.2) / distance)**2
        if c > 1:
            return f / 200
        else:
            return 0

    def increase_speed(self):
        self.speed += 1

    def check_infront():
        pass

    def get_matrix(self, transform):  #local transfer to global
        rotation = transform.rotation
        location = transform.location
        c_y = np.cos(np.radians(rotation.yaw))
        s_y = np.sin(np.radians(rotation.yaw))
        c_r = np.cos(np.radians(rotation.roll))
        s_r = np.sin(np.radians(rotation.roll))
        c_p = np.cos(np.radians(rotation.pitch))
        s_p = np.sin(np.radians(rotation.pitch))

        matrix = np.array(np.identity(4))

        matrix[0, 3] = location.x
        matrix[1, 3] = location.y
        matrix[2, 3] = location.z
        matrix[0, 0] = c_p * c_y
        matrix[0, 1] = c_y * s_p * s_r - s_y * c_r
        matrix[0, 2] = -c_y * s_p * c_r - s_y * s_r
        matrix[1, 0] = s_y * c_p
        matrix[1, 1] = s_y * s_p * s_r + c_y * c_r
        matrix[1, 2] = -s_y * s_p * c_r + c_y * s_r
        matrix[2, 0] = s_p
        matrix[2, 1] = -c_p * s_r
        matrix[2, 2] = c_p * c_r
        return matrix

    def GlobaltoLocalVehicle(self, target):
        location = np.dot(
            np.linalg.inv(self.matrix_transform),
            np.array([
                target.get_location().x,
                target.get_location().y,
                target.get_location().z, 1
            ]))
        velocity = np.dot(
            np.linalg.inv(self.matrix_transform),
            np.array([
                target.get_velocity().x,
                target.get_velocity().y,
                target.get_velocity().z, 0
            ]))
        return (location, velocity)

    def LocaltoGlobal(self, velocity):
        trans = np.dot(self.matrix_transform, velocity)
        return carla.Vector3D(trans[0], trans[1], trans[2])
class LearningAgent(Agent):
    """
    BasicAgent implements a basic agent that navigates scenes to reach a given
    target destination. This agent respects traffic lights and other vehicles.
    """

    def __init__(self, world):
        """
        :param vehicle: actor to apply to local planner logic onto
        """
        super(LearningAgent, self).__init__(world.player)
        self._world_obj = world
        # Learning Model
        self._model = Model()
        self._THW = None
        self._target_speed = None
        self._sin_param = None
        self._poly_param = None
        # Local plannar
        self._local_planner = LocalPlanner(world.player)
        self.update_parameters()
        # Global plannar
        self._proximity_threshold = 10.0  # meter
        self._state = AgentState.NAVIGATING
        self._hop_resolution = 0.2
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._grp = None  # global route planar
        # Behavior planning
        self._hazard_detected = False
        self._blocked_time = None
        self._perform_lane_change = False
        self._front_r = []
        self._left_front_r = []
        self._left_back_r = []

    # Update personalized parameters from model
    def update_parameters(self):
        self._THW = self._model.get_parameter("safe_distance")["THW"]
        self._target_speed = self._model.get_parameter("target_speed") * 3.6
        self._sin_param = self._model.get_parameter("sin_param")
        self._poly_param = self._model.get_parameter("poly_param")

        CONTROLLER_TYPE = 'PID' # options:MPC, PID, STANLEY
        args_lateral_dict = {'K_P': 1.0, 'K_I': 0.4, 'K_D': 0.01, 'control_type': CONTROLLER_TYPE}
        args_longitudinal_dict = {'K_P': 0.3, 'K_I': 0.2, 'K_D': 0.002}
        self._local_planner.init_controller(opt_dict={'target_speed': self._target_speed,
                                                      'lateral_control_dict': args_lateral_dict,
                                                      'longitudinal_control_dict': args_longitudinal_dict})

    # Start learning by collecting data
    def collect(self):
        # State for each step
        personalization_param = []

        # Time stamp
        personalization_param.extend([pygame.time.get_ticks()])

        # Collect vehicle position
        t = self._vehicle.get_transform()
        personalization_param.extend([t.location.x,
                                      t.location.y,
                                      t.location.z,
                                      t.rotation.yaw])

        # Collect vehicle velocity and speed
        v = self._vehicle.get_velocity()
        personalization_param.extend([v.x, v.y, v.z, self._get_speed()])                    

        # Collect radar information
        front_dis = 100
        front_vel = 50
        left_front_dis = 100
        left_front_vel = 50
        left_back_dis = -100
        left_back_vel = 0
        if self._front_r:
            front_dis = self._front_r[1][0]
            front_vel = self._front_r[2][0]
        if self._left_front_r:
            left_front_dis = self._left_front_r[1][0]
            left_front_vel = self._left_front_r[2][0]
        if self._left_back_r:
            left_back_dis = self._left_back_r[1][0]
            left_back_vel = self._left_back_r[2][0]
        personalization_param.extend([front_dis, left_front_dis, left_back_dis, 
                                      front_vel, left_front_vel, left_back_vel])

        self._model.collect(personalization_param)

    # End collection
    def end_collect(self):
        self._model.end_collect()

    # Train model
    def train_model(self):
        self._model.train_new_model()

    # Set global destination and get global waypoints
    def set_destination(self, location):
        """
        This method creates a list of waypoints from agent's position to destination location
        based on the route returned by the global router
        """
        start_waypoint = self._map.get_waypoint(self._vehicle.get_location())
        end_waypoint = self._map.get_waypoint(carla.Location(location[0], location[1], location[2]))

        route_trace = self._trace_route(start_waypoint, end_waypoint)
        assert route_trace

        self._local_planner.set_global_plan(route_trace)

    # Get global waypoints
    def _trace_route(self, start_waypoint, end_waypoint):
        """
        This method sets up a global router and returns the optimal route
        from start_waypoint to end_waypoint
        """
        # Setting up global router
        if self._grp is None:
            dao = GlobalRoutePlannerDAO(self._vehicle.get_world().get_map(), self._hop_resolution)
            grp = GlobalRoutePlanner(dao)
            grp.setup()
            self._grp = grp

        # Obtain route plan
        route = self._grp.trace_route(start_waypoint.transform.location, end_waypoint.transform.location)

        return route

    # Get vehicle speed
    def _get_speed(self):
        v = self._vehicle.get_velocity()
        ego_speed = math.sqrt(v.x**2 + v.y**2 + v.z**2)
        return ego_speed

    # Run step
    def run_step(self, debug=False):
        """
        Execute one step of navigation.
        :return: carla.VehicleControl
        """
        ## Update Environment ##
        # Check all the radars
        if self._world_obj.front_radar.detected:
            if abs(self._world_obj.front_radar.rel_pos[1]) < 1:
                self._front_r = [pygame.time.get_ticks(), self._world_obj.front_radar.rel_pos, 
                                                        self._world_obj.front_radar.rel_vel]
            self._world_obj.front_radar.detected = False                                        
        if self._world_obj.left_front_radar.detected:
            if self._world_obj.left_front_radar.rel_pos[1] < -1:
                self._left_front_r =[pygame.time.get_ticks(), self._world_obj.left_front_radar.rel_pos, 
                                                            self._world_obj.left_front_radar.rel_vel]
            self._world_obj.left_front_radar.detected = False
        if self._world_obj.left_back_radar.detected:
            if self._world_obj.left_back_radar.rel_pos[1] < -1:
                self._left_back_r = [pygame.time.get_ticks(), self._world_obj.left_back_radar.rel_pos, 
                                                            self._world_obj.left_back_radar.rel_vel]
            self._world_obj.left_back_radar.detected = False
        # Remove radar data if not detected again in 0.5 second
        if self._front_r and (pygame.time.get_ticks() - self._front_r[0] > 5000):
            self._front_r = []
        if self._left_front_r and (pygame.time.get_ticks() - self._left_front_r[0] > 5000):
            self._left_front_r = []
        if self._left_back_r and (pygame.time.get_ticks() - self._left_back_r[0] > 5000):
            self._left_back_r = []
        
        # Detect vehicles in front
        self._hazard_detected = False
        if self._front_r and (self._front_r[1][0] < 20.0):
            self._hazard_detected = True
        # update hazard existing time
        if self._hazard_detected:
            if self._blocked_time is None:
                self._blocked_time = pygame.time.get_ticks()
                hazard_time = 0
            else:
                hazard_time = pygame.time.get_ticks() - self._blocked_time
        else:
            self._blocked_time = None

        # Get a safe_distance
        safe_distance = self._THW * self._get_speed()

        '''                          
        # retrieve relevant elements for safe navigation, i.e.: traffic lights
        actor_list = self._world.get_actors()
        lights_list = actor_list.filter("*traffic_light*")
        # check for the state of the traffic lights
        light_state, traffic_light = self._is_light_red(lights_list)
        if light_state:
            if debug:
                print('=== RED LIGHT AHEAD [{}])'.format(traffic_light.id))
            self._state = AgentState.BLOCKED_RED_LIGHT
            self._hazard_detected = True
        '''
        #print(self._state)

        # Finite State Machine
        # 1, Navigating
        if self._state == AgentState.NAVIGATING:
            if self._hazard_detected:
                self._state = AgentState.BLOCKED_BY_VEHICLE

        # 2, Blocked by Vehicle
        elif self._state == AgentState.BLOCKED_BY_VEHICLE:
            if not self._hazard_detected:
                self._state = AgentState.NAVIGATING
            # The vehicle is driving at a certain speed
            # There is enough space
            else:
                if hazard_time > 5000 and \
                    190 > self._vehicle.get_location().x > 10 and \
                    10 > self._vehicle.get_location().y > 7:
                    self._state = AgentState.PREPARE_LANE_CHANGING

        # 4, Prepare Lane Change
        elif self._state == AgentState.PREPARE_LANE_CHANGING:
            if  not (self._front_r and self._front_r[1][0] < safe_distance) and \
                not (self._left_front_r and self._left_front_r[1][0] < safe_distance) and \
                not (self._left_back_r and self._left_back_r[1][0] > -10):
                    print(self._front_r)
                    print(self._left_front_r)
                    print(self._left_back_r)
                    self._state = AgentState.LANE_CHANGING
                    self._perform_lane_change = True

        # 5, Lane Change
        elif self._state == AgentState.LANE_CHANGING:
            if abs(self._vehicle.get_velocity().y) < 0.5 and \
               self._vehicle.get_location().y < 7.0:
                self._state = AgentState.NAVIGATING

        # 6, Emergency Brake
        emergency_distance = safe_distance *3/5
        emergency_front_speed = 1.0
        if self._front_r and (self._front_r[1][0] < emergency_distance or 
                                self._front_r[2][0] < emergency_front_speed):
            self._state = AgentState.EMERGENCY_BRAKE


        # Local Planner Behavior according to states
        if self._state == AgentState.NAVIGATING or self._state == AgentState.LANE_CHANGING:
            control = self._local_planner.run_step(debug=debug)

        elif self._state == AgentState.PREPARE_LANE_CHANGING:
            if self._left_front_r and self._left_front_r[1][0] < safe_distance or \
               self._front_r and self._front_r[1][0] < safe_distance:
                control = self._local_planner.empty_control(debug=debug)
            else:
                control = self._local_planner.run_step(debug=debug)

        elif self._state == AgentState.BLOCKED_BY_VEHICLE:
            # ACC
            front_dis = self._front_r[1][0]
            front_vel = self._front_r[2][0]
            ego_speed = self._get_speed()
            desired_speed = front_vel - (ego_speed-front_vel)/front_dis
            if ego_speed > 1:
                desired_speed += 2*(front_dis/ego_speed - self._THW)
            control = self._local_planner.run_step(debug=debug, target_speed=desired_speed*3.6)

        elif self._state == AgentState.EMERGENCY_BRAKE:
            control = self._local_planner.brake()
            if self._front_r:
                if self._front_r[1][0] >= emergency_distance and \
                    self._front_r[2][0] > emergency_front_speed:
                    self._state = AgentState.NAVIGATING

        elif self._state == AgentState.BLOCKED_RED_LIGHT:
            control = self._local_planner.empty_control(debug=debug)

        # When performing a lane change
        if self._perform_lane_change:
            # Record original destination
            destination = self._local_planner.get_global_destination()
            # Get lane change start location
            ref_location = self._world_obj.player.get_location()
            ref_yaw = self._world_obj.player.get_transform().rotation.yaw

            if self._local_planner.waypoint_buffer:
                waypoint = self._local_planner.waypoint_buffer[-1][0]
                ref_location = waypoint.transform.location
            
            wait_dist = 0.0  # need some time to plan
            ref = [ref_location.x + wait_dist, ref_location.y, ref_yaw]

            # Replace current plan with a lane change plan
            DL = self._left_front_r[1][0] if self._left_front_r else 100
            DH = self._left_back_r[1][0] if self._left_back_r else 100
            GMM_v = [[self._vehicle.get_velocity().x, self._sin_param["lat_dis"], DL, DH]]
            
            lane_changer = SinLaneChange(self._world_obj, self._sin_param, np.array(GMM_v))
            lane_change_plan = lane_changer.get_waypoints(ref)
            self._local_planner.set_local_plan(lane_change_plan)
            '''
            lane_changer = PolyLaneChange(self._world_obj, self._poly_param)
            lane_change_plan = lane_changer.get_waypoints(ref)
            self._local_planner.set_local_plan(lane_change_plan)
            '''
            # replan globally with new vehicle position after lane changing
            new_start = self._map.get_waypoint(lane_change_plan[-1][0].transform.location)
            route_trace = self._trace_route(new_start, destination)
            assert route_trace
            self._local_planner.add_global_plan(route_trace)

            self._perform_lane_change = False
            print("perform lane change")

        return control

    def done(self):
        """
        Check whether the agent has reached its destination.
        :return bool
        """
        return self._local_planner.done()
Пример #25
0
class TestAgent(Agent):
    """
    BasicAgent implements a basic agent that navigates scenes to reach a given
    target destination. This agent respects traffic lights and other vehicles.
    """
    def __init__(self, vehicle, target_speed=50):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(TestAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        args_lateral_dict = {'K_P': 1, 'K_D': 0.02, 'K_I': 0, 'dt': 1.0 / 20.0}
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._world = self._vehicle.get_world()
        self._map = self._vehicle.get_world().get_map()

    def set_destination(self, start_waypoint, end_waypoint, time=False):
        """
        This method creates a list of waypoints from agent's position to destination location
        based on the route returned by the global router
        """

        self.create_samples(start_waypoint, end_waypoint)

        route_trace = self._trace_route(time=time)
        assert route_trace

        self._local_planner.set_global_plan(route_trace)

    def create_samples(self,
                       start,
                       goal,
                       waypoint_dist=4,
                       disk_radius=4 * math.sqrt(2),
                       num_yaw=8):
        print(
            f'Creating samples {waypoint_dist}m apart with {num_yaw} yaw vaules and neighbors within {disk_radius}m.'
        )

        wp = []
        for mp in self._map.generate_waypoints(waypoint_dist):
            wp.append(mp.transform)

        wp.append(goal)
        wp.append(start)

        states = []
        neighbors = []
        num_neighbors = []

        # for each waypoint wp
        for i, wi in enumerate(wp):
            li = wi.location
            ni = []
            num = 0
            # find other waypoints within disk radius
            for j, wj in enumerate(wp):
                lj = wj.location
                if li == lj:
                    continue
                elif li.distance(lj) <= disk_radius:
                    # account for index shifts with adding in orientation
                    for k in range(num_yaw):
                        if k == (num_yaw) / 2:
                            continue
                        elif k > (num_yaw) / 2:
                            ni.append(j * (num_yaw - 1) + k - 1)
                        else:
                            ni.append(j * (num_yaw - 1) + k)
                        num += 1
                        if wj == start or wj == goal:
                            break

            # add in number of yaw orientations to waypoint list
            ri = wi.rotation
            for k in range(num_yaw):
                if k == (num_yaw) / 2:
                    continue

                num_neighbors.append(num)
                neighbors += ni

                theta = ri.yaw + k * 360 / (num_yaw)
                if theta >= 180:
                    theta = theta - 360
                elif theta <= -180:
                    theta = 360 - theta
                states.append([li.x, li.y, theta * np.pi / 180])
                if wi == start or wi == goal:
                    break

        self.states = np.array(states).astype(np.float32)
        self.neighbors = np.array(neighbors).astype(np.int32)
        self.num_neighbors = np.array(num_neighbors).astype(np.int32)

        init_parameters = {
            'states': self.states,
            'neighbors': self.neighbors,
            'num_neighbors': self.num_neighbors,
            'threadsPerBlock': 128
        }
        self.start = self.states.shape[0] - 1
        self.goal = self.states.shape[0] - 2

        print(
            f'start: {self.start} goal: {self.goal} total states: {self.states.shape[0]}'
        )
        print(
            f'start location: {self.states[self.start]}, goal location: {self.states[self.goal]}'
        )

        self.gmt_planner = GMT(init_parameters, debug=False)
        # self.gmt_planner = GMTmem(init_parameters, debug=False)
        # self.gmt_planner = GMTstream(init_parameters, debug=False)
        # self.gmt_planner = GMTmemStream(init_parameters, debug=False)

    @staticmethod
    def _create_bb_points(vehicle):

        cords = np.zeros((3, 4))
        extent = vehicle.bounding_box.extent

        cords[0, :] = np.array([extent.x + 2.2, extent.y + 2.2, extent.z, 1])
        cords[1, :] = np.array([-extent.x - 2.2, -extent.y - 2.2, extent.z, 1])
        cords[2, :] = np.array([0, 0, 0, 1])  # center

        return cords

    @staticmethod
    def _vehicle_to_world(cords, vehicle):

        bb_transform = carla.Transform(vehicle.bounding_box.location)
        bb_vehicle_matrix = TestAgent.get_matrix(bb_transform)
        vehicle_world_matrix = TestAgent.get_matrix(vehicle.get_transform())
        bb_world_matrix = np.dot(vehicle_world_matrix, bb_vehicle_matrix)
        world_cords = np.dot(bb_world_matrix, np.transpose(cords))
        return world_cords

    @staticmethod
    def get_matrix(transform):

        rotation = transform.rotation
        location = transform.location
        c_y = np.cos(np.radians(rotation.yaw))
        s_y = np.sin(np.radians(rotation.yaw))
        c_r = np.cos(np.radians(rotation.roll))
        s_r = np.sin(np.radians(rotation.roll))
        c_p = np.cos(np.radians(rotation.pitch))
        s_p = np.sin(np.radians(rotation.pitch))
        matrix = np.matrix(np.identity(4))
        matrix[0, 3] = location.x
        matrix[1, 3] = location.y
        matrix[2, 3] = location.z
        matrix[0, 0] = c_p * c_y
        matrix[0, 1] = c_y * s_p * s_r - s_y * c_r
        matrix[0, 2] = -c_y * s_p * c_r - s_y * s_r
        matrix[1, 0] = s_y * c_p
        matrix[1, 1] = s_y * s_p * s_r + c_y * c_r
        matrix[1, 2] = -s_y * s_p * c_r + c_y * s_r
        matrix[2, 0] = s_p
        matrix[2, 1] = -c_p * s_r
        matrix[2, 2] = c_p * c_r
        return matrix

    def _trace_route(self, debug=False, time=False):
        """
        This method sets up a global router and returns the optimal route
        from start_waypoint to end_waypoint
        """
        self.radius = 2
        self.threshold = 1

        obstacles = []
        for vehicle in self._world.get_actors().filter('vehicle.*'):
            #print(vehicle.bounding_box)
            # draw Box
            bb_points = TestAgent._create_bb_points(vehicle)
            global_points = TestAgent._vehicle_to_world(bb_points, vehicle)
            global_points /= global_points[3, :]

            my_bb_points = TestAgent._create_bb_points(self._vehicle)
            my_global_points = TestAgent._vehicle_to_world(
                my_bb_points, self._vehicle)

            my_global_points /= my_global_points[3, :]
            dist = np.sqrt((my_global_points[0, 2] - global_points[0, 2])**2 +
                           (my_global_points[1, 2] - global_points[1, 2])**2 +
                           (my_global_points[2, 2] - global_points[2, 2])**2)

            if 0 < dist:
                vehicle_box = [
                    global_points[0, 0], global_points[1, 0],
                    global_points[0, 1], global_points[1, 1]
                ]
                obstacles.append(vehicle_box)
                print(f'vehicle box: {vehicle_box}')

        print('number of near obstacles: ', len(obstacles))
        if len(obstacles) == 0:
            self.obstacles = np.array([[-1, -1, -1, -1]]).astype(np.float32)
            self.num_obs = self.num_obs = np.array([0]).astype(np.int32)
        else:
            self.obstacles = np.array(obstacles).astype(np.float32)
            self.num_obs = self.num_obs = np.array([self.obstacles.shape[0]
                                                    ]).astype(np.int32)

        iter_parameters = {
            'start': self.start,
            'goal': self.goal,
            'radius': self.radius,
            'threshold': self.threshold,
            'obstacles': self.obstacles,
            'num_obs': self.num_obs
        }

        start_timer = timer()
        route = self.gmt_planner.run_step(iter_parameters,
                                          iter_limit=1000,
                                          debug=debug,
                                          time=time)
        end_timer = timer()
        print("elapsed time: ", end_timer - start_timer)

        if time:
            self.time_df = pd.DataFrame(self.gmt_planner.time_data)

        # trace_route = []
        # for r in route:
        #     wp = carla.Transform(carla.Location(self.states[r][0].item(), self.states[r][1].item(), 1.2), carla.Rotation(roll=0,pitch=0, yaw=(self.states[r][2]*180/np.pi).item()))
        #     trace_route.append(wp)
        # draw_route(self._vehicle.get_world(), trace_route)

        index = len(route) - 1
        trace_route = []
        for i in range(len(route) - 1):
            wp = self._map.get_waypoint(
                carla.Location(self.states[route[index]][0].item(),
                               self.states[route[index]][1].item(), 1.2)
            )  # , carla.Rotation(roll=0,pitch=0, yaw=(self.states[r][2]*180/np.pi).item()
            trace_route.append((wp, -1))
            index -= 1

        return trace_route

    def run_step(self, debug=True):
        """
        Execute one step of navigation.
        :return: carla.VehicleControl
        """

        # is there an obstacle in front of us?
        hazard_detected = False

        # retrieve relevant elements for safe navigation, i.e.: traffic lights
        # and other vehicles

        actor_list = self._world.get_actors()
        vehicle_list = actor_list.filter("*vehicle*")
        lights_list = actor_list.filter("*traffic_light*")

        # check possible obstacles
        vehicle_state, vehicle = self._is_vehicle_hazard(vehicle_list)
        if vehicle_state:
            if debug:
                print('!!! VEHICLE BLOCKING AHEAD [{}])'.format(vehicle.id))

            self._state = AgentState.BLOCKED_BY_VEHICLE
            hazard_detected = True

        # check for the state of the traffic lights
        # light_state, traffic_light = False, None #
        light_state, traffic_light = self._is_light_red(lights_list)
        if light_state:
            if debug:
                print('=== RED LIGHT AHEAD [{}])'.format(traffic_light.id))

            self._state = AgentState.BLOCKED_RED_LIGHT
            hazard_detected = True

        if hazard_detected:
            control = self.emergency_stop()
        else:
            self._state = AgentState.NAVIGATING
            # standard local planner behavior
            control = self._local_planner.run_step(debug)

        return control
class BasicAgent(Agent):
    """
    BasicAgent implements a basic agent that navigates scenes to reach a given
    target destination. This agent respects traffic lights and other vehicles.
    """
    def __init__(self, vehicle, target_speed=50):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(BasicAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        args_lateral_dict = {'K_P': 1, 'K_D': 0.02, 'K_I': 0, 'dt': 1.0 / 20.0}
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._grp = None

    def set_destination(self, location):
        """
        This method creates a list of waypoints from agent's position to destination location
        based on the route returned by the global router
        """

        start_waypoint = self._map.get_waypoint(self._vehicle.get_location())
        end_waypoint = self._map.get_waypoint(
            carla.Location(location[0], location[1], location[2]))

        route_trace = self._trace_route(start_waypoint, end_waypoint)
        assert route_trace

        self._local_planner.set_global_plan(route_trace)

    def _trace_route(self, start_waypoint, end_waypoint):
        """
        This method sets up a global router and returns the optimal route
        from start_waypoint to end_waypoint
        """

        # Setting up global router
        if self._grp is None:
            dao = GlobalRoutePlannerDAO(self._vehicle.get_world().get_map(),
                                        self._hop_resolution)
            grp = GlobalRoutePlanner(dao)
            grp.setup()
            self._grp = grp

        # Obtain route plan
        route = self._grp.trace_route(start_waypoint.transform.location,
                                      end_waypoint.transform.location)

        return route

    def run_step(self, debug=False):
        """
        Execute one step of navigation.
        :return: carla.VehicleControl
        """

        # is there an obstacle in front of us?
        hazard_detected = False

        # retrieve relevant elements for safe navigation, i.e.: traffic lights
        # and other vehicles

        actor_list = self._world.get_actors()
        vehicle_list = actor_list.filter("*vehicle*")
        lights_list = actor_list.filter("*traffic_light*")

        # check possible obstacles
        vehicle_state, vehicle = self._is_vehicle_hazard(vehicle_list)
        if vehicle_state:
            if debug:
                print('!!! VEHICLE BLOCKING AHEAD [{}])'.format(vehicle.id))

            self._state = AgentState.BLOCKED_BY_VEHICLE
            hazard_detected = True

        # check for the state of the traffic lights
        light_state, traffic_light = False, None  #self._is_light_red(lights_list)
        if light_state:
            if debug:
                print('=== RED LIGHT AHEAD [{}])'.format(traffic_light.id))

            self._state = AgentState.BLOCKED_RED_LIGHT
            hazard_detected = True

        if hazard_detected:
            control = self.emergency_stop()
        else:
            self._state = AgentState.NAVIGATING
            # standard local planner behavior
            control = self._local_planner.run_step(debug)

        return control
class RainDrivingAgent(Agent):
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(RainDrivingAgent, self).__init__(vehicle)

        self._proximity_tlight_threshold = 5.0  # meters
        self._proximity_vehicle_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        args_lateral_dict = {'K_P': 1, 'K_D': 0.4, 'K_I': 0, 'dt': 1.0 / 20.0}
        self._local_planner = LocalPlanner(self._vehicle,
                                           opt_dict={
                                               'target_speed':
                                               target_speed,
                                               'lateral_control_dict':
                                               args_lateral_dict
                                           })
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._target_speed = target_speed
        self._grp = None

        # create the camera
        camera_bp = self._world.get_blueprint_library().find(
            'sensor.camera.rgb')
        camera_bp.set_attribute('image_size_x', str(1920 // 2))
        camera_bp.set_attribute('image_size_y', str(1080 // 2))
        camera_bp.set_attribute('fov', str(90))
        camera_transform = carla.Transform(carla.Location(x=-5.5, z=2.8),
                                           carla.Rotation(pitch=-15))
        self._camera = self._world.spawn_actor(camera_bp,
                                               camera_transform,
                                               attach_to=self._vehicle)
        self._camera.listen(lambda image: self._process_image(image))
        self._curr_image = None
        self._save_count = 0

    def _process_image(self, image):
        self._curr_image = image
        """
        image_array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
        image_array = np.reshape(image_array, (image.height, image.width, 4))
        image_array = image_array[:, :, :3]
        image_array = image_array[:, :, ::-1]
        """
        file_name = 'curr.jpg'
        image.save_to_disk(file_name)

        def parse_file(filename):
            image_string = tf.io.read_file(filename)
            image_decoded = tf.image.decode_jpeg(image_string, channels=3)
            return tf.cast(image_decoded, tf.float32) / 255.0

        whole_path = [file_name]
        filename_tensor = tf.convert_to_tensor(value=whole_path,
                                               dtype=tf.string)
        dataset = tf.data.Dataset.from_tensor_slices((filename_tensor))
        dataset = dataset.map(parse_file)
        dataset = dataset.prefetch(buffer_size=1)
        dataset = dataset.batch(batch_size=1).repeat()
        iterator = tf.compat.v1.data.make_one_shot_iterator(dataset)
        image_array = iterator.get_next()
        output = Network.inference(image_array,
                                   is_training=False,
                                   middle_layers=12)
        output = tf.clip_by_value(output, 0., 1.)
        output = output[0, :, :, :]
        config = tf.compat.v1.ConfigProto()
        config.gpu_options.allow_growth = True
        saver = tf.compat.v1.train.Saver()
        with tf.compat.v1.Session(config=config) as sess:
            with tf.device('/gpu:0'):
                saver.restore(sess, pre_trained_model_path)
                derained, ori = sess.run([output, image_array])
                derained = np.uint8(derained * 255.)
                skimage.io.imsave('curr_derained.png', derained)
                if self._save_count % 6 == 0:
                    image.save_to_disk('_out/%08d_orig' % image.frame)
                    skimage.io.imsave('_out/%08d_derained.png' % image.frame,
                                      derained)
        self._save_count += 1

    def set_destination(self, location):
        """
        This method creates a list of waypoints from agent's position to destination location
        based on the route returned by the global router
        """

        start_waypoint = self._map.get_waypoint(self._vehicle.get_location())
        end_waypoint = self._map.get_waypoint(
            carla.Location(location[0], location[1], location[2]))

        route_trace = self._trace_route(start_waypoint, end_waypoint)

        self._local_planner.set_global_plan(route_trace)

    def _trace_route(self, start_waypoint, end_waypoint):
        """
        This method sets up a global router and returns the optimal route
        from start_waypoint to end_waypoint
        """

        # Setting up global router
        if self._grp is None:
            dao = GlobalRoutePlannerDAO(self._vehicle.get_world().get_map(),
                                        self._hop_resolution)
            grp = GlobalRoutePlanner(dao)
            grp.setup()
            self._grp = grp

        # Obtain route plan
        route = self._grp.trace_route(start_waypoint.transform.location,
                                      end_waypoint.transform.location)

        return route

    def run_step(self, debug=False):
        """
        Execute one step of navigation.
        :return: carla.VehicleControl
        """

        # is there an obstacle in front of us?
        hazard_detected = False

        # retrieve relevant elements for safe navigation, i.e.: traffic lights
        # and other vehicles
        actor_list = self._world.get_actors()
        vehicle_list = actor_list.filter("*vehicle*")
        lights_list = actor_list.filter("*traffic_light*")

        # check possible obstacles
        vehicle_state, vehicle = self._is_vehicle_hazard(vehicle_list)
        if vehicle_state:
            if debug:
                print('!!! VEHICLE BLOCKING AHEAD [{}])'.format(vehicle.id))

            self._state = AgentState.BLOCKED_BY_VEHICLE
            hazard_detected = True

        # check for the state of the traffic lights
        light_state, traffic_light = self._is_light_red(lights_list)
        if light_state:
            if debug:
                print('=== RED LIGHT AHEAD [{}])'.format(traffic_light.id))

            self._state = AgentState.BLOCKED_RED_LIGHT
            hazard_detected = True

        if hazard_detected:
            control = self.emergency_stop()
        else:
            self._state = AgentState.NAVIGATING
            # standard local planner behavior
            control = self._local_planner.run_step(debug=debug)

        return control

    def done(self):
        """
        Check whether the agent has reached its destination.
        :return bool
        """
        return self._local_planner.done()
Пример #28
0
class BasicAgent(object):
    """
    BasicAgent implements an agent that navigates the scene.
    This agent respects traffic lights and other vehicles, but ignores stop signs.
    It has several functions available to specify the route that the agent must follow,
    as well as to change its parameters in case a different driving mode is desired.
    """
    def __init__(self, vehicle, target_speed=20, opt_dict={}):
        """
        Initialization the agent paramters, the local and the global planner.

            :param vehicle: actor to apply to agent logic onto
            :param target_speed: speed (in Km/h) at which the vehicle will move
            :param opt_dict: dictionary in case some of its parameters want to be changed.
                This also applies to parameters related to the LocalPlanner.
        """
        self._vehicle = vehicle
        self._world = self._vehicle.get_world()
        self._map = self._world.get_map()
        self._last_traffic_light = None

        # Base parameters
        self._ignore_traffic_lights = False
        self._ignore_stop_signs = False
        self._ignore_vehicles = False
        self._target_speed = target_speed
        self._sampling_resolution = 2.0
        self._base_tlight_threshold = 5.0  # meters
        self._base_vehicle_threshold = 5.0  # meters
        self._max_brake = 0.5

        # Change parameters according to the dictionary
        opt_dict['target_speed'] = target_speed
        if 'ignore_traffic_lights' in opt_dict:
            self._ignore_traffic_lights = opt_dict['ignore_traffic_lights']
        if 'ignore_stop_signs' in opt_dict:
            self._ignore_stop_signs = opt_dict['ignore_stop_signs']
        if 'ignore_vehicles' in opt_dict:
            self._ignore_vehicles = opt_dict['ignore_vehicles']
        if 'sampling_resolution' in opt_dict:
            self._sampling_resolution = opt_dict['sampling_resolution']
        if 'base_tlight_threshold' in opt_dict:
            self._base_tlight_threshold = opt_dict['base_tlight_threshold']
        if 'base_vehicle_threshold' in opt_dict:
            self._base_vehicle_threshold = opt_dict['base_vehicle_threshold']
        if 'max_brake' in opt_dict:
            self._max_steering = opt_dict['max_brake']

        # Initialize the planners
        self._local_planner = LocalPlanner(self._vehicle, opt_dict=opt_dict)
        self._global_planner = GlobalRoutePlanner(self._map,
                                                  self._sampling_resolution)

    def add_emergency_stop(self, control):
        """
        Overwrites the throttle a brake values of a control to perform an emergency stop.
        The steering is kept the same to avoid going out of the lane when stopping during turns

            :param speed (carl.VehicleControl): control to be modified
        """
        control.throttle = 0.0
        control.brake = self._max_brake
        control.hand_brake = False
        return control

    def set_target_speed(self, speed):
        """
        Changes the target speed of the agent
            :param speed (float): target speed in Km/h
        """
        self._local_planner.set_speed(speed)

    def follow_speed_limits(self, value=True):
        """
        If active, the agent will dynamically change the target speed according to the speed limits

            :param value (bool): whether or not to activate this behavior
        """
        self._local_planner.follow_speed_limits(value)

    def get_local_planner(self):
        """Get method for protected member local planner"""
        return self._local_planner

    def get_global_planner(self):
        """Get method for protected member local planner"""
        return self._global_planner

    def set_destination(self, end_location, start_location=None):
        """
        This method creates a list of waypoints between a starting and ending location,
        based on the route returned by the global router, and adds it to the local planner.
        If no starting location is passed, the vehicle local planner's target location is chosen,
        which corresponds (by default), to a location about 5 meters in front of the vehicle.

            :param end_location (carla.Location): final location of the route
            :param start_location (carla.Location): starting location of the route
        """
        if not start_location:
            start_location = self._local_planner.target_waypoint.transform.location
            clean_queue = True
        else:
            start_location = self._vehicle.get_location()
            clean_queue = False

        start_waypoint = self._map.get_waypoint(start_location)
        end_waypoint = self._map.get_waypoint(end_location)

        route_trace = self.trace_route(start_waypoint, end_waypoint)
        self._local_planner.set_global_plan(route_trace,
                                            clean_queue=clean_queue)

    def set_global_plan(self,
                        plan,
                        stop_waypoint_creation=True,
                        clean_queue=True):
        """
        Adds a specific plan to the agent.

            :param plan: list of [carla.Waypoint, RoadOption] representing the route to be followed
            :param stop_waypoint_creation: stops the automatic random creation of waypoints
            :param clean_queue: resets the current agent's plan
        """
        self._local_planner.set_global_plan(
            plan,
            stop_waypoint_creation=stop_waypoint_creation,
            clean_queue=clean_queue)

    def trace_route(self, start_waypoint, end_waypoint):
        """
        Calculates the shortest route between a starting and ending waypoint.

            :param start_waypoint (carla.Waypoint): initial waypoint
            :param end_waypoint (carla.Waypoint): final waypoint
        """
        start_location = start_waypoint.transform.location
        end_location = end_waypoint.transform.location
        return self._global_planner.trace_route(start_location, end_location)

    def run_step(self):
        """Execute one step of navigation."""
        hazard_detected = False

        # Retrieve all relevant actors
        actor_list = self._world.get_actors()
        vehicle_list = actor_list.filter("*vehicle*")
        lights_list = actor_list.filter("*traffic_light*")

        vehicle_speed = get_speed(self._vehicle) / 3.6

        # Check for possible vehicle obstacles
        max_vehicle_distance = self._base_vehicle_threshold + vehicle_speed
        affected_by_vehicle, _, _ = self._vehicle_obstacle_detected(
            vehicle_list, max_vehicle_distance)
        if affected_by_vehicle:
            hazard_detected = True

        # Check if the vehicle is affected by a red traffic light
        max_tlight_distance = self._base_tlight_threshold + vehicle_speed
        affected_by_tlight, _ = self._affected_by_traffic_light(
            lights_list, max_tlight_distance)
        if affected_by_tlight:
            hazard_detected = True

        control = self._local_planner.run_step()
        if hazard_detected:
            control = self.add_emergency_stop(control)

        return control

    def done(self):
        """Check whether the agent has reached its destination."""
        return self._local_planner.done()

    def ignore_traffic_lights(self, active=True):
        """(De)activates the checks for traffic lights"""
        self._ignore_traffic_lights = active

    def ignore_stop_signs(self, active=True):
        """(De)activates the checks for stop signs"""
        self._ignore_stop_signs = active

    def ignore_vehicles(self, active=True):
        """(De)activates the checks for stop signs"""
        self._ignore_vehicles = active

    def _affected_by_traffic_light(self, lights_list=None, max_distance=None):
        """
        Method to check if there is a red light affecting the vehicle.

            :param lights_list (list of carla.TrafficLight): list containing TrafficLight objects.
                If None, all traffic lights in the scene are used
            :param max_distance (float): max distance for traffic lights to be considered relevant.
                If None, the base threshold value is used
        """
        if self._ignore_traffic_lights:
            return (False, None)

        if not lights_list:
            lights_list = self._world.get_actors().filter("*traffic_light*")

        if not max_distance:
            max_distance = self._base_tlight_threshold

        if self._last_traffic_light:
            if self._last_traffic_light.state != carla.TrafficLightState.Red:
                self._last_traffic_light = None
            else:
                return (True, self._last_traffic_light)

        ego_vehicle_location = self._vehicle.get_location()
        ego_vehicle_waypoint = self._map.get_waypoint(ego_vehicle_location)

        for traffic_light in lights_list:
            object_location = get_trafficlight_trigger_location(traffic_light)
            object_waypoint = self._map.get_waypoint(object_location)

            if object_waypoint.road_id != ego_vehicle_waypoint.road_id:
                continue

            ve_dir = ego_vehicle_waypoint.transform.get_forward_vector()
            wp_dir = object_waypoint.transform.get_forward_vector()
            dot_ve_wp = ve_dir.x * wp_dir.x + ve_dir.y * wp_dir.y + ve_dir.z * wp_dir.z

            if dot_ve_wp < 0:
                continue

            if traffic_light.state != carla.TrafficLightState.Red:
                continue

            if is_within_distance(object_waypoint.transform,
                                  self._vehicle.get_transform(), max_distance,
                                  [0, 90]):
                self._last_traffic_light = traffic_light
                return (True, traffic_light)

        return (False, None)

    def _vehicle_obstacle_detected(self,
                                   vehicle_list=None,
                                   max_distance=None,
                                   up_angle_th=90,
                                   low_angle_th=0,
                                   lane_offset=0):
        """
        Method to check if there is a vehicle in front of the agent blocking its path.

            :param vehicle_list (list of carla.Vehicle): list contatining vehicle objects.
                If None, all vehicle in the scene are used
            :param max_distance: max freespace to check for obstacles.
                If None, the base threshold value is used
        """
        if self._ignore_vehicles:
            return (False, None, -1)

        if not vehicle_list:
            vehicle_list = self._world.get_actors().filter("*vehicle*")

        if not max_distance:
            max_distance = self._base_vehicle_threshold

        ego_transform = self._vehicle.get_transform()
        ego_wpt = self._map.get_waypoint(self._vehicle.get_location())

        # Get the right offset
        if ego_wpt.lane_id < 0 and lane_offset != 0:
            lane_offset *= -1

        # Get the transform of the front of the ego
        ego_forward_vector = ego_transform.get_forward_vector()
        ego_extent = self._vehicle.bounding_box.extent.x
        ego_front_transform = ego_transform
        ego_front_transform.location += carla.Location(
            x=ego_extent * ego_forward_vector.x,
            y=ego_extent * ego_forward_vector.y,
        )

        for target_vehicle in vehicle_list:
            target_transform = target_vehicle.get_transform()
            target_wpt = self._map.get_waypoint(target_transform.location,
                                                lane_type=carla.LaneType.Any)

            # Simplified version for outside junctions
            if not ego_wpt.is_junction or not target_wpt.is_junction:

                if target_wpt.road_id != ego_wpt.road_id or target_wpt.lane_id != ego_wpt.lane_id + lane_offset:
                    next_wpt = self._local_planner.get_incoming_waypoint_and_direction(
                        steps=3)[0]
                    if not next_wpt:
                        continue
                    if target_wpt.road_id != next_wpt.road_id or target_wpt.lane_id != next_wpt.lane_id + lane_offset:
                        continue

                target_forward_vector = target_transform.get_forward_vector()
                target_extent = target_vehicle.bounding_box.extent.x
                target_rear_transform = target_transform
                target_rear_transform.location -= carla.Location(
                    x=target_extent * target_forward_vector.x,
                    y=target_extent * target_forward_vector.y,
                )

                if is_within_distance(target_rear_transform,
                                      ego_front_transform, max_distance,
                                      [low_angle_th, up_angle_th]):
                    return (True, target_vehicle,
                            compute_distance(target_transform.location,
                                             ego_transform.location))

            # Waypoints aren't reliable, check the proximity of the vehicle to the route
            else:
                route_bb = []
                ego_location = ego_transform.location
                extent_y = self._vehicle.bounding_box.extent.y
                r_vec = ego_transform.get_right_vector()
                p1 = ego_location + carla.Location(extent_y * r_vec.x,
                                                   extent_y * r_vec.y)
                p2 = ego_location + carla.Location(-extent_y * r_vec.x,
                                                   -extent_y * r_vec.y)
                route_bb.append([p1.x, p1.y, p1.z])
                route_bb.append([p2.x, p2.y, p2.z])

                for wp, _ in self._local_planner.get_plan():
                    if ego_location.distance(
                            wp.transform.location) > max_distance:
                        break

                    r_vec = wp.transform.get_right_vector()
                    p1 = wp.transform.location + carla.Location(
                        extent_y * r_vec.x, extent_y * r_vec.y)
                    p2 = wp.transform.location + carla.Location(
                        -extent_y * r_vec.x, -extent_y * r_vec.y)
                    route_bb.append([p1.x, p1.y, p1.z])
                    route_bb.append([p2.x, p2.y, p2.z])

                if len(route_bb) < 3:
                    # 2 points don't create a polygon, nothing to check
                    return (False, None, -1)
                ego_polygon = Polygon(route_bb)

                # Compare the two polygons
                for target_vehicle in vehicle_list:
                    target_extent = target_vehicle.bounding_box.extent.x
                    if target_vehicle.id == self._vehicle.id:
                        continue
                    if ego_location.distance(
                            target_vehicle.get_location()) > max_distance:
                        continue

                    target_bb = target_vehicle.bounding_box
                    target_vertices = target_bb.get_world_vertices(
                        target_vehicle.get_transform())
                    target_list = [[v.x, v.y, v.z] for v in target_vertices]
                    target_polygon = Polygon(target_list)

                    if ego_polygon.intersects(target_polygon):
                        return (True, target_vehicle,
                                compute_distance(target_vehicle.get_location(),
                                                 ego_location))

                return (False, None, -1)

        return (False, None, -1)
Пример #29
0
class BasicAgent(Agent):
    """
    BasicAgent implements a basic agent that navigates scenes to reach a given
    target destination. This agent respects traffic lights and other vehicles.
    """
    def __init__(self, vehicle, target_speed=20):
        """

        :param vehicle: actor to apply to local planner logic onto
        """
        super(BasicAgent, self).__init__(vehicle)

        self._proximity_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING
        self._local_planner = LocalPlanner(
            self._vehicle, opt_dict={'target_speed': target_speed})
        self._hop_resolution = 2.0

        # setting up global router
        self._current_plan = None

    def set_destination(self, location):
        start_waypoint = self._map.get_waypoint(self._vehicle.get_location())
        end_waypoint = self._map.get_waypoint(
            carla.Location(location[0], location[1], location[2]))
        solution = []

        # Setting up global router
        dao = GlobalRoutePlannerDAO(self._vehicle.get_world().get_map())
        grp = GlobalRoutePlanner(dao)
        grp.setup()

        # Obtain route plan
        x1 = start_waypoint.transform.location.x
        y1 = start_waypoint.transform.location.y
        x2 = end_waypoint.transform.location.x
        y2 = end_waypoint.transform.location.y
        route = grp.plan_route((x1, y1), (x2, y2))

        current_waypoint = start_waypoint
        route.append(RoadOption.VOID)
        for action in route:

            #   Generate waypoints to next junction
            wp_choice = current_waypoint.next(self._hop_resolution)
            while len(wp_choice) == 1:
                current_waypoint = wp_choice[0]
                solution.append((current_waypoint, RoadOption.LANEFOLLOW))
                wp_choice = current_waypoint.next(self._hop_resolution)
                #   Stop at destination
                if current_waypoint.transform.location.distance(
                        end_waypoint.transform.location
                ) < self._hop_resolution:
                    break
            if action == RoadOption.VOID: break

            #   Select appropriate path at the junction
            if len(wp_choice) > 1:

                # Current heading vector
                current_transform = current_waypoint.transform
                current_location = current_transform.location
                projected_location = current_location + \
                    carla.Location(
                        x=math.cos(math.radians(current_transform.rotation.yaw)),
                        y=math.sin(math.radians(current_transform.rotation.yaw)))
                v_current = vector(current_location, projected_location)

                direction = 0
                if action == RoadOption.LEFT:
                    direction = 1
                elif action == RoadOption.RIGHT:
                    direction = -1
                elif action == RoadOption.STRAIGHT:
                    direction = 0
                select_criteria = float('inf')

                #   Choose correct path
                for wp_select in wp_choice:
                    v_select = vector(current_location,
                                      wp_select.transform.location)
                    cross = float('inf')
                    if direction == 0:
                        cross = abs(np.cross(v_current, v_select)[-1])
                    else:
                        cross = direction * np.cross(v_current, v_select)[-1]
                    if cross < select_criteria:
                        select_criteria = cross
                        current_waypoint = wp_select

                #   Generate all waypoints within the junction
                #   along selected path
                solution.append((current_waypoint, action))
                current_waypoint = current_waypoint.next(
                    self._hop_resolution)[0]
                while current_waypoint.is_intersection:
                    solution.append((current_waypoint, action))
                    current_waypoint = current_waypoint.next(
                        self._hop_resolution)[0]

        assert solution

        self._current_plan = solution
        self._local_planner.set_global_plan(self._current_plan)

    def run_step(self, debug=False):
        """
        Execute one step of navigation.
        :return: carla.VehicleControl
        """

        # is there an obstacle in front of us?
        hazard_detected = False

        # retrieve relevant elements for safe navigation, i.e.: traffic lights
        # and other vehicles
        actor_list = self._world.get_actors()
        vehicle_list = actor_list.filter("*vehicle*")
        lights_list = actor_list.filter("*traffic_light*")

        # check possible obstacles
        vehicle_state, vehicle = self._is_vehicle_hazard(vehicle_list)
        if vehicle_state:
            if debug:
                print('!!! VEHICLE BLOCKING AHEAD [{}])'.format(vehicle.id))

            self._state = AgentState.BLOCKED_BY_VEHICLE
            hazard_detected = True

        # check for the state of the traffic lights
        light_state, traffic_light = self._is_light_red(lights_list)
        if light_state:
            if debug:
                print('=== RED LIGHT AHEAD [{}])'.format(traffic_light.id))

            self._state = AgentState.BLOCKED_RED_LIGHT
            hazard_detected = True

        if hazard_detected:
            control = self.emergency_stop()
        else:
            self._state = AgentState.NAVIGATING
            # standard local planner behavior
            control = self._local_planner.run_step()

        return control
Пример #30
0
class PIDAgent(MapAgent):
    def setup(self, path_to_conf_file):
        super().setup(path_to_conf_file)

        self.save_path = None

        parent_folder = os.environ['SAVE_FOLDER']
        string = pathlib.Path(os.environ['ROUTES']).stem
        self.save_path = pathlib.Path(parent_folder) / string



    def _init(self):
        super()._init()


        self._proximity_tlight_threshold = 5.0  # meters
        self._proximity_vehicle_threshold = 10.0  # meters
        self._local_planner = None

        try:
            self._map = self._world.get_map()

        except RuntimeError as error:
            print('RuntimeError: {}'.format(error))
            print('  The server could not send the OpenDRIVE (.xodr) file:')
            print('  Make sure it exists, has the same name of your town, and is correct.')
            sys.exit(1)
        self._last_traffic_light = None



        self._proximity_tlight_threshold = 5.0  # meters
        self._proximity_vehicle_threshold = 10.0  # meters
        self._state = AgentState.NAVIGATING

        # TBD: subject to change
        self.target_speed = 7
        args_lateral_dict = {
            'K_P': 1,
            'K_D': 0.4,
            'K_I': 0,
            'dt': 1.0/20.0}
        self._local_planner = LocalPlanner(
            self._vehicle, opt_dict={'target_speed' : self.target_speed,
            'lateral_control_dict':args_lateral_dict})
        self._hop_resolution = 2.0
        self._path_seperation_hop = 2
        self._path_seperation_threshold = 0.5
        self._grp = None

        self._map = CarlaDataProvider.get_map()
        route = [(self._map.get_waypoint(x[0].location), x[1]) for x in self._global_plan_world_coord]

        self._local_planner.set_global_plan(route)







    def _get_control(self, tick_data, _draw):
        pos = self._get_position(tick_data)
        theta = tick_data['compass']
        speed = tick_data['speed']






        # is there an obstacle in front of us?
        hazard_detected = False

        # retrieve relevant elements for safe navigation, i.e.: traffic lights
        # and other vehicles
        actor_list = self._world.get_actors()
        vehicle_list = actor_list.filter("*vehicle*")
        lights_list = actor_list.filter("*traffic_light*")

        # check possible obstacles
        vehicle_state, vehicle = self._is_vehicle_hazard(vehicle_list)
        if vehicle_state:
            self._state = AgentState.BLOCKED_BY_VEHICLE
            hazard_detected = True

        # check for the state of the traffic lights
        light_state, traffic_light = self._is_light_red(lights_list)
        if light_state:
            self._state = AgentState.BLOCKED_RED_LIGHT
            hazard_detected = True

        if hazard_detected:
            control = self.emergency_stop()
        else:
            self._state = AgentState.NAVIGATING
            # standard local planner behavior
            control = self._local_planner.run_step(debug=DEBUG)








        _draw.text((5, 90), 'Speed: %.3f' % speed)
        _draw.text((5, 110), 'Target: %.3f' % self.target_speed)

        return control

    def run_step(self, input_data, timestamp):
        if not self.initialized:
            self._init()

        data = self.tick(input_data)

        rgb_with_car = cv2.cvtColor(input_data['rgb_with_car'][1][:, :, :3], cv2.COLOR_BGR2RGB)
        data['rgb_with_car'] = rgb_with_car

        topdown = data['topdown']
        rgb = np.hstack((data['rgb_left'], data['rgb'], data['rgb_right']))

        gps = self._get_position(data)


        _topdown = Image.fromarray(COLOR[CONVERTER[topdown]])
        _rgb = Image.fromarray(rgb)
        _draw = ImageDraw.Draw(_topdown)

        _topdown.thumbnail((256, 256))
        _rgb = _rgb.resize((int(256 / _rgb.size[1] * _rgb.size[0]), 256))

        _combined = Image.fromarray(np.hstack((_rgb, _topdown)))
        _draw = ImageDraw.Draw(_combined)

        # change
        control = self._get_control(data, _draw)



        steer = control.steer
        throttle = control.throttle
        brake = control.brake

        _draw.text((5, 10), 'FPS: %.3f' % (self.step / (time.time() - self.wall_start)))
        _draw.text((5, 30), 'Steer: %.3f' % steer)
        _draw.text((5, 50), 'Throttle: %.3f' % throttle)
        _draw.text((5, 70), 'Brake: %s' % brake)

        if HAS_DISPLAY:
            cv2.imshow('map', cv2.cvtColor(np.array(_combined), cv2.COLOR_BGR2RGB))
            cv2.waitKey(1)


        if self.step % 2 == 0:
            self.gather_info()

        record_every_n_steps = 3
        if self.step % record_every_n_steps == 0:
            self.save('', steer, throttle, brake, self.target_speed, data)

        return control

    def save(self, far_command, steer, throttle, brake, target_speed, tick_data):
        # frame = self.step // 10
        frame = self.step

        speed = tick_data['speed']
        string = os.environ['SAVE_FOLDER'] + '/' + pathlib.Path(os.environ['ROUTES']).stem

        center_str = string + '/' + 'rgb' + '/' + ('%04d.png' % frame)
        left_str = string + '/' + 'rgb_left' + '/' + ('%04d.png' % frame)
        right_str = string + '/' + 'rgb_right' + '/' + ('%04d.png' % frame)
        # topdown_str = string + '/' + 'topdown' + '/' + ('%04d.png' % frame)

        center = self.save_path / 'rgb' / ('%04d.png' % frame)
        left = self.save_path / 'rgb_left' / ('%04d.png' % frame)
        right = self.save_path / 'rgb_right' / ('%04d.png' % frame)
        topdown = self.save_path / 'topdown' / ('%04d.png' % frame)
        rgb_with_car = self.save_path / 'rgb_with_car' / ('%04d.png' % frame)

        data_row = ','.join([str(i) for i in [frame, far_command, speed, steer, throttle, brake, center_str, left_str, right_str]])
        with (self.save_path / 'measurements.csv').open("a") as f_out:
            f_out.write(data_row+'\n')

        Image.fromarray(tick_data['rgb']).save(center)
        Image.fromarray(tick_data['rgb_left']).save(left)
        Image.fromarray(tick_data['rgb_right']).save(right)
        # modification
        Image.fromarray(COLOR[CONVERTER[tick_data['topdown']]]).save(topdown)
        Image.fromarray(tick_data['rgb_with_car']).save(rgb_with_car)


    def _draw_line(self, p, v, z, color=(255, 0, 0)):
        if not DEBUG:
            return

        p1 = _location(p[0], p[1], z)
        p2 = _location(p[0]+v[0], p[1]+v[1], z)
        color = carla.Color(*color)

        self._world.debug.draw_line(p1, p2, 0.25, color, 0.01)






















    def _is_light_red(self, lights_list):
        """
        Method to check if there is a red light affecting us. This version of
        the method is compatible with both European and US style traffic lights.

        :param lights_list: list containing TrafficLight objects
        :return: a tuple given by (bool_flag, traffic_light), where
                 - bool_flag is True if there is a traffic light in RED
                   affecting us and False otherwise
                 - traffic_light is the object itself or None if there is no
                   red traffic light affecting us
        """
        ego_vehicle_location = self._vehicle.get_location()
        ego_vehicle_waypoint = self._map.get_waypoint(ego_vehicle_location)

        for traffic_light in lights_list:
            object_location = self._get_trafficlight_trigger_location(traffic_light)
            object_waypoint = self._map.get_waypoint(object_location)

            if object_waypoint.road_id != ego_vehicle_waypoint.road_id:
                continue

            ve_dir = ego_vehicle_waypoint.transform.get_forward_vector()
            wp_dir = object_waypoint.transform.get_forward_vector()
            dot_ve_wp = ve_dir.x * wp_dir.x + ve_dir.y * wp_dir.y + ve_dir.z * wp_dir.z

            if dot_ve_wp < 0:
                continue

            if is_within_distance_ahead(object_waypoint.transform,
                                        self._vehicle.get_transform(),
                                        self._proximity_tlight_threshold):
                if traffic_light.state == carla.TrafficLightState.Red:
                    return (True, traffic_light)

        return (False, None)

    def _get_trafficlight_trigger_location(self, traffic_light):  # pylint: disable=no-self-use
        """
        Calculates the yaw of the waypoint that represents the trigger volume of the traffic light
        """
        def rotate_point(point, radians):
            """
            rotate a given point by a given angle
            """
            rotated_x = math.cos(radians) * point.x - math.sin(radians) * point.y
            rotated_y = math.sin(radians) * point.x - math.cos(radians) * point.y

            return carla.Vector3D(rotated_x, rotated_y, point.z)

        base_transform = traffic_light.get_transform()
        base_rot = base_transform.rotation.yaw
        area_loc = base_transform.transform(traffic_light.trigger_volume.location)
        area_ext = traffic_light.trigger_volume.extent

        point = rotate_point(carla.Vector3D(0, 0, area_ext.z), math.radians(base_rot))
        point_location = area_loc + carla.Location(x=point.x, y=point.y)

        return carla.Location(point_location.x, point_location.y, point_location.z)

    def _bh_is_vehicle_hazard(self, ego_wpt, ego_loc, vehicle_list,
                           proximity_th, up_angle_th, low_angle_th=0, lane_offset=0):
        """
        Check if a given vehicle is an obstacle in our way. To this end we take
        into account the road and lane the target vehicle is on and run a
        geometry test to check if the target vehicle is under a certain distance
        in front of our ego vehicle. We also check the next waypoint, just to be
        sure there's not a sudden road id change.

        WARNING: This method is an approximation that could fail for very large
        vehicles, which center is actually on a different lane but their
        extension falls within the ego vehicle lane. Also, make sure to remove
        the ego vehicle from the list. Lane offset is set to +1 for right lanes
        and -1 for left lanes, but this has to be inverted if lane values are
        negative.

            :param ego_wpt: waypoint of ego-vehicle
            :param ego_log: location of ego-vehicle
            :param vehicle_list: list of potential obstacle to check
            :param proximity_th: threshold for the agent to be alerted of
            a possible collision
            :param up_angle_th: upper threshold for angle
            :param low_angle_th: lower threshold for angle
            :param lane_offset: for right and left lane changes
            :return: a tuple given by (bool_flag, vehicle, distance), where:
            - bool_flag is True if there is a vehicle ahead blocking us
                   and False otherwise
            - vehicle is the blocker object itself
            - distance is the meters separating the two vehicles
        """

        # Get the right offset
        if ego_wpt.lane_id < 0 and lane_offset != 0:
            lane_offset *= -1

        for target_vehicle in vehicle_list:

            target_vehicle_loc = target_vehicle.get_location()
            # If the object is not in our next or current lane it's not an obstacle

            target_wpt = self._map.get_waypoint(target_vehicle_loc)
            if target_wpt.road_id != ego_wpt.road_id or \
                    target_wpt.lane_id != ego_wpt.lane_id + lane_offset:
                next_wpt = self._local_planner.get_incoming_waypoint_and_direction(steps=5)[0]
                if target_wpt.road_id != next_wpt.road_id or \
                        target_wpt.lane_id != next_wpt.lane_id + lane_offset:
                    continue

            if is_within_distance(target_vehicle_loc, ego_loc,
                                  self._vehicle.get_transform().rotation.yaw,
                                  proximity_th, up_angle_th, low_angle_th):

                return (True, target_vehicle, compute_distance(target_vehicle_loc, ego_loc))

        return (False, None, -1)

    def _is_vehicle_hazard(self, vehicle_list):
        """

        :param vehicle_list: list of potential obstacle to check
        :return: a tuple given by (bool_flag, vehicle), where
                 - bool_flag is True if there is a vehicle ahead blocking us
                   and False otherwise
                 - vehicle is the blocker object itself
        """

        ego_vehicle_location = self._vehicle.get_location()
        ego_vehicle_waypoint = self._map.get_waypoint(ego_vehicle_location)

        for target_vehicle in vehicle_list:
            # do not account for the ego vehicle
            if target_vehicle.id == self._vehicle.id:
                continue

            # if the object is not in our lane it's not an obstacle
            target_vehicle_waypoint = self._map.get_waypoint(target_vehicle.get_location())
            if target_vehicle_waypoint.road_id != ego_vehicle_waypoint.road_id or \
                    target_vehicle_waypoint.lane_id != ego_vehicle_waypoint.lane_id:
                continue

            if is_within_distance_ahead(target_vehicle.get_transform(),
                                        self._vehicle.get_transform(),
                                        self._proximity_vehicle_threshold):
                return (True, target_vehicle)

        return (False, None)


    @staticmethod
    def emergency_stop():
        """
        Send an emergency stop command to the vehicle

            :return: control for braking
        """
        control = carla.VehicleControl()
        control.steer = 0.0
        control.throttle = 0.0
        control.brake = 1.0
        control.hand_brake = False

        return control