로봇 위치 알기

01. 여기가 어디인가요?

재간둥이 알버트 로봇이 맘껏 뛰어 놀다가 집으로 돌아가지 못하면 큰 일이다. 일반적인 로봇은 자신이 어디에 있는지 알지 못한다. 눈을 감고 돌아다니는 것과 같다. 알버트 로봇은 재간둥이라서 자신이 어디에 있는지 알 수 있다. 하지만 아무 곳에서나 뛰어 놀면 안되니까 그림 1과 같이 특수하게 제작된 내비게이션 패드가 필요하다. 내비게이션 패드 위에서는 언제 어디서든 자신의 위치를 알 수 있으므로 안전하게 집으로 돌아갈 수 있다.

그림 1. 내비게이션 패드

알버트 로봇의 위치를 알아내는 프로그램을 작성하시오.

웹 페이지 만들기를 참고하여 안드로이드 프로젝트와 웹 페이지 파일을 만들고, onInitialized(robot) 콜백 함수와 onExecute() 콜백 함수를 만들자.

 <script type="text/javascript">

 function onInitialized(robot)
 {
 }

 function onExecute()
 {
 }
 </script>

내비게이션 패드의 좌표계는 그림 2와 같이 원점이 패드의 왼쪽 아래에 있고, 가로축이 X축, 세로축이 Y축이다. 내비게이션 패드는 여러 가지 크기가 있기 때문에 패드의 크기를 알려 주지 않으면 자신이 얼마나 큰 운동장에서 놀고 있는지 모르니까 위치를 계산할 수가 없다. 따라서 우선 패드의 크기를 입력하도록 하자. 여기서는 가로 108, 세로 76 크기의 패드를 사용하였다. 패드의 크기는 그림 3과 같이 내비게이션 패드의 왼쪽 위에 적혀 있으므로 그대로 입력만 하면 된다.

그림 2. 내비게이션 패드의 좌표계

그림 3. 내비게이션 패드의 크기 정보

패드 크기에 해당하는 디바이스는 COMMAND_PAD_SIZE인데, 가로, 세로 2개의 값이 필요하므로 패드 크기 데이터는 크기 2의 배열로 되어 있으며, 각각 1부터 40000까지의 값을 가질 수 있다.

 <script type="text/javascript">

 var padSizeDevice;

 function onInitialized(robot)
 {
     padSizeDevice = robot.findDeviceById(Albert.COMMAND_PAD_SIZE);
 }

 function onExecute()
 {
     padSizeDevice.writeAt(0, 108); // 가로 크기
     padSizeDevice.writeAt(1, 76); // 세로 크기
 }
 </script>

알버트 로봇에는 위치를 알려주는 센서 디바이스로 SENSOR_POSITION이 있다. X축과 Y축 좌표가 있으므로 위치 데이터는 크기 2의 배열로 되어 있으며, 각각 -1부터 39999까지의 값을 가질 수 있다. 좌표 값은 0부터 시작하기 때문에 0부터 39999까지는 유효한 값이고, -1은 알버트 로봇이 내비게이션 패드 위에 있지 않거나 현재 위치를 알지 못할 때 표시하는 값이다.

 <script type="text/javascript">

 var padSizeDevice;
 var positionDevice;

 function onInitialized(robot)
 {
     padSizeDevice = robot.findDeviceById(Albert.COMMAND_PAD_SIZE);
     positionDevice = robot.findDeviceById(Albert.SENSOR_POSITION);
 }

 function onExecute()
 {
     padSizeDevice.writeAt(0, 108);
     padSizeDevice.writeAt(1, 76);
     var x = positionDevice.readAt(0); // X 좌표
     var y = positionDevice.readAt(1); // Y 좌표
 }
 </script>

그림 4와 같이 내비게이션 패드를 두 영역으로 나누어서 영역별로 다른 동작을 하도록 해보자. 여기서는 간단하게 하기 위해서 눈의 색상을 다르게 표현하였지만, 다양한 동작을 나타내도록 프로그램하여도 된다. 애플리케이션을 실행하고 로봇을 한 쪽 영역에 놓아두도록 하자. 로봇이 전진하다가 영역을 넘어가면 눈이 빨간색으로 변할 것이다.

