Subversion Repositories SmartDukaan

Rev

Rev 37422 | Rev 37425 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37422 Rev 37424
Line 273... Line 273...
273
            return null;
273
            return null;
274
        }
274
        }
275
    }
275
    }
276
 
276
 
277
    /**
277
    /**
278
     * Slider pixels to nudge when working out how far the puzzle piece travels per
278
     * Calibration nudge, in slider px, sized from the gap rather than fixed.
279
     * slider pixel.
-
 
280
     *
279
     *
281
     * This was 15, which was the reason the captcha only solved about 9% of the time.
280
     * A fixed 15px was far too small: it closed only ~25px, so the ratio came from a
282
     * The piece moves roughly 1.7 px per slider px, so a 15 px nudge closed the gap by
-
 
283
     * only ~25 px -- and Hough circle detection is worth about +/-2-3 px per circle, so
281
     * measurement ~20% noise and the aim landed ~30px out. A fixed 60px then proved too
284
     * the ratio was being derived from a measurement with ~20% noise in it. That error
282
     * large in the other direction -- production data showed 85% of attempts with a gap
285
     * then multiplied across the whole remaining travel: on a 150 px gap it landed ~30 px
283
     * under 60px ended up UNUSABLE (the piece shot past the hole and the measured gap
286
     * out, and the target hole is only ~30 px across, so it missed entirely.
284
     * grew), and 45% overall.
287
     *
285
     *
-
 
286
     * Aim to close about half the gap: the piece travels roughly ASSUMED_RATIO px per
288
     * A 60 px nudge closes ~100 px, so the same detection noise is ~5% instead of ~20%.
287
     * slider px, so nudge ~= gap / (2 * ratio), clamped. The real ratio is still derived
-
 
288
     * from the measurement; this only sizes the probe.
289
     */
289
     */
-
 
290
    private static final double ASSUMED_RATIO = 1.7;
290
    private static final int CALIBRATION_NUDGE = 60;
291
    private static final int MIN_NUDGE = 10;
291
 
-
 
292
    /** Stop correcting once the piece is within this many px of the hole. */
292
    private static final int MAX_NUDGE = 60;
293
    private static final double ALIGNED_PX = 2.0;
293
    private static final double ALIGNED_PX = 2.0;
294
 
294
 
-
 
295
    private static int nudgeFor(double gap) {
-
 
296
        int n = (int) Math.round(gap / (2 * ASSUMED_RATIO));
-
 
297
        return Math.max(MIN_NUDGE, Math.min(MAX_NUDGE, n));
-
 
298
    }
-
 
299
 
295
    /**
300
    /**
296
     * @return {sliderPxToMove, sliderPxPerCirclePx}, or null when the circles could not
301
     * @return {sliderPxToMove, sliderPxPerCirclePx}, or null when the circles could not
297
     *         be read. Returned rather than stored on a field: this is a singleton and
302
     *         be read. Returned rather than stored on a field: this is a singleton and
298
     *         the Oppo secondary and tertiary jobs run it concurrently.
303
     *         the Oppo secondary and tertiary jobs run it concurrently.
299
     */
304
     */
300
    private double[] calibrate(WebDriver driver, Actions actionProvider, double distance) throws Exception {
305
    private double[] calibrate(WebDriver driver, Actions actionProvider, double distance) throws Exception {
-
 
306
        int nudge = nudgeFor(distance);
301
        actionProvider.moveByOffset(CALIBRATION_NUDGE, 0).perform();
307
        actionProvider.moveByOffset(nudge, 0).perform();
302
 
308
 
303
        String fileName2 = "/tmp/" + Thread.currentThread().getName() + "-moved.png";
309
        String fileName2 = "/tmp/" + Thread.currentThread().getName() + "-moved.png";
304
        double[] movedCircles = getMatCircles2(driver, fileName2);
310
        double[] movedCircles = getMatCircles2(driver, fileName2);
305
        if (movedCircles == null) return null;
311
        if (movedCircles == null) return null;
306
 
312
 
307
        double movedDistance = Math.abs(movedCircles[0] - movedCircles[1]);
313
        double movedDistance = Math.abs(movedCircles[0] - movedCircles[1]);
308
        double closed = distance - movedDistance;
314
        double closed = distance - movedDistance;
309
        LOGGER.info("Calibration: gap {} -> {} after {}px, closed {}",
315
        LOGGER.info("Calibration: gap {} -> {} after {}px, closed {}",
310
                distance, movedDistance, CALIBRATION_NUDGE, closed);
316
                distance, movedDistance, nudge, closed);
311
 
317
 
312
        // A non-positive value means the piece did not move, or moved away from the
318
        // A non-positive value means the piece did not move, or moved away from the
313
        // hole -- either way the ratio is meaningless and guessing would waste the try.
319
        // hole -- either way the ratio is meaningless and guessing would waste the try.
314
        if (closed <= 0) return null;
320
        if (closed <= 0) return null;
315
 
321
 
316
        double sliderPerCircle = CALIBRATION_NUDGE / closed;
322
        double sliderPerCircle = nudge / closed;
317
        int moveBy = (int) Math.round(movedDistance * sliderPerCircle);
323
        int moveBy = (int) Math.round(movedDistance * sliderPerCircle);
318
        return new double[]{moveBy, sliderPerCircle};
324
        return new double[]{moveBy, sliderPerCircle};
319
    }
325
    }
320
 
326
 
321
    /**
327
    /**