Exemple #1
0
  @Override
  public void paint(Graphics2D g) {
    // create graphics with reset transform
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setTransform(new AffineTransform());

    g2.setColor(new Color(255, 255, 255));
    g2.setFont(new Font("Consolas", Font.PLAIN, 12));
    g2.drawString("State: " + state, 160.0f, 20.0f);
    g2.drawString("Guessed angle: " + ramses.getGuessedAngleToGoal(), 160.0f, 42.0f);

    // highlight the ball we're after
    if (state == State.FETCH && realTargetId != -1) {
      Ball ball = ramses.getGameInfo().getBallById(realTargetId);

      if (ball != null) {
        float radius = ball.getRadius();

        g.setStroke(new BasicStroke(0.02f));

        if (ramses.getSide() == Simulation.Side.YELLOW) {
          g.setColor(new Color(220, 220, 0));
        } else {
          g.setColor(new Color(0, 0, 220));
        }

        g.draw(
            new Ellipse2D.Float(
                ball.getX() - radius, ball.getY() - radius, radius * 2.0f, radius * 2.0f));
      }
    }
  }
Exemple #2
0
  private void stepStartState(float dt) {
    // start moving diagonally away from the corner
    ramses.setHeading(-45.0f);
    ramses.setPower(1.0f);

    // after some time, switch to searching
    if (duration > startTime) {
      setState(State.SEARCH_BALL);
    }
  }
Exemple #3
0
  private void stepGuessedAngleUpdater(float dt) {
    List<Camera.GoalInfo> goals = ramses.getCamera().getVisibleGoals();

    Simulation.Side oppositeSide =
        ramses.getSide() == Simulation.Side.BLUE ? Simulation.Side.YELLOW : Simulation.Side.BLUE;

    for (Camera.GoalInfo goal : goals) {
      if (goal.side == oppositeSide) {
        ramses.setGuessedAngleToGoal(goal.angle / (float) Math.PI * 180.0f);
      } else {
        ramses.setGuessedAngleToGoal(goal.angle / (float) Math.PI * 180.0f - 180.0f);
      }
    }
  }
Exemple #4
0
  private void stepRelocateState(float dt) {
    if (!stateReady) {
      currentRelocateHeading = lastRelocateHeading + 90.0f % 360.0f;
      lastRelocateHeading = currentRelocateHeading;
      stateReady = true;
    }

    // drive ahead full power, this can be made much smarter to avoid walls etc
    ramses.setYawRate(0.0f);
    ramses.setHeading(currentRelocateHeading);
    ramses.setPower(1.0f);

    // after given time, go to requested next state
    if (stateDuration > relocateTime) {
      setState(nextState);
    }
  }
Exemple #5
0
  private void stepFetchState(float dt) {
    ramses.setPower(0.0f);

    // quick brake
    if (stateDuration < 0.2f) {
      ramses.setYawRate(-1.0f);

      return;
    }

    List<Camera.BallInfo> balls = ramses.getCamera().getVisibleBalls();
    Camera.BallInfo target = null;

    for (Camera.BallInfo ball : balls) {
      if (ball.id == targetId) {
        target = ball;

        break;
      }
    }

    if (target == null) {
      // can't see the ball any more, search for new one
      setState(State.SEARCH_BALL);

      return;
    }

    // map the ball angle to yaw power
    float angleDegrees = target.angle / (float) Math.PI * 180.0f;
    float yawRate = Math.max(Math.min(angleDegrees / 60.0f, 1.0f), -1.0f);

    // System.out.println("#" + target.id + " (" + target._getRealId() + ") angle: " + angleDegrees
    // + "; yaw rate: " + yawRate);

    ramses.setYawRate(yawRate);

    // once the angle to ball is quite small, start moving towards it
    if (Math.abs(angleDegrees) <= maxApproachAngle) {
      // move slower when closer, also camera distance is further away than edge
      float power = Math.max(Math.min((target.distance - 0.33f) / 1.0f, 1.0f), 0.2f);

      // this one is fun to watch, like a drunkard!
      // ramses.setHeading(-angleDegrees);

      ramses.setHeading(0.0f);
      ramses.setPower(power);

      if (ramses.getDribbler().hasBall()) {
        setState(State.SEARCH_GOAL);

        return;
      }
    }
  }
Exemple #6
0
  @Override
  public void stepBeforePhysics(float dt) {
    duration += dt;
    stateDuration += dt;

    if (stateDuration > maxStateDuration) {
      setState(State.SEARCH_BALL);
    } else if (ramses.getDribbler().hasBall() && state != State.SEARCH_GOAL) {
      // whatever the current state, if we somehow get a ball, start searching for
      // the goal
      setState(State.SEARCH_GOAL);
    }

    switch (state) {
      case START:
        stepStartState(dt);
        break;

      case SEARCH_BALL:
        stepSearchBallState(dt);
        break;

      case RELOCATE:
        stepRelocateState(dt);
        break;

      case FETCH:
        stepFetchState(dt);
        break;

      case SEARCH_GOAL:
        stepSearchGoal(dt);
        break;
    }

    stepGuessedAngleUpdater(dt);
  }
