News Download Tutorial FAQ Reference Buy

자바 언어 : 햄스터 친구 따라가기

친구 따라가기
라인 트레이서를 활용하여 앞에서 주행하는 다른 햄스터 로봇과 충돌하지 않고 검은색 선을 따라 주행하도록 해봅시다. 규칙은 다음과 같습니다.

A4 용지를 준비하고 햄스터 로봇이 이동할 직선을 검은색 테이프 또는 펜으로 그립니다. 검은색 선의 폭은 양쪽 바닥 센서의 간격보다 약간 작은 정도(0.8cm)로 하는 것이 좋습니다. 미리 제작된 파일을 프린터로 인쇄해도 됩니다.

라인 트레이서 실습판 내려 받기 PDF PPT

햄스터 로봇이 검은색 선을 따라 주행하는 것은 지난 시간에 배운 센서 두 개를 사용한 라인 트레이서를 참고하도록 합시다.

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    public static void main(String[] args) {

        Hamster hamster = new Hamster();

        int diff;
        while(true) {
            diff = hamster.leftFloor() - hamster.rightFloor();
            hamster.wheels(30 + diff * 0.4, 30 - diff * 0.4);

            Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
        }
    }
}

이제 전방을 살펴보면서 앞의 햄스터 로봇과 너무 가까우면 잠시 정지하도록 코드를 수정해 봅시다.

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    public static void main(String[] args) {

        Hamster hamster = new Hamster();

        int diff;
        while(true) {
            if(hamster.leftProximity() > 50 || hamster.rightProximity() > 50) {
                hamster.stop();
            } else {
                diff = hamster.leftFloor() - hamster.rightFloor();
                hamster.wheels(30 + diff * 0.4, 30 - diff * 0.4);
            }

            Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
        }
    }
}

2인 1조가 되어 각자의 PC에서 코드를 실행한 후 뒤쪽의 햄스터 로봇이 앞의 햄스터 로봇과 충돌하지 않고 안전하게 잘 주행하는지 확인해 봅시다.

이번에는 하나의 PC에서 두 대의 햄스터 로봇을 제어해 봅시다. 하나의 PC에서 두 대의 햄스터 로봇을 사용하기 위해서는 PC에 동글을 두 개 꽂고 코드에서 new Hamster()를 두 번 호출하면 됩니다.

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    public static void main(String[] args) {

        Hamster hamster1 = new Hamster();
        Hamster hamster2 = new Hamster();
    }
}

각각의 햄스터 로봇이 전방을 살펴보면서 검은색 선을 따라 주행하는 코드는 다음과 같이 작성될 수 있습니다.

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    public static void main(String[] args) {

        Hamster hamster1 = new Hamster();
        Hamster hamster2 = new Hamster();

        int diff;
        while(true) {
            // 첫 번째 햄스터 로봇
            if(hamster1.leftProximity() > 50 || hamster1.rightProximity() > 50) {
                hamster1.stop();
            } else {
                diff = hamster1.leftFloor() - hamster1.rightFloor();
                hamster1.wheels(30 + diff * 0.4, 30 - diff * 0.4);
            }

            // 두 번째 햄스터 로봇
            if(hamster2.leftProximity() > 50 || hamster2.rightProximity() > 50) {
                hamster2.stop();
            } else {
                diff = hamster2.leftFloor() - hamster2.rightFloor();
                hamster2.wheels(30 + diff * 0.4, 30 - diff * 0.4);
            }

            Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
        }
    }
}

같은 코드를 두 번 작성하였기 때문에 뭔가 비효율적으로 보입니다. 햄스터 로봇의 수가 많아지면 어떻게 될까요? 메소드로 만드는 것이 좋겠습니다.

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    private static void trace(Hamster hamster) {
        if(hamster.leftProximity() > 50 || hamster.rightProximity() > 50) {
            hamster.stop();
        } else {
            int diff = hamster.leftFloor() - hamster.rightFloor();
            hamster.wheels(30 + diff * 0.4, 30 - diff * 0.4);
        }
    }

    public static void main(String[] args) {

        Hamster hamster1 = new Hamster();
        Hamster hamster2 = new Hamster();

        while(true) {
            trace(hamster1); // 첫 번째 햄스터 로봇
            trace(hamster2); // 두 번째 햄스터 로봇

            Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
        }
    }
}

이제 햄스터 로봇의 수가 많아져도 new Hamster()를 호출하는 부분과 trace() 메소드를 호출하는 부분만 추가하면 되기 때문에 훨씬 간단해졌습니다.

