def __init__(self, logdata=True, net=None):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2)
        )
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7),
        )
        self.data_logger = DataLogWriter() if logdata else None
        self.counter = 0

        # import the neural net that drives the car
        self.model = simpleNetV2()
        self.weights = 'simpleNetV2_epoch_3_all_tracks.csv.pkl'
        self.model.load_state_dict(torch.load(self.weights))
        self.input = torch.FloatTensor(D_in)
        self.track_check1 = False
        self.track_check2 = False

        # import the neat neural network to handle the gear
        config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
                         neat.DefaultSpeciesSet, neat.DefaultStagnation,
                         'config-neat')
        with open('winner-feedforward', 'rb') as f:
            winner = pickle.load(f)
        self.net = neat.nn.FeedForwardNetwork.create(winner, config)

        self.clock = time.time()
        self.done = False

        # initialize the fitness with zero
        self.temp_fitness = 0
Beispiel #2
0
    def __init__(self, logdata=True):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None

        # Setup the PyTorch model and load the weights
        self.model = simpleNetV3()
        weights = 'simpleNetV3_lr=0.01_epoch_1_all_tracks.csv.pkl'
        self.model.load_state_dict(torch.load(weights))

        # Initialize inputs, counters and history
        self.input = torch.zeros(D_in)
        self.crashCounter = 0
        self.reverseCounter = 0
        self.forwardCounter = 0
        self.resetGear = False
        self.crashed = False
        self.counter = 0
        self.name = '3001'
        self.history = np.zeros((5, 2), dtype=float)

        # Initialize SWARM
        self.pheromones = []
        pickle.dump(self.pheromones, open("sent_3001.txt", "wb"))
        self.straight_begin = 0
        self.straight_end = 0
        self.list_straight = []
        self.list_corner = []
        self.received = []
        self.list_average_corner = []
Beispiel #3
0
    def __init__(self, logdata=True):
        # filenames = ['aalborg.csv', 'alpine-1.csv', 'f-speedway.csv', 'data_track_2.csv']
        #filenames = ['aalborg.csv', 'alpine-1.csv', 'f-speedway.csv']
        filenames = ['forza_urja.csv', 'newdata5.csv', 'aalborg_urja.csv']
        #, 'aalborg_urja.csv', 'aalborg_urja_vx80.csv']
        #filenames = ['aalborg_new.csv', 'forza_new.csv']
        data, labels = helper_functions.readData(filenames)
        # self.network = do_the_thing(data, labels)
        learning_rate = 1e-6
        #self.network = Network(data, labels, learning_rate)
        #self.network.train()

        #torch.save(self.network, 'current_network.pt')
        self.network = torch.load('current_network_17_WINEF.pt')
        self.id = random.uniform(0, 1)

        fh = open("cooperation" + str(self.id) + ".txt", "w")
        write(str(self.id) + ": 0.0")
        fh.close()

        self.set = False

        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None
Beispiel #4
0
 def __init__(self, logdata=True):
     self.steering_ctrl = CompositeController(
         ProportionalController(0.4),
         IntegrationController(0.2, integral_limit=1.5),
         DerivativeController(2))
     self.acceleration_ctrl = CompositeController(
         ProportionalController(3.7), )
     self.data_logger = DataLogWriter() if logdata else None
Beispiel #5
0
    def __init__(self, logdata=True, models=None, explore=0.9, optimizer=None):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None

        # Algorithm variables
        self.previous_state = None
        if os.path.isfile("memory.txt") == True:
            with open("memory.txt", "rb") as fp:
                self.replay_memory = pickle.load(fp)
        else:
            self.replay_memory = []
        # Maximum size of the replay memory
        self.max_RM_size = 100000
        self.model, self.target = models
        self.criterion = torch.nn.MSELoss()
        self.model_optim = optimizer
        self.restart = False
        # Discretize the action space
        self.action_space = [
            0.9, 0.7, 0.5, 0.4, 0.3, 0.2, 0.1, 0, -0.1, -0.2, -0.3, -0.4, -0.5,
            -0.7, -0.9
        ]
        self.action = 0
        self.reward = 0

        # Model that is used for accelerating and braking
        self.model_acc_brake = simpleNetV2()

        self.pheromones = []
        # self.receiver = Receiver(6001)

        weights = 'simpleNetV2_epoch_3_all_tracks.csv.pkl'

        self.model_acc_brake.load_state_dict(torch.load(weights))
        self.input = torch.zeros(D_in)

        # STATS
        if os.path.isfile("counter.txt") == True:
            with open("counter.txt", "rb") as fp:
                self.counter = pickle.load(fp)
        else:
            self.counter = 0
        self.counter_per_game = 0
        self.train_counter = 0
        self.average_reward = 0
        self.average_loss = 0

        # Hyperparameters
        self.exploration_rate = explore
        self.batch_size = 128
        self.gamma = 0.99
Beispiel #6
0
 def __init__(self, logdata=True):
     self.steering_ctrl = CompositeController(
         ProportionalController(0.4),
         IntegrationController(0.2, integral_limit=1.5),
         DerivativeController(2))
     self.acceleration_ctrl = CompositeController(
         ProportionalController(3.7), )
     self.data_logger = DataLogWriter() if logdata else None
     self.path = []
     self.pid_steer = PID(Kp=0.5, Ki=0.0, Kd=1.0, setpoint=0, sample_time=0.02,\
          output_limits=(-1.0, 1.0), auto_mode=True, proportional_on_measurement=True)
Beispiel #7
0
 def __init__(self, logdata=True):
     self.steering_ctrl = CompositeController(
         ProportionalController(0.4),
         IntegrationController(0.2, integral_limit=1.5),
         DerivativeController(2)
     )
     self.acceleration_ctrl = CompositeController(
         ProportionalController(3.7),
     )
     self.data_logger = DataLogWriter() if logdata else None
     self.model = TwoLayerNet(D_in, hidden_size, hidden_size_2, D_out)
     self.model.load_state_dict(torch.load('LaurensNet30.pkl'))
Beispiel #8
0
 def __init__(self, log_data=False, net=None):
     # self.steering_ctrl = CompositeController(ProportionalController(0.4),IntegrationController(0.2, integral_limit=1.5),DerivativeController(2))
     # self.acceleration_ctrl = CompositeController(
     # 	ProportionalController(3.7),
     # )
     self.steering_ctrl = CompositeController(ProportionalController(0.4),
                                              DerivativeController(2))
     self.acceleration_ctrl = CompositeController(
         ProportionalController(3.7), )
     self.data_logger = DataLogWriter() if log_data else None
     self.net = net
     print("mehmehmeh")
     self.flag = False
Beispiel #9
0
    def __init__(self, logdata=True):
        # filenames = ['aalborg.csv', 'alpine-1.csv', 'f-speedway.csv', 'data_track_2.csv']
        #filenames = ['aalborg.csv', 'alpine-1.csv', 'f-speedway.csv']
        filenames = ['forza_urja.csv']
        #filenames = ['aalborg_new.csv', 'forza_new.csv']
        data, labels = helper_functions.readData(filenames)
        # self.network = do_the_thing(data, labels)
        learning_rate = 1e-6
        self.network = Network(data, labels, learning_rate)
        self.network.train()

        torch.save(self.network, 'current_network.pt')

        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None
