Search in sources :

Example 1 with PointWithToleranceAndDescription

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);
}
Also used : JsonObject(com.google.gson.JsonObject) PointWithToleranceAndDescription(com.microsoft.Malmo.Schemas.PointWithToleranceAndDescription) EntityPlayerSP(net.minecraft.client.entity.EntityPlayerSP)

Example 2 with PointWithToleranceAndDescription

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);
    }
}
Also used : AgentSection(com.microsoft.Malmo.Schemas.AgentSection) AgentQuitFromReachingPosition(com.microsoft.Malmo.Schemas.AgentQuitFromReachingPosition) PosAndDirection(com.microsoft.Malmo.Schemas.PosAndDirection) PointWithToleranceAndDescription(com.microsoft.Malmo.Schemas.PointWithToleranceAndDescription) BigDecimal(java.math.BigDecimal)

Example 3 with PointWithToleranceAndDescription

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.");
    }
}
Also used : ArrayList(java.util.ArrayList) PointWithToleranceAndDescription(com.microsoft.Malmo.Schemas.PointWithToleranceAndDescription) ObservationFromSubgoalPositionList(com.microsoft.Malmo.Schemas.ObservationFromSubgoalPositionList) BigDecimal(java.math.BigDecimal)

Aggregations

PointWithToleranceAndDescription (com.microsoft.Malmo.Schemas.PointWithToleranceAndDescription)3 BigDecimal (java.math.BigDecimal)2 JsonObject (com.google.gson.JsonObject)1 AgentQuitFromReachingPosition (com.microsoft.Malmo.Schemas.AgentQuitFromReachingPosition)1 AgentSection (com.microsoft.Malmo.Schemas.AgentSection)1 ObservationFromSubgoalPositionList (com.microsoft.Malmo.Schemas.ObservationFromSubgoalPositionList)1 PosAndDirection (com.microsoft.Malmo.Schemas.PosAndDirection)1 ArrayList (java.util.ArrayList)1 EntityPlayerSP (net.minecraft.client.entity.EntityPlayerSP)1