diff --git a/VadereGui/resources/messages.properties b/VadereGui/resources/messages.properties index 5b7be88081721d5d0887967da66e0473a59699cf..4039a782a4b3e31f618ab10b34b99784dfba5a72 100644 --- a/VadereGui/resources/messages.properties +++ b/VadereGui/resources/messages.properties @@ -307,6 +307,7 @@ TopographyChecker.source.idNotUnique=Multiple Sources have the same ID. TopographyChecker.source.overlapWithObstacle=Source overlaps with Obstacle. This leads to pedestrians spawn in obstacle. TopographyChecker.stairs.wrongTreadDim=Stair treadDepth outside of allowed dimension. TopographyChecker.target.unused=The target is not used in any source. Remove target to increase performance. +TopographyChecker.pedestrian.speedsetup=speedDistributionMean must be within min/max range. #TopographyChecker.obstacles.overlap= #TopographyChecker.source.overlap= #TopographyChecker.target.overlap= diff --git a/VadereGui/resources/messages_de_DE.properties b/VadereGui/resources/messages_de_DE.properties index ac6d05f2d5fa85fb8c3156d8ca448b751bd0336c..e74a6a6219f77f976fb58f3c74721ffb30bc290c 100644 --- a/VadereGui/resources/messages_de_DE.properties +++ b/VadereGui/resources/messages_de_DE.properties @@ -306,6 +306,7 @@ TopographyChecker.source.idNotUnique=Quellen haben keine eindeutige ID. TopographyChecker.source.overlapWithObstacle=Quelle und Hinderniss \u00fcberlappen sich. Dies kann f\u00fcrt zuf\u00fchren, dass Personen im Hinderniss erzeugt werden. TopographyChecker.stairs.wrongTreadDim=Stufentiefe ist au\u00dferhalb des Definitionsbereichs. TopographyChecker.target.unused=Das Ziel wird von keiner Quelle verwendet. Entferne das Ziel um die Performance zu erh\u00fchen +TopographyChecker.pedestrian.speedsetup=speedDistributionMean muss im Bereich min/max liegen. #TopographyChecker.obstacles.overlap= #TopographyChecker.source.overlap= #TopographyChecker.target.overlap= diff --git a/VadereSimulator/src/org/vadere/simulator/util/TopographyChecker.java b/VadereSimulator/src/org/vadere/simulator/util/TopographyChecker.java index 36c494d6a5c4f182394a321a86bfbdc2e4f76dfd..0359cc83a2d5309c0eb695ffea8d601e588e1728 100644 --- a/VadereSimulator/src/org/vadere/simulator/util/TopographyChecker.java +++ b/VadereSimulator/src/org/vadere/simulator/util/TopographyChecker.java @@ -3,12 +3,14 @@ package org.vadere.simulator.util; import org.apache.commons.math3.util.Pair; import org.jetbrains.annotations.NotNull; import org.vadere.state.scenario.Obstacle; +import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Source; import org.vadere.state.scenario.Stairs; import org.vadere.state.scenario.Target; import org.vadere.state.scenario.Topography; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -68,6 +70,27 @@ public class TopographyChecker { ret.addAll(checkSourceObstacleOverlap()); ret.addAll(checkUnusedTargets()); ret.addAll(checkStairTreadSanity()); + ret.addAll(checkPedestrianSpeedSetup()); + return ret; + } + + public List checkPedestrianSpeedSetup() { + List ret = new ArrayList<>(); + topography.getPedestrianDynamicElements().getInitialElements().forEach(p -> { + double speedMean = p.getSpeedDistributionMean(); + if (speedMean < p.getAttributes().getMinimumSpeed() || speedMean > p.getAttributes().getMaximumSpeed()){ + ret.add(msgBuilder + .error() + .target(p) + .reason(TopographyCheckerReason.PEDESTRIAN_SPEED_SETUP, + "(" + p.getAttributes().getMaximumSpeed() + + " < treadDepth > " + + p.getAttributes().getMaximumSpeed() + + ") current SpeedDistributionMean is: " + String.format("%.2f",speedMean)) + .build()); + } + }); + return ret; } diff --git a/VadereSimulator/src/org/vadere/simulator/util/TopographyCheckerReason.java b/VadereSimulator/src/org/vadere/simulator/util/TopographyCheckerReason.java index 312505e30f92c3144c7017aaf4561be16881fd4e..6a0b3c4768327780d5ca25dbb7b1d82a388fd585 100644 --- a/VadereSimulator/src/org/vadere/simulator/util/TopographyCheckerReason.java +++ b/VadereSimulator/src/org/vadere/simulator/util/TopographyCheckerReason.java @@ -18,7 +18,8 @@ public enum TopographyCheckerReason { OBSTACLES_OVERLAP("TopographyChecker.obstacles.overlap"), SOURCE_OVERLAP("TopographyChecker.source.overlap"), TARGET_OVERLAP("TopographyChecker.target.overlap"), - STAIRS_OVERLAP("TopographyChecker.stairs.overlap"); + STAIRS_OVERLAP("TopographyChecker.stairs.overlap"), + PEDESTRIAN_SPEED_SETUP("TopographyChecker.pedestrian.speedsetup"); private String msgId; diff --git a/VadereSimulator/tests/org/vadere/simulator/util/TopographyCheckerTest.java b/VadereSimulator/tests/org/vadere/simulator/util/TopographyCheckerTest.java index b5570f9a8929caeebf62fbf131647b9279d539f8..48826995ccf34bf64f0d68697b5239af7259bc58 100644 --- a/VadereSimulator/tests/org/vadere/simulator/util/TopographyCheckerTest.java +++ b/VadereSimulator/tests/org/vadere/simulator/util/TopographyCheckerTest.java @@ -4,11 +4,13 @@ import org.apache.commons.math3.util.Pair; import org.junit.Before; import org.junit.Test; import org.vadere.state.attributes.scenario.AttributesObstacle; +import org.vadere.state.attributes.scenario.builder.AttributesAgentBuilder; import org.vadere.state.attributes.scenario.builder.AttributesObstacleBuilder; import org.vadere.state.attributes.scenario.builder.AttributesSourceBuilder; import org.vadere.state.attributes.scenario.builder.AttributesStairsBuilder; import org.vadere.state.attributes.scenario.builder.AttributesTargetBuilder; import org.vadere.state.scenario.Obstacle; +import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.Source; import org.vadere.state.scenario.Topography; import org.vadere.util.geometry.shapes.VCircle; @@ -381,6 +383,72 @@ public class TopographyCheckerTest { hasNoElement(out); } + + // Test checkPedestrianSpeedSetup + + @Test + public void testCheckPedestrianSpeedSetupToSmall(){ + AttributesAgentBuilder attrAgentB = AttributesAgentBuilder.anAttributesAgent(); + + builder.addPedestrian(attrAgentB + .minimumSpeed(1.2) + .maximumSpeed(2.2) + .speedDistributionMean(0.8) + .build()); + + Topography topography = builder.build(); + TopographyChecker checker = new TopographyChecker(topography); + + List out = checker.checkPedestrianSpeedSetup(); + + TopographyCheckerMessage msg = hasOneElement(out); + isErrorMsg(msg); + assertEquals(TopographyCheckerReason.PEDESTRIAN_SPEED_SETUP, msg.getReason()); + } + + @Test + public void testCheckPedestrianSpeedSetupToBig(){ + AttributesAgentBuilder attrAgentB = AttributesAgentBuilder.anAttributesAgent(); + + builder.addPedestrian(attrAgentB + .minimumSpeed(0.5) + .maximumSpeed(2.2) + .build()); + + // SpeedDistributionMean cannot be set bigger than max speed at construction time. + Pedestrian p = (Pedestrian) builder.getLastAddedElement(); + p.getAttributes().setSpeedDistributionMean(10.0); + + Topography topography = builder.build(); + TopographyChecker checker = new TopographyChecker(topography); + + List out = checker.checkPedestrianSpeedSetup(); + + TopographyCheckerMessage msg = hasOneElement(out); + isErrorMsg(msg); + assertEquals(TopographyCheckerReason.PEDESTRIAN_SPEED_SETUP, msg.getReason()); + } + + + @Test + public void testCheckPedestrianSpeedSetupOk(){ + AttributesAgentBuilder attrAgentB = AttributesAgentBuilder.anAttributesAgent(); + + builder.addPedestrian(attrAgentB + .minimumSpeed(0.5) + .maximumSpeed(2.2) + .speedDistributionMean(0.8) + .build()); + + Topography topography = builder.build(); + TopographyChecker checker = new TopographyChecker(topography); + + List out = checker.checkPedestrianSpeedSetup(); + + hasNoElement(out); + } + + private TopographyCheckerMessage hasOneElement(List out){ assertEquals(1, out.size()); return out.get(0); diff --git a/VadereSimulator/tests/org/vadere/simulator/util/TopographyTestBuilder.java b/VadereSimulator/tests/org/vadere/simulator/util/TopographyTestBuilder.java index 4f161818166078f196e0f8e020290c594137281d..00f712abf502d4aea36cc77a86ee675fa40b4c82 100644 --- a/VadereSimulator/tests/org/vadere/simulator/util/TopographyTestBuilder.java +++ b/VadereSimulator/tests/org/vadere/simulator/util/TopographyTestBuilder.java @@ -1,10 +1,12 @@ package org.vadere.simulator.util; +import org.vadere.state.attributes.scenario.AttributesAgent; import org.vadere.state.attributes.scenario.AttributesObstacle; import org.vadere.state.attributes.scenario.AttributesSource; import org.vadere.state.attributes.scenario.AttributesStairs; import org.vadere.state.attributes.scenario.AttributesTarget; import org.vadere.state.scenario.Obstacle; +import org.vadere.state.scenario.Pedestrian; import org.vadere.state.scenario.ScenarioElement; import org.vadere.state.scenario.Source; import org.vadere.state.scenario.Stairs; @@ -13,13 +15,17 @@ import org.vadere.state.scenario.Topography; import org.vadere.util.geometry.shapes.VRectangle; import org.vadere.util.geometry.shapes.VShape; +import java.util.Random; + public class TopographyTestBuilder { Topography topography; ScenarioElement lastAddedElement; + Random rnd; public TopographyTestBuilder(){ topography = new Topography(); + rnd = new Random(1); } public Topography build(){ @@ -111,6 +117,16 @@ public class TopographyTestBuilder { return this; } + TopographyTestBuilder addPedestrian(){ + + return this; + } + TopographyTestBuilder addPedestrian(AttributesAgent attr){ + Pedestrian pedestrian = new Pedestrian(attr, rnd); + lastAddedElement = pedestrian; + topography.addInitialElement(pedestrian); + return this; + } } diff --git a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAgent.java b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAgent.java index e5e7ce00aeceb48ca97c23133d47a02a8f60fa27..3baf5a0246c31438dc9e93af7155ca7abf56b0fd 100644 --- a/VadereState/src/org/vadere/state/attributes/scenario/AttributesAgent.java +++ b/VadereState/src/org/vadere/state/attributes/scenario/AttributesAgent.java @@ -79,4 +79,38 @@ public class AttributesAgent extends AttributesDynamicElement { return acceleration; } + public void setRadius(double radius) { + checkSealed(); + this.radius = radius; + } + + public void setDensityDependentSpeed(boolean densityDependentSpeed) { + checkSealed(); + this.densityDependentSpeed = densityDependentSpeed; + } + + public void setSpeedDistributionMean(double speedDistributionMean) { + checkSealed(); + this.speedDistributionMean = speedDistributionMean; + } + + public void setSpeedDistributionStandardDeviation(double speedDistributionStandardDeviation) { + checkSealed(); + this.speedDistributionStandardDeviation = speedDistributionStandardDeviation; + } + + public void setMinimumSpeed(double minimumSpeed) { + checkSealed(); + this.minimumSpeed = minimumSpeed; + } + + public void setMaximumSpeed(double maximumSpeed) { + checkSealed(); + this.maximumSpeed = maximumSpeed; + } + + public void setAcceleration(double acceleration) { + checkSealed(); + this.acceleration = acceleration; + } } diff --git a/VadereState/src/org/vadere/state/attributes/scenario/builder/AttributesAgentBuilder.java b/VadereState/src/org/vadere/state/attributes/scenario/builder/AttributesAgentBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..10cdc499a890ee0635147064e6482f58a39c5057 --- /dev/null +++ b/VadereState/src/org/vadere/state/attributes/scenario/builder/AttributesAgentBuilder.java @@ -0,0 +1,78 @@ +package org.vadere.state.attributes.scenario.builder; + +import org.vadere.state.attributes.Attributes; +import org.vadere.state.attributes.scenario.AttributesAgent; + +public final class AttributesAgentBuilder { + private double radius = 0.195; + private boolean densityDependentSpeed = false; + // from weidmann-1992 page 18, seitz-2016c page 2 (Methods) + private double speedDistributionMean = 1.34; + // from weidmann-1992 page 18, seitz-2016c page 2 (Methods) + private double speedDistributionStandardDeviation = 0.26; + // from weidmann-1992 page 18, seitz-2016c page 2 (Methods) + private double minimumSpeed = 0.5; + // from weidmann-1992 page 18, deviates in seitz-2016c page 2 (Methods): 2.0 + private double maximumSpeed = 2.2; + private double acceleration = 2.0; + private int id = Attributes.ID_NOT_SET; + + private AttributesAgentBuilder() { + } + + public static AttributesAgentBuilder anAttributesAgent() { + return new AttributesAgentBuilder(); + } + + public AttributesAgentBuilder radius(double radius) { + this.radius = radius; + return this; + } + + public AttributesAgentBuilder densityDependentSpeed(boolean densityDependentSpeed) { + this.densityDependentSpeed = densityDependentSpeed; + return this; + } + + public AttributesAgentBuilder speedDistributionMean(double speedDistributionMean) { + this.speedDistributionMean = speedDistributionMean; + return this; + } + + public AttributesAgentBuilder speedDistributionStandardDeviation(double speedDistributionStandardDeviation) { + this.speedDistributionStandardDeviation = speedDistributionStandardDeviation; + return this; + } + + public AttributesAgentBuilder minimumSpeed(double minimumSpeed) { + this.minimumSpeed = minimumSpeed; + return this; + } + + public AttributesAgentBuilder maximumSpeed(double maximumSpeed) { + this.maximumSpeed = maximumSpeed; + return this; + } + + public AttributesAgentBuilder acceleration(double acceleration) { + this.acceleration = acceleration; + return this; + } + + public AttributesAgentBuilder id(int id) { + this.id = id; + return this; + } + + public AttributesAgent build() { + AttributesAgent attributesAgent = new AttributesAgent(id); + attributesAgent.setRadius(radius); + attributesAgent.setDensityDependentSpeed(densityDependentSpeed); + attributesAgent.setSpeedDistributionMean(speedDistributionMean); + attributesAgent.setSpeedDistributionStandardDeviation(speedDistributionStandardDeviation); + attributesAgent.setMinimumSpeed(minimumSpeed); + attributesAgent.setMaximumSpeed(maximumSpeed); + attributesAgent.setAcceleration(acceleration); + return attributesAgent; + } +}