LegoEV3+갤럭시노트로 매트 위에서 안 떨어지기

집에 놀고 있는 갤럭시 노트1을 LEGO EV3에 붙여 보았다. 갤럭시노트 센서중 가속도, 마그네틱 센서를 사용하면 휴대폰의 기울기를 쉽게? 구할수 있다고 한다. 이를 활용해서 매트 위에서 떨어짐을 감지해서 후진하도록 만들었다. 휴대폰이 수평으로 되어있으면 전진..처음 할때는 안될줄 알았는데, 안떨어지는걸 보니 신기하네.

인터넷에 LEGO EV3용 센서를 고가에 파는데 구할 수 있는데, 사기에는 좀 많이 아깝다. 빠른 반응속도가 필요하지 않으면 휴대폰 센서를 쓰는것도 괜찮다.

휴대폰은
1. 서버 역할을 하고
2. 휴대폰이 기울어져 있는지 판단한다.
3. 이를 socket으로 열어놓는다.

레고는
1. 휴대폰의 소켓으로 접속하여 매순간 데이터를 받는다.
2. 기울어졌다고 수신되면 후진
3. 수평이라 판단되면 전진

만들면서 부품이 좀 많이 부족했다. 특히 ㄱ자 브라켓?(핀 홀 방향을 바꿔주는 브라켓)이 없어서 애를 먹었다. 부품간 간격이 좀 있어 보이는데, 채윤이가 가지고 놀던 점토로 잘 붙였다.

안드로이드 가속도 센서 구현, 칼만필터 적용

추석때 집에 가니 엄마 구형 노트1이 놀고 있었다. 내가 가진 구형폰도 있었으나, 레고에 붙이기에는 좀 아까운듯하여 이 폰을 붙여보려고 한다.

일단 내장된 센서의 값을 읽는 부분을 java로 구현했다. 여기에서 대부분 참조했고, 이번엔 좀 쉽게 따라할 수 있었다. 가속도센서값의 raw data는 도저히 그대로 사용할 수 없어 보인다.

다시 찾아보니, 칼만 필터가 좋다고 하다니 적용해 보았다.

eclipse에 지원하는 logcat에서 센서값을 파일로 저장 후, 필터 적용 전후 비교를 해 보았다. 전에는 데이터값을 파일로 저장하고 다시 읽었는데, eclipse에서 파일로 저장을 지원하니 엄청 편하다..
rawdata
위 그림이 raw data..

filtereddata
위 그림이 Kalman 필터를 통과한 그림..
Kalman 필터가 제대로 적용되는 듯 하다.

Java 에서 Interface를 사용하여 Callback 구현하기

스크랩 : http://blog.saltfactory.net/java/implement-java-callback.html

서론

프로그래밍에서 꽤 유용한 기능들이 있는데 그중에서 하나가 바로 Callback 이라는 것이다. Callback은 Windows 개발자라면 익히들 알고 있지만 Java 개발자라면 어쩌면 낯선 단어일수도 있다. 하지만 Java 개발자들에게 Listner와 비슷한거라고 하면 대략적인 Callback의 의미를 상상할 수 있을거라 예상된다. 보통 Callback과 Listener는 어떠한 일을 처리하기 위해서 프로세스가 진행하는 도중에 다른 이벤트 처리에 사용하기 때문이다. 하지만 은밀히 말하면 이 두가지는 디자인 패턴(Pattern)이 다르다. Callback은 Command Pattern을 따르고 있고 Listener는 Observer Pattern을 따르고 있기 때문이다. 이 두가지의 차이점은 나중에 다른 포스팅에서 Listener를 설명하면서 다시 한번 자세히 언급하겠다.

일반적으로 프로그래밍에서 Callback 이라는 용어를 다음과 같이 이야기 한다.

호출자(Caller)가 피호출자(Callee)를 호출하는 것이 아니라 피호출자(Callee)가 호출자(Caller)를 호출하는 것을 말한다.