첫 번째 햄스터 로봇의 전원만 켜고 코드를 실행한 후 잠시 후에 두 번째 햄스터 로봇의 전원을 켜보도록 합시다. 어떻게 되나요? 첫 번째 햄스터 로봇이 통신으로 연결되었을 때 동작을 먼저 시작하게 됩니다. 두 번째 햄스터 로봇의 전원을 켜서 모든 로봇이 통신으로 연결된 후 동작을 같이 시작하게 하려면 new Hamster()를 호출한 후에 Runner.waitUntilReady() 메소드를 호출해 주면 됩니다.

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    private static void trace(Hamster hamster) {
        if(hamster.leftProximity() > 50 || hamster.rightProximity() > 50) {
            hamster.stop();
        } else {
            int diff = hamster.leftFloor() - hamster.rightFloor();
            hamster.wheels(30 + diff * 0.4, 30 - diff * 0.4);
        }
    }

    public static void main(String[] args) {

        Hamster hamster1 = new Hamster();
        Hamster hamster2 = new Hamster();

        Runner.waitUntilReady();

        while(true) {
            trace(hamster1); // 첫 번째 햄스터 로봇
            trace(hamster2); // 두 번째 햄스터 로봇

            Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
        }
    }
}

하나의 Controller가 하나의 햄스터 로봇을 제어하는 것이 더 좋겠습니다.

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    private final Hamster hamster = new Hamster();

    private void trace() {
        if(hamster.leftProximity() > 50 || hamster.rightProximity() > 50) {
            hamster.stop();
        } else {
            int diff = hamster.leftFloor() - hamster.rightFloor();
            hamster.wheels(30 + diff * 0.4, 30 - diff * 0.4);
        }
    }

    public static void main(String[] args) {

        Controller controller1 = new Controller();
        Controller controller2 = new Controller();

        Runner.waitUntilReady();

        while(true) {
            controller1.trace(); // 첫 번째 햄스터 로봇
            controller2.trace(); // 두 번째 햄스터 로봇

            Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
        }
    }
}

참고로, 배열을 사용하여 좀 더 일반적인 형태로 수정하면 다음과 같이 됩니다.

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    private final Hamster hamster = new Hamster();

    private void trace() {
        if(hamster.leftProximity() > 50 || hamster.rightProximity() > 50) {
            hamster.stop();
        } else {
            int diff = hamster.leftFloor() - hamster.rightFloor();
            hamster.wheels(30 + diff * 0.4, 30 - diff * 0.4);
        }
    }

    public static void main(String[] args) {

        Controller[] controllers = new Controller[2]; // 햄스터의 수를 변경하기 위해서는 숫자 2만 수정하면 된다.

        for(int i = 0; i < controllers.length; ++i) {
            controllers[i] = new Controller();
        }

        Runner.waitUntilReady();

        while(true) {
            for(Controller controller : controllers) {
                controller.trace();
            }

            Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
        }
    }
}
쇼트 트랙 릴레이
햄스터 로봇 두 대가 한 조가 되어 일정 거리를 유지하며 함께 이동하도록 합시다. 규칙은 다음과 같습니다.

A4 용지를 준비하고 햄스터 로봇이 이동할 직선을 검은색 테이프 또는 펜으로 그립니다. 검은색 선의 폭은 양쪽 바닥 센서의 간격보다 약간 작은 정도(0.8cm)로 하는 것이 좋습니다. 미리 제작된 파일을 프린터로 인쇄해도 됩니다.

라인 트레이서 실습판 내려 받기 PDF PPT

뒤따라가는 햄스터 로봇은 선두 로봇을 따라가야 하기 때문에 햄스터 로봇의 앞면에 있는 근접 센서를 잘 활용해야 합니다. 혹시, 햄스터 로봇을 한 대만 가지고 있다면 지우개나 조그만 상자를 선두 로봇 대신 사용해도 됩니다.

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    private final Hamster hamster = new Hamster();

    private void trace() {
        if(hamster.leftProximity() > 50 || hamster.rightProximity() > 50) {
            hamster.stop();
        } else {
            int diff = hamster.leftFloor() - hamster.rightFloor();
            hamster.wheels(30 + diff * 0.4, 30 - diff * 0.4);
        }
    }

    private static int calcSpeed(int proximity) {
        if(proximity > 60) {
            return 0;
        } else {
            return (int)((60 - proximity) * 0.8);
        }
    }

    private void chase() {
        int leftSpeed = calcSpeed(hamster.leftProximity());
        int rightSpeed = calcSpeed(hamster.rightProximity());

        hamster.wheels(leftSpeed, rightSpeed);
    }

    public static void main(String[] args) {

        Controller controller1 = new Controller();
        Controller controller2 = new Controller();

        Runner.waitUntilReady();

        while(true) {
            controller1.trace(); // 첫 번째 햄스터 로봇
            controller2.chase(); // 두 번째 햄스터 로봇

            Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
        }
    }
}

