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

feat(tutorial): WeatherServerApp now relays the last received DENM #408

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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
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
hoelger marked this conversation as resolved.
Show resolved Hide resolved
assertEquals(24,
LogAssert.count(simulationRule, "Navigation.log", ".*Change to route [2-9] for vehicle .*")
);
}
Expand Down
Loading