Beispiel #10
0
    def __init__(self, logdata=True):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None

        self.model = simpleNetV2()

        weights = 'simpleNetV2_epoch_3_all_tracks.csv.pkl'
        self.model.load_state_dict(torch.load(weights))
        self.input = torch.zeros(D_in)
        self.crashCounter = 0
        self.reverseCounter = 0
        self.forwardCounter = 0
        self.resetGear = False
        self.crashed = False
        self.counter = 0
        self.name = '3001'

        # NEAT
        self.history = np.zeros((5, 2), dtype=float)
        config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
                             neat.DefaultSpeciesSet, neat.DefaultStagnation,
                             'config-neat')
        with open('winner-feedforward', 'rb') as f:
            winner = pickle.load(f)
        self.net = neat.nn.FeedForwardNetwork.create(winner, config)

        #SWARM
        self.pheromones = []
        pickle.dump(self.pheromones, open("../sent_3001.txt", "wb"))
        self.straight_begin = 0
        self.straight_end = 0
        self.list_straight = []
        self.list_corner = []
        self.received = []
        self.list_average_corcer = []
Beispiel #11
0
    def __init__(self, logdata=True, net=None):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2)
        )
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7),
        )
        self.data_logger = DataLogWriter() if logdata else None
        self.eta = 20
        self.counter = 0
        self.model = simpleNetV2()
        self.weights = 'simpleNetV2_epoch_3_all_tracks.csv.pkl'

        self.model.load_state_dict(torch.load(self.weights))
        self.input = torch.FloatTensor(D_in)
        self.track_check1 = False
        self.track_check2 = False
        self.action_neat = None
        self.net = net
        self.clock = time.time()
        self.done = False
        self.temp_fitness = 0
    def instantiatePIDControllers(self):
        self.steering_ctrl = CompositeController(
            ProportionalController(-0.5),
            IntegrationController(-0.1, integral_limit=1),
            DerivativeController(-1))
        self.reverse_ctrl = CompositeController(
            ProportionalController(3.7),
            # IntegrationController(0.1, integral_limit=1.5),
            # DerivativeController(0.5)
        )

        self.forward_ctrl = CompositeController(
            ProportionalController(3.7),
            # IntegrationController(0.1, integral_limit=1.5),
            # DerivativeController(0.5)
        )
Beispiel #13
0
class MyDriver(Driver):


    # Override the `drive` method to create your own driver
    ...
    # def drive(self, carstate: State) -> Command:
    #     # Interesting stuff
    #     command = Command(...)
    #     return command
    def __init__(self, logdata=True):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2)
        )
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7),
        )
        self.data_logger = DataLogWriter() if logdata else None
        self.model = TwoLayerNet(D_in, hidden_size, hidden_size_2, D_out)
        self.model.load_state_dict(torch.load('LaurensNet30.pkl'))

    @property
    def range_finder_angles(self):
        """Iterable of 19 fixed range finder directions [deg].

        The values are used once at startup of the client to set the directions
        of range finders. During regular execution, a 19-valued vector of track
        distances in these directions is returned in ``state.State.tracks``.
        """
        return -90, -75, -60, -45, -30, -20, -15, -10, -5, 0, 5, 10, 15, 20, \
            30, 45, 60, 75, 90

    def on_shutdown(self):
        """
        Server requested driver shutdown.

        Optionally implement this event handler to clean up or write data
        before the application is stopped.
        """
        if self.data_logger:
            self.data_logger.close()
            self.data_logger = None

    def drive(self, carstate: State) -> Command:
        """
        Produces driving command in response to newly received car state.

        This is a dummy driving routine, very dumb and not really considering a
        lot of inputs. But it will get the car (if not disturbed by other
        drivers) successfully driven along the race track.

        """
        global fullData
        data = np.empty(25)
        data[3] = carstate.speed_x
        data[4] = carstate.z
        data[5] = carstate.angle
        for index, edge in enumerate(carstate.distances_from_edge):
        	data[3 + index] = edge
        # data = torch.from_numpy(data.T)
        # data = data.type(torch.FloatTensor)
        # data=torch.unsqueeze(data,1)
        # data =  Variable(data)

        net_input = torch.from_numpy(fullData.flatten())
        net_input = Variable(net_input.type(torch.FloatTensor))

        # force = np.random.random() < 0.5
        # data = torch.transpose(data, 0, 1)
        predict, hidden_layer = self.model.forward(net_input)
        command = Command()
        predict = predict[0].data.numpy()
        data[0] = predict[0]
        data[1] = predict[1]
        data[2] = predict[2]
        if predict[0] > 0.5:
        	command.accelerator = 1
        else:
        	command.accelerator = 0
        if predict[1] > 0.5:
            command.brake = 1
            print("BRAKING")
        else:
        	command.brake = 0
        command.steer = predict[2]
        self.steer(carstate, 0.0, command)


        # ACC_LATERAL_MAX = 6400 * 5
        # v_x = min(80, math.sqrt(ACC_LATERAL_MAX / abs(command.steering)))
        v_x = 300

        self.accelerate(carstate, v_x, command)

        if self.data_logger:
            self.data_logger.log(carstate, command)

        fullData = np.delete(fullData, 0, axis=1)
        fullData = np.append(fullData, data.reshape((25,1)), axis=1)

        return command

    def accelerate(self, carstate, target_speed, command):
        # compensate engine deceleration, but invisible to controller to
        # prevent braking:
        speed_error = 1.0025 * target_speed * MPS_PER_KMH - carstate.speed_x
        acceleration = self.acceleration_ctrl.control(
            speed_error,
            carstate.current_lap_time
        )

        # stabilize use of gas and brake:
        acceleration = math.pow(acceleration, 3)

        if acceleration > 0:
            if abs(carstate.distance_from_center) >= 1:
                # off track, reduced grip:
                acceleration = min(0.4, acceleration)

            command.accelerator = min(acceleration, 1)

            if carstate.rpm > 8000:
                command.gear = carstate.gear + 1

        # else:
        #     command.brake = min(-acceleration, 1)

        if carstate.rpm < 2500:
            command.gear = carstate.gear - 1

        if not command.gear:
            command.gear = carstate.gear or 1

    def steer(self, carstate, target_track_pos, command):
        steering_error = target_track_pos - carstate.distance_from_center
        command.steering = self.steering_ctrl.control(
            steering_error,
            carstate.current_lap_time
        )
Beispiel #14
0
class Driver:
    """
    Driving logic.

    Implement the driving intelligence in this class by processing the current
    car state as inputs creating car control commands as a response. The
    ``drive`` function is called periodically every 20ms and must return a
    command within 10ms wall time.
    """
    def __init__(self, logdata=True):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None
        self.path = []
        self.pid_steer = PID(Kp=0.5, Ki=0.0, Kd=1.0, setpoint=0, sample_time=0.02,\
             output_limits=(-1.0, 1.0), auto_mode=True, proportional_on_measurement=True)

    @property
    def range_finder_angles(self):
        """Iterable of 19 fixed range finder directions [deg].

        The values are used once at startup of the client to set the directions
        of range finders. During regular execution, a 19-valued vector of track
        distances in these directions is returned in ``state.State.tracks``.
        """
        return -90, -75, -60, -45, -30, -20, -15, -10, -5, 0, 5, 10, 15, 20, \
            30, 45, 60, 75, 90

    def on_shutdown(self):
        """
        Server requested driver shutdown.

        Optionally implement this event handler to clean up or write data
        before the application is stopped.
        """
        if self.data_logger:
            self.data_logger.close()
            self.data_logger = None

    def drive(self, carstate: State) -> Command:

        command = Command()

        self.steer(carstate, 0.0, command)

        ACC_LATERAL_MAX = 6400 * 5
        #v_x = min(120, math.sqrt(ACC_LATERAL_MAX / abs(command.steering)))
        v_x = 120

        self.accelerate(carstate, v_x, command)

        if self.data_logger:
            self.data_logger.log(carstate, command)

        return command

    def accelerate(self, carstate, target_speed, command):
        # compensate engine deceleration, but invisible to controller to
        # prevent braking:
        speed_error = 1.0025 * target_speed * MPS_PER_KMH - carstate.speed_x
        acceleration = self.acceleration_ctrl.control(
            speed_error, carstate.current_lap_time)

        # stabilize use of gas and brake:
        acceleration = math.pow(acceleration, 3)

        if acceleration > 0:
            if abs(carstate.distance_from_center) >= 1:
                # off track, reduced grip:
                acceleration = min(0.4, acceleration)

            command.accelerator = min(acceleration, 1)

            if carstate.rpm > 8000:
                command.gear = carstate.gear + 1

        else:
            command.brake = min(-acceleration, 1)

        if carstate.rpm < 2500:
            command.gear = carstate.gear - 1

        if not command.gear:
            command.gear = carstate.gear or 1

    def steer(self, carstate, target_track_pos, command):
        steering_error = target_track_pos - carstate.distance_from_center
        control = -self.pid_steer(steering_error)
        command.steering = self.steering_ctrl.control(
            control, carstate.current_lap_time)
        return control