Exemple #7
0
  private void stepSearchGoal(float dt) {
    if (!stateReady) {
      targetGoalSightDuration = -1.0f;
      searchYawDir = 1.0f;
      stateReady = true;
    }

    if (!ramses.getDribbler().hasBall()) {
      setState(State.SEARCH_BALL);

      return;
    }

    ramses.setPower(0.0f);

    List<Camera.GoalInfo> goals = ramses.getCamera().getVisibleGoals();

    Simulation.Side oppositeSide =
        ramses.getSide() == Simulation.Side.BLUE ? Simulation.Side.YELLOW : Simulation.Side.BLUE;

    Camera.GoalInfo oppositeGoal = null;

    for (Camera.GoalInfo goal : goals) {
      if (goal.side == oppositeSide) {
        oppositeGoal = goal;

        if (targetGoalSightDuration == -1.0f) {
          targetGoalSightDuration = 0.0f;

          float guessedAngle = ramses.getGuessedAngleToGoal();

          if (guessedAngle > 0.0f && guessedAngle < 180.0f) {
            searchYawDir = 1.0f;
          } else {
            searchYawDir = -1.0f;
          }
        } else {
          targetGoalSightDuration += dt;
        }

        break;
      }
    }

    if (oppositeGoal != null) {
      if (targetGoalSightDuration < 0.2f) {
        // quick brake when first sighting the goal
        float guessedAngle = ramses.getGuessedAngleToGoal();

        if (guessedAngle > 0.0f) {
          ramses.setYawRate(-1.0f);
        } else {
          ramses.setYawRate(1.0f);
        }
      } else {
        // we can see the goal, turn to it
        float angleDegrees = oppositeGoal.angle / (float) Math.PI * 180.0f;

        // we know the angle right know, set it to improve guess later
        ramses.setGuessedAngleToGoal(angleDegrees);

        // the required accuracy depends on how far away the goal is - the closer
        // we are, the more we can miss the center
        float requiredAccuracy = Math.max(10.0f / (oppositeGoal.distance * 5.0f), 2.0f);

        if (angleDegrees <= requiredAccuracy) {
          // goal is centered, shoot!

          ramses.kick();

          targetId = -1;
          realTargetId = -1;
        } else {
          // goal is not centered enough, correct
          float yawRate = Math.max(Math.min(angleDegrees / 30.0f, 1.0f), -1.0f);

          ramses.setYawRate(yawRate);
        }
      }
    } else {
      ramses.setYawRate(0.25f * searchYawDir);

      targetGoalSightDuration = -1.0f;
    }
  }
Exemple #8
0
  private void stepSearchBallState(float dt) {
    // spin around at current position
    ramses.setPower(0.0f);

    if (!stateReady) {
      // reset closest distance in first frame of state
      closestBallDistance = Float.MAX_VALUE;
      targetId = -1;
      realTargetId = -1;

      if (lastBallSearchDir == 1.0f) {
        currentBallSearchDir = -1.0f;
      } else {
        currentBallSearchDir = 1.0f;
      }

      lastBallSearchDir = currentBallSearchDir;

      stateReady = true;
    }

    if (stateDuration <= spinSearchTime) {
      // spin and find the closes ball distance
      List<Camera.BallInfo> balls = ramses.getCamera().getVisibleBalls();

      if (balls.size() == 0) {
        // no balls visible, spin faster, might not be a good idea with a real
        // camera though
        ramses.setYawRate(0.5f * currentBallSearchDir);
      } else {
        // we can see something, slow dont not to pass quikcly
        ramses.setYawRate(0.25f * currentBallSearchDir);
      }

      for (Camera.BallInfo ball : balls) {
        if (ball.distance < closestBallDistance) {
          closestBallDistance = ball.distance;

          // System.out.println("New closest: #" + ball.id + " at " + ball.distance + "m");
        }
      }

      // pick the closest of close enough balls
      if (closestBallDistance <= closeEnoughThreshold) {
        for (Camera.BallInfo ball : balls) {
          if (ball.distance == closestBallDistance) {
            // found a ball close enough, skip searching closest
            targetId = ball.id;
            realTargetId = ball._getRealId();

            setState(State.FETCH);
          }
        }
      }
    } else if (stateDuration < spinSearchTime + refindTime) {
      // find that closest ball again
      List<Camera.BallInfo> balls = ramses.getCamera().getVisibleBalls();

      if (balls.size() == 0) {
        // no balls visible, spin faster, might not be a good idea with a real
        // camera though
        ramses.setYawRate(0.25f * currentBallSearchDir);
      } else {
        // we can see something, slow dont not to pass quikcly
        ramses.setYawRate(0.1f * currentBallSearchDir);
      }

      for (Camera.BallInfo ball : balls) {
        if (Math.abs(ball.distance - closestBallDistance) <= distanceCompareThreshold) {
          // System.out.println("Found #" + ball.id + " (" + ball._getRealId() + ") at " +
          // ball.distance);

          // found a ball at similar distance, set as target
          targetId = ball.id;
          realTargetId = ball._getRealId();

          setState(State.FETCH);

          return;
        }
      }
    } else {
      // didn't find a ball, move around a bit
      setState(State.RELOCATE, State.SEARCH_BALL);
    }
  }