Skip to content

Commit

Permalink
feat(application): new version of sensor modules design after discussion
Browse files Browse the repository at this point in the history
  • Loading branch information
kschrab committed Oct 2, 2024
1 parent c55829d commit 8a4a720
Show file tree
Hide file tree
Showing 17 changed files with 97 additions and 242 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class EmergencyBrakeApp extends ConfigurableApplication<CEmergencyBrakeAp
@Override
public void onStartup() {
getOs().getAdHocModule().enable();
getOs().getSensorModule().getEnvironmentSensor().enable();
getOs().getBasicSensorModule().enable();
}

/**
Expand All @@ -68,8 +68,7 @@ public void onStartup() {
@Override
public void onVehicleUpdated(@Nullable VehicleData previousVehicleData, @Nonnull VehicleData updatedVehicleData) {

boolean obstacleDetected = getOs().getSensorModule().getEnvironmentSensor().getSensorData()
.strengthOf(SensorType.OBSTACLE) > 0;
boolean obstacleDetected = getOs().getBasicSensorModule().getStrengthOf(SensorType.OBSTACLE) > 0;

// Initiate emergency brake if obstacle is detected
if (obstacleDetected && !emergencyBrake) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@
package org.eclipse.mosaic.app.tutorial;

import org.eclipse.mosaic.fed.application.app.AbstractApplication;
import org.eclipse.mosaic.fed.application.app.api.VehicleApplication;
import org.eclipse.mosaic.fed.application.app.api.os.VehicleOperatingSystem;
import org.eclipse.mosaic.fed.application.app.api.sensor.EnvironmentSensorData;
import org.eclipse.mosaic.lib.enums.SensorType;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleData;
import org.eclipse.mosaic.lib.util.scheduling.Event;
import org.eclipse.mosaic.rti.TIME;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
* This application shall induce vehicles to slow down in hazardous environments.
* In onVehicleUpdated() the application requests new data from a vehicle's
Expand All @@ -31,19 +35,19 @@
* within a specified time frame. After the respective vehicle has left the dangerous
* zone, its speed will no longer be reduced.
*/
public class SlowDownApp extends AbstractApplication<VehicleOperatingSystem> {
public class SlowDownApp extends AbstractApplication<VehicleOperatingSystem> implements VehicleApplication {

private final static float SPEED = 25 / 3.6f;

private boolean hazardousArea = false;

@Override
public void onStartup() {
getOs().getSensorModule().getEnvironmentSensor().enable();
getOs().getSensorModule().getEnvironmentSensor().reactOnSensorDataUpdate(this::onEnvironmentSensorUpdate);
getOs().getBasicSensorModule().enable();
}

private void onEnvironmentSensorUpdate(EnvironmentSensorData environmentSensorData) {
@Override
public void onVehicleUpdated(@Nullable VehicleData previousVehicleData, @Nonnull VehicleData updatedVehicleData) {
SensorType[] types = SensorType.values();

// Initialize sensor strength
Expand All @@ -56,7 +60,7 @@ private void onEnvironmentSensorUpdate(EnvironmentSensorData environmentSensorDa
*/
for (SensorType currentType : types) {
// The strength of a detected sensor
strength = environmentSensorData.strengthOf(currentType);
strength = getOs().getBasicSensorModule().getStrengthOf(currentType);

if (strength > 0) {
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public void onStartup() {
getLog().infoSimTime(this, "Activated AdHoc Module");
}

getOs().getSensorModule().getEnvironmentSensor().enable();
getOs().getBasicSensorModule().enable();

getOs().requestVehicleParametersUpdate()
.changeColor(Color.RED)
Expand Down Expand Up @@ -150,7 +150,7 @@ private void detectSensors() {
for (SensorType currentType : SensorType.values()) {

// The strength of a detected sensor
int strength = getOs().getSensorModule().getEnvironmentSensor().getSensorData().strengthOf(currentType);
int strength = getOs().getBasicSensorModule().getStrengthOf(currentType);

if (strength > 0) {
// Method which is called to react on new or changed environment events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@
import org.eclipse.mosaic.fed.application.ambassador.simulation.communication.AdHocModule;
import org.eclipse.mosaic.fed.application.ambassador.simulation.communication.ReceivedV2xMessage;
import org.eclipse.mosaic.fed.application.ambassador.simulation.navigation.NavigationModule;
import org.eclipse.mosaic.fed.application.ambassador.simulation.sensor.DefaultSensorModule;
import org.eclipse.mosaic.fed.application.ambassador.simulation.sensor.EnvironmentSensor;
import org.eclipse.mosaic.fed.application.ambassador.util.UnitLogger;
import org.eclipse.mosaic.fed.application.app.api.os.VehicleOperatingSystem;
import org.eclipse.mosaic.fed.application.app.api.sensor.EnvironmentSensorData;
import org.eclipse.mosaic.fed.application.app.api.sensor.BasicSensorModule;
import org.eclipse.mosaic.lib.enums.SensorType;
import org.eclipse.mosaic.lib.objects.addressing.AdHocMessageRoutingBuilder;
import org.eclipse.mosaic.lib.objects.addressing.SourceAddressContainer;
Expand Down Expand Up @@ -70,21 +68,18 @@ public class WeatherWarningAppTest {
private AdHocModule adHocModuleMock;

@Mock
private DefaultSensorModule sensorModuleMock;
private BasicSensorModule sensorModuleMock;

@Before
public void setup() {
when(operatingSystem.getAdHocModule()).thenReturn(adHocModuleMock);
when(operatingSystem.getBasicSensorModule()).thenReturn(sensorModuleMock);

VehicleParameters.VehicleParametersChangeRequest vehicleParametersChangeRequestMock =
mock(VehicleParameters.VehicleParametersChangeRequest.class);
when(operatingSystem.requestVehicleParametersUpdate()).thenReturn(vehicleParametersChangeRequestMock);
when(vehicleParametersChangeRequestMock.changeColor(any())).thenReturn(vehicleParametersChangeRequestMock);

// everytime a mock returns a mock a unicorn dies. I count 3 dead unicorns.
when(operatingSystem.getSensorModule()).thenReturn(sensorModuleMock);
when(sensorModuleMock.getEnvironmentSensor()).thenReturn(mock(EnvironmentSensor.class));
when(sensorModuleMock.getEnvironmentSensor().getSensorData()).thenReturn(mock(EnvironmentSensorData.class));
}

@Test
Expand Down Expand Up @@ -127,7 +122,7 @@ public void test_SwitchRouteIfDenmWasReceived() {
}

private void setSensor(SensorType sensorType, int value) {
when(operatingSystem.getSensorModule().getEnvironmentSensor().getSensorData().strengthOf(same(sensorType))).thenReturn(value);
when(operatingSystem.getBasicSensorModule().getStrengthOf(same(sensorType))).thenReturn(value);
}

private void setupMessageRouting() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
import org.eclipse.mosaic.fed.application.ambassador.simulation.communication.ReceivedV2xMessage;
import org.eclipse.mosaic.fed.application.ambassador.simulation.navigation.CentralNavigationComponent;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.CentralPerceptionComponent;
import org.eclipse.mosaic.fed.application.ambassador.simulation.sensor.DefaultSensorModule;
import org.eclipse.mosaic.fed.application.ambassador.simulation.sensor.EnvironmentSensor;
import org.eclipse.mosaic.fed.application.ambassador.simulation.sensor.EnvironmentBasicSensorModule;
import org.eclipse.mosaic.fed.application.ambassador.util.EventNicenessPriorityRegister;
import org.eclipse.mosaic.fed.application.app.api.MosaicApplication;
import org.eclipse.mosaic.fed.application.app.api.TrafficSignAwareApplication;
Expand Down Expand Up @@ -512,26 +511,27 @@ private void process(final V2xFullMessageReception v2xFullMessageReception) {

/**
* This function does not directly fire an event, but puts it in a environmentEvents-map (see {@link AbstractSimulationUnit}).
* Use {@link DefaultSensorModule#getEnvironmentSensor()} to to determine the state of a Sensor. Keep in mind, that
* Use {@link Sensible#getBasicSensorModule()} to determine the state of a Sensor. Keep in mind, that
* the map only stores the latest {@link EnvironmentEvent} of a specific type and overwrites old values.
* <p>Events will not directly be removed from the map, but since events are mapped to their type, there
* can't be more members than there are SensorType's. Nonetheless, the map is cleared using
* {@link EnvironmentSensor#cleanPastEnvironmentEvents()}, which is invoked by {@link SimulationKernel#garbageCollection()}.
* {@link EnvironmentBasicSensorModule#cleanPastEnvironmentEvents()}, which is invoked by {@link SimulationKernel#garbageCollection()}.
* </p>
*
* @param environmentSensorUpdates the Interaction of type EnvironmentSensorUpdates to be processed
*/
private void process(final EnvironmentSensorUpdates environmentSensorUpdates) {
// store the sensor data immediately, the sensor event hold their intermittent time
final AbstractSimulationUnit simulationUnit = UnitSimulator.UnitSimulator.getUnitFromId(environmentSensorUpdates.getUnitId());
// we don't simulate vehicles without an application
if (!(simulationUnit instanceof Sensible)) {
// we don't simulate vehicles without application or correct environment sensor implementation
if (!(simulationUnit instanceof Sensible sensible) ||
!(sensible.getBasicSensorModule() instanceof EnvironmentBasicSensorModule sensor)) {
return;
}
for (EnvironmentEvent event : environmentSensorUpdates.getEvents()) {
addEvent(new Event(
environmentSensorUpdates.getTime(),
e -> simulationUnit.putEnvironmentEvent(event.type, event))
e -> sensor.addEnvironmentEvent(event.type, event))
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import org.eclipse.mosaic.fed.application.ambassador.simulation.AbstractSimulationUnit;
import org.eclipse.mosaic.fed.application.ambassador.simulation.navigation.CentralNavigationComponent;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.CentralPerceptionComponent;
import org.eclipse.mosaic.fed.application.ambassador.simulation.sensor.EnvironmentSensor;
import org.eclipse.mosaic.fed.application.ambassador.simulation.sensor.EnvironmentBasicSensorModule;
import org.eclipse.mosaic.fed.application.app.api.os.modules.Sensible;
import org.eclipse.mosaic.fed.application.config.CApplicationAmbassador;
import org.eclipse.mosaic.interactions.communication.V2xMessageRemoval;
Expand Down Expand Up @@ -351,7 +351,7 @@ void garbageCollection() {
// clean past environment events
for (AbstractSimulationUnit simulationUnit : UnitSimulator.UnitSimulator.getAllUnits().values()) {
if (simulationUnit instanceof Sensible sensible &&
sensible.getSensorModule().getEnvironmentSensor() instanceof EnvironmentSensor environmentSensor) {
sensible.getBasicSensorModule() instanceof EnvironmentBasicSensorModule environmentSensor) {
environmentSensor.cleanPastEnvironmentEvents();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
import org.eclipse.mosaic.fed.application.ambassador.simulation.communication.CommunicationModuleOwner;
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.ambassador.simulation.sensor.DefaultSensorModule;
import org.eclipse.mosaic.fed.application.ambassador.simulation.sensor.EnvironmentSensor;
import org.eclipse.mosaic.fed.application.ambassador.util.ClassNameParser;
import org.eclipse.mosaic.fed.application.ambassador.util.ClassSubsetIterator;
import org.eclipse.mosaic.fed.application.ambassador.util.UnitLoggerImpl;
Expand All @@ -33,14 +31,11 @@
import org.eclipse.mosaic.fed.application.app.api.CommunicationApplication;
import org.eclipse.mosaic.fed.application.app.api.MosaicApplication;
import org.eclipse.mosaic.fed.application.app.api.os.OperatingSystem;
import org.eclipse.mosaic.fed.application.app.api.sensor.SensorModule;
import org.eclipse.mosaic.interactions.application.ItefLogging;
import org.eclipse.mosaic.interactions.application.SumoTraciRequest;
import org.eclipse.mosaic.interactions.communication.V2xMessageAcknowledgement;
import org.eclipse.mosaic.interactions.communication.V2xMessageTransmission;
import org.eclipse.mosaic.lib.enums.SensorType;
import org.eclipse.mosaic.lib.geo.GeoPoint;
import org.eclipse.mosaic.lib.objects.environment.EnvironmentEvent;
import org.eclipse.mosaic.lib.objects.traffic.SumoTraciResult;
import org.eclipse.mosaic.lib.objects.v2x.V2xMessage;
import org.eclipse.mosaic.lib.util.scheduling.Event;
Expand Down Expand Up @@ -99,7 +94,6 @@ public abstract class AbstractSimulationUnit implements EventProcessor, Operatin

private final AdHocModule adhocModule;
private final CellModule cellModule;
private final SensorModule sensorModule;

/**
* User defined tagged value for the next CAM.
Expand All @@ -122,7 +116,6 @@ public abstract class AbstractSimulationUnit implements EventProcessor, Operatin
AtomicInteger messageSequenceNumberGenerator = new AtomicInteger();
this.adhocModule = new AdHocModule(this, messageSequenceNumberGenerator, getOsLog());
this.cellModule = new CellModule(this, messageSequenceNumberGenerator, getOsLog());
this.sensorModule = new DefaultSensorModule();
this.initialPosition = initialPosition;
}

Expand Down Expand Up @@ -389,17 +382,6 @@ private void processV2xMessageAcknowledgement(final V2xMessageAcknowledgement v2

}

public void putEnvironmentEvent(SensorType type, EnvironmentEvent environmentEvent) {
if (sensorModule.getEnvironmentSensor() instanceof EnvironmentSensor environmentSensor) {
environmentSensor.addEnvironmentEvent(type, environmentEvent);
}
}

@Override
public int getStateOfEnvironmentSensor(SensorType type) {
return sensorModule.getEnvironmentSensor().getSensorData().strengthOf(type);
}

@Override
public void triggerOnSendMessage(V2xMessageTransmission messageTransmission) {
for (CommunicationApplication application : getApplicationsIterator(CommunicationApplication.class)) {
Expand Down Expand Up @@ -430,10 +412,6 @@ public final CellModule getCellModule() {
return cellModule;
}

public final SensorModule getSensorModule() {
return sensorModule;
}

void setRequiredOperatingSystem(Class<? extends OperatingSystem> operatingSystemCheck) {
this.operatingSystemCheck = operatingSystemCheck;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
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 @@ -58,11 +57,6 @@ 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 @@ -24,10 +24,13 @@
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.NopPerceptionModule;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.PerceptionModuleOwner;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.SimplePerceptionConfiguration;
import org.eclipse.mosaic.fed.application.ambassador.simulation.sensor.EnvironmentBasicSensorModule;
import org.eclipse.mosaic.fed.application.app.api.CommunicationApplication;
import org.eclipse.mosaic.fed.application.app.api.VehicleApplication;
import org.eclipse.mosaic.fed.application.app.api.os.VehicleOperatingSystem;
import org.eclipse.mosaic.fed.application.app.api.perception.PerceptionModule;
import org.eclipse.mosaic.fed.application.app.api.sensor.BasicSensorModule;
import org.eclipse.mosaic.fed.application.app.api.sensor.LidarSensorModule;
import org.eclipse.mosaic.interactions.vehicle.VehicleLaneChange;
import org.eclipse.mosaic.interactions.vehicle.VehicleParametersChange;
import org.eclipse.mosaic.interactions.vehicle.VehicleResume;
Expand Down Expand Up @@ -63,6 +66,9 @@ public class VehicleUnit extends AbstractSimulationUnit implements VehicleOperat
@Nonnull
private final PerceptionModule<SimplePerceptionConfiguration> perceptionModule;

@Nonnull
private final BasicSensorModule basicSensorModule;

@Nonnull
private VehicleParameters vehicleParameters;

Expand Down Expand Up @@ -92,6 +98,7 @@ public VehicleUnit(String vehicleName, VehicleType vehicleType, final GeoPoint i
perceptionModule = new NopPerceptionModule(this, database, getOsLog());
}

basicSensorModule = new EnvironmentBasicSensorModule();
}

@Override
Expand Down Expand Up @@ -368,4 +375,14 @@ public IRoadPosition getRoadPosition() {
public PerceptionModule<SimplePerceptionConfiguration> getPerceptionModule() {
return perceptionModule;
}

@Override
public BasicSensorModule getBasicSensorModule() {
return basicSensorModule;
}

@Override
public LidarSensorModule getLidarSensorModule() {
throw new UnsupportedOperationException("Not yet implemented");
}
}

This file was deleted.

Loading

0 comments on commit 8a4a720

Please sign in to comment.