Beispiel #15
0
    def __init__(self, logdata=False):
        """
        set the initialization mode
        """
        self.launch_torcs = True
        self.launch_torcs_and_second_driver = False
        """
        use_mlp_opponents: if True, the output of the ESN is adjusted by the Mulit-Layer Perceptron saved at PATH_TO_MLP
        """
        self.use_mlp_opponents = True

        self.PATH_TO_ESN = "./trained_nn/evesn10808.pkl"  # for MLP evolution
        #self.PATH_TO_ESN = "./trained_nn/simple_esn.pkl" # for reservoir evolution
        self.PATH_TO_MLP = "./trained_nn/mlp_opponents.pkl"

        self.CURRENT_SPEED_LIMIT = self.SPEED_LIMIT_NORMAL
        """
        Controllers needed for the simple driver
        """
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None
        """
        launch torcs practice race when ./start.sh is executed (if torcs is not already running)
        comment out for normal use of torcs
        """

        # automatically start TORCS when './start.sh' is executed
        if self.launch_torcs:
            torcs_command = [
                "torcs", "-r",
                os.path.abspath(
                    "./config_files/current_config_file/config.xml")
            ]
            self.torcs_process = subprocess.Popen(torcs_command)

        # automatically start TORCS with two drivers when './start.sh' is executed
        elif self.launch_torcs_and_second_driver:

            # assure that TORCS is not launched again when the second car is initialized

            if not os.path.isfile('torcs_process.txt'):
                torcs_command = [
                    "torcs", "-r",
                    os.path.abspath(
                        "./config_files/current_config_file/config.xml")
                ]
                self.torcs_process = subprocess.Popen(torcs_command)

                with open('./torcs_process.txt', 'w') as file:
                    file.write('running torcs process')

                second_car_command = ["./start.sh", "-p", "3002"]
                subprocess.Popen(second_car_command)
            else:
                line = ''
                with open('./torcs_process.txt', 'r') as file:
                    line = file.readline()
                if not line.find('running torcs process') > -1:

                    torcs_command = [
                        "torcs", "-r",
                        os.path.abspath(
                            "./config_files/current_config_file/config.xml")
                    ]
                    self.torcs_process = subprocess.Popen(torcs_command)

                    with open('./torcs_process.txt', 'w') as file:
                        file.write('running torcs process')

                    second_car_command = ["./start.sh", "-p", "3002"]
                    subprocess.Popen(second_car_command)
                else:
                    with open('./torcs_process.txt', 'w') as file:
                        file.write('')
        """
        some global variables
        """

        self.previous_position = 0
        self.ID = 0
        self.is_first = True
        self.active_mlp = False
        self.current_damage = 0
        self.accel_deviation = 0
        self.steering_deviation = 0
Beispiel #16
0
class Driver:
    """
    Driving logic.

    Implement the driving intelligence in this class by processing the current
    car state as inputs creating car control commands as a response. The
    ``drive`` function is called periodically every 20ms and must return a
    command within 10ms wall time.
    """
    def __init__(self, logdata=True):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None

    @property
    def range_finder_angles(self):
        """Iterable of 19 fixed range finder directions [deg].

        The values are used once at startup of the client to set the directions
        of range finders. During regular execution, a 19-valued vector of track
        distances in these directions is returned in ``state.State.tracks``.
        """
        return -90, -75, -60, -45, -30, -20, -15, -10, -5, 0, 5, 10, 15, 20, \
            30, 45, 60, 75, 90

    def on_shutdown(self):
        """
        Server requested driver shutdown.

        Optionally implement this event handler to clean up or write data
        before the application is stopped.
        """
        if self.data_logger is not None:
            self.data_logger.close()
            self.data_logger = None

    def drive(self, carstate: State) -> Command:
        """
        Produces driving command in response to newly received car state.

        This is a dummy driving routine, very dumb and not really considering a
        lot of inputs. But it will get the car (if not disturbed by other
        drivers) successfully driven along the race track.
        """
        command = Command()
        self.steer(carstate, 0.0, command)

        # ACC_LATERAL_MAX = 6400 * 5
        # v_x = min(80, math.sqrt(ACC_LATERAL_MAX / abs(command.steering)))
        v_x = 80

        self.accelerate(carstate, v_x, command)

        if self.data_logger:
            self.data_logger.log(carstate, command)

        return command

    def accelerate(self, carstate, target_speed, command):
        # compensate engine deceleration, but invisible to controller to
        # prevent braking:
        speed_error = 1.0025 * target_speed * 1000 / 3600 - carstate.speed_x
        acceleration = self.acceleration_ctrl.control(
            speed_error, carstate.current_lap_time)

        # stabilize use of gas and brake:
        acceleration = math.pow(acceleration, 3)

        if acceleration > 0:
            if abs(carstate.distance_from_center) >= 1:
                # off track, reduced grip:
                acceleration = min(0.4, acceleration)

            command.accelerator = min(acceleration, 1)

            if carstate.rpm > 8000:
                command.gear = carstate.gear + 1

        # else:
        #     command.brake = min(-acceleration, 1)

        if carstate.rpm < 2500:
            command.gear = carstate.gear - 1

        if not command.gear:
            command.gear = carstate.gear or 1

    def steer(self, carstate, target_track_pos, command):
        steering_error = target_track_pos - carstate.distance_from_center
        command.steering = self.steering_ctrl.control(
            steering_error, carstate.current_lap_time)
