Refactor output detail and format and adapt examples
parent
8a97de3fdf
commit
99c873a4e7
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/env julia
|
#!/usr/bin/env julia
|
||||||
|
|
||||||
using TrainRuns
|
using TrainRuns
|
||||||
|
using CSV
|
||||||
|
|
||||||
paths=[]
|
paths=[]
|
||||||
push!(paths, Path("test/data/paths/const.yaml"))
|
push!(paths, Path("test/data/paths/const.yaml"))
|
||||||
|
@ -8,28 +9,16 @@ push!(paths, Path("test/data/paths/slope.yaml"))
|
||||||
push!(paths, Path("test/data/paths/speed.yaml"))
|
push!(paths, Path("test/data/paths/speed.yaml"))
|
||||||
push!(paths, Path("test/data/paths/realworld.yaml"))
|
push!(paths, Path("test/data/paths/realworld.yaml"))
|
||||||
|
|
||||||
settings=[]
|
|
||||||
push!(settings, Settings("test/data/settings/driving_course.yaml"))
|
|
||||||
|
|
||||||
trains=[]
|
trains=[]
|
||||||
push!(trains, Train("test/data/trains/freight.yaml"))
|
push!(trains, Train("test/data/trains/freight.yaml"))
|
||||||
push!(trains, Train("test/data/trains/local.yaml"))
|
push!(trains, Train("test/data/trains/local.yaml"))
|
||||||
push!(trains, Train("test/data/trains/longdistance.yaml"))
|
push!(trains, Train("test/data/trains/longdistance.yaml"))
|
||||||
|
|
||||||
driving_courses=[]
|
settings = Settings("test/data/settings/driving_course.yaml")
|
||||||
for path in paths
|
|
||||||
# println(" - - - - - - - - -")
|
|
||||||
# println("path: ", path[:name])
|
|
||||||
for train in trains
|
|
||||||
# println("train: ", train[:name])
|
|
||||||
for settings in settings
|
|
||||||
push!(driving_courses, trainrun(train, path, settings))
|
|
||||||
#driving_course = trainrun(train, path, settings)
|
|
||||||
|
|
||||||
# old: if haskey(settings, :outputFormat) && settings[:outputFormat] == "CSV"
|
for p in 1:length(paths)
|
||||||
# old: exportToCsv(resultsDict, settings)
|
for t in 1:length(trains)
|
||||||
# old: sleep(2)
|
driving_course = trainrun(trains[t], paths[p], settings)
|
||||||
# old: end
|
CSV.write("docs/examples/drivingCourse_path"*string(p)*"_train"*string(t)*".csv", driving_course, header=false)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,7 @@ using TrainRuns
|
||||||
train = Train("test/data/trains/freight.yaml")
|
train = Train("test/data/trains/freight.yaml")
|
||||||
path = Path("test/data/paths/const.yaml")
|
path = Path("test/data/paths/const.yaml")
|
||||||
|
|
||||||
runtime = trainrun(train, path)
|
runtime_dataFrame = trainrun(train, path)
|
||||||
|
runtime = runtime_dataFrame[!, 1][2]
|
||||||
|
|
||||||
println("The train needs $runtime seconds for the running path.")
|
println("The train needs $runtime seconds for the running path.")
|
||||||
|
|
|
@ -19,7 +19,7 @@ trainrun, Train, Path, Settings
|
||||||
|
|
||||||
## global variables
|
## global variables
|
||||||
global g = 9.80665 # acceleration due to gravity (in m/s^2)
|
global g = 9.80665 # acceleration due to gravity (in m/s^2)
|
||||||
global μ = 0.2 # friction as constant, todo: implement as function
|
global μ = 0.2 # friction as constant, TODO: implement as function
|
||||||
global Δv_air = 15.0/3.6 # coefficient for velocitiy difference between train and outdoor air (in m/s)
|
global Δv_air = 15.0/3.6 # coefficient for velocitiy difference between train and outdoor air (in m/s)
|
||||||
|
|
||||||
## include package files
|
## include package files
|
||||||
|
@ -49,14 +49,14 @@ xxx.xx # in seconds
|
||||||
function trainrun(train::Train, path::Path, settings=Settings()::Settings)
|
function trainrun(train::Train, path::Path, settings=Settings()::Settings)
|
||||||
# prepare the input data
|
# prepare the input data
|
||||||
movingSection = determineCharacteristics(path, train, settings)
|
movingSection = determineCharacteristics(path, train, settings)
|
||||||
settings.outputDetail == :everything && println("The moving section has been prepared.")
|
# settings.outputDetail == :verbose && println("The moving section has been prepared.")
|
||||||
|
|
||||||
# calculate the train run for oparation mode "minimum running time"
|
# calculate the train run for oparation mode "minimum running time"
|
||||||
(movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
|
(movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
|
||||||
settings.outputDetail == :everything && println("The driving course for the shortest running time has been calculated.")
|
# settings.outputDetail == :verbose && println("The driving course for the shortest running time has been calculated.")
|
||||||
|
|
||||||
# accumulate data and create an output dictionary
|
# accumulate data and create an output dictionary
|
||||||
output = createOutput(train, settings, path, movingSection, drivingCourse)
|
output = createOutput(settings, path, drivingCourse)
|
||||||
|
|
||||||
return output
|
return output
|
||||||
end # function trainrun
|
end # function trainrun
|
||||||
|
|
|
@ -52,12 +52,12 @@ function Settings(file="DEFAULT")
|
||||||
"outputDetail": {
|
"outputDetail": {
|
||||||
"description": "Selecting the detail of the result",
|
"description": "Selecting the detail of the result",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [ "running_time", "points_of_interest", "driving_course", "everything" ]
|
"enum": [ "running_time", "points_of_interest", "driving_course" ]
|
||||||
},
|
},
|
||||||
"outputFormat": {
|
"outputFormat": {
|
||||||
"description": "Output format",
|
"description": "Output format",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [ "dataframe", "dict" ]
|
"enum": [ "dataframe", "vector" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}""")
|
}""")
|
||||||
|
@ -302,7 +302,7 @@ function Train(file, type = :YAML)
|
||||||
ξ_cars = 1.06 # rotation mass factor
|
ξ_cars = 1.06 # rotation mass factor
|
||||||
transportType = :freight # "freight" or "passenger" for resistance calculation
|
transportType = :freight # "freight" or "passenger" for resistance calculation
|
||||||
v_limit = 140 # in m/s (default 504 km/h)
|
v_limit = 140 # in m/s (default 504 km/h)
|
||||||
a_braking = 0 # in m/s^2, todo: implement as function
|
a_braking = 0 # in m/s^2, TODO: implement as function
|
||||||
f_Rtd0 = 0 # coefficient for basic resistance due to the traction unit's driving axles (in ‰)
|
f_Rtd0 = 0 # coefficient for basic resistance due to the traction unit's driving axles (in ‰)
|
||||||
f_Rtc0 = 0 # coefficient for basic resistance due to the traction unit's carring axles (in ‰)
|
f_Rtc0 = 0 # coefficient for basic resistance due to the traction unit's carring axles (in ‰)
|
||||||
f_Rt2 = 0 # coefficient for air resistance of the traction unit (in ‰)
|
f_Rt2 = 0 # coefficient for air resistance of the traction unit (in ‰)
|
||||||
|
@ -712,7 +712,7 @@ function createDataPoint()
|
||||||
:R_train => 0.0, # train resistance (in N)
|
:R_train => 0.0, # train resistance (in N)
|
||||||
:R_traction => 0.0, # traction unit resistance (in N)
|
:R_traction => 0.0, # traction unit resistance (in N)
|
||||||
:R_wagons => 0.0, # set of wagons resistance (in N)
|
:R_wagons => 0.0, # set of wagons resistance (in N)
|
||||||
:label => "" # a label for importend points
|
:label => "" # a label for important points
|
||||||
)
|
)
|
||||||
return dataPoint
|
return dataPoint
|
||||||
end #function createDataPoint
|
end #function createDataPoint
|
||||||
|
|
|
@ -5,15 +5,12 @@
|
||||||
# __copyright__ = "2020-2022"
|
# __copyright__ = "2020-2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
using DataFrames
|
function createOutput(settings::Settings, path::Path, drivingCourse::Vector{Dict})
|
||||||
|
|
||||||
function createOutput(train::Train, settings::Settings, path::Path, movingSection::Dict, drivingCourse::Vector{Dict})
|
|
||||||
if settings.outputDetail == :running_time
|
if settings.outputDetail == :running_time
|
||||||
output = drivingCourse[end][:t]
|
output::Vector{Dict} = [Dict(:t => drivingCourse[end][:t])]
|
||||||
|
|
||||||
elseif settings.outputDetail == :points_of_interest
|
elseif settings.outputDetail == :points_of_interest && !isempty(path.poi)
|
||||||
# add points of interest
|
# add points of interest
|
||||||
if !isempty(path.poi)
|
|
||||||
|
|
||||||
# output = Dict[]
|
# output = Dict[]
|
||||||
# POI = 1
|
# POI = 1
|
||||||
|
@ -28,77 +25,45 @@ function createOutput(train::Train, settings::Settings, path::Path, movingSectio
|
||||||
|
|
||||||
# get only the driving course's data points with POI labels
|
# get only the driving course's data points with POI labels
|
||||||
output = Dict[]
|
output = Dict[]
|
||||||
for point in 1:length(drivingCourse)
|
for point in drivingCourse
|
||||||
if point[:label] != ""
|
if point[:label] != ""
|
||||||
push!(output, point)
|
push!(output, point)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
elseif settings.outputDetail == :driving_course
|
else #if settings.outputDetail == :driving_course || (settings.outputDetail == :points_of_interest && !isempty(path.poi))
|
||||||
output = drivingCourse
|
output = drivingCourse
|
||||||
|
|
||||||
elseif settings.outputDetail == :everything
|
|
||||||
output = Dict{Symbol,Any}()
|
|
||||||
merge!(output, Dict(:train => train, :path => path, :settings => settings))
|
|
||||||
|
|
||||||
|
|
||||||
# add moving section and driving courses
|
|
||||||
merge!(output, Dict(:movingSection => movingSection,
|
|
||||||
:drivingCourse => drivingCourse))
|
|
||||||
|
|
||||||
|
|
||||||
# add points of interest
|
|
||||||
if !isempty(path.poi)
|
|
||||||
pointsOfInterest = Dict[]
|
|
||||||
# get only the driving course's data points with POI labels
|
|
||||||
output = Dict[]
|
|
||||||
for point in 1:length(drivingCourse)
|
|
||||||
if point[:label] != ""
|
|
||||||
push!(pointsOfInterest, point)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
merge!(output, Dict(:pointsOfInterest => pointsOfInterest))
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if settings.outputFormat == :dataframe
|
if settings.outputFormat == :dataframe
|
||||||
return createDataFrameForDataPoints(output[:drivingCourse])
|
return createDataFrame(output, settings.outputDetail)
|
||||||
else
|
elseif settings.outputFormat == :vector
|
||||||
return output
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if settings.outputFormat == :dataframe
|
|
||||||
return createDataFrame(output)
|
|
||||||
else
|
|
||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function createDataFrame(runningTime::AbstractFloat)
|
function createDataFrame(output_vector::Vector{Dict}, outputDetail)
|
||||||
|
if outputDetail == :running_time
|
||||||
# create DataFrame with running time information
|
# create DataFrame with running time information
|
||||||
dataFrame = DataFrame(column1=["t (in s)", runningTime])
|
dataFrame = DataFrame(column1=["t (in s)", output_vector[end][:t]])
|
||||||
end
|
else # :points_of_interest or :driving_course
|
||||||
|
header = ["label", "driving mode", "s (in m)", "v (in m/s)", "t (in s)", "a (in m/s^2)", "F_T (in N)", "F_R (in N)", "R_path (in N)", "R_traction (in N)", "R_wagons (in N)"]
|
||||||
function createDataFrame(dataPoints::Vector{Dict})
|
columnSymbols = [:label, :behavior, :s, :v, :t, :a, :F_T, :F_R, :R_path, :R_traction, :R_wagons]
|
||||||
header = ["i", "behavior", "station label", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)","a (in m/s^2)"]
|
|
||||||
columnSymbols = [:i, :behavior, :label, :Δs, :s, :Δt, :t, :Δv, :v, :F_T, :F_R, :R_path, :R_train, :R_traction, :R_wagons, :a]
|
|
||||||
|
|
||||||
allColumns = Array{Any,1}[]
|
allColumns = Array{Any,1}[]
|
||||||
for column in 1:length(header)
|
for column in 1:length(header)
|
||||||
currentColumn = Any[]
|
currentColumn = Any[]
|
||||||
push!(currentColumn, header[column])
|
push!(currentColumn, header[column])
|
||||||
for point in dataPoints
|
for point in output_vector
|
||||||
push!(currentColumn, point[columnSymbols[column]])
|
push!(currentColumn, point[columnSymbols[column]])
|
||||||
end
|
end
|
||||||
push!(allColumns, currentColumn)
|
push!(allColumns, currentColumn)
|
||||||
end # for
|
end # for
|
||||||
|
|
||||||
# combine the columns in a data frame
|
# combine the columns in a data frame
|
||||||
dataFrame = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16])
|
dataFrame = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11])
|
||||||
|
end
|
||||||
|
|
||||||
return dataFrame
|
return dataFrame
|
||||||
end #createDataFrameForDrivingCourse
|
end #createDataFrameForDrivingCourse
|
||||||
|
|
|
@ -11,9 +11,9 @@ struct Settings
|
||||||
stepVariable::Symbol # variable of the linear multistep method: ":distance", ":time" or ":velocity".
|
stepVariable::Symbol # variable of the linear multistep method: ":distance", ":time" or ":velocity".
|
||||||
stepSize::Real # step size, unit depends on stepVariable - :distance in meter, time in seconds and velocity in meter/second.
|
stepSize::Real # step size, unit depends on stepVariable - :distance in meter, time in seconds and velocity in meter/second.
|
||||||
approxLevel::Int # value for approximation; used when rounding or iterating.
|
approxLevel::Int # value for approximation; used when rounding or iterating.
|
||||||
outputDetail::Symbol # single Float() ":running_time", Array() of ":points_of_interest",
|
outputDetail::Symbol # single Float() ":running_time", Vector() of ":points_of_interest",
|
||||||
# complete Array() ":driving_course", or Dict() ":everything".
|
# or complete Vector() ":driving_course"
|
||||||
outputFormat::Symbol # output as ":dataframe" or as ":dict".
|
outputFormat::Symbol # output as ":dataframe" or as ":vector".
|
||||||
|
|
||||||
end #struct Settings
|
end #struct Settings
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
%YAML 1.2
|
%YAML 1.2
|
||||||
---
|
---
|
||||||
settings:
|
settings:
|
||||||
outputDetail: "driving_course" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
outputDetail: "driving_course" # single value "running_time", list of "points_of_interest", complete "driving_course"
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
settings:
|
|
||||||
outputDetail: "everything" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
|
|
@ -1,4 +1,4 @@
|
||||||
%YAML 1.2
|
%YAML 1.2
|
||||||
---
|
---
|
||||||
settings:
|
settings:
|
||||||
outputDetail: "points_of_interest" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
outputDetail: "points_of_interest" # single value "running_time", list of "points_of_interest", complete "driving_course"
|
||||||
|
|
|
@ -14,25 +14,24 @@ settings = Dict()
|
||||||
@testset "load data" begin
|
@testset "load data" begin
|
||||||
|
|
||||||
println("testing load train data")
|
println("testing load train data")
|
||||||
push!(trains, :freight => @time Train("data/trains/freight.yaml"))
|
push!(trains, :freight => @time Train("test/data/trains/freight.yaml"))
|
||||||
push!(trains, :local => @time Train("data/trains/local.yaml"))
|
push!(trains, :local => @time Train("test/data/trains/local.yaml"))
|
||||||
push!(trains, :longdistance => @time Train("data/trains/longdistance.yaml"))
|
push!(trains, :longdistance => @time Train("test/data/trains/longdistance.yaml"))
|
||||||
|
|
||||||
println("testing load path data")
|
println("testing load path data")
|
||||||
push!(paths, :const => @time Path("data/paths/const.yaml"))
|
push!(paths, :const => @time Path("test/data/paths/const.yaml"))
|
||||||
push!(paths, :slope => @time Path("data/paths/slope.yaml"))
|
push!(paths, :slope => @time Path("test/data/paths/slope.yaml"))
|
||||||
push!(paths, :speed => @time Path("data/paths/speed.yaml"))
|
push!(paths, :speed => @time Path("test/data/paths/speed.yaml"))
|
||||||
push!(paths, :realworld => @time Path("data/paths/realworld.yaml"))
|
push!(paths, :realworld => @time Path("test/data/paths/realworld.yaml"))
|
||||||
|
|
||||||
println("testing load settings data")
|
println("testing load settings data")
|
||||||
push!(settings, "default" => @time Settings())
|
push!(settings, "default" => @time Settings())
|
||||||
push!(settings, "poi" => @time Settings("data/settings/points_of_interest.yaml"))
|
push!(settings, "poi" => @time Settings("test/data/settings/points_of_interest.yaml"))
|
||||||
push!(settings, "drivingcourse" => @time Settings("data/settings/driving_course.yaml"))
|
push!(settings, "drivingcourse" => @time Settings("test/data/settings/driving_course.yaml"))
|
||||||
push!(settings, "everything" => @time Settings("data/settings/everything.yaml"))
|
push!(settings, "strip" => @time Settings("test/data/settings/strip.yaml"))
|
||||||
push!(settings, "strip" => @time Settings("data/settings/strip.yaml"))
|
push!(settings, "time" => @time Settings("test/data/settings/time.yaml"))
|
||||||
push!(settings, "time" => @time Settings("data/settings/time.yaml"))
|
push!(settings, "timestrip" => @time Settings("test/data/settings/time_strip.yaml"))
|
||||||
push!(settings, "timestrip" => @time Settings("data/settings/time_strip.yaml"))
|
push!(settings, "velocity" => @time Settings("test/data/settings/velocity.yaml"))
|
||||||
push!(settings, "velocity" => @time Settings("data/settings/velocity.yaml"))
|
|
||||||
|
|
||||||
@test typeof(first(paths)[2]) == Path
|
@test typeof(first(paths)[2]) == Path
|
||||||
@test typeof(first(settings)[2]) == Settings
|
@test typeof(first(settings)[2]) == Settings
|
||||||
|
@ -75,7 +74,8 @@ anticipated = Dict(
|
||||||
for test in tests
|
for test in tests
|
||||||
test_name = String(test[1][1]) * "_" * String(test[2][1])
|
test_name = String(test[1][1]) * "_" * String(test[2][1])
|
||||||
println("testing $test_name")
|
println("testing $test_name")
|
||||||
@time result = trainrun(test[1][2],test[2][2])
|
@time result_dataFrame = trainrun(test[1][2], test[2][2])
|
||||||
|
result = result_dataFrame[!, 1][2]
|
||||||
expected = anticipated[:default][Symbol(test_name)]
|
expected = anticipated[:default][Symbol(test_name)]
|
||||||
# compare result to test data set
|
# compare result to test data set
|
||||||
@test isapprox(result, expected, rtol=0.01)
|
@test isapprox(result, expected, rtol=0.01)
|
||||||
|
|
Loading…
Reference in New Issue