로봇 움직이기

01. 전진하기

웹 페이지 만들기를 참고하여 안드로이드 프로젝트와 웹 페이지 파일을 만들어 간단한 프로그램을 작성해 보자.

알버트 로봇을 직진시키기 위한 프로그램을 작성하시오.

손쉽게 로봇을 움직이기 위해 웹 페이지에 onInitialized(robot) 콜백 함수와 onExecute() 콜백 함수를 만들자.

 <script type="text/javascript">

 function onInitialized(robot)
 {
 }

 function onExecute()
 {
 }
 </script>

로봇을 움직이려면 뭔가 로봇에 접근할 수 있는 객체가 필요할 것 같다. 다행히도 onInitialized(robot) 콜백 함수를 살펴보면 Robot 객체가 아규먼트로 넘어오는 것을 알 수 있다. onInitialized(robot) 콜백 함수에서 Robot 객체의 findDeviceById(deviceId) 함수를 사용하여 필요한 디바이스의 객체를 얻도록 하자. 알버트 로봇에는 좌우 바퀴의 속도에 해당하는 디바이스로 EFFECTOR_LEFT_WHEELEFFECTOR_RIGHT_WHEEL이 있다.

 <script type="text/javascript">

 var leftWheelDevice;
 var rightWheelDevice;
 
 function onInitialized(robot)
 {
     leftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
     rightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
 }

 function onExecute()
 {
 }
 </script>

튜토리얼은 알버트 로봇을 대상으로 설명하지만, 다른 로봇의 경우에도 같은 방법으로 할 수 있다. 예를 들어, 알파 로봇을 움직이기 위해서는 Albert.EFFECTOR_LEFT_WHEEL과 같이 Albert.으로 시작하는 디바이스 ID 대신에 Alpha.EFFECTOR_LEFT_WHEEL과 같이 Alpha.으로 시작하는 디바이스 ID를 입력하면 된다.

이제 알버트 로봇을 움직이기 위한 명령을 입력해 보도록 하자. 좌우 바퀴의 속도 데이터는 -100부터 100까지의 값을 가지는데 양수 값이면 바퀴가 앞으로 굴러가고 0이면 멈춘다. 우선 왼쪽 바퀴를 앞으로 굴리기 위해 속도를 20으로 하고, 오른쪽 바퀴의 속도도 똑같이 20으로 해보자. 알버트 로봇이 똑바로 직진하기 위해서는 왼쪽과 오른쪽 바퀴의 속도를 같게 입력해야 한다.

 <script type="text/javascript">

 var leftWheelDevice;
 var rightWheelDevice;
 
 function onInitialized(robot)
 {
     leftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
     rightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
 }

 function onExecute()
 {
     leftWheelDevice.write(20);
     rightWheelDevice.write(20);
 }
 </script>

이제, 알버트 로봇이 앞으로 달려가는 프로그램이 완성되었다. 간단하다. 프로그램을 실행하기 전에 로봇이 달려갈 공간을 확인하도록 하자. 책상 위에서 로봇이 달려가다가 책상에서 떨어지면 곤란하다. 돈이 많아서 로봇을 새로 살 수 있다면 책상 위를 로봇이 달리다가 바닥으로 점프해도 된다.

스마트 로봇 론처를 실행하여 로봇과 연결한 후, 애플리케이션을 실행하면 로봇이 전진하고, 애플리케이션을 종료하면 멈출 것이다.

좌우 바퀴의 속도를 입력하기 위해 Device 객체의 write(data) 함수를 사용하였는데, data 아규먼트는 디바이스에 입력할 데이터 값이다. 다른 디바이스에 대해서도 같은 방법으로 하면 되는데 앞으로 조금씩 배워가도록 하자.

바퀴의 속도를 0부터 100까지 변경하면서 로봇의 이동 속도가 어떻게 달라지는지 관찰해 보자. 바퀴의 속도를 작게 했을 때 로봇이 움직이지 않는다고 슬퍼하지 않기 바란다. 움직이려고 애를 쓰지만 힘이 없어 움직이지 못하는 것이다. 귀엽고 예쁜 알버트 로봇이 안쓰러우니 바퀴의 속도를 높여 힘을 내도록 해주자.

02. 후진하기

알버트 로봇의 주행 방향은 부호로 설정할 수 있다. 바퀴의 속도를 양수 값으로 하면 바퀴가 앞으로 굴러가고, 음수 값으로 하면 뒤로 굴러간다. 물론 바퀴의 속도가 0이면 멈춘다.