Beispiel #17
0
class MyDriver(Driver):

    # Override the `drive` method to create your own driver
    ...

    # def drive(self, carstate: State) -> Command:
    #     # Interesting stuff
    #     command = Command(...)
    #     return command
    def __init__(self, logdata=True):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None

        self.model = simpleNetV2()

        weights = 'simpleNetV2_epoch_3_all_tracks.csv.pkl'
        self.model.load_state_dict(torch.load(weights))
        self.input = torch.zeros(D_in)
        self.crashCounter = 0
        self.reverseCounter = 0
        self.forwardCounter = 0
        self.resetGear = False
        self.crashed = False
        self.counter = 0
        self.name = '3001'

        # NEAT
        self.history = np.zeros((5, 2), dtype=float)
        config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
                             neat.DefaultSpeciesSet, neat.DefaultStagnation,
                             'config-neat')
        with open('winner-feedforward', 'rb') as f:
            winner = pickle.load(f)
        self.net = neat.nn.FeedForwardNetwork.create(winner, config)

        #SWARM
        self.pheromones = []
        pickle.dump(self.pheromones, open("../sent_3001.txt", "wb"))
        self.straight_begin = 0
        self.straight_end = 0
        self.list_straight = []
        self.list_corner = []
        self.received = []
        self.list_average_corcer = []

    @property
    def range_finder_angles(self):
        """Iterable of 19 fixed range finder directions [deg].

        The values are used once at startup of the client to set the directions
        of range finders. During regular execution, a 19-valued vector of track
        distances in these directions is returned in ``state.State.tracks``.
        """
        return -90, -75, -60, -45, -30, -20, -15, -10, -5, 0, 5, 10, 15, 20, \
            30, 45, 60, 75, 90

    def on_shutdown(self):
        """
        Server requested driver shutdown.

        Optionally implement this event handler to clean up or write data
        before the application is stopped.
        """
        if self.data_logger:
            self.data_logger.close()
            self.data_logger = None

    def update_history_seq_len(self, output, carstate):

        # Roll the sequence so the last history is now at front
        throwaway = self.input_sequence[0]
        keep = self.input_sequence[1:]
        self.input_sequence = torch.cat((keep, throwaway.view(1, -1)), 0)

        #Overwrite old values with new prediction and carstate
        self.input_sequence[-1][0] = self.pred[0]
        self.input_sequence[-1][1] = self.pred[1]
        self.input_sequence[-1][2] = self.pred[2]
        self.input_sequence[-1][3] = carstate.speed_x * 3.6
        self.input_sequence[-1][4] = carstate.distance_from_center
        self.input_sequence[-1][5] = carstate.angle

        for index, edge in enumerate(carstate.distances_from_edge):
            self.input_sequence[-1][6 + index] = edge

    def make_input(self, carstate, out):
        inputs = [carstate.rpm / 10000, carstate.speed_x / 100, out[0], out[1]]
        return inputs

    def update_state(self, pred, carstate):

        # # Roll the sequence so the last history is now at front
        # throwaway = self.input_sequence[0]
        # print(self.input_sequence.shape)

        state_t_plus = torch.FloatTensor(D_in)
        # print(state_t_plus)
        # sys.exit()
        #Overwrite old values with new prediction and carstate
        # print('[BEFORE]')
        # print(state_t_plus[0][2])
        # sys.exit()

        state_t_plus[0] = pred.data[0]
        state_t_plus[1] = pred.data[1]
        state_t_plus[2] = pred.data[2]
        state_t_plus[3] = carstate.speed_x * 3.6
        state_t_plus[4] = carstate.distance_from_center
        state_t_plus[5] = carstate.angle

        for index, edge in enumerate(carstate.distances_from_edge):
            state_t_plus[6 + index] = edge
        return state_t_plus

    def update_history(self, carstate):
        # Roll the sequence so the last history is now at front
        self.history = np.roll(self.history, 1)
        self.history[0][0] = carstate.distance_from_start

    def detect_crash(self):
        if (self.history[0][0] - self.history[-1][0] < 0.2):
            self.crashCounter += 1
        else:
            self.crashCounter = 0

        if self.crashCounter > 100:
            self.crashed = True
            self.crashCounter = 0

    def check_back_on_track(self, carstate):
        if self.reverseCounter < 200:
            # print(abs(carstate.distance_from_center))

            if abs(carstate.distance_from_center) < 0.5 and abs(
                    carstate.angle) < 45:
                # print(abs(carstate.angle))
                # print("-------------Found center!")
                self.crashed = False
                self.forwardCounter = 250
                self.reverseCounter = 0
            else:
                self.reverseCounter += 1
        else:
            # print("---------------ReverseCounter Finished!")
            self.crashed = False
            self.forwardCounter = 250
            self.reverseCounter = 0

    def check_for_corner(self, steering, distance_from_start):
        begin_corner = 0
        if steering > 0.4 or steering < -0.4:
            self.list_corner.append(distance_from_start)
            self.list_average_corcer.append(steering)
        else:
            if len(self.list_corner) > 25:
                average = np.average(np.asarray(self.list_average_corcer))
                begin_corner = self.list_corner[0]
                print(average)
            self.list_corner = []
        return begin_corner

    def check_for_acceleration(self, steering, distance_from_start):
        begin_accel = 0
        end_accel = 0
        if steering > -0.05 and steering < 0.05:
            self.list_straight.append((steering, distance_from_start))
        else:
            if len(self.list_straight) > 500:
                begin_accel = self.list_straight[0][1]
                end_accel = self.list_straight[-1][1] - 100
                if begin_accel > end_accel:

                    self.pheromones.append(("Accel", begin_accel, 100000))
                    self.begin_accel = 0
                self.list_straight = []

        return begin_accel, end_accel

    def check_for_info(self, received, distance_from_start, carspeed):
        for info in received:
            #if info[0] == "Accel" and distance_from_start > info[1] + 75  and distance_from_start < info[2] - 30:
            #return 360, 1, 0, None
            if info[0] == "Corner" and distance_from_start > info[
                    1] - 75 and distance_from_start < info[1] - 20:
                if carspeed * 3.6 < 135:
                    return 135, 0.6, 0, None
                return 135, 0, 0.6, 0
        return None, None, None, None

    def drive(self, carstate: State) -> Command:
        command = Command()
        out = self.model(Variable(self.input))
        self.input = self.update_state(out, carstate)

        # If crashed -> reversing
        if self.crashed:
            self.check_back_on_track(carstate)

            command.accelerator = 0.5
            command.gear = -1

            # Only steer if incorrect angle and off track
            if abs(carstate.angle) > 20 and abs(
                    carstate.distance_from_center) < 1:

                # If car orientated towards the right
                if carstate.angle > 0:

                    # Steer to right while reversing
                    command.steering = -1
                    # self.forward_steer_direction = 1
                    self.forward_steer_direction = 0.5

                else:
                    # Steer to left while reversing
                    command.steering = 1

                    # else:
                    # Steer to right while reversing
                    # command.steering = -1
                    # self.forward_steer_direction = 1
                    self.forward_steer_direction = -0.5

            # command.steering = 1
            # self.forwardCounter -= 1
            self.resetGear = True

        elif self.forwardCounter > 0:
            # print("Turning to correct direction")
            if self.forwardCounter > 200:
                command.brake = 1

            # if abs(carstate.angle) > :
            if carstate.angle > 0:
                command.steering = 0.5
            else:
                command.steering = -0.5
            # command.steering = self.forward_steer_direction
            command.accelerator = 0.5
            command.gear = 1
            self.forwardCounter -= 1

        # Normal behaviour
        else:

            out = self.model(Variable(self.input))

            self.input = self.update_state(out, carstate)
            self.update_history(carstate)
            self.detect_crash()

            command.accelerator = out.data[0]
            command.brake = out.data[1]
            command.steering = out.data[2]

            begin_corner = self.check_for_corner(command.steering,
                                                 carstate.distance_from_start)
            begin_acceleration, end_acceleration = self.check_for_acceleration(
                command.steering, carstate.distance_from_start)
            if begin_corner > 0:
                self.pheromones.append(("Corner", begin_corner))
            if begin_acceleration > 0:
                self.pheromones.append(
                    ("Accel", begin_acceleration, end_acceleration))
            if self.counter % 50 == 0:
                pickle.dump(self.pheromones, open("../sent_3001.txt", "wb"))
                if os.path.isfile("../sent_3001.txt"):
                    self.received = pickle.load(open("../sent_3001.txt", "rb"))
            v_x = 500

            max_speed, accel, brake, steer = self.check_for_info(
                self.received, carstate.distance_from_start, carstate.speed_x)
            if max_speed is not None:
                v_x = max_speed
                command.accelerator = accel
                command.brake = brake
                if steer == 0:
                    command.steering = steer

            #command.gear = self.get_gear(carstate)  USE NEAT TO SHIFT GEARS

            self.accelerate(carstate, v_x, command)
            if self.resetGear:
                #command.gear = self.get_gear(carstate)
                self.resetGear = False

            if carstate.speed_x * 3.6 < 20:
                command.brake = 0

        self.counter += 1

        self.input[2] = command.accelerator
        return command

    def get_gear(self, carstate):
        output = self.net.activate([carstate.rpm / 10000])

        # convert the outcome into a command
        command = Command()
        if (output[0] < -0.5):
            gear = carstate.gear - 1
        elif (output[0] > 0.5):
            gear = carstate.gear + 1
        else:
            gear = carstate.gear
        if gear < 1:
            gear = 1
        if gear > 6:
            gear = 6
        return gear

    def accelerate(self, carstate, target_speed, command):
        # compensate engine deceleration, but invisible to controller to
        # prevent braking:
        speed_error = 1.0025 * target_speed * MPS_PER_KMH - carstate.speed_x
        acceleration = self.acceleration_ctrl.control(
            speed_error, carstate.current_lap_time)

        # stabilize use of gas and brake:
        acceleration = math.pow(acceleration, 3)

        if acceleration > 0:
            if abs(carstate.distance_from_center) >= 1:
                # off track, reduced grip:
                acceleration = min(0.4, acceleration)

            command.accelerator = min(acceleration, 1)
            if carstate.rpm > 8000:
                command.gear = carstate.gear + 1

        # else:
        #     command.brake = min(-acceleration, 1)

        if carstate.rpm < 4000:
            command.gear = carstate.gear - 1

        if not command.gear:
            command.gear = carstate.gear or 1

    def steer(self, carstate, target_track_pos, command):
        steering_error = target_track_pos - carstate.distance_from_center
        command.steering = self.steering_ctrl.control(
            steering_error, carstate.current_lap_time)
