use of com.microsoft.Malmo.Schemas.PointWithToleranceAndDescription in project malmo by Microsoft.
the class ObservationFromSubgoalPositionListImplementation method writeObservationsToJSON.
@Override
public void writeObservationsToJSON(JsonObject json, MissionInit missionInit) {
int nTargets = this.positions.getPoint().size();
boolean foundNextPoint = false;
double targetx = 0;
double targetz = 0;
EntityPlayerSP player = Minecraft.getMinecraft().player;
if (player == null)
// Nothing we can do.
return;
double sourcex = player.posX;
double sourcez = player.posZ;
while (this.subgoalIndex < nTargets && !foundNextPoint) {
targetx = this.positions.getPoint().get(this.subgoalIndex).getX().doubleValue();
targetz = this.positions.getPoint().get(this.subgoalIndex).getZ().doubleValue();
double tol = this.positions.getPoint().get(this.subgoalIndex).getTolerance().doubleValue();
if (Math.abs(targetx - sourcex) + Math.abs(targetz - sourcez) < tol)
this.subgoalIndex++;
else
foundNextPoint = true;
}
if (!foundNextPoint)
// Finished.
return;
// Calculate which way we need to turn in order to point towards the target:
double dx = (targetx - sourcex);
double dz = (targetz - sourcez);
double targetYaw = (Math.atan2(dz, dx) * 180.0 / Math.PI) - 90;
double sourceYaw = player.rotationYaw;
// Find shortest angular distance between the two yaws, preserving sign:
double difference = targetYaw - sourceYaw;
while (difference < -180) difference += 360;
while (difference > 180) difference -= 360;
// Normalise:
difference /= 180.0;
json.addProperty("yawDelta", difference);
PointWithToleranceAndDescription point = this.positions.getPoint().get(this.subgoalIndex);
JsonObject pointElement = new JsonObject();
pointElement.addProperty("XPos", point.getX().doubleValue());
pointElement.addProperty("YPos", point.getY().doubleValue());
pointElement.addProperty("ZPos", point.getZ().doubleValue());
pointElement.addProperty("description", point.getDescription());
json.add("nextSubgoal", pointElement);
}
use of com.microsoft.Malmo.Schemas.PointWithToleranceAndDescription in project malmo by Microsoft.
the class MazeDecoratorImplementation method recordStartAndEndPoints.
private void recordStartAndEndPoints(Cell start, Cell end, MissionInit missionInit) {
// TODO: how do we set the goal position, now it no longer has a declaration in the Mission xml?
int scale = this.mazeParams.getSizeAndPosition().getScale();
// Position the start point:
PosAndDirection p = new PosAndDirection();
p.setX(new BigDecimal(scale * (start.x + 0.5) + this.xOrg));
p.setY(new BigDecimal(1 + this.yOrg + this.startHeight));
p.setZ(new BigDecimal(scale * (start.z + 0.5) + this.zOrg));
this.startPosition = p;
// TODO - for the moment, force all players to being at the maze start point - but this needs to be optional.
for (AgentSection as : missionInit.getMission().getAgentSection()) {
p.setPitch(as.getAgentStart().getPlacement().getPitch());
p.setYaw(as.getAgentStart().getPlacement().getYaw());
as.getAgentStart().setPlacement(p);
}
if (this.mazeParams.getAddQuitProducer() != null) {
String desc = this.mazeParams.getAddQuitProducer().getDescription();
this.quitter = new AgentQuitFromReachingPosition();
PointWithToleranceAndDescription endpoint = new PointWithToleranceAndDescription();
endpoint.setDescription(desc);
endpoint.setTolerance(new BigDecimal(0.5 + scale / 2.0));
double endX = scale * (end.x + 0.5) + this.xOrg;
// Assuming we approach on the optimal path, need the height of the goal to be reachable.
double endY = 1 + this.optimalPathHeight + this.yOrg;
double endZ = scale * (end.z + 0.5) + this.zOrg;
endpoint.setX(new BigDecimal(endX));
endpoint.setY(new BigDecimal(endY));
endpoint.setZ(new BigDecimal(endZ));
this.quitter.getMarker().add(endpoint);
}
}
use of com.microsoft.Malmo.Schemas.PointWithToleranceAndDescription in project malmo by Microsoft.
the class MazeDecoratorImplementation method findSubgoals.
private void findSubgoals(Cell[] grid, Cell start, Cell end) {
System.out.println("Attempting to find subgoals...");
// Attempt to find subgoals - this represents the "smoothed" optimal path.
// It uses something akin to line-of-sight smoothing, to reduce the rectilinear path into something a bit more
// like what a human agent would use.
// First, copy the optimal path into an array:
ArrayList<Cell> opath = new ArrayList<Cell>();
Cell cur = end;
while (cur != start) {
opath.add(0, cur);
cur = cur.predecessor;
}
opath.add(0, start);
// Now walk the path, removing any points that aren't required.
// For example, if the agent can walk from A directly to C, we can safely remove point B.
// This will help remove some of the 90 degree turns - eg instead of walking one square north, then one square east,
// the agent could just walk directly north-east.
int startindex = 0;
int removalcandidateindex = 1;
int destindex = 2;
if (opath.size() > 2) {
// Walk the path, removing any points we can:
while (destindex != opath.size()) {
Cell smoothstart = opath.get(startindex);
Cell smoothremovalcandidate = opath.get(removalcandidateindex);
Cell smoothdest = opath.get(destindex);
// Traverse the shortest line from smoothstart to smoothdest looking for collisions.
// If there are none, we can safely remove the removal candidate.
double xa = smoothstart.x + 0.5;
double za = smoothstart.z + 0.5;
double xb = smoothdest.x + 0.5;
double zb = smoothdest.z + 0.5;
double dist = Math.sqrt((xb - xa) * (xb - xa) + (zb - za) * (zb - za));
int samplepoints = (int) Math.ceil(dist * 5);
boolean walkable = true;
for (int sample = 0; sample < samplepoints && walkable; sample++) {
double f = (double) sample / (double) samplepoints;
double xs = xa + (xb - xa) * f;
double zs = za + (zb - za) * f;
int cellx = (int) Math.floor(xs);
int cellz = (int) Math.floor(zs);
// Is this cell blocked?
int cellindex = cellx + cellz * width;
if (cellindex < 0 || cellindex >= grid.length || grid[cellindex] == null)
walkable = false;
if (walkable && gapHeight > optimalPathHeight && !gapBlock.getBlock().getDefaultState().equals(Blocks.AIR.getDefaultState())) {
// The "gaps" are in fact walls, so we need to be a bit more conservative with our path, since the
// player has a width of 0.4 cells. We do this in a very unsophisticated, brute-force manor by testing
// the four corner points of the square the player would occupy if he was standing centrally in the cell.
int lowerx = (int) Math.floor(xs - 0.2);
int upperx = (int) Math.floor(xs + 0.2);
int lowerz = (int) Math.floor(zs - 0.2);
int upperz = (int) Math.floor(zs + 0.2);
int[] cellsToTest = new int[4];
// Speed is not really an issue here so we don't worry about testing the same cells multiple times.
cellsToTest[0] = lowerx + lowerz * width;
cellsToTest[1] = lowerx + upperz * width;
cellsToTest[2] = upperx + lowerz * width;
cellsToTest[3] = upperx + upperz * width;
// Are these cells blocked?
for (int i = 0; i < 4 && walkable; i++) {
int ctt = cellsToTest[i];
if (ctt < 0 || ctt >= grid.length || grid[ctt] == null)
walkable = false;
}
}
}
if (walkable) {
// Can safely remove the candidate point - start->dest is walkable without it.
// Will effectively increment destindex and smoothremovalindex.
opath.remove(removalcandidateindex);
} else {
// We need the candidate point, so set that as our new start index.
startindex = removalcandidateindex;
removalcandidateindex = startindex + 1;
destindex = startindex + 2;
smoothremovalcandidate.isSubgoal = true;
}
}
}
if (this.mazeParams.getAddNavigationObservations() != null) {
// Add the subgoals to an observation producer:
this.navigator = new ObservationFromSubgoalPositionList();
int scale = this.mazeParams.getSizeAndPosition().getScale();
double y = 1 + this.optimalPathHeight + this.yOrg;
int i = 1;
for (Cell cell : opath) {
double x = scale * (cell.x + 0.5) + this.xOrg;
double z = scale * (cell.z + 0.5) + this.zOrg;
PointWithToleranceAndDescription ptd = new PointWithToleranceAndDescription();
ptd.setTolerance(new BigDecimal(1.0));
ptd.setX(new BigDecimal(x));
ptd.setY(new BigDecimal(y));
ptd.setZ(new BigDecimal(z));
ptd.setDescription("MazeSubpoint_" + String.valueOf(i));
i++;
this.navigator.getPoint().add(ptd);
}
System.out.println("Found subgoals.");
}
}
Aggregations