왼쪽 근접 센서의 값으로 왼쪽 바퀴의 속도를 제어하고 오른쪽 근접 센서의 값으로 오른쪽 바퀴의 속도를 제어합니다. 각각의 근접 센서는 하나의 바퀴 속도만 제어하기 때문에 코드가 간단하고 센서와 바퀴 속도 간의 관계가 명확합니다.

쇼트 트랙 경기장처럼 생긴 라인 트레이서 실습판 위에 햄스터 로봇 두 대를 가까이 올려 놓고 코드를 실행해 봅시다. 뒤따라가는 햄스터 로봇은 근접 센서를 사용하여 선두 로봇을 따라가기 때문에 급격한 회전은 잘 따라가지 못합니다. 완만한 곡선으로 된 큰 원이나 타원의 실습판을 사용하세요.

USB 동글을 꽂는 위치에 따라 선두 로봇과 뒤따라가는 로봇의 순서가 바뀔 수 있습니다. 이 경우에는 다음과 같이 선두 로봇과 뒤따라가는 로봇을 서로 바꾸어 주면 됩니다.

while(true) {
    controller2.trace(); // 첫 번째 햄스터 로봇
    controller1.chase(); // 두 번째 햄스터 로봇

    Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
}

선두 로봇과 뒤따라가는 로봇을 고정시키기 위해서는 다음과 같이 시리얼 포트 이름을 지정해 주어도 됩니다. (클라우드 PC 환경에서 작업하기 참고)

import org.roboid.hamster.Hamster;
import org.roboid.runtime.Runner;

public class Controller {
    private final Hamster hamster;

    public Controller(String portName) {
        hamster = new Hamster(portName);
    }

    private void trace() {
        if(hamster.leftProximity() > 50 || hamster.rightProximity() > 50) {
            hamster.stop();
        } else {
            int diff = hamster.leftFloor() - hamster.rightFloor();
            hamster.wheels(30 + diff * 0.4, 30 - diff * 0.4);
        }
    }

    private static int calcSpeed(int proximity) {
        if(proximity > 60) {
            return 0;
        } else {
            return (int)((60 - proximity) * 0.8);
        }
    }

    private void chase() {
        int leftSpeed = calcSpeed(hamster.leftProximity());
        int rightSpeed = calcSpeed(hamster.rightProximity());

        hamster.wheels(leftSpeed, rightSpeed);
    }

    public static void main(String[] args) {

        Controller controller1 = new Controller("COM57");
        Controller controller2 = new Controller("COM70");

        Runner.waitUntilReady();

        while(true) {
            controller1.trace(); // 첫 번째 햄스터 로봇
            controller2.chase(); // 두 번째 햄스터 로봇

            Runner.wait(10); // 너무 빨리 반복하지 않도록 한다.
        }
    }
}
목차
Hardware
  1. Hamster robot
  2. USB dongle
Preparation for Class
  1. Software installation
  2. Robot to PC connection
  3. Run example files
Basic
  1. Create a new project
  2. Work in the cloud PC environment (optional)
  3. Move on a board #1 (sequence, repetition)
  4. Move and turn
  5. Turn on LEDs and make a sound
  6. Command in order repeatedly
  7. Use proximity sensors
  8. Move on a board #2 (repeat while)
  9. Use floor sensors
  10. Use light and acceleration sensors
  11. Braitenberg's robot
Advanced
  1. Create a board game
  2. Keyboard events
  3. Graphical interface
  4. Line following with one sensor
  5. Line following with two sensors
  6. Follow hamster friends (2 people 1 pair)
  7. Follow a wall
  8. Imitating a robot cleaner
  9. Line following at intersection
  10. Escape a maze
Extension Kit
  1. Assembling
  2. Pin/socket layout
  3. Digital input - Press button to beep
  4. Digital output - LED is on when it is dark
  5. Digital output - flashing twinkling LED
  6. Digital output - LED is on in tilting direction
  7. Analog input - Rotating the potentiometer changes the pitch.
  8. Analog input - please do not let it get hot
  9. Analog Input - Move along the light
  10. PWM output - LED light gently brighter and darker
  11. PWM output - LED candle shakes in the wind
  12. Analog servo output - hamster robot has tail
More Advanced
  1. Behavior based robot control
  2. Path navigation
  3. Swap
Copyright Robot Software Education Institute. All rights reserved.
Please contact prof. Kwang-Hyun Park (akaii@kw.ac.kr) if you have any problem.