class UnstuckLayer4(Layer):
    def __init__(self, ):
        super(UnstuckLayer4, self).__init__()

        self.stuck_count = 0
        self.instantiatePIDControllers()

        self.attempts = 0
        self.attempts_limit = 100

        self.last_applicable = False

        self.last_action = 0  # 1: forward, 2: backward
        self.time_threshold = 30

    def instantiatePIDControllers(self):
        self.steering_ctrl = CompositeController(
            ProportionalController(-0.5),
            IntegrationController(-0.1, integral_limit=1),
            DerivativeController(-1))
        self.reverse_ctrl = CompositeController(
            ProportionalController(3.7),
            # IntegrationController(0.1, integral_limit=1.5),
            # DerivativeController(0.5)
        )

        self.forward_ctrl = CompositeController(
            ProportionalController(3.7),
            # IntegrationController(0.1, integral_limit=1.5),
            # DerivativeController(0.5)
        )

    def update(self, carstate: State):
        # min_dist = min(carstate.distances_from_edge)
        v = get_projected_speed(carstate.speed_x, carstate.speed_y,
                                carstate.angle)
        if v < 5 or (carstate.speed_x < 0
                     and carstate.gear == -1):  # and min_dist < 4
            self.stuck_count += 1
        else:
            self.stuck_count = 0

    def applicable(self, carstate: State):

        self.update(carstate)
        min_dist = min(carstate.distances_from_edge)

        if math.fabs(carstate.distance_from_center) > 1.2:
            result = True
        elif min_dist < 3 and math.fabs(carstate.distance_from_center) > 0.6:
            result = self.stuck_count > self.time_threshold
        else:
            result = self.stuck_count > 3 * self.time_threshold

        if not result:
            print(self.stuck_count / self.time_threshold, '% getting stuck')

        if not self.last_applicable and result:
            self.steering_ctrl.reset()
            self.forward_ctrl.reset()
            self.reverse_ctrl.reset()
            self.attempts = 0

        self.last_applicable = result
        return result

    def step(self, carstate: State, command: Command):

        if math.fabs(self.attempts) >= self.attempts_limit:
            self.attempts = 0  # -1 * self.attempts_limit
            self.last_action = 0

        position = np.sign(carstate.distance_from_center) * carstate.angle

        dist = carstate.distance_from_center

        threshold = 0.8
        slope = 3

        action = self.last_action

        if math.fabs(dist) <= threshold:
            target_angle = 0
        else:
            target_angle = np.arctan(
                slope * (dist - threshold * np.sign(dist))) * 180.0 / math.pi

        print('Target angle =', target_angle)

        if math.fabs(carstate.angle) > 165:
            if self.attempts >= 0:
                print('WRONG DIRECTION! GO FORWARD!', self.attempts)
                self.forward(carstate, 70, command)
            else:
                print('WRONG DIRECTION! GO BACKWARD!', self.attempts)
                self.reverse(carstate, -40, command)

            self.steer(carstate, 0, command)
        else:

            if carstate.speed_x >= 2 and math.fabs(
                    carstate.angle) < 30 and math.fabs(dist) < 1.2:
                print("LET'S GO FORWARD!")
                self.forward(carstate, 100, command)
                self.steer(carstate, target_angle, command)
            elif (position >= -20 and
                  self.attempts >= 0) or (carstate.distances_from_edge[9] > 5
                                          and math.fabs(carstate.angle) < 100):
                print('GO FORWARD!', self.attempts)
                self.forward(carstate, 80, command)
                self.steer(carstate, target_angle, command)
            else:
                print('GO BACKWARD!', self.attempts)
                self.reverse(carstate, -50, command)
                self.steer(carstate, -1 * target_angle, command)

            if math.fabs(carstate.speed_x) < 3:
                self.attempts += self.last_action

            if action * self.last_action < 0:
                self.stuck_count = 0

            if command.gear * carstate.gear < 0:
                self.steering_ctrl.reset()

            return True

    def forward(self, carstate, target_speed, command):

        self.last_action = 1
        command.gear = 1

        if not carstate.gear or carstate.gear <= 0:
            self.forward_ctrl.reset()

        if carstate.speed_x < -2:
            command.accelerator = 0
            command.brake = 1
        else:
            # compensate engine deceleration, but invisible to controller to
            # prevent braking:
            speed_error = 1.0025 * target_speed * MPS_PER_KMH - carstate.speed_x
            # get_projected_speed(carstate.speed_x, carstate.speed_y,carstate.angle)

            acceleration = self.forward_ctrl.control(speed_error,
                                                     carstate.current_lap_time)

            # stabilize use of gas and brake:
            acceleration = math.pow(acceleration, 3)

            if acceleration > 0:
                # if abs(carstate.distance_from_center) >= 1:
                #     # off track, reduced grip:
                #     acceleration = min(0.4, acceleration)
                command.accelerator = min(acceleration, 1)
            else:
                command.brake = min(-acceleration, 1)

    def reverse(self, carstate, target_speed, command):

        if carstate.gear >= 0:
            self.reverse_ctrl.reset()

        command.gear = -1

        self.last_action = -1

        if carstate.speed_x > 2:
            command.accelerator = 0
            command.brake = 1
        else:
            # compensate engine deceleration, but invisible to controller to
            # prevent braking:
            speed_error = 1.0025 * target_speed * MPS_PER_KMH - carstate.speed_x

            acceleration = self.reverse_ctrl.control(speed_error,
                                                     carstate.current_lap_time)

            # stabilize use of gas and brake:
            acceleration = math.pow(acceleration, 3)

            acceleration *= -1

            if acceleration > 0:
                # if abs(carstate.distance_from_center) >= 1:
                #     # off track, reduced grip:
                #     acceleration = min(0.4, acceleration)

                command.accelerator = min(acceleration, 1)

            else:
                command.brake = min(-acceleration, 1)

    def steer(self, carstate, target_angle, command):

        steering_error = target_angle - carstate.angle
        command.steering = np.sign(command.gear) * self.steering_ctrl.control(
            steering_error, carstate.current_lap_time)
        command.steering = max(-1, min(command.steering, 1))
