def acUpdate(deltaT): global appWindow global current_gear, current_rpm, max_rpm, shift_light, alpha, images_light, images_digits, gear_display, current_speed, max_fuel, current_fuel global rpm_display, boost_display, percentage_boost, current_boost, max_boost, percentage_rpm, truncated_rpm, fuel_display, percentage_fuel global min_rpm_spinner_Label, max_rpm_spinner_Label, units_spinner_Label #Keep app window transparent ac.setBackgroundOpacity(appWindow, 0) ac.drawBorder(appWindow, 0) max_rpm = sim_info.static.maxRpm if max_rpm == 0 else max_rpm #This is pulled from shared memory, read only once max_fuel = sim_info.static.maxFuel if max_fuel == 0 else max_fuel #This is read from shared memory, read only once current_fuel = sim_info.physics.fuel #This is read from shared memory, read every deltaT percentage_fuel = current_fuel/max_fuel*100 current_gear = ac.getCarState(0, acsys.CS.Gear) #This is read from the API every update current_gear = current_gear - 1 current_rpm = ac.getCarState(0, acsys.CS.RPM) #This is read from the API every update truncated_rpm = 100*round(current_rpm/100) current_boost = ac.getCarState(0,acsys.CS.TurboBoost) #This is read from the API every update if units == 1: current_speed = ac.getCarState(0,acsys.CS.SpeedMPH) if units == 2: current_speed = ac.getCarState(0,acsys.CS.SpeedKMH) if (current_boost > max_boost): #Calcualate maximum turbo boost pressure - Due to limitations in the api/shared memory currently the only way max_boost = current_boost percentage_boost = current_boost/max_boost*100 #Calculate the percent of turbo boost being generated percentage_rpm = current_rpm/max_rpm*100 speed_display.setText("%d" % current_speed) if (current_gear >0): if (percentage_rpm < max_user_rpm): gear_display.setText("%d" % current_gear).setFontColor(1,1,1,1) else: gear_display.setText("%d" % current_gear).setFontColor(1,0,0,1) if (current_gear == 0): if (percentage_rpm < max_user_rpm): gear_display.setText("N").setFontColor(1,1,1,1) else: gear_display.setText("N").setFontColor(1,0,0,1) if (current_gear < 0): if (percentage_rpm < max_user_rpm): gear_display.setText("R").setFontColor(1,1,1,1) else: gear_display.setText("R").setFontColor(1,0,0,1) rpm_display.setText("%d" % abs(truncated_rpm)) #fuel_display.setText("%0.1f" % percentage_fuel).setFontColor(1,0,1,1) if (percentage_fuel > 10): fuel_display.setText("%0.1f" % percentage_fuel).setFontColor(1,1,1,1) if (percentage_fuel < 10): fuel_display.setText("%0.1f" % percentage_fuel).setFontColor(1,1,0,1) if (percentage_fuel < 5): fuel_display.setText("%0.1f" % percentage_fuel).setFontColor(1,0,0,1)
def onRender(*args): global prev_p, k, f_loc, started, passed_half, finished, n track_name = ac.getTrackName(0) basename = "%s_%i.csv"%(track_name, n) f_loc = os.path.join(os.path.dirname(os.path.realpath(__file__)), basename) if (k == 20): x,y,z = ac.getCarState(ac.getCarsCount() - 1,acsys.CS.WorldPosition) p = ac.getCarState(ac.getCarsCount() - 1,acsys.CS.NormalizedSplinePosition) if not started: if prev_p > 0.5 and p < 0.5: started = True prev_p = p else: if prev_p > 0.5 and p < 0.5: n += 1 prev_p = p return prev_p = p uiElements.update(x,y,z) f = open(f_loc, "a") f.write("{0:.5f}, {1:.5f}, {2:.5f}, {3: .5f}\n".format(x,y,z,p)) f.close() k=0 k +=1
def onFormRender(deltaT): global TYREINFO, optimal_spinner_id, optimal_spinner_shown tFL, tFR, tRL, tRR = ac.getCarState(0, acsys.CS.CurrentTyresCoreTemp) pFL, pFR, pRL, pRR = ac.getCarState(0, acsys.CS.DynamicPressure) dFL, dFR, dRL, dRR = ac.getCarState(0, acsys.CS.TyreDirtyLevel) wFL, wFR, wRL, wRR = readTyreWear() drawTyresAll(w_tyre, h_tyre, round(tFL, 4), round(tFR, 4), round(tRL, 4), round(tRR, 4), dFL, dFR, dRL, dFR) if inFahrenheit: tFL = CelsiusToFahrenheit(tFL) tFR = CelsiusToFahrenheit(tFR) tRL = CelsiusToFahrenheit(tRL) tRR = CelsiusToFahrenheit(tRR) TYREINFO.setTemp(tFL, tFR, tRL, tRR) TYREINFO.setPressure(pFL, pFR, pRL, pRR) #TYREINFO.setDirt(dFL, dFR, dRL, dRR) TYREINFO.setWear(wFL, wFR, wRL, wRR) TYREINFO.setMaxT(tFL, tFR, tRL, tRR) TYREINFO.setMaxP(pFL, pFR, pRL, pRR) isInPit = readIsInPit() if isInPit == 1 and optimal_spinner_shown == 0: ac.setVisible(optimal_spinner_id, 1) optimal_spinner_shown = 1 elif isInPit == 0 and optimal_spinner_shown == 1: ac.setVisible(optimal_spinner_id, 0) optimal_spinner_shown = 0
def acUpdate(deltaT): global l_velocity, last_rec, f, first curr_milliseconds = time.time() * 1000 if curr_milliseconds - last_rec >= 250: if first: first = False else: f.write(',') last_rec = curr_milliseconds timestamp = datetime.utcnow() acceleration_g = ac.getCarState(0, acsys.CS.AccG) local_angular_velocity = ac.getCarState(0, acsys.CS.LocalAngularVelocity) ac.setText(l_velocity, "Velocity: {}".format(acceleration_g)) f.write('\n\t("0x610-0", "' + str(clamp(acceleration_g[0], -16, 16)) + '", "' + str(timestamp) + '"),') f.write('\n\t("0x610-1", "' + str(clamp(acceleration_g[1], -16, 16)) + '", "' + str(timestamp) + '"),') f.write('\n\t("0x610-2", "' + str(clamp(acceleration_g[2], -16, 16)) + '", "' + str(timestamp) + '"),') f.write('\n\t("0x611-0", "' + str(local_angular_velocity[0]) + '", "' + str(timestamp) + '"),') f.write('\n\t("0x611-1", "' + str(local_angular_velocity[1]) + '", "' + str(timestamp) + '"),') f.write('\n\t("0x611-2", "' + str(local_angular_velocity[2]) + '", "' + str(timestamp) + '")')
def update_custom_car_info(self, interpolation, dt, car_id): try: self.car_id = car_id if len(self.pit_spline["the_x"]) > 0 and len(self.track_spline["the_x"]) > 0: self.car_pos = ac.getCarState(self.car_id, acsys.CS.WorldPosition) self.car_pos = vec(self.car_pos[0], self.car_pos[2]) self.nsp = ac.getCarState(self.car_id, acsys.CS.NormalizedSplinePosition) self.track_spline_pos = vec3() self.track_spline_pos.x = interpolation.interpolate_spline(self.nsp, self.track_spline["the_x"], self.track_spline["loc_x"], True) self.track_spline_pos.y = interpolation.interpolate_spline(self.nsp, self.track_spline["the_x"], self.track_spline["loc_y"], True) self.track_spline_pos.z = interpolation.interpolate_spline(self.nsp, self.track_spline["the_x"], self.track_spline["loc_z"], True) if self.nsp < 0.5: self.nsp += 1 self.pit_spline_pos = vec() self.pit_spline_pos.x = interpolation.interpolate_spline(self.nsp, self.pit_spline["the_x"], self.pit_spline["loc_x"]) self.pit_spline_pos.y = interpolation.interpolate_spline(self.nsp, self.pit_spline["the_x"], self.pit_spline["loc_y"]) self.distance_2_track_spline_pow = math.pow(self.car_pos.x - self.track_spline_pos.x, 2) + math.pow(self.car_pos.y - self.track_spline_pos.y, 2) self.distance_2_pit_spline_pow = math.pow(self.car_pos.x - self.pit_spline_pos.x, 2) + math.pow(self.car_pos.y - self.pit_spline_pos.y, 2) #------------------------------------------------------------------- #car in pitline if self.distance_2_pit_spline_pow < self.distance_2_track_spline_pow: self.car_is_in_pitline[self.i] = True else: self.car_is_in_pitline[self.i] = False #------------------------------------------------------------------- #car out self.car_out_threshold = 80 if self.distance_2_pit_spline_pow > self.distance_2_track_spline_pow: if self.distance_2_track_spline_pow > self.car_out_threshold: self.car_is_out["status"][self.car_id] = True self.car_is_out["duration"][self.car_id] += dt self.car_is_out["pos_expected"][self.car_id] = self.track_spline_pos else: self.car_is_out["status"][self.car_id] = False self.car_is_out["duration"][self.car_id] = 0 self.car_is_out["pos_expected"][self.car_id] = vec3() else: self.car_is_out["status"][self.car_id] = False self.car_is_out["duration"][self.car_id] = 0 self.car_is_out["pos_expected"][self.car_id] = vec3() else: if ac.isCarInPitline(self.car_id) == 1: self.car_is_in_pitline[self.i] = True else: self.car_is_in_pitline[self.i] = False except Exception as e: debug(e)
def acUpdate(ms): global BEST_LOGGED_LAP, LAP_HISTORY, UPDATE_DELTA, CURRENT_LAP_VALID, LAP_VALID_INDICATOR if ACTIVE: if CURRENT_LAP_VALID and info.physics.numberOfTyresOut > TIRES_THRESHOLD: ac.setText(LAP_VALID_INDICATOR, 'Dirty') CURRENT_LAP_VALID = False #UPDATE_DELTA += ms #if UPDATE_DELTA < UPDATE_THRESHOLD: # return #UPDATE_DELTA = 0 last_lap = ac.getCarState(DRIVER_ID_SELF, acsys.CS.LastLap) valid = CURRENT_LAP_VALID and not ac.getCarState( DRIVER_ID_SELF, acsys.CS.LapInvalidated) if last_lap and (not LAP_HISTORY or not last_lap == LAP_HISTORY[-1]): ac.console('Last lap: %s%s' % (last_lap, '' if valid else ' (invalid)')) reportLap({ 'driver': DRIVER, 'track': TRACK, 'car': CAR, 'lap': last_lap }) refreshLapDisplay() # reset lap tracking ac.setText(LAP_VALID_INDICATOR, 'Clean') CURRENT_LAP_VALID = True LAP_HISTORY.append(last_lap)
def getSpeed(car=0, unit="kmh"): if unit == "kmh": return ac.getCarState(car, acsys.CS.SpeedKMH) elif unit == "mph": return ac.getCarState(car, acsys.CS.SpeedMPH) elif unit == "ms": return ac.getCarState(car, acsys.CS.SpeedMS)
def acUpdate(deltaT): global l_lapcount, lapcount, l_laptime, laptime # Don't write anything to the console from here unless it's in an if statement - it causes a crash, deltaT must # be approx every ms # Update current lap time in app window laptime = (ac.getCarState(0, acsys.CS.LapTime)) / 1000 ac.setText(l_laptime, "Current lap (s): {}".format(laptime)) # if statement using difference between lapcount and the laps output from AC to record data laps = ac.getCarState(0, acsys.CS.LapCount) if laps > lapcount: # Uses the difference between laps and lap count to limit recording to once per lap lapcount = laps ac.setText(l_lapcount, "Laps Completed: {}".format(lapcount)) # Write last lap data to csv last_lap_raw = ((ac.getCarState(0, acsys.CS.LastLap))) / 1000 ac.console("**Last_lap recorded") last_lap_m = last_lap_raw // 60 last_lap_s = last_lap_raw % 60 ac.console("**Last_lap split into minutes and seconds") with open('stintoutputfile.csv', 'a') as f: f.write("{},{:.0f}:{:.3f}\n".format(lapcount, last_lap_m, last_lap_s)) ac.console("** stint tracker: lap written to file") ac.console("{},{:.0f}:{:.3f}\n".format(lapcount, last_lap_m, last_lap_s))
def updateToMemory(self, stop=True): car_positions = [] car_velocities = [] car_npos = [] for i in range(ac.getCarsCount()): x, y, z = ac.getCarState(i, acsys.CS.WorldPosition) pos = {"X": x, "Y": y, "Z": z} car_positions.append(pos) x, y, z = ac.getCarState(i, acsys.CS.Velocity) vel = {"X": x, "Y": y, "Z": z} car_velocities.append(vel) pos = ac.getCarState(i, acsys.CS.NormalizedSplinePosition) car_npos.append(pos) #heading = info.physics.heading #pitch = info.physics.pitch #roll = info.physics.roll dict = { "car_positions": car_positions, "car_velocities": car_velocities, "normalized_car_positions": car_npos, "stop": stop #"heading" : heading, #"pitch" : pitch, #"roll" : roll } memoryMap = self._getMemoryMap() memoryMap.seek(0) memoryMap.write(1024 * b"\0") memoryMap.seek(0) memoryMap.write(json.dumps(dict).encode()) memoryMap.close()
def calcBrakeVibe(self): speed = ac.getCarState(0, acsys.CS.SpeedMS) rpm = ac.getCarState(0, acsys.CS.RPM) brake = ac.getCarState(0, acsys.CS.Brake) #Calculates the ratio between the RPM and car speed #If RPM is minimum and the car is still moving -> we probably have locked tires if speed > 1: self.old_ratio = self.ratio self.ratio = rpm / speed else: self.old_ratio = 0 self.ratio = 0 return 0 #Check if we are pressing the brakes and the ratio is increasing (same RPM and less speed = higher ratio) send = 0 thresh = Config.instance.cfgBrakeTol / 100 sens = 0.010 - (Config.instance.cfgBrakeSens / 1000) if (brake > thresh) and (self.ratio > 0): if (self.ratio > self.old_ratio) or (abs((self.ratio - self.old_ratio) / self.ratio) > sens): send = 1 return send
def __get_next_car(self, data, car_id, pitline_validation=False): try: self.nsp = ac.getCarState(car_id, acsys.CS.NormalizedSplinePosition) self.next_car = [car_id, 1] for self.iteration in range(32): #max cars if ac.isConnected(self.iteration) == 1 and self.iteration != car_id: self.pitline_condition = True if pitline_validation: if data.is_car_in_pitline(self.iteration) == data.is_car_in_pitline(car_id): self.pitline_condition = True else: self.pitline_condition = False if self.pitline_condition: if self.nsp < ac.getCarState(self.iteration, acsys.CS.NormalizedSplinePosition): self.distance = abs(self.nsp - ac.getCarState(self.iteration, acsys.CS.NormalizedSplinePosition)) else: self.distance = 1 - abs(self.nsp - ac.getCarState(self.iteration, acsys.CS.NormalizedSplinePosition)) if self.distance < self.next_car[1]: self.next_car = [self.iteration, self.distance] return self.next_car[0] except Exception as e: debug(e)
def get_performance_gap(self, sector, time): if self.currentVehicle.value > 0: if len(self.reference_lap_time_others[ self.currentVehicle.value]) < 10: return round( ac.getCarState(self.currentVehicle.value, acsys.CS.PerformanceMeter) * 1000) if sector > 0.5: reference_lap = reversed( self.reference_lap_time_others[self.currentVehicle.value]) else: reference_lap = self.reference_lap_time_others[ self.currentVehicle.value] for l in reference_lap: if l.sector == sector: return time - l.time return False # do not update # Car user if len(self.referenceLap) < 10: return round(ac.getCarState(0, acsys.CS.PerformanceMeter) * 1000) if sector > 0.5: reference_lap = reversed(self.referenceLap) else: reference_lap = self.referenceLap for l in reference_lap: if l.sector == sector: return time - l.time return False # do not update
def get_progresses(): progs = [] for i in range(NCARS): if ac.isConnected(i): lap = ac.getCarState(i, acsys.CS.LapCount) spline = ac.getCarState(i, acsys.CS.NormalizedSplinePosition) prg = lap + spline progs.append(prg) return progs
def acUpdate(deltaT): global s, addr, client_stat, ai_lane, fileDest global sct, monitor, seq global csvfile, writer, starttime try: recv = s.recvfrom(1024) client_stat = recv[0].decode().split('\n')[0] addr = recv[1] if client_stat == 'init': s.sendto((fileDest + '\n').encode(), addr) elif client_stat == 'query': ego_stat['time'] = time.time() - starttime s.sendto((json.dumps(ego_stat) + '\n').encode(), addr) elif client_stat == 'imquery': im = sct.grab(monitor) fname = "{:02d}.png".format(seq) mss.tools.to_png(im.rgb, im.size, level=1, output=("apps/python/aclab_py/captures/" + fname)) s.sendto((os.path.join(os.getcwd(), 'apps', 'python', 'aclab_py', 'captures', fname) + '\n').encode(), addr) seq = (seq + 1) % 10 except: # ac.console(client_stat) ego_stat['gas'] = info.physics.gas ego_stat['brake'] = info.physics.brake ego_stat['steerAngle'] = info.physics.steerAngle ego_stat['velocity'] = info.physics.velocity[:] ego_stat['accG'] = info.physics.accG[:] ego_stat['wheelSlip'] = info.physics.wheelSlip[:] ego_stat['wheelLoad'] = info.physics.wheelLoad[:] ego_stat['heading'] = info.physics.heading ego_stat['pitch'] = info.physics.pitch ego_stat['roll'] = info.physics.roll ego_stat['localAngularVel'] = info.physics.localAngularVel[:] ego_stat['localVelocity'] = info.physics.localVelocity[:] ego_stat['normalizedCarPosition'] = info.graphics.normalizedCarPosition ego_stat['carCoordinates'] = info.graphics.carCoordinates[:] ego_stat['surfaceGrip'] = info.graphics.surfaceGrip ego_stat['numCars'] = info.static.numCars for car in range(info.static.numCars): if car is 0: continue env_stat['velocity'] = ac.getCarState(car, acsys.CS.Velocity) env_stat['normalizedCarPosition'] = ac.getCarState( car, acsys.CS.NormalizedSplinePosition) env_stat['carCoordinates'] = ac.getCarState( car, acsys.CS.WorldPosition) ego_stat['env_stat'][car] = copy.deepcopy(env_stat) # ac.console(json.dumps(ego_stat)+'\n') ac.console(str(time.time() - starttime - ego_stat['time'])) if time.time() - starttime - ego_stat['time'] > 0.99: writer.writerow(ego_stat) ego_stat['time'] = time.time() - starttime
def onFormRender(deltaT): global TYREINFO tFL, tFR, tRL, tRR = ac.getCarState(0, acsys.CS.CurrentTyresCoreTemp) pFL, pFR, pRL, pRR = ac.getCarState(0, acsys.CS.DynamicPressure) dFL, dFR, dRL, dRR = ac.getCarState(0, acsys.CS.TyreDirtyLevel) TYREINFO.setTemp(tFL, tFR, tRL, tRR) TYREINFO.setPressure(pFL, pFR, pRL, pRR) TYREINFO.setDirt(dFL, dFR, dRL, dRR) TYREINFO.setMaxT(tFL, tFR, tRL, tRR) TYREINFO.setMaxP(pFL, pFR, pRL, pRR) drawTyresAll(w_tyre, h_tyre, round(tFL, 4), round(tFR, 4), round(tRL, 4), round(tRR, 4), dFL, dFR, dRL, dFR)
def acUpdate(deltaT): global appName, appWindow, info, imagePath global output_speed, speed, gear, output_gear, max_rpm, rpm global output_Fuel_R global absVal, text_abs, tcsVal, text_tcs #Speed speed = ac.getCarState(0, acsys.CS.SpeedKMH) ac.setText(output_speed, "%01d" % (speed)) #Gear gear = ac.getCarState(0, acsys.CS.Gear) - 1 if gear == -1: ac.setText(output_gear, "R") elif gear == 0: ac.setText(output_gear, "N") else: ac.setText(output_gear, "%01d" % (gear)) #ABS absVal = info.physics.abs if absVal == 0: ac.setFontColor(text_abs, 1, 1, 1, 0.4) else: ac.setFontColor(text_abs, 1, 1, 1, 0.83) #TCS tcsVal = info.physics.tc if tcsVal == 0: ac.setFontColor(text_tcs, 1, 1, 1, 0.4) else: ac.setFontColor(text_tcs, 1, 1, 1, 0.83) # RPM Actions rpm = info.physics.rpms max_rpm = info.static.maxRpm max_rpm_remap = round(((rpm) * (20) / (max_rpm))) # Assign image per Rounded RPM for i in hud20: ac.setBackgroundTexture( appWindow, imagePath + "hud/h" + str(max_rpm_remap) + ".png") # max_rpm_remap gets rounded to a solid number (based on the amount of images) # That number gets used as the image number # Fuel_Remaining fuel_R = info.physics.fuel ac.setText(output_Fuel_R, "{:.2f} l".format(fuel_R)) ac.setBackgroundOpacity(appWindow, 0)
def acUpdate(deltaT): global current_lap_time, is_lap_started # logic to detect starting of new lap current_lap_time = ac.getCarState(0, acsys.CS.LapTime) if (current_lap_time < 300) and (is_lap_started == False): is_lap_started = True newLap() if current_lap_time > 2000: is_lap_started = False onUpdate(ac.getCarState(0, acsys.CS.Gear)) updateGearsInfo(False)
def acUpdate(delta_t): """Update continuously with the data from the game.""" global TOTAL_LAPS_COUNTER if not MESSAGES.empty(): ac.setText(NOTIFICATION, MESSAGES.get()) update_laptimes() total_laps = ac.getCarState(0, acsys.CS.LapCount) # delay a bit(100 milliseconds) cause just after start/finish line data is # not yet correct by the game if total_laps != TOTAL_LAPS_COUNTER and \ ac.getCarState(0, acsys.CS.LapTime) > 100: TOTAL_LAPS_COUNTER = total_laps if TOTAL_LAPS_COUNTER > 0: # laps might got reset add_laptime(ac.getLastSplits(0), CAR, TRACK, LAYOUT)
def handleDrifting(): global currentscorelabel, lastDrift, highscore, waitForInvalid, waitTime, storeDriftScore cs = round(ac.getCarState(0, acsys.CS.InstantDrift)) if cs > 0: if ac.getCarState(0, acsys.CS.IsDriftInvalid): resetDriftScoring() ac.setText(currentscorelabel, "Drift invalid") else: ac.setText(currentscorelabel, "Drift Score: " + str(cs)) if lastDrift > cs: # drift done #if lastDrift > highscore: # do not send if not highscore drift waitForInvalid = waitTime storeDriftScore = lastDrift lastDrift = cs
def updateSharedMemory(): global sharedMem sharedmem = sharedMem.getsharedmem() sharedmem.numVehicles = ac.getCarsCount() sharedmem.focusVehicle = ac.getFocusedCar() #now we'll build the slots, so we later know every single (possible) car carIds = range(0, ac.getCarsCount(), 1) for carId in carIds: #first we'll check wether there is a car for this id; as soon it returns -1 #it's over if str(ac.getCarName(carId)) == '-1': break else: sharedmem.vehicleInfo[carId].carId = carId sharedmem.vehicleInfo[carId].driverName = ac.getDriverName(carId).encode('utf-8') sharedmem.vehicleInfo[carId].carModel = ac.getCarName(carId).encode('utf-8') sharedmem.vehicleInfo[carId].speedMS = ac.getCarState(carId, acsys.CS.SpeedMS) sharedmem.vehicleInfo[carId].bestLapMS = ac.getCarState(carId, acsys.CS.BestLap) sharedmem.vehicleInfo[carId].lapCount = ac.getCarState(carId, acsys.CS.LapCount) sharedmem.vehicleInfo[carId].currentLapInvalid = ac.getCarState(carId, acsys.CS.LapInvalidated) sharedmem.vehicleInfo[carId].currentLapTimeMS = ac.getCarState(carId, acsys.CS.LapTime) sharedmem.vehicleInfo[carId].lastLapTimeMS = ac.getCarState(carId, acsys.CS.LastLap) sharedmem.vehicleInfo[carId].worldPosition = ac.getCarState(carId, acsys.CS.WorldPosition) sharedmem.vehicleInfo[carId].isCarInPitline = ac.isCarInPitline(carId) sharedmem.vehicleInfo[carId].isCarInPit = ac.isCarInPit(carId) sharedmem.vehicleInfo[carId].carLeaderboardPosition = ac.getCarLeaderboardPosition(carId) sharedmem.vehicleInfo[carId].carRealTimeLeaderboardPosition = ac.getCarRealTimeLeaderboardPosition(carId) sharedmem.vehicleInfo[carId].spLineLength= ac.getCarState(carId, acsys.CS.NormalizedSplinePosition) sharedmem.vehicleInfo[carId].isConnected = ac.isConnected(carId)
def acUpdate(deltaT): global l_lapcount, l_speed, lapcount, topspeed, l_fuel, fuel, LTR_TO_GAL_CONVERSION laps = ac.getCarState(0, acsys.CS.LapCount) speed = ac.getCarState(0, acsys.CS.SpeedMPH) fuel = info.physics.fuel * LTR_TO_GAL_CONVERSION ac.setText(l_fuel, "Current Fuel Level: {} gal".format(round(fuel, 2))) if speed > topspeed: topspeed = round(speed, 2) ac.setText(l_speed, "Highest Top Speed: {} MPH".format(topspeed)) if laps > lapcount: lapcount = laps ac.setText(l_lapcount, "Laps: {}".format(lapcount))
def update(self, delta: float): for c in range(0, self._server.cars): if ac.isCarInPit(c) or not ac.isConnected(c): continue lap = ac.getCarState(c, acsys.CS.LapCount) pos = ac.getCarState(c, acsys.CS.NormalizedSplinePosition) invalid = ac.getCarState( c, acsys.CS.LapInvalidated) and self._valid[c] sec = int(pos * 3) #msec = int(pos * 12) if lap != self._lap_index[c]: self._valid[c] = True self._start_lap_time[c] = time() * 1000 best_lap = ac.getCarState(c, acsys.CS.BestLap) if not invalid and best_lap > 0: if best_lap < self._gb_lap_time: self._gb_lap_time = best_lap self._pb_lap_time[c] = best_lap elif best_lap < self._pb_lap_time[c]: self._pb_lap_time[c] = best_lap self._lap_index[c] = lap self._current_lap_time[c] = time() * 1000 - self._start_lap_time[c] if sec > 0: self._current_sector_time[c][sec] = self._current_lap_time[ c] - sum(self._current_sector_time[c][:sec]) else: self._current_sector_time[c][sec] = self._current_lap_time[c] if sec != self._sector_index[c]: last_sec = self._sector_index[c] if not invalid and self._current_sector_time[c][last_sec] > 0: if self._current_sector_time[c][ last_sec] < self._gb_sector_time[last_sec]: self._gb_sector_time[ last_sec] = self._current_sector_time[c][last_sec] self._pb_sector_time[c][ last_sec] = self._current_sector_time[c][last_sec] elif self._current_sector_time[c][ last_sec] < self._pb_sector_time[c][last_sec]: self._pb_sector_time[c][ last_sec] = self._current_sector_time[c][last_sec] self._sector_index[c] = sec
def acUpdate(deltaT): global AngleLabel, Angle, PeakAngleLabel, PeakAngle, Timer, MinKMH, PeakKMHLabel ac.setFontAlignment(AngleLabel, "center") ac.setPosition(AngleLabel, 100, 20) # raw data carKMH = ac.getCarState(0, acsys.CS.SpeedKMH) fl, fr, rl, rr = ac.getCarState(0, acsys.CS.SlipAngle) vx, vy, vz = ac.getCarState(0, acsys.CS.LocalVelocity) # model data Angle = getDriftAngle(rl, rr, vz) # spin : over angle if Angle > MaxAngle and carKMH > MinKMH: ac.setText(AngleLabel, "Spin") ac.setText(peakKMHLabel, "0") PeakAngle = 0 return # spin : lower speed if Angle > 60 and carKMH < MinKMH and vz > 0: ac.setText(AngleLabel, "Spin") ac.setText(peakKMHLabel, "0") PeakAngle = 0 return # drifting if carKMH > MinKMH: ac.setText(AngleLabel, "{:.0f}°".format(Angle)) if Angle > PeakAngle: PeakAngle = Angle ac.setText(PeakAngleLabel, "{:.0f}°".format(PeakAngle)) ac.setText(PeakKMHLabel, "{:.0f}".format(carKMH)) # Wait anim else: ac.setPosition(AngleLabel, 37, 20) Timer += deltaT ac.setFontAlignment(AngleLabel, "left") if int(Timer) % 3 == 0: ac.setText(AngleLabel, "ready") if int(Timer) % 3 == 1: ac.setText(AngleLabel, "ready.") if int(Timer) % 3 == 2: ac.setText(AngleLabel, "ready..") PeakAngle = 0 ac.setText(PeakAngleLabel, "{:.0f}°".format(PeakAngle)) ac.setText(PeakKMHLabel, "0")
def acUpdate(deltaT): global current_inpit, lapnumber, current_lap_inpit, compound, lap_valid, time_list, lap_list, pit_list, laptime_list, compound_list, valid_list, last_lap, get_laptime # invalidate lap when more than 2 tyres off the track if dmrp.info.physics.numberOfTyresOut > 2: lap_valid_tmp = 0 if lap_valid_tmp != lap_valid: lap_valid = lap_valid_tmp pit = ac.isCarInPitline(0) if pit != current_inpit: # get compound after car left the pitlane if pit == 0: compound = dmrp.info.graphics.tyreCompound current_inpit = pit if current_inpit == 1: current_lap_inpit = current_inpit lap = ac.getCarState(0, acsys.CS.LapCount) # new lap if lap != lapnumber: dt = time.strftime('%Y%m%d%H%M%S', time.localtime()) lapnumber = lap get_laptime = 1 # update lists time_list.append(dt) lap_list.append(lapnumber) pit_list.append(current_lap_inpit) compound_list.append(compound) valid_list.append(lap_valid) current_lap_inpit = 0 current_inpit = 0 lap_valid = 1 # get last lap time after 1 second curent_laptime = ac.getCarState(0, acsys.CS.LapTime) if curent_laptime > 1000 and get_laptime == 1: last_lap = ac.getCarState(0, acsys.CS.LastLap) # update laptime list laptime_list.append(last_lap) get_laptime = 0
def get_closest_opponent(self, car_id, interpolation, x, data): self.max_cars = 32 self.nsp = ac.getCarState(car_id, acsys.CS.NormalizedSplinePosition) self.next_car = vec(car_id, 1) for self.i in range(32): #max cars if ac.isConnected(self.i) == 1 and self.i != car_id: if data.is_car_in_pitline(car_id) == data.is_car_in_pitline(self.i): self.distance_a = abs(self.nsp - ac.getCarState(self.i, acsys.CS.NormalizedSplinePosition)) self.distance_b = 1 - abs(self.nsp - ac.getCarState(self.i, acsys.CS.NormalizedSplinePosition)) self.distance = min(self.distance_a, self.distance_b) if self.distance < self.next_car.y: self.next_car = vec(self.i, self.distance) return self.next_car.x
def update(self): self.gas = ac.getCarState(0, acsys.CS.Gas) self.brake = ac.getCarState(0, acsys.CS.Brake) self.clutch = ac.getCarState(0, acsys.CS.Clutch) self.gear = ac.getCarState(0, acsys.CS.Gear) - 1 self.steer = ac.getCarState(0, acsys.CS.Steer) # # Update labels # ac.setText(self.l_gas, "Gas: {:04.2f}".format(self.gas)) # ac.setText(self.l_brake, "Brake: {:04.2f}".format(self.brake)) # ac.setText(self.l_clutch, "Clutch: {:04.2f}".format(self.clutch)) # ac.setText(self.l_gear, "Gear: {:01d}".format(self.gear)) # ac.setText(self.l_steer, "Steer: {:04.2f}".format(self.steer)) return self.gas, self.brake, self.clutch, self.gear, self.steer
def acUpdate(deltaT): try: global Speed, DoPit, FuelMax, InPit, FuelIn, session, delta # Position,InitialPosition vars can be removed from the code global PitX, PitY, PitZ # added global variables initiliased as 0,0,0. X,Y,Z co-ords of pit box global AppInitialised # added global variable initiliased as False global Notify if not AppInitialised: # First call to app, set variables getNotification() if AutoUpdate: CheckNewUpdate() InPit = info.graphics.isInPit FuelMax = int(info.static.maxFuel) ac.setRange(FuelSelection, 0, FuelMax) ReadPreset() ac.setValue(Preset1, 1) AppInitialised = True if abs(PitX) < 1e-5: # set pit position InPit = info.graphics.isInPit if InPit: PitX, PitY, PitZ = ac.getCarState(0, acsys.CS.WorldPosition) ac.log("BoxRadio: Pit position initialized at X:" + str(PitX) + " Y:" + str(PitY) + " Z:" + str(PitZ)) Speed = ac.getCarState(0, acsys.CS.SpeedKMH) if Speed < 0.1 and DoPit == 0: session = info.graphics.session # session number, 2 is race InPit = info.graphics.isInPit if session == 2: PosX, PosY, PosZ = ac.getCarState( 0, acsys.CS.WorldPosition) # current co-ord position delta = ((PosX - PitX)**2 + (PosY - PitY)**2 + (PosZ - PitZ)** 2)**0.5 # straight line dist between pitbox and car FuelIn = int(info.physics.fuel) if delta < 8.0 or InPit == 1: # if InPit or within 8m of pitbox, quite relaxed limit guarantees app trigger on menu appear PitStop() ac.log("BoxRadio: Pit performed at X:" + str(PosX) + " Y:" + str(PosY) + " Z:" + str(PosZ)) ac.log("BoxRadio: Delta:" + str(delta)) DoPit = 1 if Speed >= 0.1: DoPit = 0 except Exception as e: ac.log("BoxRadio: Error in acUpdate: %s" % e)
def acUpdate(deltaT): ac.setBackgroundOpacity(appWindow, 0) ac.drawBorder(appWindow, 0) global l_kmph, l_rpm, l_gear, speed, RPM, gear, acceleration speed = str(ac.getCarState(0, acsys.CS.SpeedKMH)) RPM = str(ac.getCarState(0, acsys.CS.RPM)) gear = str(ac.getCarState(0, acsys.CS.Gear)) ac.setText(l_kmph, speed) ac.setText(l_rpm, RPM) ac.setText(l_gear, gear) global ascii_RPM, ARPM iRPM = float(RPM) maxRPM = float(info.static.maxRpm) ARPM = tacho(iRPM) if iRPM >= (maxRPM - 200): ARPM = ARPM + "[!]" ac.setText(ascii_RPM, ARPM) accelerationS = str(ac.getCarState(0, acsys.CS.AccG)) # returns a tuple with x y z; so X is sideways, Y is up and down and Z forward reverse accelerationTest = ac.getCarState(0, acsys.CS.AccG) # this is the non-printing one I'm gonna work with global gX, gY, gZ, gZback, gXleft gX = round(accelerationTest[0], 3) # then the car's turning left basically, gforces pulling the car to the right if gX > 0: gXleft = 0 else: gXleft = gX gX = 0.0 gY = round(accelerationTest[1], 3) gZ = round(accelerationTest[2], 3) gZback = gZ # forking gZ into two, this one will be used for reverse gforces if gZ < 0: gZback = gZ gZ = 0.0 else: gZback = 0.0 ac.setText(acceleration, accelerationS) print(acceleration)
def drawBrakeGauge(): global posting, post_time_elapsed, post_total_time inner_min_rad = math.asin((brake_gauge_root_y-brake_gauge_min_y)/brake_gauge_inner_radius) inner_max_rad = math.asin((brake_gauge_root_y-brake_gauge_max_y)/brake_gauge_inner_radius) outer_min_rad = math.asin((brake_gauge_root_y-brake_gauge_min_y)/brake_gauge_outer_radius) outer_max_rad = math.asin((brake_gauge_root_y-brake_gauge_max_y)/brake_gauge_outer_radius) for i in range(0,int((ac.getCarState(0,acsys.CS.Brake))*100),1): # p1 = inner, p2 = outer # p3 = inner, p4 = outer rad1 = (inner_max_rad-inner_min_rad)/100*i + inner_min_rad + (math.pi if brake_gauge_right else 0) rad2 = (outer_max_rad-outer_min_rad)/100*i + outer_min_rad + (math.pi if brake_gauge_right else 0) rad3 = (inner_max_rad-inner_min_rad)/100*(i+1) + inner_min_rad + (math.pi if brake_gauge_right else 0) rad4 = (outer_max_rad-outer_min_rad)/100*(i+1) + outer_min_rad + (math.pi if brake_gauge_right else 0) p1_x = math.cos(rad1)*brake_gauge_inner_radius + brake_gauge_root_x p1_y = brake_gauge_root_y - math.sin(rad1)*brake_gauge_inner_radius p2_x = math.cos(rad2)*brake_gauge_outer_radius + brake_gauge_root_x p2_y = brake_gauge_root_y - math.sin(rad2)*brake_gauge_outer_radius p3_x = math.cos(rad3)*brake_gauge_inner_radius + brake_gauge_root_x p3_y = brake_gauge_root_y - math.sin(rad3)*brake_gauge_inner_radius p4_x = math.cos(rad4)*brake_gauge_outer_radius + brake_gauge_root_x p4_y = brake_gauge_root_y - math.sin(rad4)*brake_gauge_outer_radius ac.glBegin(2) ac.glColor4f(brake_gauge_color[0],brake_gauge_color[1],brake_gauge_color[2],brake_gauge_color[3]) ac.glVertex2f(p1_x,p1_y) ac.glVertex2f(p2_x,p2_y) ac.glVertex2f(p3_x,p3_y) ac.glEnd() ac.glBegin(2) ac.glColor4f(brake_gauge_color[0],brake_gauge_color[1],brake_gauge_color[2],brake_gauge_color[3]) ac.glVertex2f(p3_x,p3_y) ac.glVertex2f(p2_x,p2_y) ac.glVertex2f(p4_x,p4_y) ac.glEnd()
def update(self): """Update data.""" self.gear = ac.getCarState(self.id, acsys.CS.Gear) if self.cfg.use_kmh: self.speed = ac.getCarState(self.id, acsys.CS.SpeedKMH) else: self.speed = ac.getCarState(self.id, acsys.CS.SpeedMPH) # Gear label if self.gear == 0: self.gear_text = "R" elif self.gear == 1: self.gear_text = "N" else: self.gear_text = str(self.gear - 1)
def drawClutchGauge(): global posting, post_time_elapsed, post_total_time inner_min_rad = math.asin((clutch_gauge_root_y-clutch_gauge_min_y)/clutch_gauge_inner_radius) inner_max_rad = math.asin((clutch_gauge_root_y-clutch_gauge_max_y+1)/clutch_gauge_inner_radius) outer_min_rad = math.asin((clutch_gauge_root_y-clutch_gauge_min_y)/clutch_gauge_outer_radius) outer_max_rad = math.asin((clutch_gauge_root_y-clutch_gauge_max_y+1)/clutch_gauge_outer_radius) for i in range(0,int((1-ac.getCarState(0,acsys.CS.Clutch))*100),1): # p1 = inner, p2 = outer # p3 = inner, p4 = outer rad1 = (inner_max_rad-inner_min_rad)/100*(100-i) - inner_max_rad + (math.pi if clutch_gauge_right else 0) rad2 = (outer_max_rad-outer_min_rad)/100*(100-i) - outer_max_rad + (math.pi if clutch_gauge_right else 0) rad3 = (inner_max_rad-inner_min_rad)/100*(100 - i+1) - inner_max_rad + (math.pi if clutch_gauge_right else 0) rad4 = (outer_max_rad-outer_min_rad)/100*(100 - i+1) - outer_max_rad + (math.pi if clutch_gauge_right else 0) p1_x = math.cos(rad1)*clutch_gauge_inner_radius + clutch_gauge_root_x p1_y = clutch_gauge_root_y - math.sin(rad1)*clutch_gauge_inner_radius p2_x = math.cos(rad2)*clutch_gauge_outer_radius + clutch_gauge_root_x p2_y = clutch_gauge_root_y - math.sin(rad2)*clutch_gauge_outer_radius p3_x = math.cos(rad3)*clutch_gauge_inner_radius + clutch_gauge_root_x p3_y = clutch_gauge_root_y - math.sin(rad3)*clutch_gauge_inner_radius p4_x = math.cos(rad4)*clutch_gauge_outer_radius + clutch_gauge_root_x p4_y = clutch_gauge_root_y - math.sin(rad4)*clutch_gauge_outer_radius ac.glBegin(2) ac.glColor4f(clutch_gauge_color[0],clutch_gauge_color[1],clutch_gauge_color[2],clutch_gauge_color[3]) ac.glVertex2f(p1_x,p1_y) ac.glVertex2f(p2_x,p2_y) ac.glVertex2f(p3_x,p3_y) ac.glEnd() ac.glBegin(2) ac.glColor4f(clutch_gauge_color[0],clutch_gauge_color[1],clutch_gauge_color[2],clutch_gauge_color[3]) ac.glVertex2f(p3_x,p3_y) ac.glVertex2f(p2_x,p2_y) ac.glVertex2f(p4_x,p4_y) ac.glEnd()
def getDriverInformation(detectionArea): global labelStorage, appPosX, appPosY, spinner_y_offset, fov_setting triangle = Triangle(detectionArea[0], detectionArea[1], detectionArea[2]) setLabel = 0 for x in range(ac.getCarsCount()): posX, posZ, posY = ac.getCarState(x, acsys.CS.WorldPosition) if triangle.isInside((posX, posY)) and x != 0: vect_x = posX - detectionArea[0][0] vect_y = posY - detectionArea[0][1] distance = math.sqrt(math.pow(vect_x, 2) + math.pow(vect_y, 2)) newPosition = getRenderPosition(x, detectionArea, (posX, posY)) ac.setText(labelStorage[setLabel], ac.getDriverName(x)) fov_angle = ac.getValue(fov_setting) xPos = (((newPosition * windowSizeX) / fov_angle) - appPosX) yOffset = ac.getValue(spinner_y_offset) yPos = (((windowSizeY / 2) - 20) - appPosY) + int(yOffset) fontSize = (10 * (1 / (distance / 100))) * (ac.getValue(scale_factor) / 10) ac.setPosition(labelStorage[setLabel], xPos, yPos) ac.setFontSize(labelStorage[setLabel], fontSize) setLabel += 1 for z in range(ac.getCarsCount() - setLabel): ac.setText(labelStorage[setLabel + z], "")
def acUpdate(deltaT): global brake_display global gas_display steps = 20 ac_brake = round(ac.getCarState(0, acsys.CS.Brake) * 100) current_brake_step = str(round(steps * ac_brake / 100)).zfill(2) # ac.console(current_brake_step) ac.setBackgroundTexture(brake_display, "apps/python/pedalCircles/textures/brake_steps/brake_" + current_brake_step + ".png") ac_gas = round(ac.getCarState(0, acsys.CS.Gas) * 100) current_gas_step = str(round(steps * ac_gas / 100)).zfill(2) # ac.console(current_gas_step) ac.setBackgroundTexture(gas_display, "apps/python/pedalCircles/textures/gas_steps/gas_" + current_gas_step + ".png")
def update_data(self, deltaT): ''' Called by acUpdate, updates internal data ''' self.best_lap = ac.getCarState(0, acsys.CS.BestLap) # Update cars for i in range(30): try: car = self.cars[i] except IndexError: name = ac.getDriverName(i) if name == -1: # No such car break car = Car(name) self.cars.append(car) # The name can change if in no-booking mode car.name = ac.getDriverName(i) car.spline_pos = ac.getCarState(i, acsys.CS.NormalizedSplinePosition) car.lap = ac.getCarState(i, acsys.CS.LapCount) # There is currently no way to know if another car is in the pit using the API # so we consider cars going slower than 20kph and close to start/finish line to # be in the pits car.in_pits = ac.getCarState(i, acsys.CS.SpeedKMH) < 20 and \ (car.spline_pos < 0.1 or car.spline_pos > 0.9) if i == 0: self.player = car else: car.relative_position = car.spline_pos - self.player.spline_pos if car.relative_position > 0.5: car.relative_position -= 1 if car.relative_position < -0.5: car.relative_position += 1 car.delta = car.relative_position * self.best_lap # Update the cars' race position: for i, car in enumerate( sorted(self.cars, key=lambda car: (-car.lap, -car.spline_pos))): car.position = i + 1
def drawSpeedometer(): speed = ac.getCarState(0,acsys.CS.DriveTrainSpeed)/dt_ratio #Drivetrain speed seems to be about 75-90% of the real speed wtf if imperial: speed = speed / 1.632 # degree range: 190..-10 r = abs(speedo_min_angle - speedo_max_angle) speed_deg = speedo_max_angle - (speed/indicated_max_speed)*r speed_rad = math.radians(speed_deg) for i in range(0,indicated_max_speed+1,5): if i % 20 == 0: rad = math.radians(speedo_max_angle - (i/indicated_max_speed)*r) p1_x = math.cos(rad)*speedo_radius+speed_pivot_x p1_y = -math.sin(rad)*speedo_radius+speed_pivot_y p2_x = math.cos(rad)*(speedo_radius*4/5)+speed_pivot_x p2_y = -math.sin(rad)*(speedo_radius*4/5)+speed_pivot_y ac.glBegin(0) ac.glColor4f(speedo_bigline_color[0],speedo_bigline_color[1],speedo_bigline_color[2],speedo_bigline_color[3]) ac.glVertex2f(p1_x,p1_y) ac.glVertex2f(p2_x,p2_y) ac.glEnd() elif i % 5 == 0 and i != 0: rad = math.radians(speedo_max_angle - (i/indicated_max_speed)*r) p1_x = math.cos(rad)*speedo_radius+speed_pivot_x p1_y = -math.sin(rad)*speedo_radius+speed_pivot_y p2_x = math.cos(rad)*(speedo_radius*9.25/10)+speed_pivot_x p2_y = -math.sin(rad)*(speedo_radius*9.25/10)+speed_pivot_y ac.glBegin(0) ac.glColor4f(speedo_smallline_color[0],speedo_smallline_color[1],speedo_smallline_color[2],speedo_smallline_color[3]) ac.glVertex2f(p1_x,p1_y) ac.glVertex2f(p2_x,p2_y) ac.glEnd() # Needle speed_x = math.cos(speed_rad)*(speedo_radius-3)+speed_pivot_x speed_y = -math.sin(speed_rad)*(speedo_radius-3)+speed_pivot_y speed_end_x = math.cos(speed_rad+math.pi)*speedo_needle_end+speed_pivot_x speed_end_y = -math.sin(speed_rad+math.pi)*speedo_needle_end+speed_pivot_y speed_p1_x = speed_x + math.cos(speed_rad-math.pi/2)*1.5 speed_p1_y = speed_y - math.sin(speed_rad-math.pi/2)*1.5 speed_p2_x = speed_x + math.cos(speed_rad+math.pi/2)*1.5 speed_p2_y = speed_y - math.sin(speed_rad+math.pi/2)*1.5 speed_end_p1_x = speed_end_x + math.cos(speed_rad+math.pi/2)*3 speed_end_p1_y = speed_end_y - math.sin(speed_rad+math.pi/2)*3 speed_end_p2_x = speed_end_x + math.cos(speed_rad-math.pi/2)*3 speed_end_p2_y = speed_end_y - math.sin(speed_rad-math.pi/2)*3 ac.glBegin(2) ac.glColor4f(speedo_needle_color1[0],speedo_needle_color1[1],speedo_needle_color1[2],speedo_needle_color1[3]) ac.glVertex2f(speed_p1_x,speed_p1_y) ac.glVertex2f(speed_end_p1_x,speed_end_p1_y) ac.glVertex2f(speed_end_p2_x,speed_end_p2_y) ac.glEnd() ac.glBegin(2) ac.glColor4f(speedo_needle_color1[0],speedo_needle_color1[1],speedo_needle_color1[2],speedo_needle_color1[3]) ac.glVertex2f(speed_p1_x,speed_p1_y) ac.glVertex2f(speed_end_p2_x,speed_end_p2_y) ac.glVertex2f(speed_p2_x,speed_p2_y) ac.glEnd()
def get_prev_car(self, car_id): try: self.max_cars = 32 self.nsp = ac.getCarState(car_id, acsys.CS.NormalizedSplinePosition) self.prev_car = vec(car_id, 1) for self.i in range(32): #max cars if ac.isConnected(self.i) == 1 and self.i != car_id: if self.nsp > ac.getCarState(self.i, acsys.CS.NormalizedSplinePosition): self.distance = abs(self.nsp - ac.getCarState(self.i, acsys.CS.NormalizedSplinePosition)) else: self.distance = 1 - abs(self.nsp - ac.getCarState(self.i, acsys.CS.NormalizedSplinePosition)) if self.distance < self.prev_car.y: self.prev_car = vec(self.i, self.distance) return self.prev_car.x except Exception as e: debug(e)
def logging(self): if self.outputFile == None: return lapCount = ac.getCarState(self.carId, acsys.CS.LapCount) + 1 lapTime = ac.getCarState( self.carId, acsys.CS.LapTime) speed = ac.getCarState(self.carId, acsys.CS.SpeedKMH) throttle = ac.getCarState(self.carId, acsys.CS.Gas) brake = ac.getCarState(self.carId, acsys.CS.Brake) gear = ac.getCarState(self.carId, acsys.CS.Gear) rpm = ac.getCarState(self.carId, acsys.CS.RPM) distance = ac.getCarState(self.carId, acsys.CS.NormalizedSplinePosition) steer = ac.getCarState(self.carId, acsys.CS.Steer) (x, y, z) = ac.getCarState(self.carId, acsys.CS.WorldPosition) self.outputFile.write('{}\t{:.3f}\t{:.4f}\t{:.2f}\t{:.3f}\t{:.3f}\t{}\t{:.0f}\t{:.1f}\t{:.2f}\t{:.2f}\t{:.2f}\n'.format(\ lapCount, lapTime/1000, distance, speed, throttle, brake, gear, rpm, steer, x, y, z))
def acUpdate(deltaT): try: global Speed, DoPit, FuelMax, InPit, FuelIn, session, delta # Position,InitialPosition vars can be removed from the code global PitX, PitY, PitZ # added global variables initiliased as 0,0,0. X,Y,Z co-ords of pit box global AppInitialised # added global variable initiliased as False global Notify if not AppInitialised: # First call to app, set variables getNotification() if AutoUpdate: CheckNewUpdate() InPit = info.graphics.isInPit FuelMax = int(info.static.maxFuel) ac.setRange(FuelSelection, 0, FuelMax) ReadPreset() ac.setValue(Preset1, 1) AppInitialised = True if abs(PitX) < 1e-5: # set pit position InPit = info.graphics.isInPit if InPit: PitX, PitY, PitZ = ac.getCarState(0, acsys.CS.WorldPosition) ac.log("BoxRadio: Pit position initialized at X:" + str(PitX) + " Y:" + str(PitY) + " Z:" + str(PitZ)) Speed = ac.getCarState(0, acsys.CS.SpeedKMH) if Speed < 0.1 and DoPit == 0: session = info.graphics.session # session number, 2 is race InPit = info.graphics.isInPit if session == 2: PosX, PosY, PosZ = ac.getCarState(0, acsys.CS.WorldPosition) # current co-ord position delta = ((PosX - PitX) ** 2 + (PosY - PitY) ** 2 + (PosZ - PitZ) ** 2) ** 0.5 # straight line dist between pitbox and car FuelIn = int(info.physics.fuel) if delta < 8.0 or InPit == 1: # if InPit or within 8m of pitbox, quite relaxed limit guarantees app trigger on menu appear PitStop() ac.log("BoxRadio: Pit performed at X:" + str(PosX) + " Y:" + str(PosY) + " Z:" + str(PosZ)) ac.log("BoxRadio: Delta:" + str(delta)) DoPit = 1 if Speed >= 0.1: DoPit = 0 except Exception as e: ac.log("BoxRadio: Error in acUpdate: %s" % e)
def acUpdate(deltaT): # use global tyre objects global FL, FR, RL, RR # get the tyre temps from ac FLTyreTemp, FRTyreTemp, RLTyreTemp, RRTyreTemp = ac.getCarState(0, acsys.CS.CurrentTyresCoreTemp) # update temperatures for each of the tyres FL.updateTemperature(FLTyreTemp) FR.updateTemperature(FRTyreTemp) RL.updateTemperature(RLTyreTemp) RR.updateTemperature(RRTyreTemp)
def acUpdate(deltaT): global tick global memFile tick = tick + 1 forceValue=ac.getCarState(0,acsys.CS.LastFF) #steeringValue=ac.getCarState(0,acsys.CS.Steer) #buf = ctypes.create_string_buffer(10) buf = struct.pack("?if", True, tick,forceValue) memFile.seek(0) memFile.write(buf)
def update_data(self, deltaT): ''' Called by acUpdate, updates internal data ''' self.best_lap = ac.getCarState(0, acsys.CS.BestLap) # Update cars for i in range(30): try: car = self.cars[i] except IndexError: name = ac.getDriverName(i) if name == -1: # No such car break car = Car(name) self.cars.append(car) # The name can change if in no-booking mode car.name = ac.getDriverName(i) car.spline_pos = ac.getCarState(i, acsys.CS.NormalizedSplinePosition) car.lap = ac.getCarState(i, acsys.CS.LapCount) # There is currently no way to know if another car is in the pit using the API # so we consider cars going slower than 20kph and close to start/finish line to # be in the pits car.in_pits = ac.getCarState(i, acsys.CS.SpeedKMH) < 20 and \ (car.spline_pos < 0.1 or car.spline_pos > 0.9) if i == 0: self.player = car else: car.relative_position = car.spline_pos - self.player.spline_pos if car.relative_position > 0.5: car.relative_position -= 1 if car.relative_position < -0.5: car.relative_position += 1 car.delta = car.relative_position * self.best_lap # Update the cars' race position: for i, car in enumerate(sorted(self.cars, key=lambda car: (-car.lap, -car.spline_pos))): car.position = i + 1
def acUpdate(deltaT): global ser, ac, acsys, count if count == 15: value = ac.getCarState(0, acsys.CS.SpeedMPH) value = str(round(value)) toSend = "1:" + value + ";" ser.write(toSend.encode()) count = 0 else: count = count + 1
def getStandingsPosition(self,vehicule): #mainly for replay standings = [] for i in range(self.carsCount): bl=ac.getCarState(i,acsys.CS.BestLap) if bl > 0 and bool(ac.isConnected(vehicule)): standings.append((i,bl)) standings = sorted(standings, key=lambda student: student[1]) p=[i for i, v in enumerate(standings) if v[0] == vehicule] if len(p) > 0: return p[0]+1 return 0
def acUpdate(delta_t): ac.setBackgroundOpacity(toe_app, 0) ac.setBackgroundOpacity(rpm_app, 0) rpm = ac.getCarState(0, acsys.CS.RPM) boost = ac.getCarState(0, acsys.CS.TurboBoost) fuel = simInfo.physics.fuel ac.setText(rpm_label, str(round(rpm)) + "\n" + str(round(boost, 3)) + "\n" + str(round(fuel, 1))) value_fl = ac.getCarState(0, acsys.CS.ToeInDeg, acsys.WHEELS.FL) value_fr = ac.getCarState(0, acsys.CS.ToeInDeg, acsys.WHEELS.FR) value_rl = ac.getCarState(0, acsys.CS.ToeInDeg, acsys.WHEELS.RL) value_rr = ac.getCarState(0, acsys.CS.ToeInDeg, acsys.WHEELS.RR) toeP(prev_fl, value_fl) toeP(prev_fr, value_fr) toeP(prev_rl, value_rl) toeP(prev_rr, value_rr) ac.setText( toe_label, toeSl(prev_fl, value_fl) + "\t" + toeSr(prev_fr, value_fr) + "\n" + toeSl(prev_rl, value_rl) + "\t" + toeSr(prev_rr, value_rr), )
def drawGMeter(): global posting, post_time_elapsed, post_total_time # Colors c1 = [0.0,200/255,1.0,g_meter_opacity] # Middle one c2 = [0.0,150/255,1.0,g_meter_opacity] # Inner c3 = [0.0,125/255,1.0,g_meter_opacity] # Middle inner c4 = [0.0,100/255,1.0,g_meter_opacity] # Outer g = ac.getCarState(0,acsys.CS.AccG)[0] # Neg range: 660..511 # Pos range: 660..809 l_x = r_x = 0 pixels = int(abs(g)*(g_meter_range/2.52)) if abs(g) >= 2.52: pixels = g_meter_range # ALL OF THEM if g < 0: r_x = g_meter_x_anchor l_x = r_x - pixels else: l_x = g_meter_x_anchor r_x = l_x + pixels t_y = g_meter_y_anchor for i in range(0,11,1): c = [] offset = 0 if i == 0 or i == 1 or i == 9 or i == 10: c = c4 offset = 4 elif i == 2 or i == 8: c = c3 offset = 2 elif i == 3 or i == 7: c = c3 offset = 1 elif i == 4 or i == 6: c = c2 offset = 1 else: c = c1 if g > 0 and r_x - offset <= l_x: continue elif g < 0 and l_x + offset >= r_x: continue l_offset = r_offset = 0 if g > 0: r_offset = - offset if g < 0: l_offset = offset ac.glBegin(0) ac.glColor4f(c[0],c[1],c[2],c[3]) ac.glVertex2f(l_x+l_offset,t_y+i) ac.glVertex2f(r_x+r_offset,t_y+i) ac.glEnd()
def acUpdate(deltaT): global ser,ac,acsys,count if count == 15: value=ac.getCarState(0,acsys.CS.RPM) value = str(round(value)) toSend="1:" + value + ";" ser.write(toSend.encode()) gear=ac.getCarState(0,acsys.CS.Gear) gear = int(gear) gear = gear - 1 if gear == 0: gear = "n" elif gear == -1: gear = "r" else: gear = str(gear) toSendGear = "2:" + gear + ";" ser.write(toSendGear.encode()) count = 0 else: count = count + 1
def getPerformanceGap(self, sector, time): if len(self.referenceLap) < 10: return round(ac.getCarState(0, acsys.CS.PerformanceMeter) * 1000) # if self.referenceLap[sector*100] if sector > 0.5: referenceLap = reversed(self.referenceLap) else: referenceLap = self.referenceLap for l in referenceLap: if l.sector == sector: return time - l.time # do not update return False
def update_sector(self, new_sector): if new_sector == 0: if self.data.sectors_available: # On a new lap, lastSectorTime is not immediately available sector_time = ac.getLastSplits(0)[-1] else: sector_time = sim_info.info.graphics.iLastTime - sum(self.lap.splits) sector_time = max(0, sector_time) if self.sector_lookup is None: self.generate_sector_lookup() else: # Normal new sector update if self.data.sectors_available: sector_time = sim_info.info.graphics.lastSectorTime else: sector_time = ac.getCarState(0, acsys.CS.LapTime) - sum(self.lap.splits) sector_time = max(0, sector_time) # ^ TODO? refactor above to "get_sector_time"? sector_number = new_sector - 1 # 'last' if sector_number == -1: sector_number = self.track.sector_count - 1 # Always record the time, even if the lap is invalid. self.lap.splits[sector_number] = sector_time # But do not check for fastest when invalid, just bail out. if self.lap.invalid_sectors[sector_number]: return # Should not really happen except maybe on initial sector discovery. # This also happens when 'reset session' is used. if sector_time == 0: return fastest = self.data.fastest_splits if (fastest[sector_number] is None or not fastest[sector_number].splits[sector_number] or sector_time < fastest[sector_number].splits[sector_number]): fastest[sector_number] = self.lap session = self.data.session_splits if (session[sector_number] is None or not session[sector_number].splits[sector_number] or sector_time < session[sector_number].splits[sector_number]): session[sector_number] = self.lap # Now show the actual optimal time... if self.statusbox is not None: self.statusbox.update_optimal()
def acUpdate(self, delta_t): if sim_info.info.graphics.status != sim_info.AC_LIVE: # You probably do not want to do anything until the sim is active. return if self.first_update: # App was just hot reloaded, or is otherwise running for the first time. self.first_update = False self.reinitialize_app() new_text = ( """ Total Frames: {frame_count} Since Reload: {local_frame_count} TRY CHANGING THIS AND RUN 'client_debug.py send' Current Lap: {current_lap} Lap Time: {lap_time} """.format(frame_count = self.data.frame_count, local_frame_count = self.local_frame_count, current_lap = ac.getCarState(0, acsys.CS.LapCount), lap_time = ac.getCarState(0, acsys.CS.LapTime))) ac.setText(self.data.banner, new_text)
def acUpdate(deltaT): global l_lapcount, lapcount, b_benzina, benzina laps = ac.getCarState(0, acsys.CS.LapCount) info = sim_info.SimInfo() remaining = info.physics.fuel if laps > lapcount: lapcount = laps ac.setText(l_lapcount, "Laps: {}".format(lapcount)) if remaining < benzina: benzina = remaining ac.setText(b_benzina, "Fuel: {}".format(benzina))
def drawNeedle(delta_t): speed = ac.getCarState(0, acsys.CS.SpeedKMH) if limited and speed > speedMaximum: speed = speedMaximum radValue = speed / speedMaximum * radRange + radStartingPoint dx = math.sin(radValue) dy = math.cos(radValue) tx = halfWidth - dx * halfWidth ty = halfHeight + dy * halfHeight ax = dx * halfArrowWidth ay = dy * halfArrowWidth ac.glColor4f(1.0, 0.2, 0.2, 0.8) # color ac.glBegin(acsys.GL.Quads) ac.glVertex2f(halfWidth + ay, halfHeight + ax) ac.glVertex2f(halfWidth - ay, halfHeight - ax) ac.glVertex2f(tx - ay, ty - ax) ac.glVertex2f(tx + ay, ty + ax) ac.glEnd()
def update(self, deltaT): # # Reading the static section within the shared memory needs to be done within the acUpdate(), but the # first frame is all we need. # if not self.static_set: self.data['static'] = struct_to_hash(self.info.static) self.static_set = True # # Check if we should update # current_tick = perf_counter() if current_tick - self.last_update_tick < self.interval: self.frames_skipped += 1 return self.last_update_tick = current_tick # # Dynamic updates # self.data['delta'] = ac.getCarState(0, acsys.CS.PerformanceMeter) # Delta gibts aus der Python API self.data['graphics'] = struct_to_hash(self.info.graphics) self.data['physics'] = struct_to_hash(self.info.physics) self.data['frames_skipped'] = self.frames_skipped self.frames_skipped = 0 # # Handle events # for event in pygame.event.get(): if event.type == pygame.JOYBUTTONDOWN: self.data['button_pressed'] = event.dict['button'] # if self.valid_config and self.i % 10 == 0: if self.valid_config: self.emit() # Only update the debugwindow if we haven't if self.show_debug_window: self.update_labels_in_debug_window()
def acUpdate(deltaT): global PitButton,Speed,DoPitOnce Speed = ac.getCarState(0,acsys.CS.SpeedMS) if Speed <= 0.060 and DoPitOnce == 0: PitButton = "1" DoPitOnce = 1 PushPitButton() if DoPitOnce == 1: PitButton = "0" PushPitButton() if Speed > 0.060: DoPitOnce = 0 PushPitButton() ResponseWit() ac.console("[PV]Refresh at " + str(datetime.datetime.now())) ac.log("[PV]Refresh at " + str(datetime.datetime.now()))
def acMain(ac_version): global session # Create session object session = Session(ac, acsys) session.app_size_x = app_size_x session.app_size_y = app_size_y session.freq = FREQ session.trackname = ac.getTrackName(0) session.carname = ac.getCarName(0) # Initialise UI: ui = UI(session) session.ui = ui # Load best lap time if it exists for current track and car session.load_best_lap() # Create first lap session.new_lap(ac.getCarState(0, acsys.CS.LapCount)) return "Racing Line"
def acUpdate(deltaT): global tick, trackname, lapcount, l_lapcount, l_distance, l_fuel, distance, in_tank, fuel tick += 1 # info.physics.fuel is 0 until the outlap begins if in_tank == 0: in_tank = info.physics.fuel current_tank = info.physics.fuel difference = in_tank - round(current_tank, 2) if difference > 0.01: in_tank = current_tank fuel += difference ac.setText(l_fuel, "Fuel used: {:.3f}".format(fuel)) laps = ac.getCarState(0, acsys.CS.LapCount) if laps > lapcount: lapcount = laps distance += tracklength[trackname] ac.log("{} laps of {}. That's {:.3f} kilometers this session".format(lapcount, trackname, distance)) ac.console("{} laps of {}. That's {:.3f} kilometers this session".format(lapcount, trackname, distance)) ac.setText(l_lapcount, "Laps: {}".format(lapcount)) ac.setText(l_distance, "Kilometers: {:.3f}".format(distance))
def compileDataPacket(self): ac_gear = ac.getCarState(0, acsys.CS.Gear) ac_speed = int(round(ac.getCarState(0, acsys.CS.SpeedMPH)) if Config.instance.cfgSpeedUnit == "MPH" else round(ac.getCarState(0, acsys.CS.SpeedKMH))) rpms = int(ac.getCarState(0, acsys.CS.RPM)) self.maxRPM = self.simInfo.static.maxRpm if self.maxRPM == 0 else self.maxRPM #blank the if statement if sim-info issue where max rpm doesn't change is fixed shift = 0 if self.maxRPM > 0: thresh = self.maxRPM*0.65 if rpms >= thresh: shift = round(((rpms-thresh)/(self.maxRPM-thresh))*16) if shift > 16: shift = 16 engine = 0 if self.simInfo.physics.pitLimiterOn and not self.simInfo.graphics.isInPit: engine = 1 current_fuel = self.simInfo.physics.fuel fuel = 0 if Config.instance.cfgFuelDisp == "PERCENTAGE": self.maxFuel = self.simInfo.static.maxFuel if self.maxFuel == 0 else self.maxFuel fuel = int((current_fuel/self.maxFuel)*100) engine |= 3 << 1 else: if self.fuelEst != 0: fuel = round(current_fuel/self.fuelEst, 2) if fuel > 99.9: fuel = round(fuel) elif fuel > 9.99: fuel = round(fuel*10) engine |= 1 << 1 else: fuel = round(fuel*100) engine |= 2 << 1 else: fuel = 0 if fuel > 999: fuel = 999 lapCount = self.simInfo.graphics.completedLaps + Config.instance.cfgLapOffset if lapCount > 199: lapCount = 199 boost = round(ac.getCarState(0, acsys.CS.TurboBoost), 1) b1 = int(boost*10) if b1 < 0: b1 = 0 if Config.instance.cfgBrakeEnable == 1: engine |= (self.calcBrakeVibe() << 3) delta = 0 deltaNeg = 0 mins = 0 if self.prevFuel != 0: engine |= (1 << 4) if self.sendTimeReset == 1: self.sendTimeReset = 0 engine |= (1 << 5) if self.sendTime == 1: self.sendTime = 0 engine |= (1 << 6) time = self.simInfo.graphics.lastTime.split(":") delta = (int(time[1]) << 9) | int(time[2]) mins = int(time[0]) if mins > 99: mins = 99 else: delta = ac.getCarState(0, acsys.CS.PerformanceMeter) deltaNeg = 0 if delta <= 0: deltaNeg = 1 delta = int(abs(delta) * 1000) if delta > 9999: delta = 9999 bSetting = int(deltaNeg << 7) | int(Config.instance.cfgIntensity << 4) | int(Config.instance.cfgStartPage) key = bytes([255, bSetting, ac_gear, (ac_speed >> 8 & 0x00FF), (ac_speed & 0x00FF), ((rpms >> 8) & 0x00FF), (rpms & 0x00FF), ((fuel >> 8) & 0x00FF), (fuel & 0x00FF), shift, engine, lapCount, b1, ((delta >> 8) & 0x00FF), (delta & 0x00FF), mins]) return key
def init_lap(self): self.lap.track = self.track.name self.lap.car = ac.getCarName(0) self.lap.lap_number = ac.getCarState(0, acsys.CS.LapCount) self.lap.splits = [0] * self.track.sector_count self.lap.invalid_sectors = [False] * self.track.sector_count
def acUpdate(self, delta_t): if sim_info.info.graphics.status != sim_info.AC_LIVE: return if self.first_update: self.first_update = False self.ui.reinitialize() self.reinitialize_app() self.reinitialize_statusbox() pos = ac.getCarState(0, acsys.CS.NormalizedSplinePosition) if self.lap is None: if self.lap_wait is not None: if time.time() < self.lap_wait: return else: self.lap_wait = None if ac.getCarState(0, acsys.CS.LapTime) == 0: # Only record once the clock is ticking. return elif pos > 0.5: # It appears we have not reached the start line yet. # Or at least, not that we know about. return else: self.lap = lap.Lap() self.init_lap() current_lap = ac.getCarState(0, acsys.CS.LapCount) current_sector = sim_info.info.graphics.currentSectorIndex # NOTE: When acsys.CS.LapInvalidated works, add here or at numberOfTyresOut. # Exceptional cases that we need to handle first. if (current_lap < self.lap.lap_number or sim_info.info.graphics.session != self.last_session): # Lap number decreased? # Session was reset or changed between practice/qualifying/race? self.last_session = sim_info.info.graphics.session # Abandon the lap and start over. self.clear_screen_data() self.lap = None self.lap_wait = time.time() + 2.0 # Do not begin a new lap for 2 seconds. return if not self.data.sectors_available: # See if they have become available now. if current_sector > 0: self.data.sectors_available = True else: # Use lookup table. # However, beware of the car jumping position (vallelunga). current_sector = self.get_sector(current_lap, pos) use_sector = self.check_sector(current_lap, current_sector, pos) if self.lap.lap_number != current_lap: self.finalize_lap() self.lap = None self.clear_screen_data() return elapsed_seconds = ac.getCarState(0, acsys.CS.LapTime) speed_ms = ac.getCarState(0, acsys.CS.SpeedMS) self.lap.add(pos, elapsed_seconds, speed_ms, ac.getCarState(0, acsys.CS.Gas), ac.getCarState(0, acsys.CS.Brake), sim_info.info.physics.steerAngle, ac.getCarState(0, acsys.CS.Gear), sim_info.info.graphics.distanceTraveled) if sim_info.info.physics.numberOfTyresOut > 2: self.lap.invalid = True if use_sector: self.lap.invalid_sectors[current_sector] = True if self.statusbox is not None and use_sector and current_sector >= 0: self.statusbox.update_frame(self.lap, elapsed_seconds, current_sector, pos, self.lap.invalid_sectors[current_sector]) if self.bar_mode == config.FASTEST_LAP: if hasattr(self.data, 'fastest_lap'): self.update_bar_data(self.data.fastest_lap, -1, pos, elapsed_seconds, speed_ms, 0, 0) else: self.clear_screen_data() elif self.bar_mode == config.SESSION_LAP: if hasattr(self.data, 'session_lap'): self.update_bar_data(self.data.session_lap, -1, pos, elapsed_seconds, speed_ms, 0, 0) else: self.clear_screen_data() elif not use_sector: self.clear_screen_data() else: if self.bar_mode == config.FASTEST_SECTOR: fastest = self.data.fastest_splits[current_sector] elif self.bar_mode == config.SESSION_SECTOR: fastest = self.data.session_splits[current_sector] elif self.bar_mode == config.FASTEST_OPTIMAL: # TODO: Clean this up! It is not pretty but it works. fastest = self.data.fastest_splits[current_sector] if fastest is None: self.clear_screen_data() return min1 = 0 min2 = sum(fastest.splits[0:current_sector]) for _sector in range(current_sector): _sector_lap = self.data.fastest_splits[_sector] if _sector_lap is None: self.clear_screen_data() return min1 += _sector_lap.splits[_sector] self.update_bar_data(fastest, -1, pos, # -1 means use lap.invalid. elapsed_seconds, speed_ms, min1, min2) return elif self.bar_mode == config.SESSION_OPTIMAL: fastest = self.data.session_splits[current_sector] if fastest is None: self.clear_screen_data() return min1 = 0 min2 = sum(fastest.splits[0:current_sector]) for _sector in range(current_sector): _sector_lap = self.data.session_splits[_sector] if _sector_lap is None: self.clear_screen_data() return min1 += _sector_lap.splits[_sector] self.update_bar_data(fastest, -1, pos, # -1 means use lap.invalid. elapsed_seconds, speed_ms, min1, min2) return else: fastest = None if fastest is None: self.clear_screen_data() else: # We could cache this and only update it in update_sector. min1 = sum(self.lap.splits[0:current_sector]) min2 = sum(fastest.splits[0:current_sector]) self.update_bar_data(fastest, current_sector, pos, elapsed_seconds, speed_ms, min1, min2)