【问题标题】:Java: Wait for function for up n seconds, if no complete re-tryJava:等待函数最多n秒,如果没有完成重试
【发布时间】:2012-02-13 10:56:06
【问题描述】:

背景(可以跳到下面的问题...)

目前正在使用乐高 Mindstorm 机器人和 icommand API (http://lejos.sourceforge.net/p_technologies/nxt/icommand/api/index.html)。

其中一种电机控制方法出现问题。这些方法将电机旋转给定角度:

Motor.A.rotateTo(target);

在电机完成运动之前,此功能不会返回。这很好,但有时电机无法停止并会无限期地继续,从而停止程序。

问题

无论如何我可以让程序等待方法Motor.A.rotateTo(target);返回n秒。然后如果在那段时间内没有返回,则再次调用该方法。 (如果可以循环直到成功,那就更好了。)

感谢您的阅读,任何帮助将不胜感激。

问候, 乔

编辑:从Motor.A.rotate(target); 更正为Motor.A.rotateTo(target);

【问题讨论】:

  • 但是在执行过程中不停止方法会不会导致对象的状态不一致?
  • @Tudor 啊是的,是的。我的意思是写Motor.A.rotateTo(target);对不起我的错误!电机有转速计,记录它们转动了多远(顺时针正,逆时针负,1 转速 = 1 度)。所以我可以简单地重新调用该方法,它会旋转直到达到目标转速计。

标签: java multithreading time concurrency icommand


【解决方案1】:

Motor#rotate(long count, boolean returnNow) 呢?如果您希望电机在特定时间后停止,您可以致电stop()

Motor.A.rotate(150, true);
Thread.sleep(3000);
Motor.A.stop();

【讨论】:

  • 感谢您的回复,我考虑过这个,但是如何知道电机是否完成了旋转?
【解决方案2】:

您可以使用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;
        }
    }
}

【讨论】:

    【解决方案3】:

    类似的东西呢:

    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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-16
      相关资源
      最近更新 更多