Skip to content

Commit

Permalink
feat(mapping): configure type distributions for ScenarioVehicle (#333)
Browse files Browse the repository at this point in the history
* allows defining multiple application types for equal vehicle type names in large sumo scenario
* feat(mapping): use type distributions in LuST scenario
* clean: reformated LuST mapping
* clean: removed old bus type from LuST mapping
* clean(mapping): minor cleanup of SpawningFramework
* clean(mapping): avoid instantiation of selectors using map cache
* feat(mapping): reuse predefined prototype, added integration test for Sievekingplatz
* fix: fixed invalid mapping_config of LuST scenario
  • Loading branch information
kschrab authored Jul 31, 2023
1 parent 0fca8ab commit 750a77a
Show file tree
Hide file tree
Showing 8 changed files with 345 additions and 174 deletions.
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
{
"prototypes":[
{
"name":"passenger1",
"applications":[
"org.eclipse.mosaic.app.tutorial.eventprocessing.sampling.HelloWorldApp"
]
},
"prototypes": [
{
"name":"passenger2a",
"applications":[

"name": "passenger1",
"applications": [
"org.eclipse.mosaic.app.tutorial.eventprocessing.sampling.HelloWorldApp"
]
},
},
{
"name":"passenger2b",
"applications":[

"name": "passenger2a",
"applications": [
]
},
},
{
"name":"passenger3",
"applications":[

"name": "passenger2b",
"applications": [
]
},
},
{
"name":"passenger4",
"applications":[

"name": "passenger3",
"applications": [
]
},
},
{
"name":"passenger5",
"applications":[

"name": "passenger4",
"applications": [
]
},
},
{
"name":"bus",
"applications":[
"org.eclipse.mosaic.app.tutorial.eventprocessing.sampling.HelloWorldApp"
"name": "passenger5",
"applications": [
]
}
]
}
],
"typeDistributions": {
"bus": [
{
"name": "bus",
"applications": [
"org.eclipse.mosaic.app.tutorial.eventprocessing.sampling.HelloWorldApp"
],
"weight": 0.5
},
{
"name": "bus",
"applications": [ ],
"weight": 0.5
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
},
{
"name": "Bike",
"weight": 0.8,
"applications": [ "org.eclipse.mosaic.app.tutorial.eventprocessing.sampling.HelloWorldApp" ]
},
{
Expand All @@ -13,10 +14,22 @@
},
{
"name": "Bus",
"weight": 0.4,
"applications": [ "org.eclipse.mosaic.app.tutorial.eventprocessing.sampling.HelloWorldApp" ]
}
],
"typeDistributions": {
"Bus": [
{
"name": "Bus",
"weight": 0.4
},
{
"name": "Bus",
"weight": 0.6,
"applications": [ ]
}
]
},
"vehicles": [
{
"startingTime": "10.0 s",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package org.eclipse.mosaic.fed.mapping.ambassador;

import org.eclipse.mosaic.fed.mapping.ambassador.weighting.StochasticSelector;
import org.eclipse.mosaic.fed.mapping.config.CMappingAmbassador;
import org.eclipse.mosaic.fed.mapping.config.CPrototype;
import org.eclipse.mosaic.interactions.mapping.VehicleRegistration;
Expand All @@ -32,6 +33,9 @@

import org.apache.commons.lang3.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;

/**
Expand All @@ -54,7 +58,8 @@ public class MappingAmbassador extends AbstractFederateAmbassador {
/**
* Read the <code>CMappingAmbassador</code> from the configuration.
*/
private CMappingAmbassador mappingAmbassadorConfiguration;
private final CMappingAmbassador mappingAmbassadorConfiguration;


/**
* Pointer to save the {@link ScenarioTrafficLightRegistration} when it arrives too early.
Expand All @@ -63,6 +68,11 @@ public class MappingAmbassador extends AbstractFederateAmbassador {

private RandomNumberGenerator randomNumberGenerator;

/**
* Cache stochastic selectors to avoid unnecessary instantiations.
*/
private final Map<String, StochasticSelector<CPrototype>> typeDistributionSelectors = new HashMap<>();

/**
* Constructor for the {@link MappingAmbassador}.
*
Expand All @@ -89,7 +99,7 @@ public MappingAmbassador(AmbassadorParameter ambassadorParameter) {
@Override
protected void processInteraction(Interaction interaction) throws InternalFederateException {
try {
log.info("processInteraction(): " + interaction.getClass().getCanonicalName());
log.debug("processInteraction(): " + interaction.getTypeId());
if (interaction.getTypeId().equals(ScenarioTrafficLightRegistration.TYPE_ID)) {
handleInteraction((ScenarioTrafficLightRegistration) interaction);
} else if (interaction.getTypeId().equals(ScenarioVehicleRegistration.TYPE_ID)) {
Expand Down Expand Up @@ -121,46 +131,69 @@ private void handleInteraction(ScenarioTrafficLightRegistration interaction) {
*/
private void handleInteraction(ScenarioVehicleRegistration scenarioVehicle) throws InternalFederateException {
if (framework != null) {
final CPrototype prototype = framework.getPrototypeByName(scenarioVehicle.getVehicleType().getName());
if (prototype == null) {
log.debug(
"There is no such prototype \"{}\" configured. No application will be mapped for vehicle \"{}\".",
scenarioVehicle.getVehicleType().getName(),
scenarioVehicle.getId()
);
return;
}

if (randomNumberGenerator.nextDouble() >= ObjectUtils.defaultIfNull(prototype.weight, 1.0)) {
log.debug(
"This scenario vehicle \"{}\" of prototype \"{}\" will not be equipped due to a weight condition of {}.",
scenarioVehicle.getId(),
scenarioVehicle.getVehicleType().getName(),
prototype.weight
final List<CPrototype> typeDistribution = framework.getTypeDistributionByName(scenarioVehicle.getVehicleType().getName());
if (!typeDistribution.isEmpty()) {
StochasticSelector<CPrototype> selector = typeDistributionSelectors.get(scenarioVehicle.getVehicleType().getName());
if (selector == null) {
selector = new StochasticSelector<>(typeDistribution, randomNumberGenerator);
typeDistributionSelectors.put(scenarioVehicle.getVehicleType().getName(), selector);
}
final CPrototype selected = selector.nextItem();
final CPrototype predefined = framework.getPrototypeByName(selected.name);
sendVehicleRegistrationForScenarioVehicle(scenarioVehicle,
// use group/application list from predefined type, if not defined in type distribution
selected.group == null && predefined != null ? predefined.group : selected.group,
selected.applications == null && predefined != null ? predefined.applications : selected.applications
);
return;
} else {
final CPrototype prototype = framework.getPrototypeByName(scenarioVehicle.getVehicleType().getName());
if (prototype == null) {
log.debug(
"There is no such prototype \"{}\" configured. No application will be mapped for vehicle \"{}\".",
scenarioVehicle.getVehicleType().getName(),
scenarioVehicle.getId()
);
return;
}

if (randomNumberGenerator.nextDouble() >= ObjectUtils.defaultIfNull(prototype.weight, 1.0)) {
log.debug(
"This scenario vehicle \"{}\" of prototype \"{}\" will not be equipped due to a weight condition of {}.",
scenarioVehicle.getId(),
scenarioVehicle.getVehicleType().getName(),
prototype.weight
);
return;
}
sendVehicleRegistrationForScenarioVehicle(scenarioVehicle, prototype.group, prototype.applications);
}

final VehicleRegistration vehicleRegistration = new VehicleRegistration(
scenarioVehicle.getTime(),
scenarioVehicle.getName(),
prototype.group,
prototype.applications,
null,
scenarioVehicle.getVehicleType()
);
try {
log.info("Mapping Scenario Vehicle. time={}, name={}, type={}, apps={}",
framework.getTime(), scenarioVehicle.getName(), scenarioVehicle.getVehicleType().getName(), prototype.applications);
rti.triggerInteraction(vehicleRegistration);
} catch (Exception e) {
throw new InternalFederateException(e);
}
} else {
log.warn("No mapping configuration available. Skipping {}", scenarioVehicle.getClass().getSimpleName());
}
}

private void sendVehicleRegistrationForScenarioVehicle(
ScenarioVehicleRegistration scenarioVehicle, String group, List<String> applications
) throws InternalFederateException {
final VehicleRegistration vehicleRegistration = new VehicleRegistration(
scenarioVehicle.getTime(),
scenarioVehicle.getName(),
group,
applications,
null,
scenarioVehicle.getVehicleType()
);
try {
log.info("Mapping Scenario Vehicle. time={}, name={}, type={}, apps={}",
framework.getTime(), scenarioVehicle.getName(), scenarioVehicle.getVehicleType().getName(), applications);
rti.triggerInteraction(vehicleRegistration);
} catch (Exception e) {
throw new InternalFederateException(e);
}
}

@Override
protected void processTimeAdvanceGrant(long time) throws InternalFederateException {
try {
Expand All @@ -182,6 +215,7 @@ public void initialize(long startTime, long endTime) throws InternalFederateExce
// enriched with functionality)
framework = new SpawningFramework(mappingAmbassadorConfiguration, scenarioTrafficLightRegistration, rti, randomNumberGenerator);

typeDistributionSelectors.clear();
// Send out the VehicleTypesInitialization, publishing information
// about the different vehicle types in the simulation
rti.triggerInteraction(framework.generateVehicleTypesInitialization());
Expand Down
Loading

0 comments on commit 750a77a

Please sign in to comment.