Skip to content

Commit

Permalink
front: add speedlimits boundaries to simulation export to csv
Browse files Browse the repository at this point in the history
Signed-off-by: Alice K. <[email protected]>
  • Loading branch information
Alice K. committed Feb 17, 2025
1 parent f1b10fb commit 02974c0
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
import { describe, it, expect } from 'vitest';

import { findActualVmax } from '../utils';
import { findActualVmaxs } from '../utils';

describe('findActualVmax', () => {
const vMax = { internalBoundaries: [2000, 3400, 5300, 6000], speeds: [10, 100, 200, 100, 150] };

it('should return the correct Vmax', () => {
const result = findActualVmax(2500, vMax);
expect(result).toEqual(100);
it('should return the correct Vmax when the givenPosition is in an intermediary interval', () => {
const result = findActualVmaxs(2500, vMax);
expect(result).toEqual([100]);
});

it('should return the correct Vmax when the givenPosition is in the last interval', () => {
const result = findActualVmax(7000, vMax);
expect(result).toEqual(150);
const result = findActualVmaxs(7000, vMax);
expect(result).toEqual([150]);
});

it('should return the correct Vmax when the givenPosition is in thefirst interval', () => {
const result = findActualVmax(1000, vMax);
expect(result).toEqual(10);
const result = findActualVmaxs(1000, vMax);
expect(result).toEqual([10]);
});

it('should return the min Vmax when givenPosition is equal to a boundary (min before)', () => {
const result = findActualVmax(3400, vMax);
expect(result).toEqual(100);
it('should return both Vmax before and after when givenPosition is equal to a boundary (min before)', () => {
const result = findActualVmaxs(3400, vMax);
expect(result).toEqual([100, 200]);
});

it('should return the min Vmax when givenPosition is equal to a boundary (min after)', () => {
const result = findActualVmax(5300, vMax);
expect(result).toEqual(100);
it('should return both Vmax before and after when givenPosition is equal to a boundary (min after)', () => {
const result = findActualVmaxs(5300, vMax);
expect(result).toEqual([200, 100]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -222,20 +222,37 @@ export default function exportTrainCSV(
simulatedTrain.electrical_profiles
);

const steps = speedsWithOPsAndSpeedLimits.map((speed) => ({
op: speed.op || '',
ch: speed.ch || '',
trackName: speed.trackName,
time: timestampToHHMMSS(speed.time),
seconds: pointToComma(+speed.time.toFixed(1)),
position: pointToComma(+(speed.position / 1000).toFixed(3)),
speed: pointToComma(+(speed.speed * 3.6).toFixed(3)),
speedLimit: pointToComma(getActualVmax(speed.position, formattedMrsp)),
lineCode: speed.lineCode,
electrificationType: speed.electrificationType,
electrificationMode: speed.electrificationMode,
electrificationProfile: speed.electrificationProfile,
}));
const steps: CSVData[] = [];
speedsWithOPsAndSpeedLimits.forEach((speed, index) => {
const actualVmaxs = getActualVmax(speed.position, formattedMrsp);
const newStep = {
op: speed.op || '',
ch: speed.ch || '',
trackName: speed.trackName,
time: timestampToHHMMSS(speed.time),
seconds: pointToComma(+speed.time.toFixed(1)),
position: pointToComma(+(speed.position / 1000).toFixed(3)),
speed: pointToComma(+(speed.speed * 3.6).toFixed(3)),
speedLimit: pointToComma(actualVmaxs[0]),
lineCode: speed.lineCode,
electrificationType: speed.electrificationType,
electrificationMode: speed.electrificationMode,
electrificationProfile: speed.electrificationProfile,
};
steps.push(newStep);

// If there's a second speed limit (meaning we are at a boundary)
// and it's the last step at this position, we add a copy of the step with the new limit
const isLastStepAtPosition =
index === speedsWithOPsAndSpeedLimits.length - 1 ||
speed.position !== speedsWithOPsAndSpeedLimits[index + 1].position;
if (actualVmaxs.length > 1 && isLastStepAtPosition) {
steps.push({
...newStep,
speedLimit: pointToComma(actualVmaxs[1]),
});
}
});

if (steps) createFakeLinkWithData(train.train_name, spreadDataBetweenSteps(steps));
}
24 changes: 10 additions & 14 deletions front/src/modules/simulationResult/SimulationResultExport/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,27 @@ export function massWithOneDecimal(number: number) {
// to prevent a white screen when datas are computing and synchronizing when switching the selected train

/**
* Get the Vmax at a givenPosition (in meters), using vmax (MRSP in m/s)
* Returns the current Vmax if in the middle of an interval, or
* the min of the Vmax before and after if exactly at a bound.
* Get the Vmax values at a givenPosition (in meters), using vmax (MRSP in m/s)
* Returns a list containing only the current Vmax if in the middle of an interval,
* or the Vmax values before and after if exactly at a bound.
*/
export function findActualVmax(givenPosition: number, vmax: SpeedRanges): number {
export function findActualVmaxs(givenPosition: number, vmax: SpeedRanges): number[] {
// givenPosition is in meters
const vmaxUpperBoundIndex = d3.bisectRight(vmax.internalBoundaries, givenPosition);
// Error case: vmax doesn't respect the SpeedRanges specifications on the lists' lengths
if (vmaxUpperBoundIndex > vmax.speeds.length - 1) return 0;
// If exactly on a speed-limit change, use the minimal value of both side
const actualVmaxMetersPerSecond =
vmaxUpperBoundIndex > 0 && vmax.internalBoundaries[vmaxUpperBoundIndex - 1] === givenPosition
? Math.min(vmax.speeds[vmaxUpperBoundIndex], vmax.speeds[vmaxUpperBoundIndex - 1])
: vmax.speeds[vmaxUpperBoundIndex];

return actualVmaxMetersPerSecond;
if (vmaxUpperBoundIndex > vmax.speeds.length - 1) return [0];
if (vmaxUpperBoundIndex > 0 && vmax.internalBoundaries[vmaxUpperBoundIndex - 1] === givenPosition)
return [vmax.speeds[vmaxUpperBoundIndex - 1], vmax.speeds[vmaxUpperBoundIndex]];
return [vmax.speeds[vmaxUpperBoundIndex]];
}

/**
* Given the position in m and the vmax in m/s (boundaries in m too),
* return the actual vmax at the givenPosition in km/h
*/
export function getActualVmax(givenPosition: number, vmax: SpeedRanges) {
const actualVMax = findActualVmax(givenPosition, vmax);
return msToKmhRounded(actualVMax);
const actualVMaxs = findActualVmaxs(givenPosition, vmax);
return actualVMaxs.map((actualVMax) => msToKmhRounded(actualVMax));
}

/**
Expand Down

0 comments on commit 02974c0

Please sign in to comment.