Saturday, 18 November 2017

Trains: High Speed Trains... in Sweden???

No one who is reading my blog can question my passion for trains. A part of me would be very enthusiastic about entering a Thalys-like train at Malmö Central, reaching Stockholm two and a half hours later. Another part of me is looking at the numbers.

In two previous blog posts, I've seen that the population is much smaller for Sweden, compared with the lines in France, Germany, Spain and Japan.

Trafikverket (The Swedish Transport Administration) has made an economical assessment of the proposed high speed rail lines. That report saw significant advantages with high speed trains:
  • Increased capacity in the entire rail system, including existing lines.
  • Cargo trains won't slow down passenger trains.
  • Great reductions in travel time (36-64% reduction between Swedish towns along the line)
The value of the benefits were estimated to 150 billion SEK. However, the costs were estimated to be some 409 billion SEK. The return of investment would be 40%, a very poor prospect.

As the rail system in Sweden is already mature, the benefits of such a big project will smaller than the costs and the conclusion from the report is that high speed rail in Sweden will be too expensive.

I agree with that report. Such a project would starve out other investments that are necessary. The money should be used to build on the existing rail network, resolve bottle-necks and maintain the lines properly. High speed rail will starve out other, more efficient improvements.

Saturday, 11 November 2017

TrafficControl: Crash When Using a Network Without Coordinates

In a previous blog post, I've seen that the program asserts when using a network without coordinates.

The assert is trigged when the train is in state "RUNNING":

After adding prints, I've seen that the issue comes when the train is in Train::runningState. The train tries to set the new position on the track using this->setTrackPosition.

The train is trying to get coordinates for a position on the track. But as the track has no coordinates, the code asserts.

The program is trying to act on the coordinateList that doesn't exist,
One solution can be to check if the coordinateList has length = 0. If that is the case, return 0. Also, the calling program should check if the track has coordinates. I'll add a boolean hasCoordinates to Track, and a corresponding get method.

The fix for train::setTrackPosition() is:

Saturday, 4 November 2017

Trains: High Speed Trains... to Lyon???

In the first blog post about the planned 320 km/h high speed rail in Sweden, I calculated the population along the line from Lund to Järna (Malmö/Copenhagen to Stockholm).

Image credit: Wikimedia Commons
As of 2017, there are only four high speed lines of 320 km/h: Madrid to Barcelona, Paris (eastbound and westbound) and Dijon to Basel.

The following table compares some existing lines with the planned Swedish line. The populations are calculated within a 10 km and a 25 km radius from the stations. For the Swedish line, I exclude and include København in the calculations.

Start End Speed Stations Length Pop 10 km Pop 25 km
Malmö Stockholm 320 km/h 12 460 km 1,6 M/2,5 M 3 M/4,5 M
Paris Lyon 300 km/h 4 427 km 4,3 M 10 M
Paris Strasbourg 320 km/h 5 409 km 4,8 M 10 M
Madrid Barcelona 320 km/h 8 600 km 5,7 M 12 M
Tokyo Niigata 320 km/h 12/5 270 km 8,5 M 26 M

I also added the Japanese Joetshu Shinkanshen line, one of the smaller lines in the Shinksanshen network.

The proposed Swedish line will serve a much smaller population than the other lines. Also, that line has 12 stations, that will make the trains slower. One stop will take some five minutes, according to the time tables for the French/Spanish lines.

For the Paris/Strasbourg line, there are 17 departures per day in each direction. 13 of them doesn't stop between Paris and Strasbourg. A similar tradeoff will be necessary for the train operator in Sweden: Either stop at many stops, using the stations that are built but also making the train slower, or travel directly between Malmö/Copenhagen and Stockholm, passing several important stations without stopping.

Intermediate conclusion: 
Sweden has a much smaller population density and smaller cities than the European countries. The demand for travels will be much smaller than for the existing lines.

Saturday, 28 October 2017

TrafficControl: Protecting the Code With Asserts

Asserts are checking whether a condition is met. If the condition isn't met, the program will throw an error message and break. They are used to ensure that something never ever happens in the program (asserts are only used when debug flag is enabled).

TrafficControl is based on three lists of objects (trainList, trackList and stationList), The elements in those lists are called directly, so the entire logic of the program is based on a direct relation between the ID's of the elements and their position in the lists. Removing elements will not be allowed.

For example: Add three trains to the network. The result is a trainList:
trainList.at(0) has ID: 0
trainList.at(1) has ID: 1
trainList.at(2) has ID: 2
totalNbrOfTrains = 3

Remove the second train and reduce the totalNbrOfTrains:
trainList.at(0) has ID: 0
trainList.at(1) has ID: 2 
totalNbrOfTrains = 2

Now, there is a mismatch between the ID for the second train in the trainList and its position. 

