진동 액션

01. 장애물을 만나면 부르르~

스마트 폰으로 로봇을 조종할 때 장애물을 만나면 스마트 폰에 진동이 울리도록 해보자.

알버트 로봇이 전진하다가 앞에 장애물이 나타나면 정지하고 스마트 폰의 진동을 울리는 프로그램을 작성하시오.

웹 페이지 만들기를 참고하여 안드로이드 프로젝트와 웹 페이지 파일을 만들자. onInitialized(robot) 콜백 함수와 onExecute() 콜백 함수를 만들고, 웹 페이지가 닫힐 때 호출되는 window.onunload 함수도 만들자.

 <script type="text/javascript">

 function onInitialized(robot)
 {
 }

 function onExecute()
 {
 }

 window.onunload = function()
 {
 }
 </script>

Vibration 액션의 객체를 얻기 위해서는 Action 객체의 obtain(actionId) 함수에서 actionId에 Action.Vibration.ID를 입력하면 된다.

 <script type="text/javascript">

 var action = Action.obtain(Action.Vibration.ID); // 액션 객체를 얻는다.

 function onInitialized(robot)
 {
 }

 function onExecute()
 {
 }

 window.onunload = function()
 {
     action.deactivate(); // 액션을 중지한다.
     action.dispose(); // 액션을 폐기한다.
 }
 </script>

window.onunload 함수에서 액션을 중지 및 폐기하였지만 어디에서 해도 상관은 없다. 웹 페이지가 닫히기 전에 액션을 모두 폐기하여야 한다는 것만 잊지 않도록 하자.

Vibration 액션에는 진동의 지속 시간을 나타내는 디바이스로 COMMAND_TIME이 있다. 진동의 지속 시간을 1000분의 1초 단위(ms)로 나타내며, 0부터 65535까지의 값을 가질 수 있다.

 <script type="text/javascript">

 var action = Action.obtain(Action.Vibration.ID);
 var timeDevice = action.findDeviceById(Action.Vibration.COMMAND_TIME);
 timeDevice.write(100); // 진동의 지속 시간을 쓴다.

 function onInitialized(robot)
 {
 }

 function onExecute()
 {
 }

 window.onunload = function()
 {
     action.deactivate();
     action.dispose();
 }
 </script>

이제 알버트 로봇이 전진하다가 장애물을 만나면 진동을 울리도록 해보자.

 <script type="text/javascript">

 var leftProximityDevice;
 var rightProximityDevice;
 var leftWheelDevice;
 var rightWheelDevice;

 var action = Action.obtain(Action.Vibration.ID);
 var timeDevice = action.findDeviceById(Action.Vibration.COMMAND_TIME);
 timeDevice.write(100);

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

 function onExecute()
 {
     var leftProximity = leftProximityDevice.read();
     var rightProximity = rightProximityDevice.read();
     if(leftProximity > 50 || rightProximity > 50)
     {
         leftWheelDevice.write(0);
         rightWheelDevice.write(0);
         action.activate(); // 액션을 시작한다.
     }
     else
     {
         leftWheelDevice.write(20);
         rightWheelDevice.write(20);
     }
 }

 window.onunload = function()
 {
     action.deactivate();
     action.dispose();
 }
 </script>

프로그램을 실행하고 앞으로 달려가는 알버트 로봇의 앞을 손으로 막으면 전방 센서의 값이 50보다 커져서 알버트 로봇이 정지하고 스마트 폰의 진동이 울릴 것이다.

02. 후진합니다. 비켜 나세요.

장애물을 만나면 뒤로 후진하면서 뚜뚜뚜 빠르게 진동을 울리도록 해보자. 대신, 전진할 때는 알버트 로봇의 심장 박동을 진동으로 표현하도록 하자.

알버트 로봇이 전진할 때는 진동을 천천히 울리고, 앞에 장애물이 나타나면 후진하면서 빠르게 진동을 울리는 프로그램을 작성하시오.

앞에서 작성한 프로그램을 약간 수정하면 되는데, 진동을 계속 울리는 것이 아니라 뚜뚜뚜 울리도록 하기 위해서는 진동 패턴을 만들어야 한다.

두 가지 진동 패턴이 있기 때문에 진동 액션을 두 개 얻어서 경우에 따라 다른 액션을 시작하면 된다고 생각할 수 있지만 같은 ID를 가진 액션은 여러 개 만들 수 없다. 따라서 전진할 때와 후진할 때 진동 패턴만 다르게 주면 된다.

또한 액션이 시작되어 실행되고 있는 중에 activate() 함수를 호출하면 액션이 다시 시작되므로 플래그를 두어 다시 시작되지 않도록 하자.

 <script type="text/javascript">

 var leftProximityDevice;
 var rightProximityDevice;
 var leftWheelDevice;
 var rightWheelDevice;
 var forward = false;

 var action = Action.obtain(Action.Vibration.ID);
 var patternDevice = action.findDeviceById(Action.Vibration.COMMAND_PATTERN);
 var repeatDevice = action.findDeviceById(Action.Vibration.COMMAND_REPEAT);
 repeatDevice.write(0); // 패턴의 처음부터 반복한다.

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

 function onExecute()
 {
     var leftProximity = leftProximityDevice.read();
     var rightProximity = rightProximityDevice.read();
     if(leftProximity > 50 || rightProximity > 50)
     {
         leftWheelDevice.write(-20);
         rightWheelDevice.write(-20);
         if(forward)
         {
             forward = false;
             patternDevice.writeArray([ 0, 100, 100 ]); // 빠른 진동 패턴을 쓴다.
             action.activate();
         }
     }
     else
     {
         leftWheelDevice.write(20);
         rightWheelDevice.write(20);
         if(!forward)
         {
             forward = true;
             patternDevice.writeArray([ 0, 100, 1000 ]); // 느린 진동 패턴을 쓴다.
             action.activate();
         }
     }
 }

 window.onunload = function()
 {
     action.deactivate();
     action.dispose();
 }
 </script>