알버트 로봇을 후진시키기 위한 프로그램을 작성하시오.

앞에서 작성한 프로그램에서 바퀴의 속도만 음수 값으로 변경하면 된다.

 <script type="text/javascript">

 var leftWheelDevice;
 var rightWheelDevice;
 
 function onInitialized(robot)
 {
     leftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
     rightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
 }

 function onExecute()
 {
     leftWheelDevice.write(-20);
     rightWheelDevice.write(-20);
 }
 </script>

애플리케이션을 실행하기 전에 로봇이 후진할 공간을 확인하도록 하자. 애플리케이션을 실행하면 로봇이 후진하는 것을 확인할 수 있다. 마찬가지로 애플리케이션을 종료하면 로봇이 멈출 것이다.

바퀴의 속도를 0부터 -100까지 변경하면서 로봇의 이동 속도가 어떻게 달라지는지 관찰해 보자.

03. 제자리 돌기

알버트 로봇이 제자리에서 돌도록 프로그램을 작성하시오.

그림 1과 같이 왼쪽 바퀴와 오른쪽 바퀴의 회전 속도를 반대로 하면 회전하는 중심점은 어디일까? 답은 좌우 바퀴를 연결하는 선의 중심이다. 이렇게 두 바퀴의 회전 방향을 반대로 하고 속도 크기(속력)를 같게 하면 제자리에서 회전하게 된다. 이러한 회전 동작은 어떤 미션을 완료한 후 자축 세레모니로 활용할 수 있다.

그림 1. 제자리에서 돌기 위한 바퀴의 속도와 회전 방향

 <script type="text/javascript">

 var leftWheelDevice;
 var rightWheelDevice;
 
 function onInitialized(robot)
 {
     leftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
     rightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
 }

 function onExecute()
 {
     leftWheelDevice.write(-20);
     rightWheelDevice.write(20);
 }
 </script>

04. 피봇 턴

알버트 로봇의 왼쪽 바퀴를 축으로 회전하는 프로그램을 작성하시오.

그림 2와 같이 왼쪽 바퀴를 정지하고 오른쪽 바퀴에만 속도 값을 주면 로봇이 회전하는 중심점은 어디일까? 답은 로봇의 왼쪽 바퀴이다. 오른쪽 바퀴는 회전하는데 왼쪽 바퀴가 움직이지 않으므로 로봇은 왼쪽 바퀴를 중심으로 회전하게 된다. 사람도 마찬가지이다. 왼쪽 발을 땅에 고정시키고 오른쪽 발만 앞으로 가면 어떻게 될까? 앞에서 프로그램한 제자리 돌기보다는 회전 반경이 크지만 그림 3과 같이 한쪽 바퀴를 기준으로 회전할 때 사용하는 방식이다.

그림 2. 왼쪽 바퀴를 중심으로 회전하기 위한 바퀴의 속도와 회전 방향

그림 3. 왼쪽 바퀴를 중심으로 회전하는 경로

 <script type="text/javascript">

 var leftWheelDevice;
 var rightWheelDevice;
 
 function onInitialized(robot)
 {
     leftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
     rightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
 }

 function onExecute()
 {
     leftWheelDevice.write(0);
     rightWheelDevice.write(20);
 }
 </script>

반대로 오른쪽 바퀴를 중심으로 회전하도록 해보고, 시계 방향, 반시계 방향 등 다양한 회전을 만들어 보자.

05. 라운드 턴

알버트 로봇이 원을 그리며 회전하는 프로그램을 작성하시오.

그림 4와 같이 왼쪽 바퀴는 20의 속도로 회전하고 오른쪽 바퀴는 50의 속도로 회전하면 그림 5와 같이 알버트 로봇이 원을 그리면서 왼쪽으로 회전하게 된다. 두 바퀴 간의 속도 차이에 의해 회전하게 되므로 두 바퀴 간의 속도 차이가 작을수록 큰 원을 그리면서 회전한다.

그림 4. 원을 그리며 회전하기 위한 바퀴의 속도와 회전 방향

그림 5. 원을 그리며 회전하기

 <script type="text/javascript">

 var leftWheelDevice;
 var rightWheelDevice;
 
 function onInitialized(robot)
 {
     leftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
     rightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
 }

 function onExecute()
 {
     leftWheelDevice.write(20);
     rightWheelDevice.write(50);
 }
 </script>

좌우 바퀴의 속도를 다양하게 변경해 보면서 로봇이 회전하는 원의 크기가 어떻게 달라지는지 관찰해 보도록 하자.