To detect when it happens, I've added an assert that fires if there is such a mismatch for the last items in the lists.
The trainList must always be empty, or its last element' ID must match the length of the list.
If the assert fails, a dialog pops up and the user can decide whether to retry, abort or ignore the error.
The button are using the language specified by the operating system. In this case, they are: Abort, Retry and Ignore.
As a side note, I've discovered two bugs that I need to fix. I'll address the issues in future blog posts:

The program asserts when using a network without coordinates. It happens when the train is running on tracks and is trying to calculate its coordinates.

Solution: Check if the train and track has coordinates when updating the position for a train on the track.

The program is slower when importing network file. Before refactoring it, it took the program 5 seconds to scan the file. Now, it takes 25 seconds.

Solution: Scan all lines and send as a stringlist to new NetworkControl::parseNetworkCommands(QStringList). 

Saturday, 21 October 2017

Trains: High Speed Trains... to Tranås???

Swedish railways suffer from limited capacity and maintenance lagging behind. There are negotiations regarding some future high speed rail lines, that would connect the biggest population centres in Sweden in the future (Stockholm, Göteborg and Malmö/København). The speed is planned to be 320 km/h.

There is some debate whether the project is a good idea, and I'll discuss my opinion in two blog posts. As a Malmö resident, I'll focus on the line between Malmö and Stockholm.

Let's start with demography and geography.

I'll compare the proposed line with some existing lines with respect to length, number of stops and population near the stations. I'll use an online tool to calculate the population in a 10 km radius and in a 25 km radius from the station.

The proposed line between Malmö and Stockholm (high speed between Lund and Järna) will be 550 km (approximately 500 km high speed rail). There will be nine stops between Malmö and Stockholm and the time will be 2½h according to Europakorridoren.

Excluding København (60 km from Lund), the total population of all towns served by the line will be 1.6 M/ 3 M. Including København, the population of all towns will be 2.5 M/ 4.5 M. Some of the smaller stations include Tranås and Vagnhärad with populations of 10 to 20 thousand people.

A future blog post will compare the Swedish project with some existing European high speed lines with similar speeds.

Saturday, 14 October 2017

TrafficControl: Using Test Fixtures for Unit Tests

For many unit tests, there are some similarities that can be used to reduce some redundant code.

For example, the datamodels for the trafficDataModels (for train, station and track), a pointer to the QML part of the program and the networkControl object.

Google Test offers test fixtures, that makes it possible to setup the same parameters for a set of tests. The test code will be cleaner and each test case will have (more or less) the same setup.


A test fixture is a class where some pointers to some objects are defined.

In SetUp, the data models are defined, a null pointer is set for the QML part and a networkControl object is created.

The TearDown method will free up the allocated memory and clean up the test environment.


The test case is then defined using TEST_F, where the appendix indicates that a test fixture will be used. The test case is networkTest, that was defined above.

In the test case, the networkControl, the needed elements are already defined. The cleanup will be done automatically by TearDown when the test is done.

The concept isn't water-proof, however. The traffic elements (for example trains) has a static int variable to count the total number of trains/stations/tracks. I didn't reset that parameter initially, which caused some test cases to fail. 
  1. Before the first test with the test fixture, that parameter was 0. 
  2. After the first test case, where a train was created, the parameter was set to 1. 
  3. When deleting the train object (called in the networkControl destructor), the static parameter wasn't affected.
  4. In the second test case, the totalNbrOfTrains was 1, but it should have been 0. This caused the test to fail since the test checked the totalNbrOfTrains parameter. 

To fix that issue, the totalNbrOfTrains is set to 0 in the destructor for networkControl.

Saturday, 7 October 2017

Trains: Double Decker Trains Above Öresund

On June, this year, the committee of public transportation of Region Skåne decided to introduce double decker trains on one of the busiests train line in the Öresund area (Copenhagen-Malmö-Lund-Helsingborg).

This is needed to increase the capacity on the line between Copenhagen and Malmö, that is very used by commuters and people going to and from Copenhagen airport, the busiest airport in Scandinavia.

Currently, a maximum of three trains (three 78.9 meter trains) can be connected and used, with a total capacity of some 600 passengers. The limit is the platform length of the sub-terranean station Triangeln in Malmö.

With the new trains, the capacity will increase to 800 to 900 passengers per train.

It is not yet decided which type of trains will be used but one likely candidate is Alstom Coradia Duplex, that is already in use in Sweden. Comparing that model with the current Öresundståg (X31), it seems that the capacity in terms of seats per meter is almost the same.

Öresundståg (X31) has a length of 78,9 meters and a capacity of 229 seats (2.9 passengers per meter).
Alstom Coradia Duplex (X40) comes in different lengths. The five car option has a length of 134 meters and a capacity of 570 seats (4,2 passengers per meter). The seven car option has a length of 186,7 meters and a capacity of 810 seats (4,33 passengers per meter).

The new trains are planned to be in use from 2019.