Skip to content

Commit

Permalink
Railsim: Moving blocks & Deadlock avoidance (#3075)
Browse files Browse the repository at this point in the history
* first step to move reroute and link request into one method

* prepare test and enum for moving blocks

* start restructure rail resources

* add approved dist to state, prepare some restructuring

* change reservation logic to be based on distance, no exceptions for now, but slight difference in some tests still need fixing

* disposition can now give an approved speed, update speed calculation to include approved speed from disposition, fixes the failing tests

* overhaul of the resource management, removed completely from RailLink and put into separate classes

* change resource interfaces to be distance based as well

* use current train position for checking reservation distance

* worked on moving block implementation, still WIP

* worked on moving block implementation, still WIP

* worked on moving block implementation, still WIP

* add track number to reservation interface, this will allow for more fine-grained control by disposition

* reworked track assignment in moving block

* worked on resources, test partially working now

* moving block train following test now working, prepare to add more tests and scenarion

* add a multi-track test for moving block

* add case when dist is 0 to calc target speed

* adding another network and test case

* small fixed, more complex mixed test case now working

* fixed situation where train blocks a link that has the same length as itself, all moving block tests now working

* prepare interfaces and network for deadlock tests

* worked on DeadlockAvoidance interface and tests

* allow to specify if one track for the opposite direction always needs to be reserved

* implemented non blocking reserve mode for fixed blocks as well, improved interfaces, update tests

* improved interfaces, first draft for simple deadlock avoidance

* tests for simple deadlock avoidance

* update deadlock tests, improve network

* added events for stuck trains, reworked dead lock avoidance interface and simple strategy

* update test cases, improve deadlock avoidance

* fixed dead lock avoidance for moving blocks, enabled re-routing again, but still wip

* deadlock avoidance checks for re-routing, fixed remaining issues in tests

* add two more deadlock tests

* update to junit5
  • Loading branch information
rakow authored Jan 26, 2024
1 parent 0eb2eb7 commit 3e798c9
Show file tree
Hide file tree
Showing 46 changed files with 2,660 additions and 596 deletions.
5 changes: 5 additions & 0 deletions contribs/railsim/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
<artifactId>railsim</artifactId>
<dependencies>

<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
</dependency>

<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
package ch.sbb.matsim.contrib.railsim;

import ch.sbb.matsim.contrib.railsim.config.RailsimConfigGroup;
import ch.sbb.matsim.contrib.railsim.qsimengine.resources.ResourceType;
import org.matsim.api.core.v01.network.Link;
import org.matsim.vehicles.VehicleType;

import java.math.BigDecimal;
import java.math.RoundingMode;


/**
* Utility class for working with Railsim and its specific attributes.
*
Expand All @@ -40,6 +42,7 @@ public final class RailsimUtils {
public static final String LINK_ATTRIBUTE_MINIMUM_TIME = "railsimMinimumTime";
public static final String VEHICLE_ATTRIBUTE_ACCELERATION = "railsimAcceleration";
public static final String VEHICLE_ATTRIBUTE_DECELERATION = "railsimDeceleration";
public static final String RESOURCE_TYPE = "railsimResourceType";

private RailsimUtils() {
}
Expand Down Expand Up @@ -155,4 +158,19 @@ public static void setTrainAcceleration(VehicleType vehicle, double acceleration
vehicle.getAttributes().putAttribute(VEHICLE_ATTRIBUTE_ACCELERATION, acceleration);
}

/**
* Return the resource type for a link, if not set, fixed block is assumed.
*/
public static ResourceType getResourceType(Link link) {
Object attr = link.getAttributes().getAttribute(RESOURCE_TYPE);
return attr != null ? ResourceType.valueOf(attr.toString()) : ResourceType.fixedBlock;
}

/**
* Sets the resource type for the link.
*/
public static void setResourceType(Link link, ResourceType type) {
link.getAttributes().putAttribute(RESOURCE_TYPE, type.toString());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,14 @@ private RailsimCsvWriter() {
* Write {@link RailsimLinkStateChangeEvent} to a csv file.
*/
public static void writeLinkStatesCsv(List<RailsimLinkStateChangeEvent> events, String filename) throws UncheckedIOException {
String[] header = {"link", "time", "state", "vehicle", "track"};
String[] header = {"link", "time", "state", "vehicle"};

try (CSVPrinter csv = new CSVPrinter(IOUtils.getBufferedWriter(filename), CSVFormat.DEFAULT.builder().setHeader(header).build())) {
for (RailsimLinkStateChangeEvent event : events) {
csv.print(event.getLinkId().toString());
csv.print(event.getTime());
csv.print(event.getState().toString());
csv.print(event.getVehicleId() != null ? event.getVehicleId().toString() : "");
csv.print(event.getTrack());
csv.println();
}
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
package ch.sbb.matsim.contrib.railsim.eventmappers;

import ch.sbb.matsim.contrib.railsim.events.RailsimLinkStateChangeEvent;
import ch.sbb.matsim.contrib.railsim.qsimengine.TrackState;
import ch.sbb.matsim.contrib.railsim.qsimengine.resources.ResourceState;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.network.Link;
Expand All @@ -38,8 +38,7 @@ public RailsimLinkStateChangeEvent apply(GenericEvent event) {
event.getTime(),
asId(attributes.get(RailsimLinkStateChangeEvent.ATTRIBUTE_LINK), Link.class),
asId(attributes.get(RailsimLinkStateChangeEvent.ATTRIBUTE_VEHICLE), Vehicle.class),
TrackState.valueOf(attributes.get(RailsimLinkStateChangeEvent.ATTRIBUTE_STATE)),
Integer.parseInt(attributes.get(RailsimLinkStateChangeEvent.ATTRIBUTE_TRACK))
ResourceState.valueOf(attributes.get(RailsimLinkStateChangeEvent.ATTRIBUTE_STATE))
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ public class RailsimDetourEvent extends Event implements HasVehicleId {
public static final String EVENT_TYPE = "railsimDetourEvent";

private final Id<Vehicle> vehicleId;
private final Id<Link> entry;
private final Id<Link> exit;
private final Id<Link> start;
private final Id<Link> end;
private final List<Id<Link>> detour;
private final Id<TransitStopFacility> newStop;

public RailsimDetourEvent(double time, Id<Vehicle> vehicleId, Id<Link> entry, Id<Link> exit, List<Id<Link>> detour,
public RailsimDetourEvent(double time, Id<Vehicle> vehicleId, Id<Link> start, Id<Link> end, List<Id<Link>> detour,
Id<TransitStopFacility> newStop) {
super(time);
this.vehicleId = vehicleId;
this.entry = entry;
this.exit = exit;
this.start = start;
this.end = end;
this.detour = detour;
this.newStop = newStop;
}
Expand All @@ -70,8 +70,8 @@ public Map<String, String> getAttributes() {
Map<String, String> attributes = super.getAttributes();

attributes.put(HasVehicleId.ATTRIBUTE_VEHICLE, vehicleId.toString());
attributes.put("entry", entry.toString());
attributes.put("exit", exit.toString());
attributes.put("start", start.toString());
attributes.put("end", end.toString());
attributes.put("detour", detour.stream().map(Object::toString).collect(Collectors.joining(",")));
attributes.put("newStop", Objects.toString(newStop));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

package ch.sbb.matsim.contrib.railsim.events;

import ch.sbb.matsim.contrib.railsim.qsimengine.TrackState;
import ch.sbb.matsim.contrib.railsim.qsimengine.resources.ResourceState;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.Event;
import org.matsim.api.core.v01.events.HasLinkId;
Expand All @@ -30,26 +30,23 @@
import java.util.Map;

/**
* Event thrown when the {@link ch.sbb.matsim.contrib.railsim.qsimengine.TrackState} of a {@link Link} changes.
* Event thrown when the {@link ResourceState} of a {@link Link} changes.
*/
public final class RailsimLinkStateChangeEvent extends Event implements HasLinkId, HasVehicleId {

public static final String EVENT_TYPE = "railsimLinkStateChangeEvent";

public static final String ATTRIBUTE_STATE = "state";
public static final String ATTRIBUTE_TRACK = "track";

private final Id<Link> linkId;
private final Id<Vehicle> vehicleId;
private final TrackState state;
private final int track;
private final ResourceState state;

public RailsimLinkStateChangeEvent(double time, Id<Link> linkId, Id<Vehicle> vehicleId, TrackState state, int track) {
public RailsimLinkStateChangeEvent(double time, Id<Link> linkId, Id<Vehicle> vehicleId, ResourceState state) {
super(time);
this.linkId = linkId;
this.vehicleId = vehicleId;
this.state = state;
this.track = track;
}

@Override
Expand All @@ -67,21 +64,16 @@ public Id<Vehicle> getVehicleId() {
return this.vehicleId;
}

public TrackState getState() {
public ResourceState getState() {
return state;
}

public int getTrack() {
return track;
}

@Override
public Map<String, String> getAttributes() {
Map<String, String> attr = super.getAttributes();
attr.put(ATTRIBUTE_LINK, this.linkId.toString());
attr.put(ATTRIBUTE_VEHICLE, this.vehicleId.toString());
attr.put(ATTRIBUTE_STATE, this.state.toString());
attr.put(ATTRIBUTE_TRACK, String.valueOf(track));
return attr;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@
*/
final class FuzzyUtils {

private static final double EPSILON = 1E-5;
/**
* The allowed deviation for small numbers to be considered equal.
* Contrary to intuition, this value should not be too large.
* It might happen that trains are moved too earlier over links.
*/
private static final double EPSILON = 1E-6;

private FuzzyUtils() {
}
Expand Down

This file was deleted.

Loading

0 comments on commit 3e798c9

Please sign in to comment.