/**
*
*/
package iamrescue.util;
import iamrescue.agent.ISimulationTimer;
import iamrescue.belief.IAMWorldModel;
import iamrescue.belief.provenance.IProvenanceInformation;
import iamrescue.belief.provenance.ProvenanceLogEntry;
import iamrescue.belief.provenance.SensedOrigin;
import java.util.Iterator;
import java.util.NavigableSet;
import rescuecore2.misc.Pair;
import rescuecore2.standard.entities.Human;
import rescuecore2.standard.entities.StandardPropertyURN;
import rescuecore2.standard.view.PositionHistoryLayer;
import rescuecore2.worldmodel.EntityID;
/**
* @author Sebastian
*
*/
public class HumanMovementUtility {
/**
* Returns the distance travelled by this agent in the last time step. This
* only works if we have the x and y coordinates of the agent and its
* position history.
*
* @param human
* The human to check
* @param model
* The world model
* @return The distance, or -1 if not enough information is known.
*/
public static int getDistanceJustTravelled(Human human, IAMWorldModel model) {
Pair<Integer, Integer> location = human.getLocation(model);
if (location == null) {
return -1;
} else {
if (!human.isPositionHistoryDefined()) {
return 0;
}
int[] positionHistory = human.getPositionHistory();
if (positionHistory.length == 0 || positionHistory.length == 1
|| positionHistory.length == 2) {
return 0;
}
double sum = 0;
PositionXY lastPosition = null;
for (int i = 0; i < positionHistory.length - 2; i = i + 2) {
PositionXY thisPosition = new PositionXY(positionHistory[i],
positionHistory[i + 1]);
if (lastPosition != null) {
sum += lastPosition.distanceTo(thisPosition);
}
lastPosition = thisPosition;
}
PositionXY current = new PositionXY(location);
sum += lastPosition.distanceTo(current);
return (int) Math.round(sum);
}
}
/**
* Returns the position of the agent during the last time step.
*
* @return The position of the agent, or null if it was unknown / undefined
* / too early
*/
public static PositionXY findLastKnownPosition(EntityID id,
IAMWorldModel worldModel, ISimulationTimer timer) {
int currentTime = timer.getTime();
// 2 arrays for x and y, respectively
IProvenanceInformation[] provenances = new IProvenanceInformation[2];
provenances[0] = worldModel.getProvenance(id, StandardPropertyURN.X);
provenances[1] = worldModel.getProvenance(id, StandardPropertyURN.Y);
int[] lastPositions = new int[2];
boolean found = false;
// cycle through entries to find latest
for (int i = 0; i < 2; i++) {
found = false;
Iterator<ProvenanceLogEntry> iterator = provenances[i]
.getAllLatestFirst();
// iterator = all.descendingIterator();
while (iterator.hasNext()) {
ProvenanceLogEntry entry = iterator.next();
if (entry.getTimeStep() == currentTime - 1) {
if (entry.getOrigin().equals(SensedOrigin.INSTANCE)) {
if (entry.getProperty().isDefined()) {
lastPositions[i] = (Integer) entry.getProperty()
.getValue();
found = true;
break;
} else {
// Undefined
break;
}
}
} else if (entry.getTimeStep() < currentTime - 1) {
// Too late
break;
}
}
if (!found) {
// No point to continue for second value
break;
}
}
if (!found) {
return null;
} else {
return new PositionXY(lastPositions[0], lastPositions[1]);
}
}
/**
* @param e
* @param worldModel
* @param timer
* @return
*/
public static int getAbsoluteDistanceJustTravelled(Human e,
IAMWorldModel worldModel, ISimulationTimer timer) {
if (!(e.isXDefined() && e.isYDefined() && e.isPositionDefined())) {
return -1;
}
PositionXY currentPosition = new PositionXY(e.getLocation(worldModel));
PositionXY findLastKnownPosition = findLastKnownPosition(e.getID(),
worldModel, timer);
if (findLastKnownPosition == null) {
return -1;
}
return (int) Math.round(currentPosition
.distanceTo(findLastKnownPosition));
}
}