Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

front: add speedlimits boundaries to simulation export to csv #10837

Merged
merged 1 commit into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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));
}
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
Loading