package iamrescue.belief.inference; import iamrescue.agent.ISimulationTimer; import iamrescue.belief.IAMWorldModel; import iamrescue.belief.entities.RoutingInfoBlockade; import iamrescue.belief.provenance.IPropertyMerger; import iamrescue.belief.provenance.InferredOrigin; import iamrescue.belief.provenance.ProvenanceLogEntry; import iamrescue.routing.WorldModelConverter; import iamrescue.routing.costs.BlockCheckerUtil; import iamrescue.util.PositionXY; import java.util.ArrayList; import java.util.List; import java.util.Set; import javolution.util.FastSet; import rescuecore2.standard.entities.StandardEntity; import rescuecore2.standard.entities.StandardEntityURN; import rescuecore2.standard.entities.StandardPropertyURN; import rescuecore2.worldmodel.ChangeSet; import rescuecore2.worldmodel.Entity; import rescuecore2.worldmodel.EntityListener; import rescuecore2.worldmodel.Property; import rescuecore2.worldmodel.WorldModel; import rescuecore2.worldmodel.WorldModelListener; import rescuecore2.worldmodel.properties.IntArrayProperty; /** * Detects passable roads based on an agent's position history. * * @author Sebastian * */ public class RoutingInfoUpdater implements WorldModelListener<StandardEntity>, EntityListener { private IAMWorldModel worldModel; private WorldModelConverter converter; private Set<RoutingInfoBlockade> updated = new FastSet<RoutingInfoBlockade>(); private ISimulationTimer timer; private IPropertyMerger propertyMerger; public RoutingInfoUpdater(IAMWorldModel worldModel, WorldModelConverter converter, ISimulationTimer timer, IPropertyMerger propertyMerger) { this.worldModel = worldModel; this.converter = converter; this.timer = timer; this.propertyMerger = propertyMerger; worldModel.addWorldModelListener(this); for (StandardEntity blockade : worldModel .getEntitiesOfType(StandardEntityURN.BLOCKADE)) { blockade.addEntityListener(this); } } public ChangeSet inferUpdatedBlockades() { ChangeSet changed = new ChangeSet(); for (RoutingInfoBlockade b : updated) { if (b.isApexesDefined()) { List<Integer> positionArray = new ArrayList<Integer>(); // Only update if we have observed apexes, and know position // System.out.println("Checking block " + // b.getFullDescription()); List<Integer> neighbours = converter.getSortedNeighbours(b .getPosition().getValue()); // System.out.println("Neighbours: " + neighbours); for (int i = 0; i < neighbours.size() - 1; i++) { for (int j = i + 1; j < neighbours.size(); j++) { PositionXY from = converter.getSimpleGraphNode( neighbours.get(i)).getRepresentativePoint(); PositionXY to = converter.getSimpleGraphNode( neighbours.get(j)).getRepresentativePoint(); if (BlockCheckerUtil.isBlocking(b, from, to)) { /* * positionArray.add(from.getX()); * positionArray.add(from.getY()); * positionArray.add(to.getX()); * positionArray.add(to.getY()); */ positionArray.add(i); positionArray.add(j); // System.out.println("Blocking " + // neighbours.get(i) // + " to " + neighbours.get(j)); } } } int[] blocking = new int[positionArray.size()]; for (int i = 0; i < blocking.length; i++) { blocking[i] = positionArray.get(i); } /* * if (positionArray.size() > 0) { * * * IntArrayProperty blockedEdgesProperty = b * .getBlockedEdgesProperty(); * * boolean needsUpdating = false; * * if (!blockedEdgesProperty.isDefined()) { needsUpdating = * true; } else { int[] previous = b.getBlockedEdges(); if * (previous.length != blocking.length) { needsUpdating = true; * } else { for (int i = 0; i < previous.length; i++) { if * (previous[i] != blocking[i]) { needsUpdating = true; break; } * } } } * * if (needsUpdating) { * * } } */ IntArrayProperty newProperty = new IntArrayProperty( RoutingInfoBlockade.BLOCK_INFO_URN); newProperty.setValue(blocking); ProvenanceLogEntry entry = new ProvenanceLogEntry(timer .getTime(), InferredOrigin.INSTANCE, newProperty); worldModel.storeProvenance(b.getID(), entry); Property decidedValue = propertyMerger.decideValue(worldModel .getProvenance(b.getID(), RoutingInfoBlockade.BLOCK_INFO_URN)); changed.addChange(b.getID(), RoutingInfoBlockade.BLOCK_INFO_URN, decidedValue); Property property = b.getBlockedEdgesProperty(); if (decidedValue.isDefined()) { property.takeValue(decidedValue); } else { property.undefine(); } } } if (updated.size() > 0) { updated.clear(); } return changed; } /* * (non-Javadoc) * * @see * rescuecore2.worldmodel.WorldModelListener#entityAdded(rescuecore2.worldmodel * .WorldModel, rescuecore2.worldmodel.Entity) */ @Override public void entityAdded(WorldModel<? extends StandardEntity> model, StandardEntity e) { if (e instanceof RoutingInfoBlockade) { e.addEntityListener(this); updated.add((RoutingInfoBlockade) e); } } /* * (non-Javadoc) * * @seerescuecore2.worldmodel.WorldModelListener#entityRemoved(rescuecore2. * worldmodel.WorldModel, rescuecore2.worldmodel.Entity) */ @Override public void entityRemoved(WorldModel<? extends StandardEntity> model, StandardEntity e) { if (e instanceof RoutingInfoBlockade) { e.removeEntityListener(this); } } /* * (non-Javadoc) * * @see * rescuecore2.worldmodel.EntityListener#propertyChanged(rescuecore2.worldmodel * .Entity, rescuecore2.worldmodel.Property, java.lang.Object, * java.lang.Object) */ @Override public void propertyChanged(Entity e, Property p, Object oldValue, Object newValue) { if (p.getURN().equals(StandardPropertyURN.APEXES)) { updated.add((RoutingInfoBlockade) e); } } }