Initial client-side stats from BRouter StdPath.java

- `computeKinematic` and dependencies extracted from:
57da34d205/brouter-core/src/main/java/btools/router/StdPath.java
- transpiled with JSweet 3.0.0 - http://www.jsweet.org/jsweet-live-sandbox/
- manual cleanup
This commit is contained in:
Norbert Renner 2021-10-04 10:26:54 +02:00
parent fe05081678
commit af1a11872a

146
js/util/StdPath.js Normal file
View file

@ -0,0 +1,146 @@
(function () {
// Calculates time and energy stats
//
// from BRouter btools.router.StdPath
class BExpressionContextWay {
getMaxspeed() {
return 45.0;
}
getCostfactor() {
return 1.0;
}
}
class BExpressionContext {
getVariableValue(name, defaultValue) {
return defaultValue;
}
}
class RoutingContext {
constructor() {
this.expctxGlobal = new BExpressionContext();
this.expctxWay = new BExpressionContextWay();
this.bikeMode = true;
this.footMode = false;
this.totalMass = this.expctxGlobal.getVariableValue('totalMass', 90.0);
this.maxSpeed = this.expctxGlobal.getVariableValue('maxSpeed', this.footMode ? 6.0 : 45.0) / 3.6;
this.S_C_x = this.expctxGlobal.getVariableValue('S_C_x', 0.5 * 0.45);
this.defaultC_r = this.expctxGlobal.getVariableValue('C_r', 0.01);
this.bikerPower = this.expctxGlobal.getVariableValue('bikerPower', 100.0);
}
}
class StdPath {
constructor() {
this.totalTime = 0;
this.totalEnergy = 0;
this.elevation_buffer = 0;
}
/**
* Approximation to Math.exp for small negative arguments
* @param {number} e
* @return {number}
*/
static exp(e) {
var x = e;
var f = 1.0;
while (e < -1.0) {
{
e += 1.0;
f *= 0.367879;
}
}
return f * (1.0 + x * (1.0 + x * (0.5 + x * (0.166667 + 0.0416667 * x))));
}
static solveCubic(a, c, d) {
var v = 8.0;
var findingStartvalue = true;
for (var i = 0; i < 10; i++) {
{
var y = (a * v * v + c) * v - d;
if (y < 0.1) {
if (findingStartvalue) {
v *= 2.0;
continue;
}
break;
}
findingStartvalue = false;
var y_prime = 3 * a * v * v + c;
v -= y / y_prime;
}
}
return v;
}
resetState() {
this.totalTime = 0.0;
this.totalEnergy = 0.0;
this.elevation_buffer = 0.0;
}
calcIncline(dist) {
var min_delta = 3.0;
var shift;
if (this.elevation_buffer > min_delta) {
shift = -min_delta;
} else if (this.elevation_buffer < min_delta) {
shift = -min_delta;
} else {
return 0.0;
}
var decayFactor = StdPath.exp(-dist / 100.0);
var new_elevation_buffer = (this.elevation_buffer + shift) * decayFactor - shift;
var incline = (this.elevation_buffer - new_elevation_buffer) / dist;
this.elevation_buffer = new_elevation_buffer;
return incline;
}
computeKinematic(rc, dist, delta_h, detailMode) {
if (!detailMode) {
return;
}
this.elevation_buffer += delta_h;
var incline = this.calcIncline(dist);
var wayMaxspeed;
wayMaxspeed = rc.expctxWay.getMaxspeed() / 3.6;
if (wayMaxspeed === 0) {
wayMaxspeed = rc.maxSpeed;
}
wayMaxspeed = Math.min(wayMaxspeed, rc.maxSpeed);
var speed;
var f_roll = rc.totalMass * StdPath.GRAVITY * (rc.defaultC_r + incline);
if (rc.footMode || rc.expctxWay.getCostfactor() > 4.9) {
speed = rc.maxSpeed * 3.6;
speed = (speed * StdPath.exp(-3.5 * Math.abs(incline + 0.05))) / 3.6;
} else if (rc.bikeMode) {
speed = StdPath.solveCubic(rc.S_C_x, f_roll, rc.bikerPower);
speed = Math.min(speed, wayMaxspeed);
} else {
speed = wayMaxspeed;
}
var dt = dist / speed;
this.totalTime += dt;
var energy = dist * (rc.S_C_x * speed * speed + f_roll);
if (energy > 0.0) {
this.totalEnergy += energy;
}
}
getTotalTime() {
return this.totalTime;
}
getTotalEnergy() {
return this.totalEnergy;
}
}
StdPath.GRAVITY = 9.81;
BR.StdPath = StdPath;
})();