extraParams in addition to routing-profile

This commit is contained in:
Arndt Brenschede 2018-03-10 09:25:46 +01:00
parent c9593331bd
commit 0325c33cdf
9 changed files with 99 additions and 37 deletions

View file

@ -5,7 +5,8 @@
*/ */
package btools.router; package btools.router;
import btools.expressions.BExpressionContext; import java.util.Map;
import btools.expressions.BExpressionContextNode; import btools.expressions.BExpressionContextNode;
import btools.expressions.BExpressionContextWay; import btools.expressions.BExpressionContextWay;
@ -27,6 +28,7 @@ class KinematicModel extends OsmPathModel
public double f_air; public double f_air;
public double f_recup; public double f_recup;
public double p_standby; public double p_standby;
public double outside_temp;
public double recup_efficiency; public double recup_efficiency;
public double totalweight; public double totalweight;
public double vmax; public double vmax;
@ -44,34 +46,51 @@ class KinematicModel extends OsmPathModel
protected BExpressionContextWay ctxWay; protected BExpressionContextWay ctxWay;
protected BExpressionContextNode ctxNode; protected BExpressionContextNode ctxNode;
protected Map<String,String> params;
private boolean initDone = false;
@Override @Override
public void init( BExpressionContextWay expctxWay, BExpressionContextNode expctxNode ) public void init( BExpressionContextWay expctxWay, BExpressionContextNode expctxNode, Map<String,String> extraParams )
{ {
ctxWay = expctxWay; if ( !initDone )
ctxNode = expctxNode; {
ctxWay = expctxWay;
BExpressionContext expctxGlobal = expctxWay; // just one of them... ctxNode = expctxNode;
wayIdxMaxspeed = ctxWay.getOutputVariableIndex( "maxspeed", false );
wayIdxMinspeed = ctxWay.getOutputVariableIndex( "minspeed", false );
nodeIdxMaxspeed = ctxNode.getOutputVariableIndex( "maxspeed", false );
initDone = true;
}
turnAngleDecayLength = expctxGlobal.getVariableValue( "turnAngleDecayLength", 50.f ); params = extraParams;
f_roll = expctxGlobal.getVariableValue( "f_roll", 232.f );
f_air = expctxGlobal.getVariableValue( "f_air", 0.4f ); turnAngleDecayLength = getParam( "turnAngleDecayLength", 50.f );
f_recup = expctxGlobal.getVariableValue( "f_recup", 400.f ); f_roll = getParam( "f_roll", 232.f );
p_standby = expctxGlobal.getVariableValue( "p_standby", 250.f ); f_air = getParam( "f_air", 0.4f );
recup_efficiency = expctxGlobal.getVariableValue( "recup_efficiency", 0.7f ); f_recup = getParam( "f_recup", 400.f );
totalweight = expctxGlobal.getVariableValue( "totalweight", 1640.f ); p_standby = getParam( "p_standby", 250.f );
vmax = expctxGlobal.getVariableValue( "vmax", 80.f ) / 3.6; outside_temp = getParam( "outside_temp", 20.f );
leftWaySpeed = expctxGlobal.getVariableValue( "leftWaySpeed", 12.f ) / 3.6; recup_efficiency = getParam( "recup_efficiency", 0.7f );
rightWaySpeed = expctxGlobal.getVariableValue( "rightWaySpeed", 12.f ) / 3.6; totalweight = getParam( "totalweight", 1640.f );
vmax = getParam( "vmax", 80.f ) / 3.6;
leftWaySpeed = getParam( "leftWaySpeed", 12.f ) / 3.6;
rightWaySpeed = getParam( "rightWaySpeed", 12.f ) / 3.6;
xweight = 1./( 2. * f_air * vmax * vmax * vmax - p_standby ); xweight = 1./( 2. * f_air * vmax * vmax * vmax - p_standby );
timecost0 = 1./vmax + xweight*(f_roll + f_air*vmax*vmax + p_standby/vmax ); timecost0 = 1./vmax + xweight*(f_roll + f_air*vmax*vmax + p_standby/vmax );
}
wayIdxMaxspeed = ctxWay.getOutputVariableIndex( "maxspeed", false );
wayIdxMinspeed = ctxWay.getOutputVariableIndex( "minspeed", false );
nodeIdxMaxspeed = ctxNode.getOutputVariableIndex( "maxspeed", false ); protected float getParam( String name, float defaultValue )
{
String sval = params == null ? null : params.get( name );
if ( sval != null )
{
return Float.parseFloat( sval );
}
float v = ctxWay.getVariableValue( name, defaultValue );
params.put( name, "" + v );
return v;
} }
public float getWayMaxspeed() public float getWayMaxspeed()

