next up previous
Next: 6.5.4 Actionインタフェース Up: 6.5 ロボットの行動プログラム Previous: 6.5.2 Main.java

6.5.3 Subsumptionクラス

Subsumptionクラスでは,スレッドのサブクラスである Taskのインスタンスを保存するtasks変数を持つ. RCXのRUNボタンが押されたらば実行されるように addButtonListenerに自分を登録している. そのために,Subsumptionクラスは,ButtonListener インタフェースを実装している.

/**
 * Coordinates a prioritised set
 * of tasks. Tasks with higher priority
 * completely block those of a
 * lower priority. Creates the following
 * tasks with increasing order of priority:
 * - Wander:      wander around
 * - RightBumber: avoid obstacles on the right.
 * - LeftBumber:  avoid obstacles on the left.
 * Plus it gates access to the effectors
 * (i.e. the motors) ensuring
 * that it's priority policy is strictly
 * enforced.
 */
class Subsumption implements ButtonListener {
    public boolean running;
    public int owner;
    Task tasks[];
        
    public Subsumption() {
        running = true;
        Button.RUN.addButtonListener(this);
        tasks = new Task[3];
        tasks[0]=new Wander();
        tasks[1]=new RightBumber();
        tasks[2]=new LeftBumber();
        tasks[0].start();
        tasks[1].start();
        tasks[2].start();
    }

    int getPriority(Task t) {
        for (int i=0; i<tasks.length; i++) {
            if (tasks[i] == t) return i;
        }
        return -1;
    }

    /**
     * Arbitrates between the various tasks.
     */        
    public synchronized
    void execute(Task requestor) {
        int pri = getPriority(requestor);

        // If its a lower priorty than
        // the current task, ignore it.
        if (pri < owner)
            return;

        // This is the new owner of
        // the single output that we have
        owner = pri;

        // Start new owner from
        // beginning (even if it was the same one)
        tasks[owner].reset();
    }

    /**
     * Only allow the owner to do stuff,
     * just in case some other task calls us
     */        
    public synchronized
    void setMotor(Task requestor,
                  Motor motor,
                  int power,
                  boolean forward) {
        if (owner == getPriority(requestor)) {
            motor.setPower(power);
            if (forward)
                motor.forward();
            else
                motor.backward();
        }
    }

    /**
     * Task has finished.
     * Re-start next runnable task.
     */        
    public synchronized
    void release(Task releaser) {
        int pri = getPriority(releaser);
                
        // If it isn't the owner
        // releasing, ignore it.
        if (owner == pri) {
            // Search for the first
            // runnable task.
            // There is always one.
            for(int i=pri-1; i >= 0; i--) {
                if (tasks[i].running()) {
                    owner = i;
                    tasks[owner].reset();
                }        
            }
        }
    }

    /**
     * Called within the scope of
     * a thread defined by
     * Button.addButtonListener().
     */                        
    public void buttonPressed(Button b) {
        running=false;
    }
                
    public void buttonReleased(Button b) {
    }
}


generated through LaTeX2HTML. M.Inaba 平成18年5月7日