Skip to content

Commit

Permalink
feat(tutorial): WeatherServerApp now relays the last received DENM (#408
Browse files Browse the repository at this point in the history
)

* fix: disallow servers to read environmental data
* fix: adapt ReleaseBarnimIT tests
* fix: enable assert in ReleaseBarnimLibsumoIT
  • Loading branch information
hoelger authored Sep 30, 2024
1 parent 8d16c36 commit b5d6372
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@

package org.eclipse.mosaic.app.tutorial;

import org.eclipse.mosaic.fed.application.ambassador.simulation.communication.CamBuilder;
import org.eclipse.mosaic.fed.application.ambassador.simulation.communication.ReceivedAcknowledgement;
import org.eclipse.mosaic.fed.application.ambassador.simulation.communication.ReceivedV2xMessage;
import org.eclipse.mosaic.fed.application.app.AbstractApplication;
import org.eclipse.mosaic.fed.application.app.api.CommunicationApplication;
import org.eclipse.mosaic.fed.application.app.api.os.ServerOperatingSystem;
import org.eclipse.mosaic.interactions.communication.V2xMessageTransmission;
import org.eclipse.mosaic.lib.enums.SensorType;
import org.eclipse.mosaic.lib.geo.GeoCircle;
import org.eclipse.mosaic.lib.geo.GeoPoint;
import org.eclipse.mosaic.lib.objects.v2x.MessageRouting;
import org.eclipse.mosaic.lib.objects.v2x.V2xMessage;
import org.eclipse.mosaic.lib.objects.v2x.etsi.Denm;
import org.eclipse.mosaic.lib.objects.v2x.etsi.DenmContent;
import org.eclipse.mosaic.lib.util.scheduling.Event;
Expand All @@ -31,25 +37,18 @@
* about certain hazards on the road. The hazard is hard-coded for tutorial purposes,
* in more realistic scenarios the location would've been updated dynamically.
*/
public class WeatherServerApp extends AbstractApplication<ServerOperatingSystem> {
public class WeatherServerApp extends AbstractApplication<ServerOperatingSystem> implements CommunicationApplication {

/**
* Send hazard location at this interval, in seconds.
* Send warning at this interval, in seconds.
*/
private final static long INTERVAL = 2 * TIME.SECOND;

/**
* Location of the hazard which causes the route change.
*/
private final static GeoPoint HAZARD_LOCATION = GeoPoint.latLon(52.633047, 13.565314);

/**
* Road ID where hazard is located.
* Save the last received DEN message for relaying.
*/
private final static String HAZARD_ROAD = "311964536_1313885442_2879911873";

private final static SensorType SENSOR_TYPE = SensorType.ICE;
private final static float SPEED = 25 / 3.6f;
private Denm lastReceivedMessage = null;


/**
Expand Down Expand Up @@ -87,10 +86,14 @@ public void processEvent(Event event) throws Exception {
* and thus the DENM is sent periodically at this interval.
*/
private void sample() {
final Denm denm = constructDenm(); // Construct exemplary DENM

getOs().getCellModule().sendV2xMessage(denm);
getLog().infoSimTime(this, "Sent DENM");
if (lastReceivedMessage == null) {
getLog().infoSimTime(this, "No warning present.");
} else {
final Denm denm = constructDenm();
getLog().debugSimTime(this, "{}", denm);
getOs().getCellModule().sendV2xMessage(denm);
getLog().infoSimTime(this, "Relayed last DENM");
}
// Line up new event for periodic sending
getOs().getEventManager().addEvent(
getOs().getSimulationTime() + INTERVAL, this
Expand All @@ -106,34 +109,65 @@ private void sample() {
* @return The constructed DENM
*/
private Denm constructDenm() {
final GeoCircle geoCircle = new GeoCircle(HAZARD_LOCATION, 3000.0D);
final GeoCircle geoCircle = new GeoCircle(lastReceivedMessage.getEventLocation(), 3000.0D);
final MessageRouting routing = getOs().getCellModule().createMessageRouting().geoBroadcastBasedOnUnicast(geoCircle);

final int strength = getOs().getStateOfEnvironmentSensor(SENSOR_TYPE);

return new Denm(routing,
new DenmContent(
getOs().getSimulationTime(),
null,
HAZARD_ROAD,
SENSOR_TYPE,
strength,
SPEED,
0.0f,
HAZARD_LOCATION,
null,
null
lastReceivedMessage.getTime(),
lastReceivedMessage.getSenderPosition(),
lastReceivedMessage.getEventRoadId(),
lastReceivedMessage.getWarningType(),
lastReceivedMessage.getEventStrength(),
lastReceivedMessage.getCausedSpeed(),
lastReceivedMessage.getSenderDeceleration(),
lastReceivedMessage.getEventLocation(),
lastReceivedMessage.getEventArea(),
lastReceivedMessage.getExtendedContainer()
),
200
);
}

@Override
public void onMessageReceived(ReceivedV2xMessage receivedV2xMessage) {
final V2xMessage msg = receivedV2xMessage.getMessage();
getLog().infoSimTime(this, "Received {} from {}.",
msg.getSimpleClassName(),
msg.getRouting().getSource().getSourceName()
);
// Only DEN Messages are handled
if (!(msg instanceof Denm)) {
getLog().infoSimTime(this, "Ignoring message of type: {}", msg.getSimpleClassName());
return;
}
lastReceivedMessage = (Denm) msg;
getLog().debugSimTime(this, "DENM content: Sensor Type: {}", lastReceivedMessage.getWarningType().toString());
getLog().debugSimTime(this, "DENM content: Event position: {}", lastReceivedMessage.getEventLocation());
getLog().debugSimTime(this, "DENM content: Event Strength: {}", lastReceivedMessage.getEventStrength());
getLog().debugSimTime(this, "DENM content: Road Id of the Sender: {}", lastReceivedMessage.getEventRoadId());
}

@Override
public void onAcknowledgementReceived(ReceivedAcknowledgement acknowledgement) {

}

@Override
public void onCamBuilding(CamBuilder camBuilder) {

}

@Override
public void onMessageTransmitted(V2xMessageTransmission v2xMessageTransmission) {

}

/**
* This method is called by mosaic-application when the simulation has finished.
*/
@Override
public void onShutdown() {
getLog().infoSimTime(this, "Shutdown application");
getLog().infoSimTime(this, "Shutdown server.");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,12 @@ public void onMessageReceived(ReceivedV2xMessage receivedV2xMessage) {
return;
}

// Message was received via cell from the WeatherServer
if (msg.getRouting().getSource().getSourceName().equals("server_0")) {
getLog().infoSimTime(this, "Received message from cell from WeatherServer");
// Message was received via cell from the WeatherServer
getLog().infoSimTime(this, "Received message over cell from WeatherServer");
}
else {
getLog().infoSimTime(this, "Received message from {}", msg.getRouting().getSource().getSourceName());
}

getLog().infoSimTime(this, "Processing DEN message");
Expand Down Expand Up @@ -210,7 +213,7 @@ private void reactOnEnvironmentData(SensorType type, int strength) {
* with a builder and build a geoBroadCast for the circle area defined in dest.
*/
if (useCellNetwork()) {
mr = getOs().getCellModule().createMessageRouting().geoBroadcastBasedOnUnicast(dest);
mr = getOs().getCellModule().createMessageRouting().topoCast("server_0");
} else {
mr = getOs().getAdHocModule().createMessageRouting().geoBroadCast(dest);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ public final void cleanPastEnvironmentEvents() {
}

@Override
public final int getStateOfEnvironmentSensor(SensorType type) {
public int getStateOfEnvironmentSensor(SensorType type) {
EnvironmentEvent event = environmentEvents.get(type);
// If an event of this type in the map yet?
if (event != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.eclipse.mosaic.fed.application.ambassador.simulation.navigation.IRoutingModule;
import org.eclipse.mosaic.fed.application.ambassador.simulation.navigation.NavigationModule;
import org.eclipse.mosaic.fed.application.app.api.os.ServerOperatingSystem;
import org.eclipse.mosaic.lib.enums.SensorType;
import org.eclipse.mosaic.lib.objects.mapping.ServerMapping;
import org.eclipse.mosaic.lib.util.scheduling.Event;

Expand Down Expand Up @@ -53,10 +54,15 @@ public ServerUnit(String unitName) {
}

@Override
public CamBuilder assembleCamMessage(CamBuilder camBuilder) {
public final CamBuilder assembleCamMessage(CamBuilder camBuilder) {
throw new UnsupportedOperationException("Servers can't send CAMs.");
}

@Override
public final int getStateOfEnvironmentSensor(SensorType type) {
throw new UnsupportedOperationException("Servers can't access Environment functionality.");
}

@Override
public IRoutingModule getRoutingModule() {
return routingModule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public void navigationSuccessful() throws Exception {
assertEquals(36,
LogAssert.count(simulationRule, "Navigation.log", ".*Request to switch to new route for vehicle .*")
);
// 14 adhoc vehicles + 12 cell vehicles
assertEquals(26,
// 14 adhoc vehicles + 10 cell vehicles
assertEquals(24,
LogAssert.count(simulationRule, "Navigation.log", ".*Change to route [2-9] for vehicle .*")
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,9 @@ public void correctUnitRegistrations() throws Exception {
assertEquals(120, LogAssert.count(simulationRule, "output.csv",
".*VEHICLE_REGISTRATION;.*"
));
// //FIXME currently, libsumo.TrafficLightGetPrograms returns an empty list in any case
// assertEquals(53, LogAssert.count(simulationRule, "output.csv",
// ".*TRAFFICLIGHT_REGISTRATION;.*"
// ));
assertEquals(42, LogAssert.count(simulationRule, "output.csv",
".*TRAFFICLIGHT_REGISTRATION;.*"
));
LogAssert.contains(simulationRule, "output.csv", "SERVER_REGISTRATION;0;server_0;WeatherServer;\\[.*\\]");
}

Expand Down

0 comments on commit b5d6372

Please sign in to comment.