View file

@ -5,6 +5,8 @@
*/ */
package btools.router; package btools.router;
import java.util.Map;
import btools.expressions.BExpressionContextNode; import btools.expressions.BExpressionContextNode;
import btools.expressions.BExpressionContextWay; import btools.expressions.BExpressionContextWay;
@ -41,7 +43,7 @@ final class KinematicModelDummy extends KinematicModel
public double timecost0 = 1./vmax + xweight*(f_roll + f_air*vmax*vmax + p_standby/vmax ); public double timecost0 = 1./vmax + xweight*(f_roll + f_air*vmax*vmax + p_standby/vmax );
@Override @Override
public void init( BExpressionContextWay expctxWay, BExpressionContextNode expctxNode ) public void init( BExpressionContextWay expctxWay, BExpressionContextNode expctxNode, Map<String,String> extraParams )
{ {
} }

View file

@ -37,7 +37,7 @@ final class KinematicPath extends OsmPath
} }
@Override @Override
protected double processWaySection( RoutingContext rc, double dist, double delta_h, double angle, double cosangle, boolean isStartpoint, int nsection, int lastpriorityclassifier ) protected double processWaySection( RoutingContext rc, double dist, double delta_h, double elevation, double angle, double cosangle, boolean isStartpoint, int nsection, int lastpriorityclassifier )
{ {
KinematicModel km = (KinematicModel)rc.pm; KinematicModel km = (KinematicModel)rc.pm;
@ -113,7 +113,15 @@ final class KinematicPath extends OsmPath
cutEkin( km.totalweight, turnspeed ); // apply turnspeed cutEkin( km.totalweight, turnspeed ); // apply turnspeed
} }
double distanceCost = evolveDistance( km, dist, delta_h ); // linear temperature correction
double tcorr = (20.-km.outside_temp)*0.0035;
// air_pressure down 1mb/8m
double ecorr = 0.0001375 * (elevation - 100.);
double f_air = km.f_air * ( 1. + tcorr - ecorr );
double distanceCost = evolveDistance( km, dist, delta_h, f_air );
if ( message != null ) if ( message != null )
{ {
@ -124,7 +132,7 @@ final class KinematicPath extends OsmPath
} }
protected double evolveDistance( KinematicModel km, double dist, double delta_h ) protected double evolveDistance( KinematicModel km, double dist, double delta_h, double f_air )
{ {
// elevation force // elevation force
double fh = delta_h * km.totalweight * 9.81 / dist; double fh = delta_h * km.totalweight * 9.81 / dist;
@ -134,7 +142,7 @@ final class KinematicPath extends OsmPath
{ {
return -1.; return -1.;
} }
double elow = 0.5*emax; // recup phase below half energy (=70% vmax) double elow = 0.7*emax; // recup phase below 70% energy (=84% vmax)
double elapsedTime = 0.; double elapsedTime = 0.;
double dissipatedEnergy = 0.; double dissipatedEnergy = 0.;
@ -146,23 +154,24 @@ final class KinematicPath extends OsmPath
boolean slow = ekin < elow; boolean slow = ekin < elow;
boolean fast = ekin >= emax; boolean fast = ekin >= emax;
double etarget = slow ? elow : emax; double etarget = slow ? elow : emax;
double f = km.f_roll + km.f_air*v*v + fh; double f = km.f_roll + f_air*v*v + fh;
double f_recup = Math.max( 0., fast ? -f : (slow ? km.f_recup :0 ) -fh ); // additional recup for slow part double f_recup = Math.max( 0., fast ? -f : (slow ? km.f_recup :0 ) -fh ); // additional recup for slow part
f += f_recup; f += f_recup;
double delta_ekin; double delta_ekin;
double timeStep;
double x; double x;
if ( fast ) if ( fast )
{ {
x = d; x = d;
delta_ekin = x*f; delta_ekin = x*f;
elapsedTime += x/v; timeStep = x/v;
ekin = etarget; ekin = etarget;
} }
else else
{ {
delta_ekin = etarget-ekin; delta_ekin = etarget-ekin;
double b = 2.*km.f_air / km.totalweight; double b = 2.*f_air / km.totalweight;
double x0 = delta_ekin/f; double x0 = delta_ekin/f;
double x0b = x0*b; double x0b = x0*b;
x = x0*(1. - x0b*(0.5 + x0b*(0.333333333-x0b*0.25 ) ) ); // = ln( delta_ekin*b/f + 1.) / b; x = x0*(1. - x0b*(0.5 + x0b*(0.333333333-x0b*0.25 ) ) ); // = ln( delta_ekin*b/f + 1.) / b;
@ -180,13 +189,19 @@ final class KinematicPath extends OsmPath
} }
double v2 = Math.sqrt( 2. * ekin / km.totalweight ); double v2 = Math.sqrt( 2. * ekin / km.totalweight );
double a = f / km.totalweight; // TODO: average force? double a = f / km.totalweight; // TODO: average force?
elapsedTime += (v2-v)/a; timeStep = (v2-v)/a;
v = v2; v = v2;
} }
d -= x; d -= x;
elapsedTime += timeStep;
// dissipated energy does not contain elevation and efficient recup // dissipated energy does not contain elevation and efficient recup
dissipatedEnergy += delta_ekin - x*(fh + f_recup*km.recup_efficiency); dissipatedEnergy += delta_ekin - x*(fh + f_recup*km.recup_efficiency);
// correction: inefficient recup going into heating is half efficient
double ieRecup = x*f_recup*(1.-km.recup_efficiency);
double eaux = timeStep*km.p_standby;
dissipatedEnergy -= Math.max( ieRecup, eaux ) * 0.5;
} }
dissipatedEnergy += elapsedTime * km.p_standby; dissipatedEnergy += elapsedTime * km.p_standby;

