package iamrescue.belief.inference; import iamrescue.belief.IAMWorldModel; import iamrescue.belief.entities.BlockInfoRoad; import iamrescue.belief.spatial.ISpatialIndex; import iamrescue.belief.spatial.SpatialQueryFactory; import iamrescue.util.PositionXY; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import javolution.util.FastList; import javolution.util.FastMap; import rescuecore2.standard.entities.Human; import rescuecore2.standard.entities.Road; import rescuecore2.standard.entities.StandardEntity; import rescuecore2.standard.entities.StandardEntityURN; import rescuecore2.standard.entities.StandardPropertyURN; import rescuecore2.worldmodel.ChangeSet; import rescuecore2.worldmodel.EntityID; /** * Detects passable roads based on an agent's position history. * * @author Sebastian * */ public class PassableRoadsDetector { private IAMWorldModel worldModel; private static final boolean CONSIDER_ONLY_YOURSELF = true; private static final ChangeSet EMPTY_CHANGE_SET = new ChangeSet(); // Keeps track of when positions were last inferred for a given entity. private Map<EntityID, Integer> lastUpdate = new FastMap<EntityID, Integer>(); // private ISpatialIndex spatial; private EntityID myself; private boolean skip = false; public PassableRoadsDetector(IAMWorldModel worldModel, EntityID myself) { this.worldModel = worldModel; // this.spatial = spatial; this.myself = myself; if (!(worldModel.getEntity(myself) instanceof Human) && CONSIDER_ONLY_YOURSELF) { skip = true; } worldModel.index(); } public ChangeSet inferPassableRoads() { if (skip) { return EMPTY_CHANGE_SET; } ChangeSet changed = new ChangeSet(); // Get all humans Collection<StandardEntity> humans; if (CONSIDER_ONLY_YOURSELF) { humans = Collections.singletonList(worldModel.getEntity(myself)); } else { humans = worldModel.getEntitiesOfType( StandardEntityURN.AMBULANCE_TEAM, StandardEntityURN.POLICE_FORCE, StandardEntityURN.FIRE_BRIGADE, StandardEntityURN.CIVILIAN); } // Get position histories for (StandardEntity standardEntity : humans) { // if (standardEntity instanceof Human) { Human human = (Human) standardEntity; if (human.isPositionHistoryDefined()) { // Check when this was done Integer previous = lastUpdate.get(human.getID()); int timeStep = worldModel.getProvenance(human.getID(), StandardPropertyURN.POSITION_HISTORY).getLatest() .getTimeStep(); if (previous == null || previous != timeStep) { // Consider this processHuman(human, changed); lastUpdate.put(human.getID(), timeStep); } // } } } return changed; } private void processHuman(Human human, ChangeSet changed) { int[] positionHistory = human.getPositionHistory(); List<StandardEntity> traversed = new FastList<StandardEntity>(); for (int i = 0; i < positionHistory.length; i = i + 2) { /* * Collection<StandardEntity> result = spatial * .query(SpatialQueryFactory.queryWithinDistance( new * PositionXY(positionHistory[i], positionHistory[i + 1]), 0, * BlockInfoRoad.class)); */ Collection<StandardEntity> result = worldModel.getObjectsInRange( positionHistory[i], positionHistory[i + 1], 0); for (StandardEntity standardEntity : result) { if (standardEntity instanceof BlockInfoRoad) { traversed.add(standardEntity); } } } // Mark all passed roads - if not, this // should be inferred through the actual blockades seen (or communicated // by the relevant agent). for (StandardEntity se : traversed) { if (se instanceof Road) { assert se instanceof BlockInfoRoad; BlockInfoRoad road = (BlockInfoRoad) se; if (!road.isBlockadesDefined()) { if (!road.isHasBeenPassedDefined() || !road.hasBeenPassed()) { road.setHasBeenPassed(true); changed .addChange(road, road .getHasBeenPassedProperty()); } } } } } }