마이크로폰 액션

01. 소리 질러~~

스마트 폰의 마이크로 입력되는 소리의 크기에 따라 알버트 로봇을 움직여 보자.

스마트 폰의 마이크에 입으로 후~ 불면 알버트 로봇이 뒤로 물러나는 프로그램을 작성하시오.

로봇을 움직이기 위해 RobotActivity 클래스를 상속한 액티비티를 만들고, onInitialized(Robot) 메소드와 onExecute() 메소드를 상속받아 새로 구현하자. Activity 클래스의 onDestroy() 메소드도 상속받아 새로 구현하고, 프로젝트에 스마트 로봇 라이브러리를 포함하는 것을 잊지 않기를 바란다.

 public class SampleActivity extends RobotActivity
 {
     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();
     }

     @Override
     public void onInitialized(Robot robot)
     {
     }

     @Override
     public void onExecute()
     {
     }
 }

Microphone 액션의 객체를 얻기 위해서는 Action 클래스의 obtain(Context context, String actionId) 메소드에서 actionId에 Action.Microphone.ID를 입력하면 된다.

 public class SampleActivity extends RobotActivity
 {
     private Action mAction;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mAction = Action.obtain(this, Action.Microphone.ID); // 액션 객체를 얻는다.
         mAction.activate(); // 액션을 시작한다.
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mAction.deactivate(); // 액션을 중지한다.
         mAction.dispose(); // 액션을 폐기한다.
     }

     @Override
     public void onInitialized(Robot robot)
     {
     }

     @Override
     public void onExecute()
     {
     }
 }

onCreate(Bundle savedInstanceState) 메소드에서 액션을 얻어서 시작하고 onDestroy() 메소드에서 액션을 중지 및 폐기하였지만 어디에서 해도 상관은 없다. 애플리케이션을 종료하기 전에 액션을 모두 폐기하여야 한다는 것만 잊지 않도록 하자.

Microphone 액션에는 스마트 폰의 마이크로 입력된 소리의 크기를 읽는 디바이스로 SENSOR_LEVEL이 있다. 입력된 소리의 파워를 데시벨로 나타내며, -100부터 0까지의 값을 가지는데 소리의 파워가 커질수록 값이 커진다.

 public class SampleActivity extends RobotActivity
 {
     private Action mAction;
     private Device mLevelDevice;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mAction = Action.obtain(this, Action.Microphone.ID);
         mLevelDevice = mAction.findDeviceById(Action.Microphone.SENSOR_LEVEL);
         mAction.activate();
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mAction.deactivate();
         mAction.dispose();
     }

     @Override
     public void onInitialized(Robot robot)
     {
     }

     @Override
     public void onExecute()
     {
         float level = mLevelDevice.readFloat();
     }
 }

이제 스마트 폰의 마이크로 입력된 소리의 크기에 따라 알버트 로봇을 움직여 보도록 하자.

 public class SampleActivity extends RobotActivity
 {
     private Action mAction;
     private Device mLevelDevice;
     private Device mLeftWheelDevice;
     private Device mRightWheelDevice;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mAction = Action.obtain(this, Action.Microphone.ID);
         mLevelDevice = mAction.findDeviceById(Action.Microphone.SENSOR_LEVEL);
         mAction.activate();
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mAction.deactivate();
         mAction.dispose();
     }

     @Override
     public void onInitialized(Robot robot)
     {
         mLeftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
         mRightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
     }

     @Override
     public void onExecute()
     {
         float level = mLevelDevice.readFloat();
         if(level > -10)
         {
             mLeftWheelDevice.write(-20);
             mRightWheelDevice.write(-20);
         }
         else
         {
             mLeftWheelDevice.write(0);
             mRightWheelDevice.write(0);
         }
     }
 }

스마트 로봇 론처를 실행하여 로봇과 연결한 후 애플리케이션을 실행하자. 스마트 폰을 알버트 로봇에 올려 놓고 스마트 폰의 마이크에 입으로 후~ 불면 작고 앙증맞은 알버트 로봇이 바람에 날려 뒤로 밀리는 것을 볼 수 있다. 너무 세게 불면 머리가 아프니까 경계값 -10을 변경하면서 적절한 값을 찾아 보도록 하자.

액션의 경우에도 로봇과 마찬가지로 onDeviceDataChanged(Device device, Object values, long timestamp) 메소드를 통해 디바이스의 데이터를 얻을 수 있다. 이를 위해서는 우선 addDeviceDataChangedListener(Device.DeviceDataChangedListener listener) 메소드를 사용하여 액션에 리스너를 등록해야 한다.

 public class SampleActivity extends RobotActivity
 {
     private Action mAction;
     private Device mLeftWheelDevice;
     private Device mRightWheelDevice;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mAction = Action.obtain(this, Action.Microphone.ID);
         mAction.addDeviceDataChangedListener(this); // 리스너를 등록한다.
         mAction.activate();
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mAction.deactivate();
         mAction.dispose();
     }

     @Override
     public void onInitialized(Robot robot)
     {
         mLeftWheelDevice = robot.findDeviceById(Albert.EFFECTOR_LEFT_WHEEL);
         mRightWheelDevice = robot.findDeviceById(Albert.EFFECTOR_RIGHT_WHEEL);
     }

     @Override
     public void onDeviceDataChanged(Device device, Object values, long timestamp)
     {
         float level;
         switch(device.getId())
         {
         case Action.Microphone.SENSOR_LEVEL:
             level = ((float[])values)[0];
             if(level > -10)
             {
                 mLeftWheelDevice.write(-20);
                 mRightWheelDevice.write(-20);
             }
             else
             {
                 mLeftWheelDevice.write(0);
                 mRightWheelDevice.write(0);
             }
             break;
         }
     }
 }