(참조 http://cafe.naver.com/devctrl.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=1727)

위키에서는 다음과 같이 정의하고 있다.

프로그래밍에서 콜백(callback)은 다른 코드의 인수로서 넘겨받는 서브루틴이다. 이를 통해 높은 수준의 층에 정의된 서브루틴(또는 함수)을 낮은 수준의 추상화층이 호출할 수 있게 된다. 일반적으로 먼저 높은 수준의 코드가 낮은 수준의 코드에 있는 함수를 호출할 때, 다른 함수의 포인터나 핸들을 넘겨준다. 낮은 수준의 함수를 실행하는 동안에 그 넘겨받은 함수를 적당히 회수, 호출하고, 부분 작업을 실행하는 경우도 있다. 다른 방식으로는 낮은 수준의 함수는 넘겨받은 함수를 ‘핸들러’로서 등록하고, 낮은 수준의 층에서 비동기적으로(어떠한 반응의 일부로서) 다음에 호출하는데 사용한다. 콜백은 폴리모피즘과 제네릭프로그래밍의 단순화된 대체 수법이며, 어떤 함수의 정확한 동작은 그 낮은 수준의 함수에 넘겨주는 함수 포인터(핸들러)에 의해 바뀐다. 이것은 코드 재사용을 하는 매우 강력한 기법이라고 말할 수 있다.

위의 정의에서 보듯 callback은 포인터나 핸들러를 넘겨줘서 피호출자(Callee)가 호출자(Caller)를 호출하는 기법으로 코드 재상용이 가능하고, 비동기적으로 처리할 수 있으며 함수를 추상화 할 수 있기 때문에 UI나 비동기 처리 시스템에서 callback 기법을 많이 사용한다.

Android에서 Callback

왜 Java에서 Callback을 포스팅하는가 하면 바로 Android 앱을 개발할 때 Fragment를 테스트하기 위한 샘플 코드를 만들게 되면 Activity와 Fragment가 바로 Callback을 사용하고 있기 때문이다. 아래는 이클립스에서 Fragment를 이용한 예제를 샘플로 만들면 만들어지는 코드이다.

package net.saltfactory.tutorial;

import net.saltfactory.tutorial.dummy.DummyContent;

import android.R;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;


public class ItemListFragment extends ListFragment {

    private static final String STATE_ACTIVATED_POSITION = "activated_position";

    private Callbacks mCallbacks = sDummyCallbacks;
    private int mActivatedPosition = ListView.INVALID_POSITION;

    public interface Callbacks {

        public void onItemSelected(String id);
    }

    private static Callbacks sDummyCallbacks = new Callbacks() {
        @Override
        public void onItemSelected(String id) {
        }
    };

    public ItemListFragment() {
    }

   ... 생략 ...

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (!(activity instanceof Callbacks)) {
            throw new IllegalStateException("Activity must implement fragment's callbacks.");
        }

        mCallbacks = (Callbacks) activity;
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mCallbacks = sDummyCallbacks;
    }

    @Override
    public void onListItemClick(ListView listView, View view, int position, long id) {
        super.onListItemClick(listView, view, position, id);
        mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
    }

    ... 생략

위 코드를 자세히 살펴보면 Callback을 사용하기 위해서 Java의 Interface를 사용한 것을 확인 할 수 있다.

Interface를 사용하여 Callback 구현

Java에서는 Callback을 사용하기 위해서 interface를 사용한다. 좀더 이해를 돕기 위해서 다음 코드를 살펴보자.

처음으로 살펴볼 것은 Callback을 사용할 수 있는 Interface를 만드는 것이다. 그리고 그 안에는 callbackMethod를 추가한다.

/**
 * filename : CallbackEvent.java
 *
 */
package net.saltfactory.tutorial;

public interface CallbackEvent {
	public void callbackMethod();
}

다음은 Callback을 외부에서 Callback method를 등록할 수 있는 EventRegistration 을 만든다. 이때 생성자에서 Callback으로 구현된 객체를 외부에서 전달 받아서 EventRegistration의 doWork() 메소드에서 외부에서 정의한 callbackMethod를 실행하게 한다.

/**
 * filename : EventRegistration.java
 *
 */

package net.saltfactory.tutorial;

public class EventRegistration {
	private CallbackEvent callbackEvent;

	public EventRegistration(CallbackEvent event){
		callbackEvent = event;
	}

	public void doWork(){
		callbackEvent.callbackMethod();
	}
}

다음은 Main에서 호출자(Caller)와 피호출자(Callee)를 만들어서 콜백을 테스트한다. 아래와 같이 호출자(caller)에 구현된 callbackMethod를 등록해서 피호출자(callee)가 호출자(caller)에 구현된 callbackMethod를 실행할 수 있게 되었다.

/**
 * filename :EventApplication.java
 *  
 */

package net.saltfactory.tutorial;

public class EventApplication {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		CallbackEvent callbackEvent = new CallbackEvent(){

			@Override
			public void callbackMethod() {
				// TODO Auto-generated method stub
				System.out.println("call callback method from callee");
			}

		};

		EventRegistration eventRegistration = new EventRegistration(callbackEvent);
		eventRegistration.doWork();
	}

}