View file

@ -305,8 +305,9 @@ abstract class OsmPath implements OsmLinkHolder
} }
} }
double elevation = ele2 == Short.MIN_VALUE ? 100. : ele2/4.;
double sectionCost = processWaySection( rc, dist, delta_h, angle, cosangle, isStartpoint, nsection, lastpriorityclassifier ); double sectionCost = processWaySection( rc, dist, delta_h, elevation, angle, cosangle, isStartpoint, nsection, lastpriorityclassifier );
if ( ( sectionCost < 0. || costfactor > 9998. && !detailMode ) || sectionCost + cost >= 2000000000. ) if ( ( sectionCost < 0. || costfactor > 9998. && !detailMode ) || sectionCost + cost >= 2000000000. )
{ {
cost = -1; cost = -1;
@ -413,7 +414,7 @@ abstract class OsmPath implements OsmLinkHolder
return (short)( e1*(1.-fraction) + e2*fraction ); return (short)( e1*(1.-fraction) + e2*fraction );
} }
protected abstract double processWaySection( RoutingContext rc, double dist, double delta_h, double angle, double cosangle, boolean isStartpoint, int nsection, int lastpriorityclassifier ); protected abstract double processWaySection( RoutingContext rc, double dist, double delta_h, double elevation, double angle, double cosangle, boolean isStartpoint, int nsection, int lastpriorityclassifier );
protected abstract double processTargetNode( RoutingContext rc ); protected abstract double processTargetNode( RoutingContext rc );

View file

