def __init__(self, controllers, bgeCars, racingLine, lap=2): self.controllers = controllers self.bgeCars = bgeCars self.registerCars() self.racingLine = racingLine self.lap = lap self.raceLapManager = RaceLapManager(bgeCars) self.raceRankingManager = RaceRankingManager(bgeCars, racingLine, self.raceLapManager) self.logger = LoggerHandler(appname=self.__class__.__name__)
def __init__(self,bgeCar): self.bgeCar = bgeCar self.logger = LoggerHandler(appname=self.bgeCar.carname + self.__class__.__name__)
class BGECarPositionHandler: def __init__(self,bgeCar): self.bgeCar = bgeCar self.logger = LoggerHandler(appname=self.bgeCar.carname + self.__class__.__name__) #update internal state based on recent position def update(self): self.logger.info(str(self.bgeCar)) idx_inf = self.bgeCar.racingLinePointInf idx_sup = self.bgeCar.racingLinePointSup iprev = self.bgeCar.racingLine.getPreviousIndex(idx_inf) inext = self.bgeCar.racingLine.getNextIndex(idx_sup) carobj_position = self.bgeCar.getPosition() vecSupInf = self.bgeCar.racingLine.getCoord(idx_sup) - self.bgeCar.racingLine.getCoord(idx_inf) vecSupCar = self.bgeCar.racingLine.getCoord(idx_sup) - carobj_position vecInfCar = self.bgeCar.racingLine.getCoord(idx_inf) - carobj_position vecInfSup = self.bgeCar.racingLine.getCoord(idx_inf) - self.bgeCar.racingLine.getCoord(idx_sup) #get previous/next interface point index next_interface_idx = self.bgeCar.next_interface_idx next_interface_point_idx = self.bgeCar.tiManager.getInterface(next_interface_idx).racingLinePointIdx prev_interface_point_idx = self.bgeCar.tiManager.getPreviousInterface(next_interface_idx).racingLinePointIdx #check angle at point_idx_inf (inf to car and inf to sup): if superior to 90 degree, need to increment idx #ie: car is moving forward as expected if tools3d.angleFormated(vecSupInf,vecSupCar)>90.0: #print('going forward: ' + str(vecSupInf.angle(vecSupCar))) self.bgeCar.racingLinePointInf = idx_sup self.bgeCar.racingLinePointSup = inext #check if need to increment interface (idx_sup is then the new 'point_idx_inf') if idx_sup==next_interface_point_idx: self.shiftInterfaceByOne(1) #check for new lap (idx_sup is then the new 'point_idx_inf') if idx_sup == 0: self.bgeCar.notifyEndOfLap() self.bgeCar.start_race = False #self.logger.info(str(self.bgeCar)) #check angle at point_idx_sup (sup to car and sup to inf): if superior to 90 degree, need to decrement idx #ie: car is somehow moving backward for some reason elif tools3d.angleFormated(vecInfSup,vecInfCar)>90.0: #print('going backward: ' + str(vecSupInf.angle(vecInfCar))) self.bgeCar.racingLinePointInf = iprev self.bgeCar.racingLinePointSup = idx_inf #check if need to decrement interface (idx_inf is then the new 'point_idx_sup') if idx_inf==next_interface_point_idx: self.shiftInterfaceByOne(-1) #project car position orthogonally on the racing line orth_pos = self.bgeCar.getOrthPosition() #distance to next interface self.bgeCar.dist_next_interface = self.getDistanceToNextInterface(orth_pos) #distance in current lap self.bgeCar.dist_lap = self.getDistanceLap(orth_pos) #increment/decrement car object's next interface by one def shiftInterfaceByOne(self,iShift): if iShift==1: self.bgeCar.next_interface_idx = self.bgeCar.tiManager.getNextInterfaceIdx(self.bgeCar.next_interface_idx) elif iShift==-1: self.bgeCar.next_interface_idx = self.bgeCar.tiManager.getPreviousInterfaceIdx(self.bgeCar.next_interface_idx) #get distance between car position (orthogonally projected on the spline) #and the next interface def getDistanceToNextInterface(self,carobj_position_orth): idx_inf = self.bgeCar.racingLinePointInf idx_sup = self.bgeCar.racingLinePointSup #distance between proj orth and next point dist = (carobj_position_orth - self.bgeCar.racingLine.getCoord(idx_sup)).length #remaining distance to next interface remaining_dist = self.bgeCar.racingLine.getRelativeDistance( idx_sup,self.bgeCar.tiManager.getInterfaceRLIdx(self.bgeCar.next_interface_idx)) #case when AI are thrown far from the track #the interface count may then be screwed up #in that case we just need to reset next interface idx if dist + remaining_dist > max(self.bgeCar.tiManager.interfaceDistances): #TO DO print('issue') return dist + remaining_dist #compute distance in current lap #-> used by RaceManager to get ranking def getDistanceLap(self,carobj_position_orth): #special case - start of the race if self.bgeCar.start_race: return 0.0 #get distance between pos orth and previous point dist_orth_prev = (carobj_position_orth - self.bgeCar.racingLine.getCoord(self.bgeCar.racingLinePointInf)).length #get distance between previous point and racing line starting point (point[0]) dist_prev_start = self.bgeCar.racingLine.getDistanceToStart(self.bgeCar.racingLinePointInf) return dist_orth_prev + dist_prev_start
class RaceManager: def __init__(self, controllers, bgeCars, racingLine, lap=2): self.controllers = controllers self.bgeCars = bgeCars self.registerCars() self.racingLine = racingLine self.lap = lap self.raceLapManager = RaceLapManager(bgeCars) self.raceRankingManager = RaceRankingManager(bgeCars, racingLine, self.raceLapManager) self.logger = LoggerHandler(appname=self.__class__.__name__) # observer pattern - need to register each car to race manager def registerCars(self): for bgeCar in self.bgeCars: bgeCar.registerRaceManager(self) # return list of carname ordered by crossed distance DESC def getRanking(self): return self.raceRankingManager.getRanking() # log current ranking def logCurrentRanking(self): self.logger.info(self.raceRankingManager.printCurrentRankingNicely()) # log final ranking def logFinalRanking(self): self.logger.info(self.raceRankingManager.printFinalRankingNicely()) # log best lap times def logBestLapTimes(self): self.logger.info(self.raceLapManager.printBestLapTimesNicely()) # kind of observer pattern: # bgeCar will call this method and pass itself as argument # to notify raceManager that it has finished a lap # raceManager then handles all necessary action def notifyEndOfLap(self, bgeCar): # update list of lap time self.raceLapManager.notifyEndOfLap(bgeCar) # test race completion for given car if self.raceCompletedForCar(bgeCar): self.raceRankingManager.addToFinalRanking(bgeCar) # update controller to end of race state - if AI if bgeCar.carname[:3] == "cpu": controller = self.controllers[bgeCar.carname] controller.setControl("eor") # test race completion if self.raceCompleted(): self.logger.info( "\n" + "############################################\n" + "######### RACE COMPLETED ###################\n" + "############################################\n" ) self.logFinalRanking() self.logBestLapTimes() # test race completion def raceCompleted(self): return self.raceLapManager.raceCompleted(self.lap) # test race completion def raceCompletedForCar(self, bgeCar): return self.raceLapManager.raceCompletedForCar(self.lap, bgeCar)