이 코드를 실행하면 다음과 같은 결과를 확인 할 수 있다.

이 코드를 유사하게 Android에서는 Activity와 Fragment에 Callback을 사용하고 있는데 이는 Fragment는 반드시 Activity를 가져야하고 Fragment는 Activity의 메소드를 비동기적으로 요청해야하기 때문이다. 이와 같은 상황을 콜백메소드를 이용해서 비동기적인 문제를 해결하고 코드를 재사용할 수 있게 Java의 Interface를 사용해서 Callback을 구현한 것이다.

결론

Callback은 호출자(Caller)에서 구현한 메소드를 피호출자(Callee)가 호출해서 사용할 수 있다. 이렇게 외부에서 메소드를 구현화 시키기 때문에 코드의 재사용성이 높아진다. 그리고 Callback는 피호출자(Callee)가 호출자(Caller)에게 비동기적으로 메세지를 보내어서 데이터처리를 비동기 적으로 처리할 수 있는 장점을 가진다. 자바에서 이러한 Callback 구현은 Java의 Interface의 특징을 이용하여 구현할 수 있다.

참고

  1. http://blog.danieldee.com/2009/06/callback-vs-listener.html
  2. http://cafe.naver.com/devctrl.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=1727
  3. http://ko.wikipedia.org/wiki/콜백
  4. http://www.javaworld.com/javatips/jw-javatip10.html

Lego 조립 설명서

Lego City 60022 Cargo Terminal

index
1번
2번
3번
4번


 

 

Lego City 60060 Auto Transporter
60060-0000-XX-12-1
1번
2번
3번


 

 

Lego City 60083 Snowplow Truck
60083-0000-XX-12-1
1번

Lego City 60042 HighSpeed Police Chase City Police
60042-0000-XX-12-1
1번


 

 

Lego City 60043 Prisoner Transporter
60043-0000-XX-12-1

1번


 

 

Lego City 60001 Fire Chief Car
60001-0000-XX-12-1
1번


 

 

Lego Mindstorm EV3 31313
index
기본 메뉴얼


 

 

 

 

 

Lego Mindstorm NXT 8527
NXT1-8527Box
기본 메뉴얼


Lego Technic 42007 MotoCross Bike
42007-0000-XX-12-1
1번
2번


 

 

10507 My First Train Set DUPLO Town
10507-0000-XX-12-1

1번


 

 

10506 Train Accessory Set DUPLO Town
10506-0000-XX-12-1

1번


 

 

 

 

많이도 샀네..