@ -5,7 +5,8 @@
*/ */
package btools.router; package btools.router;
import btools.expressions.BExpressionContext; import java.util.Map;
import btools.expressions.BExpressionContextNode; import btools.expressions.BExpressionContextNode;
import btools.expressions.BExpressionContextWay; import btools.expressions.BExpressionContextWay;
@ -16,5 +17,5 @@ abstract class OsmPathModel
public abstract OsmPath createPath(); public abstract OsmPath createPath();
public abstract void init( BExpressionContextWay expctxWay, BExpressionContextNode expctxNode ); public abstract void init( BExpressionContextWay expctxWay, BExpressionContextNode expctxNode, Map<String,String> keyValues );
} }

View file

@ -39,7 +39,8 @@ public final class ProfileCache
profileDir = new File( profileBaseDir ); profileDir = new File( profileBaseDir );
profileFile = new File( profileDir, rc.localFunction + ".brf" ) ; profileFile = new File( profileDir, rc.localFunction + ".brf" ) ;
} }
rc.profileTimestamp = profileFile.lastModified();
rc.profileTimestamp = profileFile.lastModified() + rc.getKeyValueChecksum()<<24;
File lookupFile = new File( profileDir, "lookups.dat" ); File lookupFile = new File( profileDir, "lookups.dat" );
// check for re-use // check for re-use

View file

@ -9,6 +9,7 @@ import java.io.DataOutput;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import btools.expressions.BExpressionContext; import btools.expressions.BExpressionContext;
import btools.expressions.BExpressionContextNode; import btools.expressions.BExpressionContextNode;
@ -30,6 +31,8 @@ public final class RoutingContext
public String localFunction; public String localFunction;
public long profileTimestamp; public long profileTimestamp;
public Map<String,String> keyValues;
public String rawTrackPath; public String rawTrackPath;
public String getProfileName() public String getProfileName()
@ -91,9 +94,27 @@ public final class RoutingContext
throw new RuntimeException( "Cannot create path-model: " + e ); throw new RuntimeException( "Cannot create path-model: " + e );
} }
} }
pm.init( expctxWay, expctxNode ); initModel();
} }
public void initModel()
{
pm.init( expctxWay, expctxNode, keyValues );
}
public long getKeyValueChecksum()
{
long s = 0L;
if ( keyValues != null )
{
for( Map.Entry<String,String> e : keyValues.entrySet() )
{
s += e.getKey().hashCode() + e.getValue().hashCode();
}
}
return s;
}
public void readGlobalConfig() public void readGlobalConfig()
{ {
BExpressionContext expctxGlobal = expctxWay; // just one of them... BExpressionContext expctxGlobal = expctxWay; // just one of them...

View file

@ -5,6 +5,8 @@
*/ */
package btools.router; package btools.router;
import java.util.Map;
import btools.expressions.BExpressionContext; import btools.expressions.BExpressionContext;
import btools.expressions.BExpressionContextNode; import btools.expressions.BExpressionContextNode;
import btools.expressions.BExpressionContextWay; import btools.expressions.BExpressionContextWay;
@ -27,7 +29,7 @@ final class StdModel extends OsmPathModel
@Override @Override
public void init( BExpressionContextWay expctxWay, BExpressionContextNode expctxNode ) public void init( BExpressionContextWay expctxWay, BExpressionContextNode expctxNode, Map<String,String> keyValues )
{ {
ctxWay = expctxWay; ctxWay = expctxWay;
ctxNode = expctxNode; ctxNode = expctxNode;

View file

@ -34,7 +34,7 @@ final class StdPath extends OsmPath
} }
@Override @Override
protected double processWaySection( RoutingContext rc, double distance, double delta_h, double angle, double cosangle, boolean isStartpoint, int nsection, int lastpriorityclassifier ) protected double processWaySection( RoutingContext rc, double distance, double delta_h, double elevation, double angle, double cosangle, boolean isStartpoint, int nsection, int lastpriorityclassifier )
{ {
// calculate the costfactor inputs // calculate the costfactor inputs
float turncostbase = rc.expctxWay.getTurncost(); float turncostbase = rc.expctxWay.getTurncost();