Source code for raidnr.core.speed_curve



# ----------------------------------------------------
# 
# 
# ██████╗  █████╗ ██╗██████╗     ███╗   ██╗██████╗ 
# ██╔══██╗██╔══██╗██║██╔══██╗    ████╗  ██║██╔══██╗
# ██████╔╝███████║██║██║  ██║    ██╔██╗ ██║██████╔╝
# ██╔══██╗██╔══██║██║██║  ██║    ██║╚██╗██║██╔══██╗
# ██║  ██║██║  ██║██║██████╔╝    ██║ ╚████║██║  ██║
# ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═════╝     ╚═╝  ╚═══╝╚═╝  ╚═╝
# 
# 
# ----------------------------------------------------
# 
# 
#-----------------------------------------------------
# 
# Speed Curve v.01
# 21.06.18
# Ioannis Toumpalidis
# 
#-----------------------------------------------------
# Description
#-----------------------------------------------------
# 
# Scripts modeling the actuall speed of a train, given 
# an aligment and the permissable speed for each segment.
# 
#-----------------------------------------------------


import pandas as pd
import numpy as np

import matplotlib.pyplot as plt

from shapely.geometry import LineString

import os

import geopandas as gpd

from matplotlib.colors import Normalize
from matplotlib import cm
import math

from scipy.interpolate import interp1d

# raidnr
from raidnr.config import acceleration_x, acceleration_y


# set module's global variables
f2a=interp1d(acceleration_x, acceleration_y, kind='linear')


[docs]def set_acceleration_curve(acc_x=[0,17.8816,20.1168,22.352,24.587,26.822,60], acc_y=[0.49,0.240,0.195,0.156,0.126,0.120,0.05], kind="linear"): """ Set the kind of the interpolation for the acceleration curve """ global f2a f2a =interp1d(acc_x, acc_y, kind=kind)
[docs]def get_acceleration_curve(): """ """ global f2a xticks = np.arange(0,60) yticks = [f2a(i) for i in xticks] fig,ax = plt.subplots(figsize=(4,4)) ax.plot(xticks,yticks) plt.show()
[docs]def v_given_s(v0,smax,braking=False): """ """ # if braking constant deceleration of a=0.5 m/s if(braking): try: v=math.sqrt((v0**2)-(2*0.5*smax)) except: v=0 else: # otherwise compute acceleration based on the curve s=v=0 # approximating the integral da/dt while(s<smax): s+=1 v=math.sqrt(v0**2+2*f2a(v0)) v0=v return v
[docs]def s_to_reach_v(v0,v_final): """ """ s=0 if(v_final>v0): while(v0<v_final): s += ((v0+0.1)**2-v0**2)/float(2*f2a(v0)) v0+=0.1 else: s = abs((v_final**2-v0**2)/float(2*0.5)) return s
[docs]def max_speed_before_braking(v0,v_final,smax): """ """ curposition=0 required_distance=0 while(required_distance<smax): curposition+=1 v=math.sqrt(v0**2+2*f2a(v0)) braking_distance = s_to_reach_v(v,v_final) required_distance = curposition+ braking_distance v0=v return v,curposition
[docs]def interpolate_segment(distance,segment): """ """ newPoint=segment.interpolate(distance) return newPoint.coords[0]
[docs]def find_speed_curve(segments,speeds): """ """ vEnteringSegment=0 speedPointsSpeed=[0] speedPointsDistance=[0] pointSegments=[segments[0].coords[0]] sTravelled=0 for n in range(len(segments)): # given a segment_n E segments=[segment_1,segment_2,...segment_N] segment = segments[n] # a maxSpeed for this segment: maxSpeed = speeds[n] # and a v0 (m/s) that the train has while entering the segment v0=vEnteringSegment if(v0>maxSpeed): print("Bad transition") print(vEnteringSegment,maxSpeed,n) # Check if we can achieve maxSpeed in the current segment # check if sVmax > segment.length sVmax=s_to_reach_v(v0,maxSpeed) # if sVmax grater than segment.length # compute the speed of train in the end of the segment (assume vLeavingSegment(i) == vEnteringSemgnt(i+1) ) if(sVmax>segment.length): curspeed=v_given_s(v0,segment.length) sVmax = segment.length remaining_distance =0 else: # otherwise we reached MaxSpeed curspeed = maxSpeed # for the remaining distance remaining_distance = segment.length - sVmax # if a following segment exists if(n+1< len(segments)): # find the next segment's max speed nextSegmentMaxSpeed = speeds[n+1] else: # if not, suppose stopping of the train after this segment nextSegmentMaxSpeed = 0 # we compute if braking needs to be applied # keeping in mind that we can not accelerate further and exceed the maxSpeed # (1) we only consider the case that the nextSegmentMaxSpeed is lower than the current's segment maxSpeed...(1) if(nextSegmentMaxSpeed< curspeed): # so we claculate the braking distance required for the train to enter the next segment with the required speed brakingDistance=s_to_reach_v(curspeed,nextSegmentMaxSpeed) # there might be cases where the brakingDistance exceeds the remaining distance if(remaining_distance < brakingDistance): # so we need to "go back" and shorten the length of the first segment where we accelerated to reach the maxSpeed # find the new max speed that can be reached so we can safely brake and enter the next segment with # the nextSegmentMaxSpeed speed maxSpeedReached,brakingPoint= max_speed_before_braking(v0,nextSegmentMaxSpeed,segment.length) speedPointsSpeed.append(maxSpeedReached) speedPointsDistance.append(brakingPoint + sTravelled) # control Point cp = interpolate_segment(brakingPoint, segment) pointSegments.append(cp) # due to the step, integral might vary # so to be accurate # vLeavingSegment= v_given_s(maxSpeedReached,segment.length - brakingPoint, True) # continue to the next segment vEnteringSegment = nextSegmentMaxSpeed speedPointsSpeed.append(nextSegmentMaxSpeed) speedPointsDistance.append(segment.length + sTravelled) # control Point pointSegments.append(segments[n].coords[-1]) else: brakingPoint = segment.length-brakingDistance # continue to the next segment vEnteringSegment = nextSegmentMaxSpeed vLeavingSegment = nextSegmentMaxSpeed speedPointsDistance.append(sVmax+sTravelled) speedPointsSpeed.append(curspeed) # control Point cp = interpolate_segment(sVmax, segment) pointSegments.append(cp) speedPointsDistance.append(brakingPoint + sTravelled) speedPointsSpeed.append(curspeed) # control Point cp = interpolate_segment(brakingPoint, segment) pointSegments.append(cp) speedPointsDistance.append(segment.length + sTravelled) speedPointsSpeed.append(nextSegmentMaxSpeed) # control Point cp = segment.coords[-1] pointSegments.append(cp) #...else from statement (1) #we continue with the current speed till the end of the segment else: # first part till we reach maxspeed speedPointsSpeed.append(curspeed) speedPointsDistance.append(sVmax + sTravelled) # control Point cp = interpolate_segment(sVmax, segment) pointSegments.append(cp) # second part till we move out the segment speedPointsSpeed.append(curspeed) speedPointsDistance.append(segment.length + sTravelled) # control Point cp = segment.coords[-1] pointSegments.append(cp) # continue to the next segment vEnteringSegment = curspeed # move train to the next segment sTravelled += segment.length return speedPointsDistance,speedPointsSpeed, pointSegments