Beispiel #19
0
class MyDriver(Driver):
    def __init__(self, logdata=True):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None

        # Setup the PyTorch model and load the weights
        self.model = simpleNetV3()
        weights = 'simpleNetV3_lr=0.01_epoch_1_all_tracks.csv.pkl'
        self.model.load_state_dict(torch.load(weights))

        # Initialize inputs, counters and history
        self.input = torch.zeros(D_in)
        self.crashCounter = 0
        self.reverseCounter = 0
        self.forwardCounter = 0
        self.resetGear = False
        self.crashed = False
        self.counter = 0
        self.name = '3001'
        self.history = np.zeros((5, 2), dtype=float)

        # Initialize SWARM
        self.pheromones = []
        pickle.dump(self.pheromones, open("sent_3001.txt", "wb"))
        self.straight_begin = 0
        self.straight_end = 0
        self.list_straight = []
        self.list_corner = []
        self.received = []
        self.list_average_corner = []

    @property
    def range_finder_angles(self):
        """Iterable of 19 fixed range finder directions [deg].

        The values are used once at startup of the client to set the directions
        of range finders. During regular execution, a 19-valued vector of track
        distances in these directions is returned in ``state.State.tracks``.
        """
        return -90, -75, -60, -45, -30, -20, -15, -10, -5, 0, 5, 10, 15, 20, \
            30, 45, 60, 75, 90

    def on_shutdown(self):
        """
        Server requested driver shutdown.

        Optionally implement this event handler to clean up or write data
        before the application is stopped.
        """
        if self.data_logger:
            self.data_logger.close()
            self.data_logger = None

    # Create new input for the network with predicted values and carstate
    def update_state(self, pred, carstate):

        # Create empty vector
        state_t_plus = torch.FloatTensor(D_in)

        # Fill with predicted values and carstate
        state_t_plus[0] = pred.data[0][0]
        state_t_plus[1] = pred.data[0][1]
        state_t_plus[2] = pred.data[0][2]
        state_t_plus[3] = carstate.speed_x * 3.6
        state_t_plus[4] = carstate.distance_from_center
        state_t_plus[5] = carstate.angle

        for index, edge in enumerate(carstate.distances_from_edge):
            state_t_plus[6 + index] = edge

        return state_t_plus

    # Update the distance_from_start history
    def update_history(self, carstate):
        # Roll the sequence so the last history is now at front
        self.history = np.roll(self.history, 1)
        self.history[0][0] = carstate.distance_from_start

    # Checks if distance_from_start in the last 5 ticks increased less than 0.2 meters,
    # if so, adds one to the crashCounter.
    # Once the crashCounter reaches 100, sets crashed to true which starts auto-reset behaviour
    def detect_crash(self):
        # Check if not standing still or moving really slowly
        if (self.history[0][0] - self.history[-1][0] < 0.2):
            self.crashCounter += 1
        else:
            self.crashCounter = 0

        # Activate auto-reset behaviour
        if self.crashCounter > 100:
            self.crashed = True
            self.crashCounter = 0

    # Checks whether the car is back on track and has the correct angle.
    # If after 200 ticks still not back on track, start driving forward
    def check_back_on_track(self, carstate):
        if self.reverseCounter < 200:

            # Check back on track with correct angle, if correct activate forward counter
            if abs(carstate.distance_from_center) < 0.5 and abs(
                    carstate.angle) < 45:
                self.crashed = False
                self.forwardCounter = 250
                self.reverseCounter = 0
            else:
                self.reverseCounter += 1
        # Reversecounter finished, so start moving in forward direction
        else:
            self.crashed = False
            self.forwardCounter = 250
            self.reverseCounter = 0

    # Detects sharp corners by checking if the steering angle is more than 0.4 for 25 ticks
    def check_for_corner(self, steering, distance_from_start):
        begin_corner = 0

        # Check if steering angle is more than 0.4 in either direction
        if steering > 0.4 or steering < -0.4:
            self.list_corner.append(distance_from_start)
            self.list_average_corner.append(steering)
        else:
            # Check if steering sharply for more than 25 ticks
            if len(self.list_corner) > 25:
                average = np.average(np.asarray(self.list_average_corner))
                begin_corner = self.list_corner[0]
                print(average)
            self.list_corner = []
        return begin_corner

    # Checks for pheromones placed on track, if 20 meters ahead, start braking
    def check_for_info(self, received, distance_from_start, carspeed):
        for info in received:
            if info[0] == "Corner" and distance_from_start > info[
                    1] - 75 and distance_from_start < info[1] - 20:
                if carspeed * 3.6 < 135:
                    return 135, 0.6, 0, None
                return 135, 0, 0.6, 0
        return None, None, None, None

    # Returns appropriate commands for the car, depending on the currenst carstate
    def drive(self, carstate: State) -> Command:
        command = Command()

        # If crashed, reverse
        if self.crashed:
            self.check_back_on_track(carstate)

            command.accelerator = 0.5
            command.gear = -1

            # Only steer if incorrect angle and off track
            if abs(carstate.angle) > 20 and abs(
                    carstate.distance_from_center) < 1:

                # If car orientated towards the right
                if carstate.angle > 0:

                    # Steer to right while reversing
                    command.steering = -1
                    self.forward_steer_direction = 0.5

                # Car orientated towards left
                else:
                    # Steer to left while reversing
                    command.steering = 1
                    self.forward_steer_direction = -0.5

            self.resetGear = True

        # If forwardCounter is activated, drive forward, steering in the correct direction
        elif self.forwardCounter > 0:

            # Start by braking
            if self.forwardCounter > 200:
                command.brake = 1

            # Then drive forward steering in the correct direction
            if carstate.angle > 0:
                command.steering = 0.5
            else:
                command.steering = -0.5

            command.accelerator = 0.5
            command.gear = 1

            self.forwardCounter -= 1

        # Normal behaviour
        else:
            # Run input through model to predict next commands
            out = self.model(Variable(self.input))
            self.input = self.update_state(out, carstate)

            self.update_history(carstate)
            self.detect_crash()

            # Create command with predictions
            command.accelerator = out.data[0][0]
            command.brake = out.data[0][1]
            command.steering = out.data[0][2]

            # Check for corners, if found, place pheromones
            begin_corner = self.check_for_corner(command.steering,
                                                 carstate.distance_from_start)

            if begin_corner > 0:
                self.pheromones.append(("Corner", begin_corner))

            # Save pheromones to file
            if self.counter % 50 == 0:
                pickle.dump(self.pheromones, open("sent_3001.txt", "wb"))
                if os.path.isfile("sent_3001.txt"):
                    self.received = pickle.load(open("sent_3001.txt", "rb"))

            # Maximum target speed
            v_x = 500

            # Use information from pheromones
            max_speed, accel, brake, steer = self.check_for_info(
                self.received, carstate.distance_from_start, carstate.speed_x)
            if max_speed is not None:
                v_x = max_speed
                command.accelerator = accel
                command.brake = brake
                if steer == 0:
                    command.steering = steer

            self.accelerate(carstate, v_x, command)
            if self.resetGear:
                self.resetGear = False

            # Prevent the car from braking when driving slowly, causing it to get stuck when off track
            if carstate.speed_x * 3.6 < 20:
                command.brake = 0

        self.counter += 1

        self.input[2] = command.accelerator
        return command

    def get_gear(self, carstate):
        output = self.net.activate([carstate.rpm / 10000])

        # convert the outcome into a command
        command = Command()
        if (output[0] < -0.5):
            gear = carstate.gear - 1
        elif (output[0] > 0.5):
            gear = carstate.gear + 1
        else:
            gear = carstate.gear
        if gear < 1:
            gear = 1
        if gear > 6:
            gear = 6
        return gear

    def accelerate(self, carstate, target_speed, command):
        # compensate engine deceleration, but invisible to controller to
        # prevent braking:
        speed_error = 1.0025 * target_speed * MPS_PER_KMH - carstate.speed_x
        acceleration = self.acceleration_ctrl.control(
            speed_error, carstate.current_lap_time)

        # stabilize use of gas and brake:
        acceleration = math.pow(acceleration, 3)

        if acceleration > 0:
            if abs(carstate.distance_from_center) >= 1:
                # off track, reduced grip:
                acceleration = min(0.4, acceleration)

            command.accelerator = min(acceleration, 1)
            if carstate.rpm > 8000:
                command.gear = carstate.gear + 1

        # else:
        #     command.brake = min(-acceleration, 1)

        if carstate.rpm < 4000:
            command.gear = carstate.gear - 1

        if not command.gear:
            command.gear = carstate.gear or 1
