2009-10-25 2 views
1

Я своего рода новичок в Java, так что еще не полностью поняли концепцию multithreading.I хотели бы создать класс PIDController, что позволяет мне сделать это:Как реализовать многопоточный PID-контроллер в Java?

ControllerMethods methods = new ControllerMethods() 
          { 
           public long getError(long setpoint) 
           { 
            //get an input 
           } 
           public void setOutput(long value) 
           { 
            //do something 
           } 
           public void isComplete(long setpoint) 
           { 
            return getError() == 0; 
           } 
          }; 

PIDController motorPID = new PIDController(setpoint, kp, ki, kd, methods); 

motorPID.run(); 
//runs the PID controller to completion (methods.isComplete() == true) 

motorPID.run(false); 
//starts the PID controller in a separate thread, allowing 
//continual monitoring in the current thread 

while(motorPID.isRunning()) 
{ 
    //do something else 
    if(condition1) 
     motorPID.pause(); 
     //pause the PID controller, preventing the integral from increasing 
    else if(condition2) 
     motorPID.stop(); 
} 

Я работал, как для вычисления стандартных ПИД-алгоритмов, но я не могу решить, как обеспечить асинхронную функциональность.

Может ли кто-нибудь сказать мне, как я могу достичь аналогичного API?

ответ

1

Вы уже реализовали метод run() для PIDController, так что вы также должны реализовать интерфейс Runnable:

class PIDController implements Runnable { 
    .... 
} 

Теперь вы можете начать свой PIDController asynchonous, позвонив по телефону:

pidControllerThread = new Thread(pidController); 
pidControllerThread.start(); 

Для синхронизации (если необходимо), вы должны взглянуть на солнце concurrency guide.

+2

Если вам нужен лучший контроль, то пусть Исполнитель (многие из них в ExecutorService) управляют им, а не имеют свободный поток. http://java.sun.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html –

+0

В настоящее время мой класс 'PIDController' имеет экземпляр внутреннего класса, производного от' Thread'. Я не могу решить, будет ли контроллер shoud быть «Thread» или содержать «Thread» – Eric

+0

. Я бы рекомендовал переместить многопоточный код из вашего класса PIDController и в PIDManager или что-то еще, что отвечает за настройку PIDControllers в отдельных потоках. –

0

На сегодняшний день лучшим механизмом для прикрепления нитей к чему-либо является разделение объекта, который выполняет работу с объектом, являющимся нитью. Интерфейс Runnable может быть привлекательным, поскольку он позволяет людям передавать объект конструктору или Исполнителю Thread и запускать его. Однако, если у вас есть требования к управлению жизненным циклом для вашего объекта, которые находятся вне «выполнения до завершения», например, пауза, то в большинстве случаев вам будет более уместно управлять потоком внутри вашего объекта, чтобы вы знали, какой поток (да, вы можете установить экземпляр объекта в Thread.currentThread() для записи, но ...).

Итак, я думаю, что у вас есть хорошее начало. Вам нужно добавить использование некоторой блокировки, чтобы помочь вам управлять pause() и другим управлением потоками.

 

    public class PIDController { 
     private final Object myLock = new Object(); 
     private final ControllerMethods ctrl; 
     private volatile Thread thread; 
     private volatile Runner runner; 
     private int pidInterval = 700; 
     private final double setPoint, kp, ki, kd; 

     public PIDController(double setPoint, double kp, double ki, double kd, ControllerMethods inst) { 
      this.ctrl = inst; 
      this.setPoint = setPoint; 
      this.kp = kp; 
      this.ki = ki; 
      this.kd = kd; 
     } 

     public void pause() { 
      synchronized(myLock) { 
       if(runner.paused) { 
        throw new IllegalOperationException(this+": already paused"); 
       } 
       runner.paused = true; 
      } 
     } 

     public void resume() { 
      synchronized(myLock) { 
       if(!runner.paused) { 
        throw new IllegalOperationException(this+": already resumed"); 
       } 
       runner.paused = false; 
      } 
     } 

     public bool isRunning() { 
      return running; 
     } 

     public void start() { 
      if(thread != null) { 
       throw new IllegalOperationException(this+": already running"); 
      } 
      myThread = new Thread(runner = new Runner()); 
      myThread.start(); 
     } 

     public void stop() { 
      if(runner == null) { 
       throw new IllegalOperationException(this+": PID is not running"); 
      } 
      runner.running = false; 
      if(runner.paused) 
       resume(); 
      runner = null; 
     } 


     // It is important, anytime that you implement a stoppable Runnable, that 
     // you include the "running" flag as a member of an innner instance class like 
     // this so that when you ask this instance to stop, you can immediately restart 
     // another instance and not have the two threads observing the same "running" flag 
     private class Runner implements Runnable { 
      volatile bool running = false, bool paused; 
      public void run() { 
       running = true; 
       while(running) { 
        // do this at the top of the loop so that a wake from 
        // pause will check running, before recomputing. 
        reComputePID(); 

        // Use the double check idiom to 
        if(paused) { 
         synchronized(myLock) { 
          while(paused) { 
           myLock.wait(); 
          } 
         } 
        } 
        Thread.sleep(pidInterval); 
       } 
      } 
     } 

     public void reComputePID() { 
      ... 
     } 
    } 

+0

'присоединение нитей к чему-либо' - этот вариант не имеет смысла. Может быть, это сообщение SO могло бы добавить некоторую ценность для вашего собственного понимания - http://stackoverflow.com/questions/23414744/java-thread-please-clarify-this-understanding – spiderman

+0

Я не уверен, что вы предлагаете здесь? Основываясь на этом сообщении, кажется, что у вас могут возникнуть проблемы с работой потоков. Вам нужно больше объяснять здесь, что происходит выше? – grwww

+0

np, я думал, что вы на той же странице, где я был когда-то, когда вы написали «attach threads» .. pls ignore – spiderman

Смежные вопросы