def step(self, carstate: State, command: Command): if self.front_stuck > 15: d = min(carstate.distances_from_edge) command.accelerator = max(0, min(1, 1.3 - 0.7 * d)) command.gear = -1 command.brake = 0.0 command.clutch = 0.0 command.steering = -1 * carstate.angle * np.pi / (180.0 * 0.785398) else: if carstate.speed_x < 3: command.gear = 1 if carstate.rpm > 8000: command.gear = min(6, command.gear + 1) if carstate.rpm < 2500: command.gear = command.gear - 1 if command.gear <= 0: command.gear = 1 command.accelerator = 1 command.gear = 1 if carstate.gear <= 0 else carstate.gear command.brake = 0.0 command.clutch = 0.0 command.steering = carstate.angle * np.pi / (180.0 * 0.785398) command.steering -= 0.35 * np.sign( carstate.distance_from_center) * min( 1.5, math.fabs(carstate.distance_from_center)) return True
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 drive(self, carstate): command = Command() command.steering = carstate.angle / 180 if carstate.angle > 30 or carstate.angle < -30: command.brake = 0.5 command.accelerator = 0 else: command.brake = 0 command.accelerator = 1 command.gear = 1 return command
def recovery_drive(self, carstate): ''' Recovery driving behaviour ''' ANGLE_THRESHOLD = 10 BRAKING_CENTER_TRACK_THRESHOLD = 0.1 command = Command() self.epochs_unmoved = 0 print("Recovery") if np.abs(carstate.angle) > ANGLE_THRESHOLD: recovery_steering = 0.9 command.steering = recovery_steering if carstate.distance_from_center > 0 else -recovery_steering command.gear = 1 if carstate.angle * carstate.distance_from_center > 0 else -1 if carstate.distance_from_center < 0: if (carstate.speed_x < -1 and carstate.angle < 0) or (carstate.speed_x > 1 and carstate.angle > 0): if carstate.distance_from_center < -BRAKING_CENTER_TRACK_THRESHOLD: command.brake = 1 command.accelerator = 0 else: command.steering = -command.steering else: command.accelerator = 0.5 command.brake = 0 else: if (carstate.speed_x < -1 and carstate.angle > 0) or (carstate.speed_x > 1 and carstate.angle < 0): if carstate.distance_from_center > BRAKING_CENTER_TRACK_THRESHOLD: command.brake = 1 command.accelerator = 0 else: command.steering = -command.steering else: command.accelerator = 0.5 command.brake = 0 else: command.steering = -1 if carstate.distance_from_center > 0 else 1 command.accelerator = .5 command.gear = -1 # check if recovery complete if -ANGLE_THRESHOLD < carstate.angle < ANGLE_THRESHOLD: self.recovery = False print("The lord hath risen!") return command
def drive(self, carstate: State) -> Command: print('Drive') self.print_log(carstate) self.update(carstate) command = Command() command.accelerator = 1 command.gear = 1 command.brake = 0 command.steering = 0 #-1 * carstate.angle * np.pi / (180.0 * 0.785398) if carstate.speed_x > 1 and command.gear >= 0 and command.brake < 0.1 and carstate.rpm > 8000: command.gear = min(6, command.gear + 1) if carstate.rpm < 2500 and command.gear > 1: command.gear = command.gear - 1 if not command.gear: command.gear = carstate.gear or 1 return command
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() stateList = self.stateToArray(carstate) # output = self.network.activate(stateList) output = self.network.forward(stateList).data print(output) #self.steer(carstate, output[0, 2], command) command.steering = output[0, 0] command.accelerator = output[0, 1] command.brake = output[0, 2] if command.accelerator > 0: if carstate.rpm > 8000: command.gear = carstate.gear + 1 if command.accelerator < 0: if carstate.rpm < 2500: command.gear = carstate.gear - 1 if not command.gear: command.gear = carstate.gear or 1 #acceleration = output[0,1]*129 #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 output[0,0]>0.5: # ACC_LATERAL_MAX = 6400 * 5 # v_x = min(80, math.sqrt(ACC_LATERAL_MAX / abs(command.steering))) #else: # v_x = 0 #self.accelerate(carstate, 85, command) if self.data_logger: self.data_logger.log(carstate, command) return command
def step(self, carstate: State, command: Command): command.accelerator = min( 1, (carstate.distance_from_center - 0.2)**4) #2 - min(carstate.distances_from_edge) command.gear = -1 command.brake = 0.0 command.clutch = 0.0 command.steering = -1 * carstate.angle * np.pi / (180.0 * 0.785398) * 1.5 return True
def to_command(self, accelerate, steer): command = Command() if accelerate >= 0: command.accelerator = accelerate else: command.brake = abs(accelerate) command.steering = (self.prev_command.steering + steer) / 2 return command
def step(self, carstate: State, command: Command): command.accelerator = 1 command.brake = 0 command.gear = carstate.gear if command.gear >= 0 and carstate.rpm > 8000: command.gear = min(6, command.gear + 1) if carstate.rpm < 2500 and command.gear > 1: command.gear = command.gear - 1 if not command.gear: command.gear = carstate.gear or 1
def drive(self, carstate: State) -> Command: # translate carstate to tensor for NN x_in = Variable(carstate_to_tensor(carstate)) # get speed/steering target acc_break_steer_prediction = self.model(x_in).data print(acc_break_steer_prediction) # based on target, implement speed/steering manually command = Command() command.accelerator = acc_break_steer_prediction[0] command.brake = acc_break_steer_prediction[1] command.steering = acc_break_steer_prediction[2] command.gear = acc_break_steer_prediction[3] self.last_command = command return command
def runModel(self, carstate: State) -> Command: top_command = Command() if self.runStack(carstate, top_command, self.toplayers, 'TopLayers'): return top_command else: commands = [] for i, model in enumerate(self.layers): command = Command() if not self.runStack(carstate, command, model, 'model' + str(i + 1)): print( 'Error!!! No layer applicable in model{}!!!!!'.format( i + 1)) commands.append(command) weight = self.oracle.activate(self.buildFeatures(carstate)) #weight = sigmoid(weight) weights = [weight[0], 1.0 - weight[0]] print('ORACLE:', weights[0]) N = 50 s = '' for i in range(N): if i < int(weights[0] * N): s += '0' else: s += '1' print(s) command = Command() for i, w in enumerate(weight): command.accelerator = w * commands[i].accelerator * np.sign( commands[i].gear) command.brake = w * commands[i].brake command.steering = w * commands[i].steering self.shift(carstate, command) return command
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 drive(self, car_state: State) -> Command: """ Produces driving command in response to newly received car state. """ self.last_state = car_state feature_vector = self.feature_transformer.transform(car_state) steering, brake, acceleration = self.network.activate(feature_vector) # print("steering", steering) # print("brake", brake) # print("acceleration", acceleration) command = Command() command.accelerator = acceleration command.brake = brake # push steering into a [-1, 1] range command.steering = (steering * 2) - 1 if acceleration > 0: if car_state.rpm > 8000: command.gear = car_state.gear + 1 if car_state.rpm < 2500 and car_state.gear > 2: command.gear = car_state.gear - 1 if not command.gear: command.gear = car_state.gear or 1 if self.data_logger: self.data_logger.log(car_state, command) if self.call_number % 100 == 0: print(command) print(car_state.distance_raced) print(self.stop_flag.value) print() # early stopping if self.call_number > 100 and car_state.distance_raced < 10: self.stop_flag.set(True) self.call_number += 1 return command
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. """ # f = open("Test_data3.txt","a+") # f.write("\n*** "+str(carstate)+"\n") command = Command() # constructing the input x_predict = [abs(carstate.speed_x)] x_predict.append(carstate.distance_from_center) x_predict.append(carstate.angle) [x_predict.append(i) for i in carstate.distances_from_edge] x_predict = np.array(x_predict) x_predict = x_predict.reshape(1, 22) x_predict = scaler.transform(x_predict) input_sensor = tf.convert_to_tensor(data_np, np.float32) # predicting the output y_predict = output, s_prev = predict_action(x_predict, s_prev, u_z, w_z, u_r, w_r, u_h, w_h, w_out) command.accelerator = y_predict[0][0] if command.accelerator < 0: command.brake = y_predict[0][1] command.steering = y_predict[0][2] if carstate.rpm < 2500 and carstate.gear > 0: command.gear = carstate.gear - 1 elif carstate.rpm > 8000: command.gear = carstate.gear + 1 if not command.gear: command.gear = carstate.gear or 1 return command
def drive(self, carstate: State) -> Command: command = Command() speed_x = carstate.speed_x speed_y = carstate.speed_y speed_z = carstate.speed_z speed = math.sqrt(speed_x**2 + speed_y**2 + speed_z**2) track_position = carstate.distance_from_center angle = carstate.angle track_edges = carstate.distances_from_edge input_data = [speed, track_position, angle] for edge in track_edges: input_data.append(edge) input_data = np.reshape(input_data, (1, 22, 1)) # output = self.model.predict(input_data) # output = self.dense_model.predict(input_data) # output = self.lstm_model.predict(input_data) acceleration = output[0][0] brake = output[0][1] steering = output[0][2] if acceleration > 0.5: brake = 0 else: acceleration = 0 if acceleration > 0: if carstate.rpm > 8000: command.gear = carstate.gear + 1 if carstate.rpm < 2500: command.gear = carstate.gear - 1 if not command.gear: command.gear = carstate.gear or 1 command.accelerator = acceleration command.brake = brake command.steering = steering return command
def drive(self, carstate): self.it += 1 x = [carstate.angle, carstate.speed_x, carstate.speed_y, carstate.speed_z] + \ list(carstate.distances_from_edge) + \ [carstate.distance_from_center] pred_y = list(self.model.predict(x).data)[0] command = Command() command.accelerator = pred_y[0] command.brake = pred_y[1] command.steering = pred_y[2] gear_flt = pred_y[3] if self.it > 750 else self.it / 250.0 command.gear = min(5, max(1, int(gear_flt + 0.5))) print(self.it, "acc: %.2f, brk: %.2f, ste: %.2f, gea: %.2f" % (command.accelerator, command.brake, command.steering, gear_flt), end='\r') return command
def make_next_command(self, carstate): command = Command() # we switch gears manually gear = self.gear_decider(carstate) # we get the steering prediction steer_pred = self.steer_decider(carstate, steering_values=self.steering_values) # steer_pred = self.steer_decider_nn(carstate) # pedal =[-1;1], combining breaking and accelerating to one variable pedal = self.speed_decider(carstate, max_speed=self.global_max_speed) # make sure we don't drive at people opponents_deltas = list(map(sub, carstate.opponents, self.last_opponents)) steer_pred, pedal = self.deal_with_opponents(steer_pred, pedal, carstate.speed_x, carstate.distance_from_center, carstate.opponents, opponents_deltas) # disambiguate pedal with smoothing brake, accel = self.disambiguate_pedal(pedal, accel_cap=1.0, break_cap=0.75, break_max_length=5) command.brake = brake command.accelerator = accel command.steering = steer_pred command.gear = gear return command
def drive(self, carstate: State) -> Command: command = Command() current_state = state_to_vector(carstate) command_vector = self.model.take_wheel(current_state) command = vector_to_command(command_vector) command.accelerator = 1.0 command.brake = 0.0 current_gear = carstate.gear current_rpm = carstate.rpm if current_gear != self.last_gear: self.last_gear = current_gear print("Added downshift", carstate.gear) self.downshift.append(carstate.rpm) if current_gear == 0: command.gear = 1 elif current_gear == 6: command.gear = current_gear elif self.upshifts[current_gear-1] <= current_rpm: command.gear = current_gear + 1 self.last_gear = current_gear else: command.gear = current_gear if self.epoch > 2500: f = open(self.save_path + "/result.txt", 'w') if carstate.distance_raced < 20000: f.write(str(carstate.distance_raced)) print(self.downshift) else: f.write(str(0)) f.close() sys.exit() self.epoch += 1 return command
def drive(self, carstate: State) -> Command: if not self.race_started and carstate.distance_from_start < 3: self.race_started = True try: position_team = int(open("mjv_partner1.txt", 'r').read()) open("mjv_partner2.txt", 'w').write(str(carstate.race_position)) self.number = 2 self.partner = 1 except: open("mjv_partner1.txt", "w").write(str(carstate.race_position)) self.number = 1 self.partner = 2 elif self.race_started: position_other = int(open("mjv_partner{}.txt".format(self.partner), 'r').read()) open("mjv_partner{}.txt".format(self.number), "w").write(str(carstate.race_position)) if carstate.race_position > position_other: self.leader = False else: self.leader = True # print("Distance: {}".format(carstate.distance_from_start)) # Select the sensors we need for our model self.speeds.append(carstate.speed_x) command = Command() distances = list(carstate.distances_from_edge) sensors = [carstate.speed_x, carstate.distance_from_center, carstate.angle, *(carstate.distances_from_edge)] # CRASHED off_road = all(distance == -1.0 for distance in distances) standing_still = self.recovers == 0 and all(abs(s) < 1.0 for s in self.speeds[-5:]) if self.race_started and (off_road or self.recovers > 0): command = self.recover(carstate, command) # NOT CRASHED else: if carstate.gear == -1: carstate.gear = 2 if self.norm: # Sensor normalization -> ? sensors = self.normalize_sensors(sensors) # Forward pass our model y = self.model(Variable(torch.Tensor(sensors))) # Create command from model output command.accelerator = np.clip(y.data[0], 0, 1) command.brake = np.clip(y.data[1], 0, 1) command.steering = np.clip(y.data[2], -1, 1) if self.race_started and self.is_leader and carstate.distance_from_start > 50: # TODO include not leader command = self.helper.drive(command, distances, carstate) # Naive switching of gear self.switch_gear(carstate, command) # print("Accelerate: {}".format(command.accelerator)) # print("Brake: {}".format(command.brake)) # print("Steer: {}".format(command.steering)) if self.record is True: sensor_string = ",".join([str(x) for x in sensors]) + "\n" self.file_handler.write(str(y.data[0]) + "," + str(y.data[1]) + "," + str(y.data[2]) + "," + sensor_string) return command
def vector_to_command(vector): res = Command() res.accelerator = vector[0] if vector[0] > 0. else 0. res.brake = -1. * vector[0] if vector[0] < 0. else 0. res.steering = vector[1] return res
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 drive(self, carstate: State) -> Command: """ Produces driving command in response to newly received car state. """ global net # define the output out = self.model(Variable(self.input)) self.input = self.update_state(out, carstate) # code to check wheter the driver is stuck, namely if it is for a long time of track 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) # this is a previous used fitness function #self.temp_fitness += carstate.speed_x * (np.cos(carstate.angle*(np.pi/180)) - np.absolute(np.sin(carstate.angle * (np.pi/180)))) # calculate the fitness if(carstate.rpm > 8000 or carstate.rpm < 2500): reward = -1 else: reward = 1 self.temp_fitness += reward # calculate the gear with the neat network output = self.net.activate([carstate.rpm/10000]) # convert the outcome into a command command = Command() if(output[0] < -0.5): command.gear = carstate.gear - 1 elif(output[0] > 0.5): command.gear = carstate.gear + 1 else: command.gear = carstate.gear if command.gear < 1: command.gear = 1 if command.gear > 6: command.gear = 6 # Define the command with output of the other neural net command.accelerator = out.data[0] command.brake = out.data[1] command.steering = out.data[2] # update the counter self.counter += 1 # log the command if self.data_logger: self.data_logger.log(carstate, command) # If car has too much damage or max time has exceeded do a restart if carstate.damage >= 9500 or carstate.last_lap_time > 0 or carstate.current_lap_time > 120: global fitness fitness = (self.temp_fitness/self.counter) command.meta = 1 return command
def drive(self, carstate: State) -> Command: command = Command() speed_x = carstate.speed_x speed_y = carstate.speed_y speed_z = carstate.speed_z speed = math.sqrt(speed_x**2 + speed_y**2 + speed_z**2) distance = carstate.distance_from_start distance_raced = carstate.distance_raced curlaptime = carstate.current_lap_time lastlaptime = carstate.last_lap_time time = curlaptime track_position = carstate.distance_from_center angle = carstate.angle track_edges = carstate.distances_from_edge input_data = [speed, track_position, angle] for edge in track_edges: input_data.append(edge) opponents = carstate.opponents for i in range(9, len(opponents), 9): input_data.append(opponents[i]) input_data = np.reshape(input_data, (1,len(input_data))) output = self.alt_model.predict(input_data) acceleration = output[0][0] brake = output[0][1] steering = output[0][2] if acceleration > 0: if carstate.rpm > 8000: command.gear = carstate.gear + 1 if carstate.rpm < 2500: command.gear = carstate.gear - 1 if not command.gear: command.gear = carstate.gear or 1 if track_edges[9] < 130.0 and track_edges[9] > 80.0: if speed > 40: acceleration = 0 brake = 0.05 elif track_edges[9] < 80 and track_edges[9] > 40: if speed > 25: acceleration = 0 brake = 0.05 elif track_edges[9] < 40: if speed > 15: acceleration = 0 brake = 0.05 if speed > 30: acceleration = 0 brake = 0.05 command.accelerator = acceleration command.brake = brake command.steering = steering # To train: #if time > 6 and distance_raced > 80 and distance > 20: # if lastlaptime < 2: # fitness = (distance*distance)/(time*1000.) # else: # fitness = 200 # print("Stop") # print(fitness) # fi = open("fitness.p","wb") # pickle.dump(fitness, fi) # fi.close() # pyautogui.press("esc") # pyautogui.press("down") # pyautogui.press("enter") # pyautogui.press("down") # pyautogui.press("enter") # pyautogui.press("right") # pyautogui.press("enter") # pyautogui.press("enter") # pyautogui.press("enter") # pyautogui.press("up") # pyautogui.press("enter") # exit(0) #else: # fitness = 0 #print(distance) #print(fitness) #if abs(angle) >= 80: # print("Stop") # print(fitness) # fi = open("fitness.p","wb") # pickle.dump(fitness, fi) # fi.close() # pyautogui.press("esc") # pyautogui.press("enter") # exit(0) #elif time > 5 and speed < 2: # print("Stop") # print(fitness) # fi = open("fitness.p","wb") # pickle.dump(fitness, fi) # fi.close() # pyautogui.press("esc") # pyautogui.press("enter") # exit(0) #elif time > 400: # print("Stop2") # print(fitness) # fitness = 250 # fi = open("fitness.p","wb") # pickle.dump(fitness, fi) # fi.close() # pyautogui.press("esc") # pyautogui.press("enter") # exit(0) #print(track_edges[9]) #print(command) return command
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() command.meta = 0 #self.steer(carstate, 0.0, command) # ACC_LATERAL_MAX = 6400 * 5 # v_x = min(80, math.sqrt(ACC_LATERAL_MAX / abs(command.steering))) x_predict = [carstate.speed_x] x_predict.append(carstate.distance_from_center) x_predict.append(carstate.angle) [x_predict.append(i) for i in carstate.distances_from_edge] l_predict = x_predict x_predict = np.array(x_predict) x_predict = x_predict.reshape(1, 22) #x_predict = scaler.transform(x_predict) input_sensor = torch.Tensor(1, 22) for i in range(0, 22): input_sensor[0, i] = float(x_predict[0][i]) x_temp = Variable(torch.zeros(1, 22), requires_grad=False) for j in range(0, 22): x_temp.data[0, j] = input_sensor[0, j] MyDriver.network.forward(x_temp) output = MyDriver.network.output self.speed_x += carstate.speed_x * (3.6) #self.distance += carstate.distance_raced self.distance = carstate.distance_raced self.brake += abs(output.data[0, 1]) self.count += 1 command.accelerator = max(0.0, output.data[0, 0]) command.accelerator = min(1.0, command.accelerator) #command.accelerator=0.8*command.accelerator command.steering = output.data[0, 2] command.steering = max(-1, command.steering) command.steering = min(1, command.steering) if (carstate.damage > 0 or carstate.distance_raced > 6400.00 or carstate.current_lap_time > 160.00): self.msg = 'f' #print("Layer Changed "+str(MyDriver.network.layer_changed)) fitness = MyDriver.w_distance * ( self.distance) + MyDriver.w_speed * ( self.speed_x / self.count) - MyDriver.w_brake * ( self.brake) + -MyDriver.w_damage * (carstate.damage) print(fitness) self.net_score[MyDriver.index] = fitness print( str(self.speed_x / self.count) + " " + str(self.distance) + " " + str(self.brake / self.count) + " " + str(carstate.current_lap_time) + " " + str(carstate.damage)) MyDriver.network.fitness = fitness if ((MyDriver.index + 1) < len(MyDriver.networks)): print(MyDriver.index) MyDriver.index += 1 else: print("else") mutate = Mutate() if (MyDriver.index <= MyDriver.num_childs): MyDriver.add_network(MyDriver.network) child_netowrk = mutate.do_mutate_network_sin( MyDriver.get_best_network()) MyDriver.index += 1 MyDriver.networks.append(child_netowrk) else: print(str(datetime.now())) folder_name = "data/evolution/" + str(datetime.now()) os.makedirs(folder_name) for i in range(0, len(MyDriver.networks)): path = folder_name + "/" + str(i) + ".pkl" Network.save_networks(MyDriver.networks[i], path) MyDriver.index = 0 print("Mutation on") MyDriver.heap_size += 5 self.sort() #MyDriver.networks=mutate.mutate_list(networks) MyDriver.num_childs = MyDriver.num_childs + int( 0.1 * MyDriver.num_childs) mutate = Mutate() child_netowrk = mutate.do_mutate_network_sin( MyDriver.get_best_network()) MyDriver.networks = [] MyDriver.networks.append(child_netowrk) MyDriver.network = MyDriver.networks[MyDriver.index] self.reinitiaze() command.meta = 1 car_speed = carstate.speed_x * (3.6) if (car_speed >= 0.0 and car_speed < 40.0): command.gear = 1 if (car_speed >= 40.0 and car_speed < 70.0): command.gear = 2 if (car_speed >= 70.0 and car_speed < 120.0): command.gear = 3 if (car_speed >= 120.0 and car_speed < 132.0): command.gear = 4 if (car_speed >= 132.0 and car_speed < 150.0): command.gear = 5 if (car_speed >= 150.0): command.gear = 6 if not command.gear: command.gear = carstate.gear or 1 command.brake = min(1, output.data[0, 1]) command.brake = max(0, command.brake) #self.accelerate(carstate, v_x, command) #if self.data_logger: # self.data_logger.log(carstate, command) logging.info( str(command.accelerator) + "," + str(command.brake) + "," + str(command.steering) + "," + str(l_predict)) return command
def make_next_command(self, carstate): """ Description Args: carstate: The full carstate object as passed to Driver() Returns: command: The command object to pass back to the server """ # checking in on the swarm position = carstate.distance_from_start position = int(position - (position % self.swarm.pos_int)) new_frame = position > (self.previous_frame_position + self.swarm.pos_int) new_lap = self.previous_frame_position > (position + self.swarm.pos_int) if ENABLE_SWARM and (new_frame or new_lap): self.max_speed = self.swarm.check_in(position, carstate.speed_x, self.crashed_in_last_frame, self.contact_in_last_frame) self.crashed_in_last_frame = False self.contact_in_last_frame = False self.previous_frame_position = position err(self.iter, "SWARM: pos=%i, max_speed=%i" % (position, self.max_speed)) # basic predictions if ENABLE_NETWORK: steer_pred = self.steering_model.predict( [carstate.angle, carstate.speed_x] + list(carstate.distances_from_edge) + [carstate.distance_from_center]) steer_pred = steer_pred[0] else: steer_pred = self.basic_control.steer_decider(carstate) gear = self.basic_control.gear_decider(carstate) pedal = self.basic_control.speed_decider(carstate, max_speed=self.max_speed) # making sure we don't drive at people opponents_deltas = list( map(sub, carstate.opponents, self.last_opponents)) steer_pred, pedal = self.basic_control.deal_with_opponents( steer_pred, pedal, carstate.speed_x, carstate.distance_from_center, carstate.opponents, opponents_deltas) # if too fast descelerate to max speed if carstate.speed_x > self.max_speed: pedal = 0.0 err(self.iter, "MAIN: capping speed") # disambiguating pedal with smoothing brake, accel = self.basic_control.disambiguate_pedal(pedal, accel_cap=1.0) # debug output if PRINT_COMMAND and self.iter % PRINT_CYCLE_INTERVAL: print("Executing comand: gear=%.2f, acc=%.2f," % (gear, accel), "break=%.2f, steering=%.2f" % (brake, steer_pred)) # command construction command = Command() command.brake = brake command.accelerator = accel command.steering = steer_pred command.gear = gear if command.steering > 0.10: debug(self.iter, "BASIC: turning left") elif command.steering < -0.10: debug(self.iter, "BASIC: turning right") return command
def drive(self, carstate: State): # if len(os.listdir('./evolver/kill_torcs/')) > 0: # self.kill(self.torcs_process.pid) # evaluation period in seconds EVAL_TIME = 90 t = carstate.current_lap_time if t < self.last_cur_lap_time: # made a lap, adjust timing events accordingly! self.period_end_time -= carstate.last_lap_time self.off_time -= carstate.last_lap_time self.recovered_time -= carstate.last_lap_time self.stopped_time -= carstate.last_lap_time self.last_cur_lap_time = t use_pca = False command = Command() ''' Handeling Evaluation Change: ''' if t > self.period_end_time and not self.recovering: # END CURRENT EVALUATION PERIOD: if self.first_evaluation: # check the right files and folders are available: # if not os.path.isdir('./evolver/pool/'): # print('NO POOL FOLDER FOUND') # return command # # if not os.path.exists('./log.csv'): # print('Creating log.csv...') # open('./log.csv', 'w').close() pass elif self.esn != None: # FITNESS CALCULATION # currently average speed (in MPS) # penalties for off track and recovery, and using brake too much # bonus points for staying in middle of track and keeping small # angle # self.fitness += (carstate.distance_raced - self.period_start_dist) self.fitness += self.period_distance_raced # log the performance: # save the network with the fitness in the title: # new_path = './evolver/queue/%s.pkl'%self.fitness # os.system('mv %s %s'%(self.PATH_TO_NEURAL_NET, new_path)) self.esn.save('./evolver/queue/%.2f.pkl' % self.fitness) # with open(new_path, 'wb') as file: # pkl.dump(self,file) # nn_id = int(self.PATH_TO_NEURAL_NET[12:-4]) # log = open('./log.csv', 'a') # log.write('%s, %.2f\n'%(nn_id, self.fitness)) # log.close() if self.fitness > 0: print('Fitness Score \033[7m%.2f\033[0m logged\n' % (self.fitness)) else: print('Fitness Score %.2f logged\n' % (self.fitness)) # START NEXT EVALUATION PERIOD: # load random net: pool = os.listdir('./evolver/driver_esn/') if len(pool) > 0: self.PATH_TO_NEURAL_NET = './evolver/driver_esn/' + str( np.random.choice(pool, 1)[0]) self.esn = neuralNet.restore_ESN(self.PATH_TO_NEURAL_NET) # remove ESN so no other driver can use it: os.system('rm %s' % self.PATH_TO_NEURAL_NET) print('Evaluating %s:' % self.PATH_TO_NEURAL_NET) else: # no choice of ESNs, use robot driver # print('No ESNS :(') self.esn = None self.recovering = True # reset values: self.fitness = 0 self.period_end_time = t + EVAL_TIME self.period_start_dist = carstate.distance_raced self.period_distance_raced = 0 self.first_evaluation = False self.init_time = t + 2 """ Collect Input Data. Speed, Track Position, Angle on the track and the 19 values of the Track Edges """ sensor_SPEED = carstate.speed_x * 3.6 # Convert from MPS to KPH sensor_TRACK_POSITION = carstate.distance_from_center sensor_ANGLE_TO_TRACK_AXIS = carstate.angle * math.pi / 180 sensor_TRACK_EDGES = carstate.distances_from_edge if sensor_SPEED < 2: if not self.is_stopped: self.is_stopped = True self.stopped_time = t else: self.is_stopped = False # reward fitness for being within 15 degress: if np.abs(sensor_ANGLE_TO_TRACK_AXIS) < 0.2618: self.fitness += 1 # reward if in center of road: if np.abs(sensor_TRACK_POSITION) < 0.1: self.fitness += 1 """ Process Inputs. Feed the sensor data into the network to produce a Accelrator, Brake and Steering command """ sensor_data = [ min(sensor_SPEED, 300) / 300, sensor_TRACK_POSITION, sensor_ANGLE_TO_TRACK_AXIS ] if self.is_stopped & (t > self.stopped_time + 3) & (not self.recovering): self.recovering = True self.is_stopped = False # print(self.RECOVER_MSG) # print('Stopped for 3 seconds...') self.fitness -= 5000 self.finished_evaluation = True if self.recovering: self.simpleDriver(sensor_data, carstate, command) if np.abs(sensor_TRACK_POSITION) < 1: # recovered! # self.stuck = 0 if not self.warm_up: # print('Back on track...') self.recovered_time = t self.warm_up = True self.off_track = False # considered recovered if moving fast and straightish if (t > self.recovered_time + 5) & (sensor_SPEED > 40) & ( np.abs(sensor_ANGLE_TO_TRACK_AXIS) < 0.5): self.recovering = False self.warm_up = False self.period_end_time = t # will end evaluation period # print('Recovered and starting new evaulation') # print('+-'*18) else: self.off_track = True self.warm_up = False else: ''' Drive using Neural Net ''' if np.abs(sensor_TRACK_POSITION) > 1: if self.off_track == False: # print("### OFF ROAD ###") self.off_time = t self.off_track = True self.fitness -= 1 if t > self.off_time + 5: # haven't recovered in 3 seconds # get back on road and start new evaluation self.fitness -= 5000 # penalty self.recovering = True self.finished_evaluation = True # print(self.RECOVER_MSG) else: self.off_track = False self.period_distance_raced = carstate.distance_raced - self.period_start_dist x = np.array(sensor_TRACK_EDGES) / 200 if use_pca: y = PCA.convert(x.T) sensor_data += list(y) else: sensor_data += list(x) # use EchoStateNet try: output = self.esn.predict(sensor_data, continuation=True) except: # pass self.esn = neuralNet.restore_ESN(self.PATH_TO_NEURAL_NET) output = self.esn.predict(sensor_data, continuation=True) # print('Loaded ' + self.PATH_TO_NEURAL_NET) if output[0] > 0: if sensor_SPEED < 120: accel = min(max(output[0], 0), 1) else: accel = 0 brake = 0.0 else: accel = 0.0 brake = min(max(-output[0], 0), 1) if sensor_SPEED < 10: self.fitness -= 1 else: if np.abs(sensor_ANGLE_TO_TRACK_AXIS) > 0.2618: self.fitness += 1 steer = min(max(output[1], -1), 1) # if np.abs(steer) < 0.1 and x[9] > 0.9: # self.fitness += 1 # # if np.abs(steer) > 0.8 and x[9] < 0.2: # self.fitness += 1 """ Apply Accelrator, Brake and Steering Commands from the neural net """ if self.train_overtaking: # reduce range to within 10m opponents = np.array(carstate.opponents) opponents = np.minimum(10, opponents) if min(opponents) < 10: # opponent nearby, engage overtaking network input2 = [output[0], steer] input2 += list(opponents / 10) ############################################ # CODE TO ALTER OUTPUTS ############################################ # for the first second do not listen to the network # this allows it to initate it's state if t > self.init_time: command.accelerator = accel command.brake = brake command.steering = steer else: self.simpleDriver(sensor_data, carstate, command) """ Automatic Transmission. Automatically change gears depending on the engine revs """ if not self.recovering: if carstate.rpm > 8000 and command.accelerator > 0: command.gear = carstate.gear + 1 elif carstate.rpm < 2500: command.gear = max(1, carstate.gear - 1) if not command.gear: command.gear = carstate.gear or 1 return command
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() stateList = self.stateToArray(carstate) # output = self.network.activate(stateList) # Set the link to find the file of the one to work with if not self.set: files = glob.glob("cooperation*.txt") for fileN in files: if fileN != "cooperation" + str(self.id) + ".txt": self.co_car = fileN break self.set = True fh = open("cooperation" + str(self.id) + ".txt", "w") fh.write(str(self.id) + ": " + str(carstate.distance_raced)) fh.close() fh = open(self.co_car, "r") lines = fh.read() distance_other = float(lines.split(": ")[-1]) fh.close() if distance_other > carstate.distance_raced: opponents = carstate.opponents # Now get information from these opponents to ride against them, # Feed that information in the network and drive # by changing the stateList output = self.network.forward(stateList).data #print(output) #print(carstate.speed_x) #print(carstate.distance_from_start) #print(carstate.opponents) #self.steer(carstate, output[0, 2], command) command.steering = output[0, 0] #self.accelerate(carstate, 80, command) if carstate.speed_x < 0.1: command.accelerator = abs(output[0, 1]) else: command.accelerator = output[0, 1] if output[0, 1] < 0.0: command.brake = output[0, 2] else: command.brake = 0 if command.accelerator > 0: if carstate.rpm > 8000: command.gear = carstate.gear + 1 if command.accelerator < 0: if carstate.rpm < 2500: command.gear = carstate.gear - 1 if not command.gear: command.gear = carstate.gear or 1 #acceleration = output[0,1]*129 #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 output[0,0]>0.5: # ACC_LATERAL_MAX = 6400 * 5 # v_x = min(80, math.sqrt(ACC_LATERAL_MAX / abs(command.steering))) #else: # v_x = 0 #self.accelerate(carstate, 85, command) if self.data_logger: self.data_logger.log(carstate, command) return command
def drive(self, carstate: State) -> Command: # threading.Thread(target=c.communicate, args=(carstate, "communication.csv")).start() command = Command() speed_x = carstate.speed_x speed_y = carstate.speed_y speed_z = carstate.speed_z speed = math.sqrt(speed_x**2 + speed_y**2 + speed_z**2) track_position = carstate.distance_from_center angle = carstate.angle track_edges = carstate.distances_from_edge input_data = [speed, track_position, angle] for edge in track_edges: input_data.append(edge) opponents = carstate.opponents for i in range(0, len(opponents), 9): if not i == 27: input_data.append(opponents[i]) input_data = np.reshape(input_data, (1,len(input_data))) # output = self.model.predict(input_data) # output = self.alt_model.predict(input_data) output = self.opponents_model.predict(input_data) acceleration = output[0][0] brake = output[0][1] steering = output[0][2] if acceleration > 0: if carstate.rpm > 8000: command.gear = carstate.gear + 1 if carstate.rpm < 2500: command.gear = carstate.gear - 1 if not command.gear: command.gear = carstate.gear or 1 if track_edges[9] < 130.0 and track_edges[9] > 80.0: if speed > 40: acceleration = 0 brake = 0.05 elif track_edges[9] < 60 and track_edges[9] > 40: if speed > 25: acceleration = 0 brake = 0.05 elif track_edges[9] < 40: if speed > 15: acceleration = 0 brake = 0.05 command.accelerator = acceleration command.brake = brake command.steering = steering return command
def drive(self, carstate: State) -> Command: command = Command() speed_x = carstate.speed_x speed_y = carstate.speed_y speed_z = carstate.speed_z speed = math.sqrt(speed_x**2 + speed_y**2 + speed_z**2) distance = carstate.distance_from_start distance_raced = carstate.distance_raced #print("Raced") #print(distance_raced) #print(distance) curlaptime = carstate.current_lap_time lastlaptime = carstate.last_lap_time time = curlaptime + lastlaptime #print(lastlaptime) #print(time) track_position = carstate.distance_from_center angle = carstate.angle track_edges = carstate.distances_from_edge input_data = [speed, track_position, angle] for edge in track_edges: input_data.append(edge) input_data = np.reshape(input_data, (1,22)) output = self.alt_model.predict(input_data) #output = self.alt_model.activate(input_data) #print(output) acceleration = output[0][0] brake = output[0][1] steering = output[0][2] if acceleration > 0: if carstate.rpm > 8000: command.gear = carstate.gear + 1 if carstate.rpm < 2500: command.gear = carstate.gear - 1 if not command.gear: command.gear = carstate.gear or 1 if track_edges[9] < 130.0 and track_edges[9] > 80.0: if speed > 40: acceleration = 0 brake = 0.05 elif track_edges[9] < 60 and track_edges[9] > 40: if speed > 25: acceleration = 0 brake = 0.05 elif track_edges[9] < 40: if speed > 15: acceleration = 0 brake = 0.05 command.accelerator = acceleration command.brake = brake command.steering = steering if time > 5 and distance_raced > 15 and distance > 15: fitness = (distance*distance)/(time*1000.) else: fitness = 0 #print(distance) #print(fitness) if abs(angle) >= 90: print("Stop") print(fitness) pickle.dump(fitness, open("fitness.p","wb")) pyautogui.press("esc") pyautogui.press("enter") exit(0) elif time > 5 and speed < 2: print("Stop") print(fitness) pickle.dump(fitness, open("fitness.p","wb")) pyautogui.press("esc") pyautogui.press("enter") exit(0) elif time > 500: print("Stop") print(fitness) pickle.dump(fitness, open("fitness.p","wb")) pyautogui.press("esc") pyautogui.press("enter") exit(0) #print(track_edges[9]) #print(command) return command
def drive(self, carstate: State) -> Command: # threading.Thread(target=c.communicate, args=(carstate, "communication.csv")).start() command = Command() speed_x = carstate.speed_x speed_y = carstate.speed_y speed_z = carstate.speed_z speed = math.sqrt(speed_x**2 + speed_y**2 + speed_z**2) track_position = carstate.distance_from_center angle = carstate.angle track_edges = carstate.distances_from_edge input_data = [speed, track_position, angle] for edge in track_edges: input_data.append(edge) opponents = carstate.opponents for i in range(0, len(opponents), 9): if not i == 27: input_data.append(opponents[i]) input_data = np.reshape(input_data, (1, len(input_data))) # output = self.model.predict(input_data) # output = self.alt_model.predict(input_data) output = self.opponents_model.predict(input_data) acceleration = output[0][0] brake = output[0][1] steering = output[0][2] if acceleration > 0: if carstate.rpm > 8000: command.gear = carstate.gear + 1 if carstate.rpm < 2500: command.gear = carstate.gear - 1 if not command.gear: command.gear = carstate.gear or 1 if track_edges[9] < 130.0 and track_edges[9] > 80.0: if speed > 40: acceleration = 0 brake = 0.05 elif track_edges[9] < 60 and track_edges[9] > 40: if speed > 25: acceleration = 0 brake = 0.05 elif track_edges[9] < 40: if speed > 15: acceleration = 0 brake = 0.05 command.accelerator = acceleration command.brake = brake command.steering = steering return command
def drive(self, carstate: State) -> Command: global car_str global friend_car_str global s global count_s global SWARM global TOTAL_STUCK_LIMIT if not hasattr(self, 'stuck'): self.stuck = False self.stuck_count = 0 self.recover_stuck = False if not hasattr(self, 'reverse'): self.reverse = False if not hasattr(self, 'total_stuck'): self.total_stuck = 0 if SWARM: if count_s == 0: s.send(b'start') count_s += 1 speed = carstate.speed_x * 3.6 if carstate.speed_x < 1: speed_x = 1 else: speed_x = carstate.speed_x # input features radio_speed_xy = carstate.speed_z / speed_x x = [ (carstate.speed_x * 3.6 - 100) / 200, carstate.distance_from_center, carstate.angle / 360, radio_speed_xy ] + ((np.array(list(carstate.distances_from_edge)) - 100) / 200).tolist() for x_idx in range(23): if str(-(x_idx + 1)) in node_dict.node_dict: node_dict.node_dict[str(-(x_idx + 1))].value = x[x_idx] # output y = forward() command = Command() command.accelerator = y[0] command.brake = y[1] command.steering = y[2] # reset feed forward network node_dict.reset() # auto switch gear if carstate.rpm > 8000: command.gear = carstate.gear + 1 if carstate.rpm < 2500: command.gear = carstate.gear - 1 if not command.gear: command.gear = carstate.gear or 1 # avoid hitting to opponents if abs(command.steering) <= 0.8: if (np.where(((np.array( list(carstate.opponents[0:13]) + list(carstate.opponents[23:36])))) <= 100)[0]).size > 0: pass #command.accelerator += 1.0 #command.brake -= 0.2 #print('oppoent behind you, accelarate! ') elif (np.where(((np.array( list(carstate.opponents[14:18]) + list(carstate.opponents[20:23])))) <= 100)[0]).size > 0: pass #command.accelerator += 1.0 #command.brake -= 0.2 #print('oppoent in front of you, accelarate! ') elif (np.where( ((np.array(list(carstate.opponents[18:19])))) < 20)[0] ).size > 0: if carstate.distance_from_center < 0.2 and carstate.distance_from_center >= 0: command.steering = command.steering - 0.1 elif carstate.distance_from_center > -0.2 and carstate.distance_from_center < 0: command.steering = command.steering + 0.1 else: command.steering = command.steering + carstate.distance_from_center * -0.2 # swarm intelligence if SWARM and self.total_stuck < TOTAL_STUCK_LIMIT: # prevent reuse self.acce car_str = str(CAR_ID) + ',' + str(round(speed, 2)) + "," + str( carstate.race_position) + "," + str( round(carstate.distance_raced, 2)) if car_str != None: s.send(car_str.encode()) friend_car_str = s.recv(128).decode() if friend_car_str == 'exit': SWARM = False elif friend_car_str != '' and friend_car_str != 'not ready': friend_car_str_split = friend_car_str.split(',') friend_car_id = int(friend_car_str_split[0]) friend_car_speed = float(friend_car_str_split[1]) friend_race_position = int(friend_car_str_split[2]) friend_distance_raced = float(friend_car_str_split[3]) if carstate.race_position > friend_race_position: # too far. closer. diff = friend_distance_raced - carstate.distance_raced if diff > 10 and diff < 100: command.brake -= 0.05 # too close elif diff <= 10: leave_diff = -(diff - 10) command.brake += 0.1 * leave_diff / 16 # detect wrong way if (carstate.angle > 170.0 or carstate.angle < -170 ) and speed > 20 and abs( carstate.distance_from_center) <= 0.7 and carstate.gear >= 1: self.reverse = True if carstate.angle < 30 and carstate.angle > -30 and abs( carstate.distance_from_center) <= 1: self.reverse = False if self.reverse: command.steering = np.sign(math.cos(carstate.angle)) * -1.0 if self.stuck == False and carstate.distance_raced > 50 and speed < 2: self.stuck = True self.total_stuck += 1 # if offtrack, try to back to road. if self.total_stuck < TOTAL_STUCK_LIMIT: if abs(carstate.distance_from_center) >= 1 and not self.stuck: self.steer(carstate, 0.0, command) # auto recover from stucked if self.stuck: if abs(carstate.distance_from_center ) <= 0.5 or self.stuck_count > 500 or ( carstate.angle < 30 and carstate.angle > -30): if carstate.gear <= -1: command.gear = -1 command.brake = 1.0 command.accelerator = 0.0 if speed >= -0.1: command.gear = 1 elif carstate.gear >= 1: command.gear = carstate.gear or 1 command.brake = 0.0 if abs(carstate.distance_from_center) >= 0.2: self.steer(carstate, 0.0, command) else: self.stuck = False self.stuck_count = 0 if self.stuck_count > 1000: self.stuck_count = 0 elif carstate.distance_from_center <= -0.5: command.gear = -1 command.accelerator = 0.5 command.steering = -1.0 command.brake = 0.0 self.stuck_steer = command.steering elif carstate.distance_from_center >= 0.5: command.gear = -1 command.accelerator = 0.5 command.steering = 1.0 command.brake = 0.0 self.stuck_steer = command.steering self.stuck_count += 1 # if stucked too many times, switch default driver. Just in case. if not self.stuck and self.total_stuck >= TOTAL_STUCK_LIMIT: self.steer(carstate, 0.0, command) self.accelerate(carstate, 40, command) return command
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 drive(self, carstate: State): t = carstate.current_lap_time if t < self.last_cur_lap_time: # made a lap, adjust timing events accordingly! self.period_end_time -= carstate.last_lap_time self.off_time -= carstate.last_lap_time self.recovered_time -= carstate.last_lap_time self.stopped_time -= carstate.last_lap_time self.last_cur_lap_time = t # initialize the driving command command = Command() """ Collect Input Data. Speed, Track Position, Angle on the track and the 19 values of the Track Edges """ sensor_SPEED = carstate.speed_x * 3.6 # Convert from MPS to KPH sensor_TRACK_POSITION = carstate.distance_from_center sensor_ANGLE_TO_TRACK_AXIS = carstate.angle * math.pi / 180 sensor_TRACK_EDGES = carstate.distances_from_edge if sensor_SPEED < 2: if not self.is_stopped: self.is_stopped = True self.stopped_time = t else: self.is_stopped = False """ Process Inputs. Feed the sensor data into the network to produce a Accelrator, Brake and Steering command """ sensor_data = [ min(sensor_SPEED, 300) / 300, sensor_TRACK_POSITION, sensor_ANGLE_TO_TRACK_AXIS ] x = np.array(sensor_TRACK_EDGES) / 200 sensor_data += list(x) if self.is_stopped & (t > self.stopped_time + 3) & (not self.recovering): self.recovering = True self.is_stopped = False #print(self.RECOVER_MSG) #print('Stopped for 3 seconds...') with open('./simulation_log.txt', 'a') as file: file.write('stopped for 3 seconds\n') if self.recovering: """ Recovery Bot """ self.simpleDriver(sensor_data, carstate, command) if np.abs(sensor_TRACK_POSITION) < 1: # recovered! # self.stuck = 0 if not self.warm_up: #print('Back on track...') self.recovered_time = t self.warm_up = True self.off_track = False # considered recovered if moving fast and straightish if (t > self.recovered_time + 5) & (sensor_SPEED > 40) & ( np.abs(sensor_ANGLE_TO_TRACK_AXIS) < 0.5): self.recovering = False self.warm_up = False self.init_time = t + 1 self.period_end_time = t # will end evaluation period #print('Recovered and starting new evaulation') #print('+-'*18) else: self.off_track = True self.warm_up = False else: """ Drive using the EchoStateNet """ # check if car is off road and if so, for how long if np.abs(sensor_TRACK_POSITION) > 1: if self.off_track == False: #print("### OFF ROAD ###") with open('./simulation_log.txt', 'a') as file: file.write('driver %.0f off road\n' % carstate.race_position) file.close() self.off_time = t self.off_track = True if t > self.off_time + 3: # haven't recovered in 3 seconds # get back on road and start new evaluation self.fitness -= 100 # penalty self.recovering = True #print(self.RECOVER_MSG) else: self.off_track = False with open('./simulation_log.txt', 'a') as file: file.write('driver %.0f on road\n' % carstate.race_position) """ load ESN if it is not yet available, predict the driving command """ try: output = self.esn.predict(sensor_data, continuation=True) # print('esn already loaded') except: # load ESN from specified path self.esn = neuralNet.restore_ESN(self.PATH_TO_ESN) # start a new 'history of states' output = self.esn.predict(sensor_data, continuation=False) """ Controller extension: Multi-Layer Perceptron that adjust the driving commands if opponents are close """ # modifiy ESN output based on the opponents data # only if car is not racing at the first position self.active_mlp = False #if self.use_mlp_opponents and carstate.race_position > 1: if self.use_mlp_opponents: opponents_data = carstate.opponents # if closest opponent is less than 50m away, use mlp to adjust outputs distance_limit = 50.0 if min(opponents_data) < distance_limit: self.active_mlp = True self.CURRENT_SPEED_LIMIT = self.SPEED_LIMIT_OVERTAKE #print('-------------use mlp---------------') mlp_input = [output[0], output[1]] #print(opponents_data) for sensor in opponents_data: # normalize opponents_data to [0,1] mlp_input.append(sensor / distance_limit) """ load MLP if it is not yet available, predict the driving commands """ try: change_output = self.mlp.predict(np.asarray(mlp_input)) except: self.mlp = neuralNet.restore_MLP(self.PATH_TO_MLP) change_output = self.mlp.predict(np.asarray(mlp_input)) # adjust the ESN output based on the MLP output # output += change_output output[0] += max(-0.5, min(0.5, change_output[0])) output[1] += max(-0.5, min(0.5, change_output[1])) self.esn.set_last_outputs(output) # determine the deviation between ESN and MLP output self.accel_deviation = abs(output[0] - mlp_input[0]) self.steering_deviation = abs(output[1] - mlp_input[1]) """ determine if car should accelerate or brake """ if output[0] > 0: if sensor_SPEED < self.CURRENT_SPEED_LIMIT: accel = min(max(output[0], 0), 1) else: accel = 0 brake = 0.0 else: accel = 0.0 brake = min(max(-output[0], 0), 1) steer = min(max(output[1], -1), 1) # uncomment to print current input and output data """ print('Speed: %.2f, Track Position: %.2f, Angle to Track: %.2f\n'%(sensor_data[0], sensor_data[1], sensor_data[2])) print('Accelrator: %.2f, Brake: %.2f, Steering: %.2f'%(accel, brake, steer)) print('Field View:') print(''.join('{:3f}, '.format(x) for x in sensor_data[3:])) """ """ Apply Accelrator, Brake and Steering Commands. """ # for the first second do not listen to the network # this allows it to initate it's state if t > self.init_time: command.accelerator = accel command.brake = brake command.steering = steer else: self.simpleDriver(sensor_data, carstate, command) """ Automatic Transmission. Automatically change gears depending on the engine revs """ if not self.recovering: if carstate.rpm > 8000 and command.accelerator > 0: command.gear = carstate.gear + 1 elif carstate.rpm < 2500: command.gear = max(1, carstate.gear - 1) if not command.gear: command.gear = carstate.gear or 1 """ write data for evaluation to the file 'simulation_log.txt' """ with open('./simulation_log.txt', 'a') as file: file.write('##################################\n') file.write('race position: %.0f\n' % carstate.race_position) file.write('current_lap_time: ' + str(carstate.current_lap_time) + '\n') if carstate.distance_from_start <= carstate.distance_raced: file.write('distance_from_start: ' + str(carstate.distance_from_start) + '\n') else: file.write('distance_from_start: 0 \n') # if overtaking was successful if self.active_mlp and carstate.race_position < self.previous_position: file.write('overtaking successful \n') # overtaking of opponent if self.active_mlp and carstate.race_position > self.previous_position: file.write('position lost \n') #file.write('damage: '+str(carstate.damage)+'\n') file.write('distance from center: ' + str(carstate.distance_from_center) + '\n') file.write('distance to opponent: ' + str(min(carstate.opponents)) + '\n') file.write('angle to track: ' + str(carstate.angle) + '\n') if self.active_mlp and self.current_damage < carstate.damage: file.write('MLP damage \n') if self.active_mlp: file.write('MLP d from center: ' + str(carstate.distance_from_center) + '\n') file.write('MLP accelerator deviation: ' + str(self.accel_deviation) + '\n') file.write('MLP steering deviation: ' + str(self.steering_deviation) + '\n') file.write('MLP speed: ' + str(carstate.speed_x) + '\n') file.write('MLP angle: ' + str(carstate.angle) + '\n') # save damage and position information for the next simulation step self.current_damage = carstate.damage self.previous_position = carstate.race_position return command