Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8a0efc0
tunnel factor added
Roli15 May 20, 2026
379d221
speed limits train length adjusted
Roli15 May 21, 2026
c79639e
wip
Roli15 May 21, 2026
9b6bc8c
wip 2
Roli15 May 21, 2026
518780b
fix tunnel parameter
Roli15 May 21, 2026
2265ec6
Merge branch 'recovered-work'
Roli15 May 21, 2026
3c32acd
gradients length dependent
Roli15 May 21, 2026
9776a58
fixed time approx
Roli15 May 22, 2026
9b9c212
curvature train length dependent
Roli15 May 22, 2026
43b6e16
bug fixes
Roli15 May 22, 2026
0e20613
bug fix
Roli15 May 22, 2026
0089887
length dependent constant values adjusted
Roli15 May 26, 2026
b1b1566
tunnel resistance made to list
Roli15 May 26, 2026
52fdc5e
update tunnel resistance format
Roli15 May 26, 2026
6a0b452
test tunnel resistance added
Roli15 May 26, 2026
97c20ab
test speed limit added
Roli15 May 27, 2026
1a2a00b
test gradients added
Roli15 May 27, 2026
8fe528e
test curvature added
Roli15 May 27, 2026
6aab544
implementation of pull request feedback
Roli15 May 27, 2026
32d3c76
bug fixes
Roli15 May 27, 2026
281cb14
wip
Roli15 Jun 1, 2026
6d4b0af
wip 2
Roli15 Jun 1, 2026
654534a
wip 3
Roli15 Jun 2, 2026
297f6a9
wip 4
Roli15 Jun 2, 2026
4c8cd77
gradient unit tests finished
Roli15 Jun 2, 2026
cc1dbcb
unit test amended
Roli15 Jun 3, 2026
ab7e79a
merged upstream origin
Roli15 Jun 3, 2026
5b58c06
bug fixes
Roli15 Jun 3, 2026
914d72a
braking curves added
Roli15 Jun 4, 2026
390c116
etcs file added
Roli15 Jun 5, 2026
52b83c7
refactoring etcs
Roli15 Jun 5, 2026
ccf8da7
revisions pull request
Roli15 Jun 8, 2026
7c986ca
small refactoring of etcs.py
Roli15 Jun 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
531 changes: 531 additions & 0 deletions mseetc/etcs.py

Large diffs are not rendered by default.

31 changes: 24 additions & 7 deletions mseetc/ocp.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from mseetc.track import computeDiscretizationPoints

from mseetc.utils import Options, var, postProcessDataFrame, splitLosses
from mseetc.utils import Options, var, postProcessDataFrame, splitLosses, computeTunnelFactor


class OptionsCasadiSolver(Options):
Expand All @@ -27,6 +27,10 @@ def __init__(self, paramsDict):

self.integrateLosses = False # integrate losses or take mid-point rule

self.chooseClosestTunnelCrossSection = True # if exact tunnel cross section is not specified in train tunnel resistances, choose the closest value

self.pwcLengthDependentTrackAttributes = False

super().__init__(paramsDict)


Expand Down Expand Up @@ -121,7 +125,7 @@ def __init__(self, train, track, optsDict={}):

# track parameters

self.points = computeDiscretizationPoints(track, numIntervals)
self.points = computeDiscretizationPoints(track, numIntervals, opts)
self.steps = np.diff(self.points.index)

# real-time parameters
Expand Down Expand Up @@ -193,16 +197,28 @@ def __init__(self, train, track, optsDict={}):

# gradient and curvature of current index
grad = self.points.iloc[i]['Gradient [permil]']/1e3
gradLinearTerm = self.points.iloc[i]["Gradient linear term [permil/m]"]/1e3
curv = self.points.iloc[i]['Curvature [1/m]']
curvLinearTerm = self.points.iloc[i]["Curvature linear term [1/m^2]"]
crossSection = self.points.iloc[i]['CrossSection [m^2]']
tunnelFactor = computeTunnelFactor(crossSection, train, opts)

# acceleration constraints
g += [trainModel.accelerationFun(ca.vertcat(time[i], velSq[i]), ca.vcat(u), grad, curv)]
g += [trainModel.accelerationFun(ca.vertcat(time[i], velSq[i], 0), ca.vcat(u), grad, gradLinearTerm, curv, curvLinearTerm, tunnelFactor)]
lbg += [accMin]
ubg += [accMax]

# coupling constraints
out = trainIntegrator.solve(time=time[i], velocitySquared=velSq[i], ds=self.steps[i],
traction=Fel[i], pnBrake=Fpb[i], gradient=grad, curvature=curv)
out = trainIntegrator.solve(time=time[i],
velocitySquared=velSq[i],
ds=self.steps[i],
traction=Fel[i],
pnBrake=Fpb[i],
gradient=grad,
gradientLinearTerm=gradLinearTerm,
curvature=curv,
curvatureLinearTerm=curvLinearTerm,
tunnelFactor=tunnelFactor)

xNxt1 = ca.vertcat(time[i+1], velSq[i+1])
xNxt2 = ca.vertcat(out['time'], out['velSquared'])
Expand Down Expand Up @@ -322,7 +338,8 @@ def solve(self, terminalTime, initialTime=0, terminalVelocity=1, initialVelocity
# initial guess
# NOTE: good idea vel0 to be compatible with f0 (power-wise) to avoid nans at first iteration

vel0 = (60/3.6)**2
vel_avg = (self.points.index[-1]-self.points.index[0])/(terminalTime-initialTime) * 0.95
vel0 = vel_avg*vel_avg

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a test that runs all paper simulations and simply checks that solver converges. We might need to slightly adapt the scripts to output solver status. Maybe on a separate PR as this one is getting too big

dt = (terminalTime - initialTime)/self.numIntervals
t0 = initialTime

Expand Down Expand Up @@ -437,4 +454,4 @@ def solve(self, terminalTime, initialTime=0, terminalVelocity=1, initialVelocity

else:

print("Solver failed!")
print("Solver failed!")
Loading