그림 4. 영역 나누기

 <script type="text/javascript">

 var padSizeDevice;
 var positionDevice;
 var leftWheelDevice;
 var rightWheelDevice;
 var leftEyeDevice;
 var rightEyeDevice;

 function onInitialized(robot)
 {
     padSizeDevice = robot.findDeviceById(Albert.COMMAND_PAD_SIZE);
     positionDevice = robot.findDeviceById(Albert.SENSOR_POSITION);
     leftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
     rightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
     leftEyeDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_EYE);
     rightEyeDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_EYE);
 }

 function onExecute()
 {
     padSizeDevice.writeAt(0, 108);
     padSizeDevice.writeAt(1, 76);
     leftWheelDevice.write(20);
     rightWheelDevice.write(20);
     var x = positionDevice.readAt(0); // X 좌표
     var r = 0, g = 0, b = 0;
     if(x > 54)
         r = 255;
     else
         g = 255;
     leftEyeDevice.writeAt(0, r);
     leftEyeDevice.writeAt(1, g);
     leftEyeDevice.writeAt(2, b);
     rightEyeDevice.writeAt(0, r);
     rightEyeDevice.writeAt(1, g);
     rightEyeDevice.writeAt(2, b);
 }
 </script>

02. 나만 바라봐

이번에는 알버트 로봇의 방향을 알아보자.

알버트 로봇의 방향을 알아내는 프로그램을 작성하시오.

알버트 로봇에는 방향을 알려주는 센서 디바이스로 SENSOR_ORIENTATION이 있다. -179부터 180까지의 값을 가질 수 있으며 방향이 몇 도인지를 알려 준다. 그림 5와 같이 내비게이션 패드의 X축 방향이 0도이며, 반시계 방향으로 0도부터 180도까지, 시계방향으로 0도부터 -179도까지 표시된다.

그림 5. 내비게이션 패드 위에서의 방향

 <script type="text/javascript">

 var padSizeDevice;
 var orientationDevice;

 function onInitialized(robot)
 {
     padSizeDevice = robot.findDeviceById(Albert.COMMAND_PAD_SIZE);
     orientationDevice = robot.findDeviceById(Albert.SENSOR_ORIENTATION);
 }

 function onExecute()
 {
     padSizeDevice.writeAt(0, 108);
     padSizeDevice.writeAt(1, 76);
     var orientation = orientationDevice.read(); // 방향
 }
 </script>

깜찍한 알버트 로봇이 나만 바라보면 좋겠다는 생각이 든다. 내비게이션 패드 위에 알버트 로봇을 어떻게 놓더라도 항상 0도 방향을 향하도록 해보자. 로봇의 방향이 양수 값이면 오른쪽으로 제자리 돌기를 하고 음수 값이면 왼쪽으로 제자리 돌기를 하면 된다. 도는 속도가 빠르면 0도 근처에서 왔다갔다 할 수 있으므로 0도 근처에서는 속도를 줄이도록 하자.

 <script type="text/javascript">

 var padSizeDevice;
 var orientationDevice;
 var leftWheelDevice;
 var rightWheelDevice;

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

 function onExecute()
 {
     padSizeDevice.writeAt(0, 108);
     padSizeDevice.writeAt(1, 76);
     var orientation = orientationDevice.read();
     var speed = 0;
     if(orientation > 0)
     {
         if(orientation < 5)
             speed = 0;
         else if(orientation < 15)
             speed = orientation * 2;
         else
             speed = 30;
     }
     else if(orientation < 0)
     {
         if(orientation > -5)
             speed = 0;
         else if(orientation > -15)
             speed = orientation * 2;
         else
             speed = -30;
     }
     leftWheelDevice.write(speed);
     rightWheelDevice.write(-speed);
 }
 </script>