diff --git a/.gitignore b/.gitignore index f09c3f70a70b8d49563cefbe57dcb2825aa41316..badcad4dc02c5bc8c33679972672151b9a7e0e42 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,6 @@ doc/**/*.pdf *.synctex.gz +*.swp testenv/ +__pycache__ diff --git a/modules/CACC/CACC-Module-Test.py b/modules/CACC/CACC-Module-Test.py index e2c8c8db58e4aaad8bd6e9f3cc0e01a818baf418..ba1aa78f5957b3441be9308b42c8205c924385b3 100644 --- a/modules/CACC/CACC-Module-Test.py +++ b/modules/CACC/CACC-Module-Test.py @@ -1,96 +1,163 @@ +import numpy as np import random +import sys import matplotlib matplotlib.use('TkAgg') from matplotlib import pyplot as plt +from kalmanfilter import KalmanFilter -class Car(object): - cSpeed = None - cPos = None - cDist = None +### is thrown if a Car is too close to its previous platoon member +class UnderCIPDerror(Exception): + pass - cIPD = None - IPD = None - PS = None +class Car(object): - def __init__(self, prev, speed, position, IPD, PS): - self.plattonPrev = prev - self.cSpeed = speed + def __init__(self, prev, speed, position, IPD, PS, tps): + self.platoonPrev = prev self.cPos = position - self.updateDis() - self.cIPD = 0.01*IPD # noch keine cIPD definition existent - self.IPD = IPD - self.PS = PS - + self.IPD = IPD + self.PS = PS + self.tps = tps + self.bcIPD = False + + # initialise calman filter + if not prev == None: + dt = 1/tps + x = np.array([[0,0]]).T + P = np.array([[10,0],[0,10]]) + + F = np.array([[1,dt],[0,1]]) + Q = np.array([[1,0],[0,1]]) + H = np.array([[1,0]]) + R = np.array([[5]]) + + self.KF = KalmanFilter(x, P, F, Q, H, R, tps) + + self.KF.predict() + + self.dIdx = 0 + self.distHistLength = 15 + self.ds = np.empty(self.distHistLength) + + RAND = 0.5 + self.SonarSystemUnc = random.uniform(-RAND,RAND) # in cm + self.SonarStatisticalUnc = lambda : random.gauss(0,RAND) # in cm + + self.SpeedSystemUnc = random.uniform(-RAND,RAND) # in meter per seconds + self.SpeedStatisticalUnc = lambda : random.gauss(0,RAND) # in meter per seconds + + self.EngineSystemUnc = random.uniform(-RAND,RAND) # in meter per seconds + + self.setSpeed(speed) + self.getDistance() + self.v_v = self.cSpeed return None def getCIPD(self): - return self.cIPD + return 0.1*self.IPD - def getPos(self): - return self.cPos - def getSpeed(self): - return self.cSpeed - + if self.cSpeed <= 1e-8: + return 0 + self.dIdx = (self.dIdx + 1) % self.distHistLength + self.ds[self.dIdx] = self.SpeedSystemUnc + self.cSpeed + self.SpeedStatisticalUnc() + return np.median(self.ds) + + def setSpeed(self,value): + if value > 1e-8: + self.cSpeed = value + self.speed = self.EngineSystemUnc + value + else: + self.cSpeed = 0 + self.speed = 0 + def getDistance(self): - return self.cDist + setLater = False + try: + self.oldDist = self.dist + except AttributeError: + setLater = True + + if not self.platoonPrev == None: + self.dist = self.SonarSystemUnc + (self.platoonPrev.cPos - self.cPos) + self.SonarStatisticalUnc() + else: + self.dist = sys.maxsize + + if setLater: + self.oldDist = self.dist + return self.dist def updatePos(self): - self.cPos = self.cPos + self.cSpeed/16 #Ticklaenge. Kann zusammen mit dem i in den Updates angepasst werden. Das Produkt beider muss 1 sein - - def updateDis(self): - if not self.plattonPrev == None: - self.cDist = - self.cPos + self.plattonPrev.getPos()#* random.uniform(0.999, 1.001) # bis zu 0.001 relative Abweichung auf die Entfernungsmessung + self.cPos += self.cSpeed/float(tps) def updateSpeed(self): if not self.bcIPD: - d_c = self.cDist - v_c = self.cSpeed + d = self.getDistance() # sensor data + v = self.getSpeed() # sesnor data IPD = self.IPD - PS = self.PS - v_n = None - - if not self.plattonPrev == None: - v_v = self.plattonPrev.getSpeed() #* random.uniform(0.9, 1.1) # bis zu 0.1 relative Abweichung auf die Geschwindigkeitsmessung - if self.checkInbound(d_c, IPD, 0.01*IPD): - if self.checkInbound (v_c, v_v, 0.01*v_v): - if self.checkInbound(v_c, PS, 0.01*PS): - v_n = PS - else: - if v_c > PS: - v_n = v_v - abs(PS-v_v)/4 - else: - v_n = v_v + abs(PS-v_v)/4 - else: - if v_c > v_v: - v_n = v_v - abs(PS-v_v)/4 - else: - v_n = v_v + abs(PS-v_v)/4 - else: - v_n = min((v_v * (d_c/IPD)**2), v_c*1.1) #Der Exponent gibt an, wie schnell die Aenderung umgesetzt werden soll + PS = self.PS + v_new = None + + if not self.platoonPrev == None: + self.KF.update(np.array([[self.getDistance()]])) + self.KF.predict() + x = self.KF.getValue() + d = x[0,0] + self.v_v = v_v = max(v + x[1,0], 0) + + v_new = self.computeNewSpeed_2(d, v, v_v, IPD, PS) inertia = 0.8 # in [0,1] und gibt die Traegheit des Fahrzeuges an - self.cSpeed = inertia * v_c + (1- inertia) * v_n + self.setSpeed(inertia * v + (1- inertia) * v_new) + + if self.getCIPD() > d: + print("raise") + raise UnderCIPDerror("under CIPD!") + + else: # this is for the LV + c = 0.5 + self.v_v = 0 + self.setSpeed(c * v + (1-c) * PS) - self.cIPD = self.IPD * 0.01 #too low - if self.cIPD > self.cDist: - self.cSpeed = 0 - self.bcIPD = True - self.cIPD = -10 #Zur Visualisierung + + def computeNewSpeed_1(self, d, v, v_v, IPD, PS): + if checkInbound(d, IPD, 0.01*IPD): + if checkInbound (v, v_v, 0.01*v_v): + if checkInbound(v, PS, 0.01*PS): + v_new = PS + else: + if v > PS: + v_new = v_v - abs(PS-v_v)/4 + else: + v_new = v_v + abs(PS-v_v)/4 else: - v_v = self.cSpeed - c = 0.8 - self.cSpeed = c * v_c + (1-c) * PS - - def checkInbound(self, argument, target, delta): #Ueberall ist ein delta von 0.01 hinterlegt - if argument > target + delta: - return False - elif argument < target - delta: - return False + if v > v_v: + v_new = v_v - abs(PS-v_v)/4 + else: + v_new = v_v + abs(PS-v_v)/4 + else: + v_new = (v_v * (d/IPD)**2) #Der Exponent gibt an, wie schnell die Aenderung umgesetzt werden soll + return v_new + + def computeNewSpeed_2(self, d, v, v_v, IPD, PS): + # Der Exponent gibt an, wie schnell die Aenderung umgesetzt werden soll + DIST_POW = 2 + SPEED_POW = 0.5 + if abs(v_v) > 1e-8: + v_new = (v_v * (d/(IPD))**DIST_POW * (PS/v_v)**SPEED_POW) else: - return True + v_new = (d - IPD)/IPD + return v_new + +def checkInbound(argument, target, delta): #Ueberall ist ein delta von 0.01 hinterlegt + if argument > target + delta: + return False + elif argument < target - delta: + return False + else: + return True def broadcastPlattonSettings(carList, newIPD, newPS): for item in carList: @@ -100,7 +167,6 @@ def broadcastPlattonSettings(carList, newIPD, newPS): def update(carList): for item in carList: item.updatePos() - item.updateDis() for item in reversed(carList): item.updateSpeed() @@ -110,12 +176,13 @@ if __name__ == "__main__": setPS = [20, 30, 10, 10, 10, 10, 10] # event of PS (activ until time event) v = [52.0, 50.0, 10.0] # startvektor (Startgeschwindikeit) - pos = [70, 30, 0] # startvektor (Startposition) + pos = [90, 30, 0] # startvektor (Startposition) + tps = 60 cars = [] - cars.append(Car(None, v[0], pos[0], setIPD[0], setPS[0])) - cars.append(Car(cars[0], v[1], pos[1], setIPD[0], setPS[0])) - cars.append(Car(cars[1], v[2], pos[2], setIPD[0], setPS[0])) + cars.append(Car(None, v[0], pos[0], setIPD[0], setPS[0],tps)) + cars.append(Car(cars[0], v[1], pos[1], setIPD[0], setPS[0],tps)) + cars.append(Car(cars[1], v[2], pos[2], setIPD[0], setPS[0],tps)) t = [] mesIPD= [] @@ -123,10 +190,13 @@ if __name__ == "__main__": y_pos = [[],[],[]] y_speed = [[],[],[]] + y_cSpeed = [[],[],[]] y_dist = [[],[],[]] - y_cdist = [[],[],[]] + y_cDist = [[],[],[]] + y_cIPD = [[],[],[]] + y_v_v = [[],[],[]] - i = 0.0 + i = 0.0; end = False for j in range(0, len(maxT)): IPD = setIPD[j] PS = setPS[j] @@ -138,39 +208,61 @@ if __name__ == "__main__": mesPS.append(PS) for k in range(0, len(cars)): - y_pos[k].append(cars[k].getPos()) + y_pos[k].append(cars[k].cPos) y_speed[k].append(cars[k].getSpeed()) + y_cSpeed[k].append(cars[k].cSpeed) + y_v_v[k].append(cars[k].v_v) for k in range(1, len(cars)): y_dist[k].append(cars[k].getDistance()) - y_cdist[k].append(cars[k].getCIPD()) + y_cDist[k].append(cars[k-1].cPos - cars[k].cPos) + y_cIPD[k].append(cars[k].getCIPD()) - i = i+0.0625 - update(cars) + i = i+1/tps + try: + update(cars) + except UnderCIPDerror: + print("catch") + end = True + break + if end: break - plt.subplot(131) - plt.plot(t, y_pos[0], 'r', label='LV') - plt.plot(t, y_pos[1], 'b', label='FV 1') - plt.plot(t, y_pos[2], 'g', label='FV 2') - plt.legend() + plt.subplot(221) + plt.plot(t, y_pos[0], 'r', label='pos LV') + plt.plot(t, y_pos[1], 'b', label='pos FV1') + plt.plot(t, y_pos[2], 'g', label='pos FV2') plt.title("Position") + plt.legend() - plt.subplot(132) - plt.plot(t, mesPS, 'r--', label='PS') - plt.plot(t, y_speed[0], 'r-', label='LV') - plt.plot(t, y_speed[1], 'b-', label='FV 1') - plt.plot(t, y_speed[2], 'g-', label='FV 2') + plt.subplot(222) + plt.plot(t, mesIPD, 'r--', label='IPD') + plt.plot(t, y_dist[1], 'b-', label='assumed dist FV1') + plt.plot(t, y_cDist[1], 'b--', label='real dist FV1') + plt.plot(t, y_cIPD[1], 'b-.', label='cIPD') + plt.plot(t, y_dist[2], 'g-', label='assumed dist FV1') + plt.plot(t, y_cDist[2], 'g--', label='real dist FV1') + plt.plot(t, y_cIPD[2], 'g-.', label='cIPD') + plt.title("Distance") plt.legend() + + plt.subplot(223) + plt.plot(t, mesPS, 'm--', label='PS') + # plt.plot(t, y_speed[0], 'r-', label='assumed speed LV') + plt.plot(t, y_cSpeed[0], 'r--', label='real speed LV') + plt.plot(t, y_v_v[1], 'b:', label='speed estiamtion FV1 for LV') + # plt.plot(t, y_speed[1], 'b-', label='assumed speed FV1') + # plt.plot(t, y_cSpeed[1], 'b--', label='real speed FV1') plt.title("Speed") + plt.legend() - plt.subplot(133) - plt.plot(t, mesIPD, 'r--', label='IPD') - plt.plot(t, y_dist[1], 'b-', label='FV1 - LV - Distance') - plt.plot(t, y_cdist[1], 'b--', label='FV1 - cIPD)') - plt.plot(t, y_dist[2], 'g-', label='FV2 - FV1 - Distance') - plt.plot(t, y_cdist[2], 'g--', label='FV2 - cIPD') + plt.subplot(224) + plt.plot(t, mesPS, 'm--', label='PS') + # plt.plot(t, y_speed[1], 'b-', label='assumed speed FV1') + plt.plot(t, y_cSpeed[1], 'b--', label='real speed FV1') + plt.plot(t, y_v_v[2], 'g:', label='speed estiamtion FV2 for FV1') + # plt.plot(t, y_speed[2], 'g-', label='assumed speed FV1') + # plt.plot(t, y_cSpeed[2], 'g--', label='real speed FV1') plt.legend() - plt.title("Distance") plt.show() diff --git a/modules/CACC/kalmanfilter.py b/modules/CACC/kalmanfilter.py new file mode 100644 index 0000000000000000000000000000000000000000..fc9d0dc4e515432ad28246ff9bad1ce97d767d0e --- /dev/null +++ b/modules/CACC/kalmanfilter.py @@ -0,0 +1,58 @@ +import numpy as np + +class KalmanFilter(object): + def __init__(self, x, P, F, Q, H, R, ticksPerSecond): + self.tps = ticksPerSecond + dt = 1/ticksPerSecond + + # Zustandsvektor + self.x = x + + # Kovarianzmatrix (hohe Werte fuer schnelle Aenderungen) + self.P = P + self.originP = P + + + # Dynamikmatrix + self.F = F + + # Prozessrausch-Matrix (Kovarianzmatrix) + self.Q = Q + + # Messmatrix um die Messung auf die relavanten Daten zu reduzieren + self.H = H + + # Messrausch-Kovarianzmatrix (nur fuer die zu messenden Groessen) + self.R = R + + # dynamisch - gross Q, klein R + # glaettung - klein Q, gross R + return None + + def predict(self): + self.x = np.dot(self.F, self.x) + self.P = np.add(np.dot(np.dot(self.F, self.P), self.F.T), self.Q) + return None + + def update(self, mesVec): + # Innovation + y = np.add(mesVec.T, - np.dot(self.H, self.x)) + + # Residualkovarianz + S = np.add(np.dot(np.dot(self.H, self.P), self.H.T), self.R) + + # Kalman - Gain + K = np.dot(np.dot(self.P, self.H.T), np.linalg.pinv(S)) + + # update the predecited values + self.x = np.add(self.x, np.dot(K, y)) + self.P = np.add(self.P, - np.dot(np.dot(K,S),K.T)) + return None + + def resetCov(self): + self.P = self.originP + return None + + + def getValue(self): + return self.x diff --git a/modules/CACC/platoonSimulation.py b/modules/CACC/platoonSimulation.py new file mode 100644 index 0000000000000000000000000000000000000000..367bca46a7ace3505d053650b6a0933546f6f5c3 --- /dev/null +++ b/modules/CACC/platoonSimulation.py @@ -0,0 +1,248 @@ +import sys +import IPython +import bisect +import time +import math +import random +import collections + +import matplotlib +matplotlib.use('TkAgg') +from matplotlib import pyplot as plt + +class CrashException(Exception): + pass + +class Vehicle(object): + def __init__(self,name,typ,road,initPos,initVelo): + + self.name = name + self.typ = typ + self.road = road + + self.velos = [] + self.posis = [] + self.dists = [] + self.velosVA = [] + + self.posi = 1.0*initPos # to make it a float value + if self.typ == "stone": + self.velo = 0 + else: + self.velo = initVelo + + self.engInAcc = (100 + random.randint(-3,3))/100.0 # constant inaccuracy for my own engine + self.sensorInAcc = (100 + random.randint(-3,3))/100.0 + + @property + def velo(self): + return self.velos[-1] + @velo.setter + def velo(self,value): + self.velos.append(value) + + @property + def posi(self): + return self.posis[-1] + @posi.setter + def posi(self,value): + self.posis.append(value) + + @property + def dist(self): + return self.dists[-1] + @dist.setter + def dist(self,value): + self.dists.append(value) + + @property + def veloVA(self): + return self.velosVA[-1] + @veloVA.setter + def veloVA(self,value): + self.velosVA.append(value) + + def __str__(self): + retStr = "---" + retStr += self.name + ".posi: " + str(self.posi) + "\n" + retStr += self.name + ".velo: " + str(self.velo) + "\n" + retStr += self.name + ".dist: " + str(self.dist) + "\n" + retStr += self.name + ".veloVA: " + str(self.veloVA) + "\n" + retStr += self.name + ".engInAcc: " + str(self.engInAcc) + "\n" + retStr += self.name + ".sensorInAcc: " + str(self.sensorInAcc) + "\n" + retStr += "---\n" + return retStr + + def update(self, tStep): + + oldVelo = self.velo + + # get sensor data + self.updateSensorData(tStep) + + # udapte position + self.posi += tStep*(oldVelo + self.velo)/2 + + # decide on values + if self.typ == "fv": + if abs(self.dist - IPD) > IPD_TOL: + self.velo = self.engInAcc*min(self.veloVA, PS)*(self.dist / IPD) + else: + self.velo = self.engInAcc*PS + + if self.typ == "lv": + if self.dist < IPD: + # self.velo = max(self.velo - 1, 0) + self.velo = 0 + else: + self.velo = self.engInAcc*PS + + def updateSensorData(self,tStep): + try: + oldDist = self.dist + except IndexError: + oldDist = self.sensorInAcc*self.road.getDistance(self) + + self.dist = self.sensorInAcc*self.road.getDistance(self) + self.veloVA = self.velo + (self.dist - oldDist)/tStep + return + + def __le__(self, other): + return self.posi <= other.posi + + def __lt__(self, other): + return self.posi < other.posi + + +class Road(object): + def __init__(self): + self.vehicles = [] + + def __str__(self): + retStr = "" + for vehicle in self.vehicles: + retStr += vehicle.__str__() + return retStr + + def placeVehicle(self, vehicle): + bisect.insort(self.vehicles, vehicle) + + def update(self,tStep): + for vIdx, vehicle in enumerate(self.vehicles): + vehicle.update(tStep) + if vIdx < len(self.vehicles)-1: + if vehicle.posi >= self.vehicles[vIdx+1].posi: + raise CrashException("Crash!") + + def draw(self): + minPosi = self.vehicles[0].posi + maxPosi = self.vehicles[-1].posi + relPos = [int((vehicle.posi - minPosi)/(maxPosi - minPosi)*100) for vehicle in self.vehicles] + + drawing = "" + relDrawProg = 0 + for vIdx, vehicle in enumerate(self.vehicles): + spaceToFill = relPos[vIdx] - relDrawProg + distStr = "<" + str(int(self.vehicles[vIdx-1].dist)).zfill(3) + ">" + if spaceToFill >= len(distStr): + frontspace = int(math.ceil((spaceToFill - len(distStr))/2.0)) + backspace = int(math.floor((spaceToFill - len(distStr))/2.0)) + for _ in range(frontspace): + drawing += " "; relDrawProg += 1 + drawing += distStr; relDrawProg += len(distStr) + for _ in range(backspace): + drawing += " "; relDrawProg += 1 + else: + for _ in range(spaceToFill): + drawing += " " + relDrawProg += 1 + drawing += vehicle.name + relDrawProg += 1 + + print("-----------------------------------------------------------------------------------------------------") + print(drawing) + print("-----------------------------------------------------------------------------------------------------") + + def getDistance(self,vehicle): + vIdx = self.vehicles.index(vehicle) + if vIdx == len(self.vehicles)-1: + return sys.maxsize + else: + return self.vehicles[vIdx + 1].posi - self.vehicles[vIdx].posi + + def getVeloVA(self, vehicle): + vIdx = self.vehicles.index(vehicle) + if vIdx == len(self.vehicles)-1: + return sys.maxsize + else: + return self.vehicles[vIdx + 1].velo + + +# GLOBALS +IPD = 15*100 # in millimetres +IPD_TOL = 1*100 # in millimetres + +PS = 15 # in millimetres per milliseconds +PS_TOL = 1 # in millimetres per milliseconds + +SENSOR_UPDATE_TIME = .5 # in milliseconds + +if __name__ == "__main__": + + tStart = 0; tStep = 1; tEnd = 500 + + road = Road() + lv = Vehicle("L","lv",road,100*100,15); road.placeVehicle(lv) + fv1 = Vehicle("1","fv",road,75*100,20); road.placeVehicle(fv1) + # fv2 = Vehicle("2","fv",road,50*100,15); road.placeVehicle(fv2) + + # startStone = Vehicle("s","stone",road,0*100,0); road.placeVehicle(startStone) + # endStone = Vehicle("S","stone",road,400*100,0); road.placeVehicle(endStone) + + t = tStart; + ts = [] + while True: + + try: + road.update(SENSOR_UPDATE_TIME) + except CrashException: + print("CRASH!") + break + + t += SENSOR_UPDATE_TIME; ts.append(t) + # print("t = ", t) + # road.draw() + # time.sleep(0.2) + + if t > tEnd: + break + plt.subplot(131) + plt.plot([tStart] + ts, lv.posis, 'm') + plt.plot([tStart] + ts, fv1.posis, 'g') + # plt.plot([tStart] + ts, fv2.posis, 'b') + plt.title("Position") + plt.ylim(7000,18000) + + plt.subplot(132) + plt.plot(ts, [PS for t in ts],'r', ts,[PS-PS_TOL for t in ts],'r--', ts,[PS+PS_TOL for t in ts],'r--') + plt.plot([tStart] + ts, lv.velos, 'm--') + plt.plot([tStart] + ts, [d/lv.engInAcc for d in lv.velos], 'm') + plt.plot([tStart] + ts, fv1.velos, 'g--') + plt.plot([tStart] + ts, [d/fv1.engInAcc for d in fv1.velos], 'g') + plt.plot(ts, fv1.velosVA, 'm.') + # plt.plot([tStart] + ts, fv2.velos, 'b--') + # plt.plot([tStart] + ts, [d/fv2.engInAcc for d in fv2.velos], 'b') + plt.title("Speed") + plt.ylim(13,26) + + plt.subplot(133) + plt.plot(ts,[IPD for t in ts],'r', ts,[IPD-IPD_TOL for t in ts],'r--', ts,[IPD+IPD_TOL for t in ts],'r--') + plt.plot(ts, fv1.dists, 'g--') + plt.plot(ts, [d/fv1.sensorInAcc for d in fv1.dists], 'g') + # plt.plot(ts, fv2.dists, 'b--') + # plt.plot(ts, [d/fv2.sensorInAcc for d in fv2.dists], 'b') + plt.title("Distance") + plt.ylim(1300,2600) + + plt.show() + diff --git a/modules/CACC/simlifiedSpeedVisualization.py b/modules/CACC/simlifiedSpeedVisualization.py new file mode 100644 index 0000000000000000000000000000000000000000..95c5a704d71e3b2a6f2285d1d238907f306b9721 --- /dev/null +++ b/modules/CACC/simlifiedSpeedVisualization.py @@ -0,0 +1,78 @@ +import numpy as np +import matplotlib +matplotlib.use('TkAgg') +from matplotlib import pyplot as plt + + +v = 20 +v_v = 0.5 +PS = 20 +IPD = 20 + +IPD_TOL = 0.05*IPD + +DIST_POW = 2 +SPEED_POW = 0.5 + +ds = np.linspace(0.*IPD, 1.5*IPD, num = 1000) +v_news = [] + +def checkInbound(argument, target, delta): #Ueberall ist ein delta von 0.01 hinterlegt + if argument > target + delta: + return False + elif argument < target - delta: + return False + else: + return True + +def variante_1(d): + v_new = None + if checkInbound(d, IPD, IPD_TOL): + if checkInbound (v, v_v, 0.01*v_v): + if checkInbound(v, PS, 0.01*PS): + v_new = PS + else: + if v > PS: + v_new = v_v - abs(PS-v_v)/4 + else: + v_new = v_v + abs(PS-v_v)/4 + else: + if v > v_v: + v_new = v_v - abs(PS-v_v)/4 + else: + v_new = v_v + abs(PS-v_v)/4 + else: + v_new = (v_v * (d/IPD)**2) #Der Exponent gibt an, wie schnell die Aenderung umgesetzt werden soll + return v_new + +def variante_2(d): + v_new = None + if d < IPD - IPD_TOL: + v_new = (v_v * (d/(IPD - IPD_TOL))**2) #Der Exponent gibt an, wie schnell die Aenderung umgesetzt werden soll + elif d > IPD + IPD_TOL: + v_new = (v_v * (d/(IPD + IPD_TOL))**2) #Der Exponent gibt an, wie schnell die Aenderung umgesetzt werden soll + else: + v_new = v_v + return v_new + +def variante_3(d): + v_new = (v_v * (d/(IPD))**DIST_POW) #Der Exponent gibt an, wie schnell die Aenderung umgesetzt werden soll + return v_new + +def variante_4(d): + v_new = (v_v * (d/(IPD))**DIST_POW * (PS/v_v)**SPEED_POW) #Der Exponent gibt an, wie schnell die Aenderung umgesetzt werden soll + return v_new + +for d in ds: + v_new = variante_4(d) + v_news.append(v_new) + +plt.plot(ds, v_news,'b', label='v_new') +plt.plot(ds, [v_v for d in ds],'tab:orange', label='v_v') +plt.plot(ds, [PS for d in ds], 'g', label='PS') +plt.plot(ds, [v for d in ds], 'b--', label='v') +plt.plot([IPD, IPD], [0, max(v_news)], 'r', label='IPD') +plt.plot([IPD - IPD_TOL, IPD - IPD_TOL], [0, max(v_news)], 'r--', label='IPD-') +plt.plot([IPD + IPD_TOL, IPD + IPD_TOL], [0, max(v_news)], 'r--', label='IPD+') +plt.legend() +plt.show()