Beispiel #20
0
class MyDriver:
    """
    Driving logic.

    Implement the driving intelligence in this class by processing the current
    car state as inputs creating car control commands as a response. The
    ``drive`` function is called periodically every 20ms and must return a
    command within 10ms wall time.
    """
    def __init__(self, logdata=True, models=None, explore=0.9, optimizer=None):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2))
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7), )
        self.data_logger = DataLogWriter() if logdata else None

        # Algorithm variables
        self.previous_state = None
        if os.path.isfile("memory.txt") == True:
            with open("memory.txt", "rb") as fp:
                self.replay_memory = pickle.load(fp)
        else:
            self.replay_memory = []
        # Maximum size of the replay memory
        self.max_RM_size = 100000
        self.model, self.target = models
        self.criterion = torch.nn.MSELoss()
        self.model_optim = optimizer
        self.restart = False
        # Discretize the action space
        self.action_space = [
            0.9, 0.7, 0.5, 0.4, 0.3, 0.2, 0.1, 0, -0.1, -0.2, -0.3, -0.4, -0.5,
            -0.7, -0.9
        ]
        self.action = 0
        self.reward = 0

        # Model that is used for accelerating and braking
        self.model_acc_brake = simpleNetV2()

        self.pheromones = []
        # self.receiver = Receiver(6001)

        weights = 'simpleNetV2_epoch_3_all_tracks.csv.pkl'

        self.model_acc_brake.load_state_dict(torch.load(weights))
        self.input = torch.zeros(D_in)

        # STATS
        if os.path.isfile("counter.txt") == True:
            with open("counter.txt", "rb") as fp:
                self.counter = pickle.load(fp)
        else:
            self.counter = 0
        self.counter_per_game = 0
        self.train_counter = 0
        self.average_reward = 0
        self.average_loss = 0

        # Hyperparameters
        self.exploration_rate = explore
        self.batch_size = 128
        self.gamma = 0.99

    @property
    def range_finder_angles(self):
        """Iterable of 19 fixed range finder directions [deg].

        The values are used once at startup of the client to set the directions
        of range finders. During regular execution, a 19-valued vector of track
        distances in these directions is returned in ``state.State.tracks``.
        """
        return -90, -75, -60, -45, -30, -20, -15, -10, -5, 0, 5, 10, 15, 20, \
            30, 45, 60, 75, 90

    def on_shutdown(self):
        """
        Server requested driver shutdown.

        Optionally implement this event handler to clean up or write data
        before the application is stopped.
        """
        if self.data_logger:
            self.data_logger.close()
            self.data_logger = None

    def get_state(self, carstate):
        state = np.zeros(26)
        state[0] = carstate.speed_x
        state[1] = carstate.speed_y
        state[2] = carstate.speed_z
        state[3] = carstate.damage
        state[4] = carstate.distance_from_center
        state[5] = carstate.angle * (np.pi / 180)
        state[6] = carstate.z
        for index, edge in enumerate(carstate.distances_from_edge):
            state[7 + index] = edge
        return state

    def get_action(self, carstate, state):
        probability = np.random.uniform()
        if probability < self.exploration_rate:
            temp_action = self.steer(carstate, 0)
            action = (
                np.absolute(np.asarray(self.action_space) - temp_action)
            ).argmin()  # Pick the action that is closest to mediocre model

            if np.random.uniform() > 0.75:
                action = np.random.randint(0, len(self.action_space))
        else:
            state = torch.from_numpy(np.array(state))
            action = self.model(
                Variable(state, volatile=True).type(torch.FloatTensor)).data
            action = np.argmax(action.numpy())
        return action

    def get_reward(self, carstate):
        #Reward function that is based on optimizing the speed in the right direction and minimizing the speed is wrong direction
        return carstate.speed_x * (
            np.cos(carstate.angle * (np.pi / 180)) -
            np.absolute(np.sin(carstate.angle * (np.pi / 180)))) - np.absolute(
                carstate.distance_from_center)

    def print_stats(self):
        print("The average reward is: ", self.average_reward / self.counter)
        print("The average  loss is: ", self.average_loss / self.train_counter)

    def update_state(self, pred, carstate):

        # # Roll the sequence so the last history is now at front
        # throwaway = self.input_sequence[0]
        # print(self.input_sequence.shape)

        state_t_plus = torch.FloatTensor(D_in)
        # print(state_t_plus)
        # sys.exit()
        #Overwrite old values with new prediction and carstate
        # print('[BEFORE]')
        # print(state_t_plus[0][2])
        # sys.exit()

        state_t_plus[0] = pred.data[0]
        state_t_plus[1] = pred.data[1]
        state_t_plus[2] = pred.data[2]
        state_t_plus[3] = carstate.speed_x * 3.6
        state_t_plus[4] = carstate.distance_from_center
        state_t_plus[5] = carstate.angle

        for index, edge in enumerate(carstate.distances_from_edge):
            state_t_plus[6 + index] = edge
        return state_t_plus

    def drive(self, carstate: State) -> Command:
        #Get current state
        state = self.get_state(carstate)

        # Get current action
        action = self.get_action(carstate, state)

        # Get current reward
        reward = self.get_reward(carstate)

        # Keep track of the average reward
        self.average_reward += reward

        if self.counter > 0:
            self.replay_memory.append(
                (self.previous_state, self.action, reward, state, False))
            # Check if replay memory is full
            while len(self.replay_memory) > self.max_RM_size:
                del self.replay_memory[np.random.randint(
                    0, len(self.replay_memory))]

        command = Command()
        # Predict brake and accelerate
        out = self.model_acc_brake(Variable(self.input))

        self.input = self.update_state(out, carstate)

        #Create command
        command = Command()
        command.brake = out.data[1] * 0.2

        # Maximum speed for training,
        v_x = 300
        self.counter += 1
        self.counter_per_game += 1
        self.accelerate(carstate, v_x, command)
        command.steering = self.action_space[action]

        self.action = action
        self.previous_state = state
        if carstate.damage > 0 or carstate.last_lap_time > 0:
            command.meta = 1
            # Add terminal states to the replay memory
            if carstate.damage > 0:
                self.replay_memory.append(
                    (self.previous_state, self.action, -100, np.ones(
                        (26, )), True))
            else:
                self.replay_memory.append(
                    (self.previous_state, self.action, 1000, np.ones(
                        (26, )), True))
            self.save_variables()
            print("distance:, ", carstate.distance_from_start)
            print(
                "------------------------------------------------------------------------------"
            )

            if self.exploration_rate == 0:

                print("TEST DRIVE AVERAGE REWARD IS: ",
                      self.average_reward / self.counter_per_game)
                print("THE DISTANCE DRIVEN BY THE AGENT IS: ",
                      carstate.distance_from_start)
                print("EPISODE ENDED")
                print(
                    "------------------------------------------------------------------------------"
                )
        return command

    def save_variables(self):
        with open("memory.txt", "wb") as fp:  # save the Replay Memory
            pickle.dump(self.replay_memory, fp)

    def accelerate(self, carstate, target_speed, command):
        # compensate engine deceleration, but invisible to controller to
        # prevent braking:
        speed_error = 1.0025 * target_speed * MPS_PER_KMH - carstate.speed_x
        acceleration = self.acceleration_ctrl.control(
            speed_error, carstate.current_lap_time)

        # stabilize use of gas and brake:
        acceleration = math.pow(acceleration, 3)

        if acceleration > 0:
            if abs(carstate.distance_from_center) >= 1:
                # off track, reduced grip:
                acceleration = min(0.4, acceleration)

            command.accelerator = min(acceleration, 1)

            if carstate.rpm > 8000:
                command.gear = carstate.gear + 1

        # else:
        #     command.brake = min(-acceleration, 1)

        if carstate.rpm < 2500:
            command.gear = carstate.gear - 1

        if not command.gear:
            command.gear = carstate.gear or 1
        if command.gear < 1:
            command.gear = 1

    def steer(self, carstate, target_track_pos):
        steering_error = target_track_pos - carstate.distance_from_center
        steering = self.steering_ctrl.control(steering_error,
                                              carstate.current_lap_time)
        return steering
