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)
Пример #2
0
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
Пример #3
0
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
Пример #4
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) + '")')
Пример #5
0
    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)
Пример #6
0
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)
Пример #7
0
 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)
Пример #8
0
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))
Пример #9
0
    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()
Пример #10
0
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
Пример #11
0
    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
Пример #12
0
    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)
Пример #13
0
    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
Пример #15
0
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
Пример #16
0
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)
Пример #17
0
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)
Пример #18
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)
Пример #19
0
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)
Пример #20
0
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
Пример #21
0
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)
Пример #22
0
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))
Пример #23
0
    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
Пример #24
0
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")
Пример #25
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
Пример #26
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
Пример #27
0
    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
Пример #28
0
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)
Пример #29
0
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()
Пример #31
0
    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()
Пример #33
0
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], "")
Пример #34
0
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")
Пример #35
0
    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()
Пример #37
0
    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)
Пример #38
0
 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))
Пример #39
0
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)
Пример #42
0
    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
Пример #43
0
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
Пример #44
0
 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
Пример #45
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()
Пример #47
0
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
Пример #48
0
 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)
Пример #51
0
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))
Пример #52
0
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()
Пример #54
0
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()))
Пример #55
0
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"
Пример #56
0
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))
Пример #57
0
    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)