Пример #1
0
  protected GPoint findGrenadeTarget(Ability A, Unit U) {
    // searches for an attackable spot that would hit the most enemies for the most damage
    // must hit at least 2 enemies
    // 1/24 chance to see aoe

    int Cur_units = 0;
    int Cur_damage = 0;
    int New_units = 0;
    int New_damage = 0;

    GPoint itarget = null;

    rando = (int) (Math.random() * 24);
    if (rando == 0) vis = A.getTilesAttackable(U, map);
    else vis = Vision.getSprintVision(map, U, 3);

    for (int i = 0; i < vis.size(); i++) {
      List<AttackedTile> tilesAffected = A.getTilesAffected(U, vis.get(i), map);
      for (int j = 0; j < tilesAffected.size(); j++) {
        if (map.getTile(tilesAffected.get(j).tile).hasUnit()) {
          if (map.getTile(tilesAffected.get(j).tile).getPlayer_id() != playerId) {
            New_units++;
            New_damage += tilesAffected.get(j).damageTaken;
          }
        }
      }

      if ((itarget == null)
          || (New_units > Cur_units)
          || ((New_units == Cur_units) && (New_damage > Cur_damage))) {
        itarget = new GPoint(vis.get(i));
        Cur_units = New_units;
        Cur_damage = New_damage;
      }

      New_units = 0;
      New_damage = 0;
    }
    vis.clear();

    if (Cur_units < 2) itarget = null;

    return itarget;
  }
  // TODO: Throw an Exception if vision fails.
  private Location getVisionOffsets(Head head, Location pickLocation) throws Exception {
    logger.debug("getVisionOffsets({}, {})", head.getName(), pickLocation);
    // Find the Camera to be used for vision
    // TODO: Consider caching this
    Camera camera = null;
    for (Camera c : head.getCameras()) {
      if (c.getVisionProvider() != null) {
        camera = c;
      }
    }

    if (camera == null) {
      throw new Exception("No vision capable camera found on head.");
    }

    head.moveToSafeZ(1.0);

    // Position the camera over the pick location.
    logger.debug("Move camera to pick location.");
    camera.moveTo(pickLocation, 1.0);

    // Move the camera to be in focus over the pick location.
    //		head.moveTo(head.getX(), head.getY(), z, head.getC());

    // Settle the camera
    Thread.sleep(camera.getSettleTimeMs());

    VisionProvider visionProvider = camera.getVisionProvider();

    Rectangle aoi = getVision().getAreaOfInterest();

    // Perform the template match
    logger.debug("Perform template match.");
    Point[] matchingPoints =
        visionProvider.locateTemplateMatches(
            aoi.getX(),
            aoi.getY(),
            aoi.getWidth(),
            aoi.getHeight(),
            0,
            0,
            vision.getTemplateImage());

    // Get the best match from the array
    Point match = matchingPoints[0];

    // match now contains the position, in pixels, from the top left corner
    // of the image to the top left corner of the match. We are interested in
    // knowing how far from the center of the image the center of the match is.
    BufferedImage image = camera.capture();
    double imageWidth = image.getWidth();
    double imageHeight = image.getHeight();
    double templateWidth = vision.getTemplateImage().getWidth();
    double templateHeight = vision.getTemplateImage().getHeight();
    double matchX = match.x;
    double matchY = match.y;

    logger.debug("matchX {}, matchY {}", matchX, matchY);

    // Adjust the match x and y to be at the center of the match instead of
    // the top left corner.
    matchX += (templateWidth / 2);
    matchY += (templateHeight / 2);

    logger.debug("centered matchX {}, matchY {}", matchX, matchY);

    // Calculate the difference between the center of the image to the
    // center of the match.
    double offsetX = (imageWidth / 2) - matchX;
    double offsetY = (imageHeight / 2) - matchY;

    logger.debug("offsetX {}, offsetY {}", offsetX, offsetY);

    // Invert the Y offset because images count top to bottom and the Y
    // axis of the machine counts bottom to top.
    offsetY *= -1;

    logger.debug("negated offsetX {}, offsetY {}", offsetX, offsetY);

    // And convert pixels to units
    Location unitsPerPixel = camera.getUnitsPerPixel();
    offsetX *= unitsPerPixel.getX();
    offsetY *= unitsPerPixel.getY();

    logger.debug("final, in camera units offsetX {}, offsetY {}", offsetX, offsetY);

    return new Location(unitsPerPixel.getUnits(), offsetX, offsetY, 0, 0);
  }
  @Override
  public void feed(Nozzle nozzle) throws Exception {
    logger.debug("feed({})", nozzle);

    if (actuatorName == null) {
      throw new Exception("No actuator name set.");
    }

    Head head = nozzle.getHead();

    /*
     * TODO: We can optimize the feed process:
     * If we are already higher than the Z we will move to to index plus
     * the height of the tape, we don't need to Safe Z first.
     * There is also probably no reason to Safe Z after extracting the
     * pin since if the tool was going to hit it would have already hit.
     */

    Actuator actuator = head.getActuatorByName(actuatorName);

    if (actuator == null) {
      throw new Exception(
          String.format(
              "No Actuator found with name %s on feed Head %s", actuatorName, head.getName()));
    }

    head.moveToSafeZ(1.0);

    if (vision.isEnabled()) {
      if (visionOffset == null) {
        // This is the first feed with vision, or the offset has
        // been invalidated for some reason. We need to get an offset,
        // complete the feed operation and then get a new offset
        // for the next operation. By front loading this we make sure
        // that all future calls can go directly to the feed operation
        // and skip checking the vision first.
        logger.debug("First feed, running vision pre-flight.");

        visionOffset = getVisionOffsets(head, location);
      }
      logger.debug("visionOffsets " + visionOffset);
    }

    // Now we have visionOffsets (if we're using them) so we
    // need to create a local, offset version of the feedStartLocation,
    // feedEndLocation and pickLocation. pickLocation will be saved
    // for the pick operation while feed start and end are used
    // here and then discarded.
    Location feedStartLocation = this.feedStartLocation;
    Location feedEndLocation = this.feedEndLocation;
    pickLocation = this.location;
    if (visionOffset != null) {
      feedStartLocation = feedStartLocation.subtract(visionOffset);
      feedEndLocation = feedEndLocation.subtract(visionOffset);
      pickLocation = pickLocation.subtract(visionOffset);
    }

    // Move the actuator to the feed start location.
    actuator.moveTo(feedStartLocation.derive(null, null, Double.NaN, Double.NaN), 1.0);

    // extend the pin
    actuator.actuate(true);

    // insert the pin
    actuator.moveTo(feedStartLocation, 1.0);

    // drag the tape
    actuator.moveTo(feedEndLocation, feedSpeed);

    head.moveToSafeZ(1.0);

    // retract the pin
    actuator.actuate(false);

    if (vision.isEnabled()) {
      visionOffset = getVisionOffsets(head, location);

      logger.debug("final visionOffsets " + visionOffset);
    }

    logger.debug("Modified pickLocation {}", pickLocation);
  }