06. 일정 시간동안 움직이기

이번에는 일정한 시간동안만 로봇이 움직이도록 해보자.

알버트 로봇을 2초 동안 직진시키기 위한 프로그램을 작성하시오.

onExecute() 콜백 함수는 20ms마다 한번씩 호출된다. 따라서 2초가 되려면 2000ms / 20ms, 즉 100번 호출되면 2초가 된다. onExecute() 콜백 함수가 호출되는 횟수를 세기 위한 변수를 하나 선언하도록 하자. 여기서는 변수 이름을 count라고 하였다. count가 100이 되기 전까지는 1씩 증가시키다가 100이 되면 좌우 바퀴의 속도를 0으로 하면 된다. 이제, 알버트 로봇이 2초 동안 앞으로 달린 후 정지하는 프로그램이 완성되었다.

 <script type="text/javascript">

 var leftWheelDevice;
 var rightWheelDevice;
 var count = 0;

 function onInitialized(robot)
 {
     leftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
     rightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
 }

 function onExecute()
 {
     if(count < 100)
     {
         leftWheelDevice.write(20);
         rightWheelDevice.write(20);
         count ++;
     }
     else
     {
         leftWheelDevice.write(0);
         rightWheelDevice.write(0);
     }
 }
 </script>

여기서 주의해야 할 점이 하나 있다. 간단하게 생각해서 좌우 바퀴의 속도를 20으로 명령한 후에 2초 쉬었다가 속도를 0으로 명령하면 되지 않을까?

onExecute() 콜백 함수에서는 이렇게 하면 안된다. write 메소드를 사용하여 속도 데이터를 썼다고 해서 하드웨어 로봇으로 데이터가 바로 전달되는 것은 아니다. onExecute() 콜백 함수를 완료한 후에 데이터를 한꺼번에 전달하도록 되어 있다.

이렇게 하는 이유는 하드웨어 로봇에 여러 개의 데이터가 동시에 전달되도록 하기 위한 것이다. 만약 왼쪽 바퀴의 속도보다 오른쪽 바퀴의 속도가 늦게 도착하게 되면 아주 짧은 시간이겠지만 왼쪽 바퀴가 먼저 출발하게 될 것이다.

따라서 onExecute() 콜백 함수에서 시간을 붙잡아 두고 있으면 안된다. 망치로 못을 계속 두드리고 있는데 손으로 망치를 붙잡고 있으면 못이 벽에 박힐리가 없다.

2초 동안 후진하거나 회전하는 프로그램 등 다양한 동작을 만들어 보자.

07. 서서히 정지하기

아무리 재빠른 알버트 로봇이라고 하더라도 갑자기 속도를 바꾸면 당황할 것 같다. 로봇을 프로그래밍할 때 서서히 속도를 높이고 내리는 작업은 중요하다. 여러분이 자전거를 타고 갈 때 갑자기 속도를 0으로 하면 어떻게 될까? 상상만 해도 겁이 난다. 이제 알버트 로봇의 속도를 서서히 높이거나 내리는 프로그램을 작성해 보도록 하자.

서서히 속도를 내려 정지하는 프로그램을 작성하시오.

지금까지는 좌우 바퀴의 속도를 상수 값으로 주었지만 속도를 서서히 내리기 위해서는 매번 속도 값을 다르게 주어야 한다. 속도 20에서 시작하여 2초 후에 속도가 0이 되도록 하려면 0.1초마다 속도를 1씩 감소시키면 된다. onExecute() 콜백 함수가 20ms마다 호출되므로 100ms / 20ms, 즉 5번 호출되면 0.1초가 된다. 바퀴의 속도를 감소시킬 변수 speed를 선언하고 count를 증가시켜 5가 될 때마다 speed를 1씩 감소시키도록 하자. 2초 후에는 속도가 0으로 유지되어야 하므로 speed가 0이 되면 더 이상 감소시키지 않도록 하자.

 <script type="text/javascript">

 var leftWheelDevice;
 var rightWheelDevice;
 var count = 0;
 var speed = 20;

 function onInitialized(robot)
 {
     leftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
     rightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
 }

 function onExecute()
 {
     if(speed > 0)
     {
         if(++count >= 5)
         {
             speed --;
             count = 0; // 5번을 다시 세어야 하므로 0으로 초기화해야 한다.
         }
     }
     leftWheelDevice.write(speed);
     rightWheelDevice.write(speed);
 }
 </script>

서서히 속도를 높여 출발하는 프로그램도 만들어 보도록 하자.