From af1a11872adaa0410695f0c1082e71108b76b1c4 Mon Sep 17 00:00:00 2001 From: Norbert Renner Date: Mon, 4 Oct 2021 10:26:54 +0200 Subject: [PATCH] Initial client-side stats from BRouter StdPath.java - `computeKinematic` and dependencies extracted from: https://github.com/abrensch/brouter/blob/57da34d205d26f22b31f667facc99ab7507d468c/brouter-core/src/main/java/btools/router/StdPath.java - transpiled with JSweet 3.0.0 - http://www.jsweet.org/jsweet-live-sandbox/ - manual cleanup --- js/util/StdPath.js | 146 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 js/util/StdPath.js diff --git a/js/util/StdPath.js b/js/util/StdPath.js new file mode 100644 index 0000000..14e45ba --- /dev/null +++ b/js/util/StdPath.js @@ -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; +})();