Java: ждать функции до n секунд, если нет полной попытки - PullRequest
2 голосов
/ 18 января 2012

Фон (можете пропустить вопрос ниже ...)

В настоящее время работает с роботом lego Mindstorm и API icommand (http://lejos.sourceforge.net/p_technologies/nxt/icommand/api/index.html).

Возникли проблемы с одним из методов управления двигателем. Способы вращения двигателя на заданный угол:

Motor.A.rotateTo(target);

Эта функция не вернется, пока двигатель не завершит движение. Это нормально, но иногда двигатель не может остановиться и будет продолжать работать бесконечно, останавливая программу.

Вопрос

Есть ли в любом случае, что я могу сделать, чтобы программа ждала до n секунд для возврата метода Motor.A.rotateTo(target);. И затем, если он не вернулся за это время, вызовите метод еще раз. (Если бы это могло быть зациклено, пока это не успешно, это было бы еще лучше.)

Спасибо за чтение, любая помощь будет высоко ценится.

С уважением, Джо

редактировать: исправлено с Motor.A.rotate(target); до Motor.A.rotateTo(target);

Ответы [ 3 ]

1 голос
/ 18 января 2012

Вы можете использовать ExecutorService или другое потоковое решение для запуска rotate в отдельном потоке и ожидания результатов.Вот полная программа, которая также повторяет указанное количество раз:

public static void main(String[] args) throws TimeoutException {
    final ExecutorService pool = Executors.newFixedThreadPool(10);
    runWithRetry(pool, 5);  //run here
}

public static void runWithRetry(final ExecutorService pool, final int retries) throws TimeoutException {
        final Future<?> result = pool.submit(new Runnable() {
            @Override
            public void run() {
                Motor.A.rotate(angle);
            }
        });
        try {
            result.get(1, TimeUnit.SECONDS);  //wait here
        } catch (InterruptedException e) {
            throw new RuntimeException(e.getCause());
        } catch (ExecutionException e) {
            throw new RuntimeException(e.getCause());
        } catch (TimeoutException e) {
            if (retries > 1) {
                runWithRetry(pool, retries - 1);  //retry here
            } else {
                throw e;
        }
    }
}
1 голос
/ 18 января 2012

А как насчет Motor#rotate(long count, boolean returnNow)? Затем вы можете позвонить stop(), если хотите, чтобы двигатель остановился через определенное время.

Motor.A.rotate(150, true);
Thread.sleep(3000);
Motor.A.stop();
0 голосов
/ 18 января 2012

Что-то вроде:

int desiredPosition = Motor.A.getTachoCount() + ANGLE_TO_TURN;
long timeout = System.currentTimeMillis + MAX_TIME_OUT;
Motor.A.forward();
while (timeout>System.currentTimeMillis && desiredPosition>Motor.A.getTachoCount()); //wait for the motor to reach the desired angle or the timeout to occur
Motor.A.stop();
...