Beispiel #21
0
class TestNeatDriver:
    """
    Driving logic.

    Implement the driving intelligence in this class by processing the current
    car state as inputs creating car control commands as a response. The
    ``drive`` function is called periodically every 20ms and must return a
    command within 10ms wall time.
    """

    def __init__(self, logdata=True, net=None):
        self.steering_ctrl = CompositeController(
            ProportionalController(0.4),
            IntegrationController(0.2, integral_limit=1.5),
            DerivativeController(2)
        )
        self.acceleration_ctrl = CompositeController(
            ProportionalController(3.7),
        )
        self.data_logger = DataLogWriter() if logdata else None
        self.eta = 20
        self.counter = 0
        self.model = simpleNetV2()
        self.weights = 'simpleNetV2_epoch_3_all_tracks.csv.pkl'

        self.model.load_state_dict(torch.load(self.weights))
        self.input = torch.FloatTensor(D_in)
        self.track_check1 = False
        self.track_check2 = False
        self.action_neat = None
        self.net = net
        self.clock = time.time()
        self.done = False
        self.temp_fitness = 0



    @property
    def range_finder_angles(self):
        """Iterable of 19 fixed range finder directions [deg].

        The values are used once at startup of the client to set the directions
        of range finders. During regular execution, a 19-valued vector of track
        distances in these directions is returned in ``state.State.tracks``.
        """
        return -90, -75, -60, -45, -30, -20, -15, -10, -5, 0, 5, 10, 15, 20, \
            30, 45, 60, 75, 90

    def on_shutdown(self):
        """
        Server requested driver shutdown.

        Optionally implement this event handler to clean up or write data
        before the application is stopped.
        """
        if self.data_logger:
            self.data_logger.close()
            self.data_logger = None

    def make_input(self, carstate, out):
        inputs = []
        inputs.extend([carstate.angle, carstate.speed_x])
        inputs.extend(out[0], out[1])
        return inputs

    def update_state(self, pred, carstate):
        
        # # Roll the sequence so the last history is now at front
        # throwaway = self.input_sequence[0]
        # print(self.input_sequence.shape)
        
        state_t_plus = torch.FloatTensor(D_in)
        # print(state_t_plus)
        # sys.exit()
        #Overwrite old values with new prediction and carstate
        # print('[BEFORE]')
        # print(state_t_plus[0][2])
        # sys.exit()

        state_t_plus[0] = pred.data[0]
        state_t_plus[1] = pred.data[1]
        state_t_plus[2] = pred.data[2]
        state_t_plus[3] = carstate.speed_x *3.6
        state_t_plus[4] = carstate.distance_from_center
        state_t_plus[5] = carstate.angle

        for index, edge in enumerate(carstate.distances_from_edge):
            state_t_plus[6 + index] = edge
        return state_t_plus

    def drive(self, carstate: State) -> Command:
        """
        Produces driving command in response to newly received car state.

        This is a dummy driving routine, very dumb and not really considering a
        lot of inputs. But it will get the car (if not disturbed by other
        drivers) successfully driven along the race track."""

        global net
        out = self.model(Variable(self.input))
        
        self.input = self.update_state(out, carstate)

        inputs = self.make_input(carstate, out.data)           

        if self.track_check1 == True and self.check_offtrack(carstate) == True:
            self.track_check2 = True

        if self.counter % 100 == 0:
            self.track_check1 = self.check_offtrack(carstate)

        self.temp_fitness += carstate.speed_x * (np.cos(carstate.angle*(np.pi/180)) - np.absolute(np.sin(carstate.angle * (np.pi/180))))
        self.counter += 1


        outputs = net.activate(inputs)


        command = Command()
        command.accelerator = outputs[0]
        command.brake = outputs[1]
        command.steering = outputs[2]
        v_x = 350
        self.counter += 1

        self.accelerate(carstate, v_x, command)

        if self.data_logger:
            self.data_logger.log(carstate, command)
        
        if carstate.damage >= 9500 or carstate.last_lap_time > 0 or carstate.current_lap_time > 60:
            positions_won = 10 - carstate.race_position 
            damage = (carstate.damage) / 1000
            global fitness
            fitness = self.eta + (self.temp_fitness/self.counter) + positions_won - damage 
            command.meta = 1
        return command


    def check_offtrack(self, carstate):
        counter = 0
        for values in carstate.distances_from_edge:
            if values == -1:
                counter += 1
        if counter == len(carstate.distances_from_edge):
            return True
        else: 
            return False


    def accelerate(self, carstate, target_speed, command):
        # compensate engine deceleration, but invisible to controller to
        # prevent braking:
        speed_error = 1.0025 * target_speed * MPS_PER_KMH - carstate.speed_x
        acceleration = self.acceleration_ctrl.control(
            speed_error,
            carstate.current_lap_time
        )

        # stabilize use of gas and brake:
        acceleration = math.pow(acceleration, 3)

        if acceleration > 0:
            if abs(carstate.distance_from_center) >= 1:
                # off track, reduced grip:
                acceleration = min(0.4, acceleration)

            command.accelerator = min(acceleration, 1)

            if carstate.rpm > 8000:
                command.gear = carstate.gear + 1

        # else:
        #     command.brake = min(-acceleration, 1)

        if carstate.rpm < 2500:
            command.gear = carstate.gear - 1

        if not command.gear:
            command.gear = carstate.gear or 1

    def steer(self, carstate, target_track_pos, command):
        steering_error = target_track_pos - carstate.distance_from_center
        command.steering = self.steering_ctrl.control(
            steering_error,
            carstate.current_lap_time
        )