6. 햄스터 로봇과 함께하는 프로젝트
햄스터 로봇의 기초 명령어를 연습을 통해 프로그래밍 방법뿐만 아니라 동작과 센서의 기본 원리도 익혀 보았다. 앞으로는 실생활과 관련된 몇 가지 프로젝트를 해결해 볼 텐데, 스스로 혹은 친구들과 협력하여 해결하다 보면 어느덧 창의적 문제해결능력이 길러져 있을 것이다. 그럼 시작해 보자.
1
도전! 햄스터 로봇 Driving License
자동차를 운전하기 위해서는 운전면허증이 필요한 것처럼 햄스터 로봇 역시 마찬가지이다. S자 도로, O자 회전, 비상 신호음 테스트를 모두 통과하고 햄스터 로봇 면허를 발급받아 보자.
가. 첫 번째는 가장 쉬운 난이도의 S자 도로 주행이다. 햄스터 로봇이 S자 도로를 주행할 수 있도록 프로그래밍 해 보자.
[생각 정리하기]
햄스터 로봇의 3가지 회전 방식 중에 어떤 것을 선택해야 S자를 그리며 움직일 수 있을까? 그리고 일정 시간을 회전한 후 회전의 방향이 바뀌도록 하려면 어떻게 해야 할까?
[생각을 프로그래밍으로 구현하기]
from roboid import *
h=Hamster()
h.wheels(20, 40)
wait(5000) # 왼쪽 방향으로 5초 동안 원을 그리며 회전한다.
h.wheels(40, 20)
wait(5000) # 오른쪽 방향으로 5초 동안 원을 그리며 회전한 후 멈춘다.
h.stop()
나. 두 번째는 O자 회전 코스이다. A4용지를 말아서 원기둥 모양으로 만들고 햄스터 로봇이 A4 원기둥을 따라 O자 회전을 하도록 프로그래밍 해 보자.
[생각 정리하기]
단순히 회전하는 명령을 통해 A4 원기둥을 돌며 움직이도록 할 수 있지만 여기서는 햄스터 로봇의 왼쪽 근접센서를 사용하여 반시계 방향으로 A4 원기둥을 따라 회전하도록 해 보자. 왼쪽 근접센서와 A4 원기둥이 가까울 때와 멀어질 때, 그 움직임이 어떻게 달라져야 할까? O자 회전의 알고리즘을 생각해 보자.
[생각을 프로그래밍으로 구현하기]
from roboid import *
h=Hamster()
while True:
sensor=h.left_proximity()
h.wheels(40, 20)
if sensor > 10:
h.wheels(50, 10)
else:
h.wheels(10, 50) # 왼쪽 근접센서의 값이 10보다 크면(A4 원기둥과 가까워지면) 오른쪽 방향으로 회전하고, 그렇지 않으면 왼쪽 방향으로 회전한다.
wait(20)
- 지그재그로 움직이면서 A4 원기둥을 따라 회전하는 햄스터 로봇이 되었다. 왼쪽과 오른쪽 바퀴의 속도 차이와 회전 움직임과는 어떤 관련이 있을까? 또 왼쪽 근접센서의 기준값과 회전 움직임과는 어떤 관련이 있을까? 한 번 생각해 보자.
다. 마지막은 비상 신호음 테스트이다. 햄스터 로봇이 직진하다 장애물이 나타나면 멈추고 비상 신호음을 내도록 프로그래밍 해 보자. 물론 장애물이 없어지면 다시 직진해야 한다.
[생각 정리하기]
직진하다 왼쪽 또는 오른쪽 근접센서에 장애물이 감지되면 바로 멈추고 비상 신호음을 내야 한다. 비상 신호음 내는 부분을 함수로 만들어서 코드를 간결히 해보면 어떨까?
[생각을 프로그래밍으로 구현하기]
from roboid import *
h=Hamster()
def beep():
h.buzzer(1000)
wait(500)
h.buzzer(0)
wait(500) # 비상신호음을 내는 beep() 함수를 정의한다.
while True:
if h.left_proximity() > 30 or h.right_proximity() > 30:
h.wheels(0)
beep() # 왼쪽 또는 오른쪽 근접센서에 중에서 하나라도 장애물을 감지하면 즉시 멈추고 비상신호음을 낸다.
else:
h.wheels(30) # 장애물이 감지되지 않으면 직진한다.
wait(20)
2
로봇 청소기처럼!
로봇 청소기는 여러 가지 센서로 장애물을 감지하고 스스로 실내를 청소한다. 이런 빈틈없는 모습에 반해 햄스터 로봇은 로봇 청소기가 되고 싶어한다. 물론 햄스터 로봇이 먼지를 빨아들이는 등의 청소는 할 수 없지만 로봇 청소기처럼 동작하는 햄스터 로봇으로 변신시켜 보자.
가. 기본적인 로봇 청소기의 움직임을 구현해 보자. 벽이나 장애물을 만나면 무작위로 방향을 바꾼 후 직진하면서 실내를 빠짐없이 청소하도록 프로그래밍 해 보자. 우선, 햄스터 로봇이 청소할 수 있는 공간이 필요할 것이다. 근접센서가 감지될 만큼의 두꺼운 책으로 둘레를 막아도 좋고, 미로판으로 만들어도 좋다.
[생각 정리하기]
햄스터 로봇이 직진하다가 왼쪽 근접센서가 벽을 감지하면 오른쪽으로 회전하게 하고, 오른쪽 근접센서가 벽을 감지하면 왼쪽으로 회전한 후 직진해야 벽에 부딪치지 않고 안전하게 동작할 수 있을 것이다. 이것을 어떻게 구현할 수 있을까?
[생각을 프로그래밍으로 구현하기]
import random
from roboid import *
h=Hamster()
while True:
if h.left_proximity() > 50:
h.wheels(30, -30)
wait(random.randint(0, 1000)) # 왼쪽 근접센서의 값이 50보다 크면(벽을 감지하면) 오른쪽 방향으로 무작위 시간 동안(최대 1초) 회전한다.
elif h.right_proximity() > 50:
h.wheels(-30, 30)
wait(random.randint(0, 1000)) # 오른쪽 근접센서의 값이 50보다 크면(벽을 감지하면) 왼쪽 방향으로 무작위 시간 동안(최대 1초) 회전한다.
else
h.wheels(30) # 벽을 감지하지 않으면 직진한다.
wait(20)
나. 벽 주변에 먼지가 많이 있다. 이번에는 벽을 따라가면서 청소하는 햄스터 로봇을 만들어 보자.
[생각 정리하기]
가장자리의 벽을 따라가면서 햄스터 로봇이 움직이려면 어떻게 해야 할까? 왼쪽 근접센서가 벽에 가까워지면 오른쪽으로 회전하고, 그렇지 않으면 왼쪽으로 회전하도록 명령하면 햄스터 로봇은 어떤 움직임을 나타낼까? 또 적외선 센서의 특성상 벽과 가까워지면 근접센서의 값이 커지지만 너무 근접해 버리면 오히려 값이 작아지는 문제점이 있다. 이 문제를 어떻게 해결할 수 있을까?
[생각을 프로그래밍으로 구현하기]
from roboid import *
h=Hamster()
while True:
if h.left_proximity() > 50:
h.wheels(50, 10) # 왼쪽 근접센서의 값이 50보다 크면(벽을 감지하면) 오른쪽 방향으로 회전한다.
elif h.left_proximity() < 15:
h.wheels(-50, -50)
wait(300) # 왼쪽 근접센서의 값이 15보다 작으면(벽에 너무 근접하면) 0.3초 동안 후진하여 벽에 닿아 있는 상황을 탈출한다.
else:
h.wheels(10, 50)
wait(10) # 왼쪽 근접센서의 값이 위의 두 조건에 해당하지 않으면 왼쪽 방향으로 회전한다.
- 코드를 실행해보면 벽을 따라가는 움직임이 원활하지 않을 것이다. 왜 이런 문제가 발생하는 것일까? 그 이유는 근접센서가 측면을 감지하지 않기 때문이다. 햄스터 로봇 액세서리 중에서 ‘햄스터 미로 찾기용 커버’를 사용하면 이 문제를 해결할 수 있다. 좌측 센서 반사판은 측면을 감지하도록 도와준다.
3
힘을 모아 목적지까지!
끝으로 친구와 함께 힘을 모아 목적지까지 이어달리기를 하는 햄스터 로봇을 만들어 보겠다. 먼저 햄스터 로봇이 선을 따라 달릴 수 있도록 검정 테이프를 바닥에 길게 붙여 준다. 출발점에 위치한 햄스터 로봇은 중간지점에 위치한 햄스터 로봇까지 선을 따라 달리기를 하고 두 번째 햄스터 로봇이 목적지까지 이어달리기를 하도록 해 보자.
(단, 본 프로젝트는 친구와 2인 1조가 되어 협력을 통해 문제를 해결하는 활동이지만 여기에서는 한 대의 PC에서 두 대의 햄스터 로봇을 제어하는 방식으로 진행해 보겠다.)
가. 햄스터 로봇이 선을 따라 달리기를 할 수 있는 알고리즘을 만들어 보자. 두 개의 바닥 센서를 사용하여 선을 따라가기에는 검정 테이프가 두꺼우므로 왼쪽 바닥 센서만 사용하도록 하겠다.
[생각 정리하기]
선을 따라가기 위해서는 왼쪽 바닥 센서가 검정 선에 닿은 상황과 그렇지 않은 상황으로 나눠볼 수 있다. 그리고 햄스터 로봇 2대가 모두 선을 따라가는 같은 알고리즘을 적용하게 되는데, 같은 코드를 두 번 작성한다면 뭔가 비효율적이다. 이런 경우에는 함수로 만드는 것이 편리할 것이다. 조건에 따른 햄스터 로봇의 움직임을 생각하여 알고리즘을 완성하여 보자.
[생각을 프로그래밍으로 구현하기]
from roboid import *
h1=Hamster()
h2=Hamster()
def linetrace(robot):
if robot.left_floor() < 50:
robot.wheels(35, 5)
else:
robot.wheels(5, 35) # 'linetrace' 함수를 만들고 선을 따라가는 알고리즘을 적용한다. 왼쪽 근접센서의 값이 50보다 작으면(검은색 선에 닿으면) 오른쪽으로 회전하고, 그렇지 않으면 왼쪽으로 회전한다.
while True:
linetrace(h1) # 코드가 실행되면 첫 번째 햄스터 로봇이 검은색 선을 따라간다.
wait(20)
나. 햄스터 로봇을 검정 테이프의 오른쪽에 두고 코드를 실행하면 지그재그로 검은색 선을 따라가게 된다. 이제는 두 대의 햄스터 로봇이 이어달리기를 하도록 프로그래밍 해 보자.
[생각 정리하기]
햄스터 로봇이 다음 주자에게 바통을 건네주는 것은 어려우므로 밝기 센서를 사용해 보면 어떨까? 우선, 두 햄스터 로봇은 마주 보고 있어야 한다. 그리고 첫 번째 햄스터 로봇이 두 번째 햄스터 로봇에게 다가가 맞닿으면 밝기 센서의 값이 낮아지므로 이 조건이 될 때까지 선을 따라 달리기를 하게 한다. 두 번째 햄스터 로봇 역시 첫 번째 햄스터 로봇이 다가와 밝기 센서의 값이 낮아질 때까지 기다리다 조건에 이르면 목적지까지 이어달리기를 시작하도록 명령해 볼 것이다. 이런 식으로 여러 대의 햄스터 로봇 이어달리기도 가능하다.
[생각을 프로그래밍으로 구현하기]
from roboid import *
h1=Hamster()
h2=Hamster()
def linetrace(robot):
if robot.left_floor() < 50:
robot.wheels(35, 5)
else:
robot.wheels(5, 35)
while True:
if h1.light() < 10:
break
else:
linetrace(h1)
wait(20) # 첫 번째 햄스터 로봇의 밝기 센서 값이 10보다 작으면(두 번째 햄스터 로봇과 맞닿으면) 반복문을 빠져나온다.
h1.stop() # 첫 번째 햄스터 로봇이 정지한다.
h2.wheels(30, -30)
wait(1900) # 두 번째 햄스터 로봇이 180° 회전한다.
while True:
if h2.light() < 10:
break
else:
linetrace(h2)
wait(20) # 두 번째 햄스터 로봇의 밝기 센서 값이 10보다 작으면(목적지에 도달하면)반복문을 빠져나온다.
h2.stop() # 두 번째 햄스터 로봇이 정지한다.