diff --git a/Car.py b/Car.py index ebda6c1..f70e08f 100644 --- a/Car.py +++ b/Car.py @@ -322,7 +322,14 @@ class Car(): return self.cligno[self.index] != self.CLIGNO_NONE def nextNonSpecialEdge(self, startOffset = 1): - return next(filter(lambda e: not e.isSpecial(), islice(self.route, self.index + startOffset, None))) + res = None + try: + res = next(filter(lambda e: not e.isSpecial(), islice(self.route, self.index + startOffset, None))) + except StopIteration: + return + else: + return res + def draw(self,painter, colorOverride): pt = QPointF(*self.pos) @@ -370,7 +377,7 @@ class Car(): if(leader is None): self.v = vmax - self.updateGraph(self.v, vmax, 0) + self.updateGraph(self.v, vmax, 0, 0) return vleader=50#self.v bleader=self.b @@ -426,7 +433,7 @@ class Car(): sai = vmax return (tti, sai) - def conduiteKrauss(self, vmax, leader, dt): + def conduiteKrauss(self, vmax, leader, leaderAtInter, dt): """if self.id == "f_00" and self.controller.t%10>5: self.v = 0 return @@ -439,38 +446,39 @@ class Car(): self.v = 0 return - if self.leaderAtInter is None: + if leaderAtInter is None: self.forceThrough = False - if leader is None: + if leader is None and leaderAtInter is None: vd = min(self.v + self.a * dt, vmax) self.v = max(0, vd-self.nu) return - vleader = leader.v - bleader = leader.b + vsecInter = vmax # si on est à une intersection - if(self.leaderAtInter is not None): + if(leaderAtInter is not None): if self.v == 0: self.timeAtInter += dt else: self.timeAtInter = 0 + + vleader = leaderAtInter.v # on calcule le temps qu'on va mettre à arriver à l'intersection # et le temps que le leader va mettre - lvmax = leader.vmax - if leader.getCurrentEdge().isSpecial(): - lvmax = leader.nextNonSpecialEdge().getSpeed() + lvmax = leaderAtInter.vmax + if leaderAtInter.getCurrentEdge().isSpecial(): + lvmax = leaderAtInter.nextNonSpecialEdge().getSpeed() nextInternalIndex = self.index # Pour la voiture actuelle, dans l'ideal on calculerait la durée selon la vitesse sur chaque troncon while not self.route[nextInternalIndex].isSpecial(): # Mais pour l'instant on prend juste la vitesse sur le troncon interne (le plus lent en general) nextInternalIndex += 1 tti, sai = self.calcTti(self.distToInter, self.v, self.route[nextInternalIndex].getLane(0).getSpeed(), self.a) # TODO : laneID - ltti, lsai = self.calcTti(self.leaderDist, vleader, lvmax, leader.a) + ltti, lsai = self.calcTti(self.leaderAtInterDist, vleader, lvmax, leaderAtInter.a) - lta = (lvmax-vleader) / leader.a # temps ou le leader accelere (i.e on ne gagne pas de vitesse relative) (on considere que leader.a==self.a) + lta = (lvmax-vleader) / leaderAtInter.a # temps ou le leader accelere (i.e on ne gagne pas de vitesse relative) (on considere que leader.a==self.a) marg = lta + (lsai-sai) / self.a # marge à prendre pour accelerer après l'intersection sans que le leader nous rattrape tts = self.v/self.b # time to stop, temps pour s'arreter si on freine mnt @@ -479,58 +487,60 @@ class Car(): #print(self.distToInter, self.minSpace, dts) # Si on est bloqué dans une dépendance circulaire - if self.timeAtInter >= 0 and self.circularLeaderDep(): + if self.timeAtInter >= 0 and self.leader is None and self.circularLeaderDep(self.leaderAtInter, 20): self.forceThrough = True - if self.forceThrough: - self.leader = None # On supprime le leader (pour que seulement la premiere voiture detecte la dependance circulaire) - self.v = min(vmax, self.v + self.a*dt) - return - - if False and self.leaderStopped > 1: - self.v = min(vmax, self.v + self.a*dt) - return - - # si on est suffisement loin de l'intersection (i.e on s'en fout du leader) # ou si on as le temps d'arriver à l'intersection avant le leader (plus un marge pour garder un distance de sécu) # alors on accelere pour s'inserer #print(tti, leader.T, marg, ltti) - if self.distToInter > self.interMinSpace + dts or (tti + leader.T + marg) < ltti: - self.v = min(vmax, self.v + self.a*dt) + if self.distToInter > self.interMinSpace + dts or (tti + leaderAtInter.T + marg) < ltti: + vsecInter = min(vmax, self.v + self.a*dt) #print(self.id, "ca passe") else:# sinon on freine - self.v = max(0, self.v - self.b*dt) - self.updateGraph(self.v, vmax, self.leaderDist) - return + vsecInter = max(0, self.v - self.b*dt) - vb = (vleader + self.v) / 2 - bb = (bleader + self.b) / 2 - vsec = vleader + (self.leaderDist - vleader * self.T - self.minSpace)/((vb/bb) + self.T) - vd = min(self.v + self.a * dt, vsec, vmax) + if self.forceThrough: + self.leaderAtInter = None # On supprime le leader (pour que seulement la premiere voiture detecte la dependance circulaire) + vsecInter = min(vmax, self.v + self.a*dt) + + vsec = vmax + if leader is not None: + vleader = leader.v + bleader = leader.b + + vb = (vleader + self.v) / 2 + bb = (bleader + self.b) / 2 + vsec = vleader + (self.leaderDist - vleader * self.T - self.minSpace)/((vb/bb) + self.T) + + vd = min(self.v + self.a * dt, vsec, vmax, vsecInter) self.v = max(0, vd-self.nu) - self.updateGraph(self.v, vmax, vsec) + self.updateGraph(self.v, vmax, vsec, vsecInter) # fonction pour verifier si on as pas une dependence circulaire de leader - def circularLeaderDep(self): - l = self.leader - timeout = 4 - ls = [] - while l is not None and timeout > 0: - ls.append(l.id) - if l.id == self.id: - #print(ls) - return True - timeout -= 1 - l = l.leader - return False + def circularLeaderDep(self, car, timeout): + if timeout <= 0: + return False - def updateGraph(self, v, vmax, vsec): + if car is None: + return False + + if car.id == self.id: + return True + + timeout -= 1 + res = self.circularLeaderDep(car.leader, timeout) + res |= self.circularLeaderDep(car.leaderAtInter, timeout) + + return res + + def updateGraph(self, v, vmax, vsec, interVsec): if self.infoWidg is None: return self.signals.addGraphPt.emit((2,self.controller.t,v)) self.signals.addGraphPt.emit((0,self.controller.t,vmax)) self.signals.addGraphPt.emit((1,self.controller.t,vsec)) + self.signals.addGraphPt.emit((3,self.controller.t,interVsec)) def update(self,dt): if self.controller.t < self.startTime: @@ -546,7 +556,7 @@ class Car(): if self.dynSpeed: vmax = max(min(self.vmax * self.controller.dynSpeedRat, self.vmax), 8) - self.conduiteKrauss(vmax,self.leader,dt) + self.conduiteKrauss(vmax,self.leader,self.leaderAtInter,dt) if self.v == 0: self.timeStopped += dt diff --git a/CarController.py b/CarController.py index 4c97cce..51d25ba 100644 --- a/CarController.py +++ b/CarController.py @@ -16,13 +16,13 @@ class carInfo(QWidget): self.ui.setupUi(self) self.maxV = 0 self.parent = parent - self.pointsCount = [0,0,0] + self.pointsCount = [0] * 4 self.minX = 0 self.chart = self.ui.speedGraph.chart() #self.chart.setAnimationOptions(QChart.AllAnimations) - speedsNames = ["vmax","vsec","Vitesse (m.s^-1)"] + speedsNames = ["vmax","vsec","Vitesse (m.s^-1)","inter vsec"] self.speedSeries = [] for ind,s in enumerate(speedsNames): self.speedSeries.append(QLineSeries())