Object Tracker

관련 문서
Visual SLAM Tool
Tracker Coordinate System in Unity
Visual SLAM Learning Guide

Visual SLAM에서 생성 / 저장한 맵을 불러오고 해당 맵 위로 3D 콘텐츠를 띄워줍니다.

3D 공간을 학습하는 방법은 Visual SLAM Learning Guide를 참고하세요.

Object Tracker 씬 구성
맵 설정
맵 추가 / 교체
Tracker 시작 / 종료
Tracking 정보 이용

Object Tracker 씬 구성

  1. 유니티용 MAXST AR SDK를 설치하세요.

  2. 새로운 씬을 생성하세요.

  3. Default로 존재하는 Main Camera를 삭제한 후, Assets > MaxstAR > Prefabs > ARCamera, ObjectTrackable을 씬에 추가하세요.

    objectPrefab

    ※ 빌드할 경우 ARCamera에 License Key를 추가해야 합니다.

  4. 빈 객체를 생성하고 Assets > MaxstARSamples > Scripts > ObjetTrackerSample 스크립트를 컴포넌트로 추가하세요.

    objectSample

  5. Visual SLAM Tool에서 생성한 맵 파일을 Assets > StreamingAssets > MaxstAR에 위치 시킨 후, 맵 파일을 ObjectTrackable의 Inspector에 드래그하여 맵 파일을 설정합니다. Real Size는 -1을 입력해줍니다. Load 버튼을 눌러 뒤에 설명될 MapViewer에 맵을 설정합니다.
    ※ 맵 파일을 StreamingAssets 폴더의 하위에 놓지 않으면 맵 파일이 인식되지 않습니다.

    ObjectMapSetting

  6. 맵 파일 로드 후, Scene View와 Game View에서는 학습한 오브젝트 위에 Visual SLAM Tool에서 설정한 Pin이 오버레이된 것을 확인할 수 있습니다. 아래 그림, 네모 박스 안에서 Pin을 확인할 수 있습니다.

    after_load.PNG

  7. MapViewer의 Inspector에서는 Show Mesh가 기본 선택되어 있습니다. Keyframe index를 조절해가면서 콘텐츠 작업하기에 편한 Keyframe을 선택합니다.

    inspector.PNG

    ※ MapViewer

    • ObjectTrackable에 맵 파일을 설정하면 ObjectTrackable 하위에 MapViewer가 자동 생성됩니다.

    • Keyframe Id: 맵을 생성할 때, 카메라로 대상을 여러 방향에서 비추게 됩니다. 이 때 특정 조건을 만족하는 방향마다 Keyframe이 생성됩니다. Keyframe Id를 변화시키면 해당 Keyframe의 Mesh / Image가 Game View에 표시됩니다. 각각의 Keyframe에서 Cube의 위치를 조절하면 Cube를 보다 정확하게 배치할 수 있습니다.

    • Show Mesh: 체크하면 Game View에 표시되던 Image가 Mesh로 바뀝니다.

    • Transparent: 체크하면 Mesh / Image가 투명해집니다.

  8. 가상 오브젝트를 Hierarchy View에서 ObjectTrackable 하위에 위치시킵니다. Maxst SDK에서는 디폴트로 maxst_cube가 하위에 배치되어 있습니다.

  9. Pin 위치는 오브젝트 학습한 사람이 가상 콘텐츠를 배치하기 위해 표시해둔 자리입니다. Pin 위치를 참고하여 적절한 위치에 가상 콘텐츠를 배치합니다.

    arrangement.PNG

  10. 앱을 빌드하고 실행하세요. 타깃 오브젝트를 카메라로 비추면 가상 콘텐츠가 배치한 위치에 증강됩니다.

  11. 웹캠이 연결된 경우 유니티의 Play 버튼을 누르면 유니티 에디터 환경에서 테스트해볼 수 있습니다.

※ You can download the target Object from the Object Target link.

맵 설정

addTrackerData ()를 호출해서 맵 파일을 등록하고 loadTrackerData ()를 호출하면 공간을 Tracking 할 수 있는 상태가 됩니다. 맵을 설정하는 방법은 다음 코드를 참고하세요.

>ObjectTrackerSample.cs

private void AddTrackerData()
{
    foreach (var trackable in objectTrackablesMap)
    {
        if (trackable.Value.TrackerDataFileName.Length == 0)
        {
            continue;
        }

        if (trackable.Value.StorageType == StorageType.AbsolutePath)
        {
            TrackerManager.GetInstance().AddTrackerData(trackable.Value.TrackerDataFileName);
        }
        else
        {
            if (Application.platform == RuntimePlatform.Android)
            {
                TrackerManager.GetInstance().AddTrackerData(trackable.Value.TrackerDataFileName, true);
            }
            else
            {
                TrackerManager.GetInstance().AddTrackerData(Application.streamingAssetsPath + "/" + trackable.Value.TrackerDataFileName);
            }
        }
    }

    TrackerManager.GetInstance().LoadTrackerData();
}

Note - 맵 호환성
Visual Slam Tool 5.1.0 부터 3dmap의 파일 형식이 변경되었습니다. Visual Slam Tool 5.1.0 이상에서 생성된 3dmap은 AR SDK 6.2.x 이상에서 지원합니다. AR SDK 6.0.x 이하를 계속 사용하시려면 Visual Slam Tool 5.0.8 Android를 이용해주세요.
또한, Object Tracker에는 같은 버전의 3dmap만 추가할 수 있습니다.


패키지 설정

다수의 오브젝트 맵을 사용할 경우 3dpkg 파일로 패키징하면 맵 로딩 속도와 인식 속도가 크게 향상됩니다.
MapPackager로 3dpkg를 생성하고, AddTrackerData ()를 호출해서 패키지 파일을 등록하고 LoadTrackerData ()를 호출하면 타깃 오브젝트를 Tracking 할 수 있는 상태가 됩니다. 오브젝트 패키지를 설정하는 방법은 다음 코드를 참고하세요.

private IEnumerator AddTrackerData()
{
    string packagePath = ... // The file must exist in the streaming asset.

    yield return new WaitForEndOfFrame();

    if (Application.platform == RuntimePlatform.Android)
    {
        List<string> fileList = new List<string>();
        yield return StartCoroutine(MaxstARUtil.ExtractAssets(packagePath, fileList));
        TrackerManager.GetInstance().AddTrackerData(fileList[0], false);
    }
    else
    {
        TrackerManager.GetInstance().AddTrackerData(Application.streamingAssetsPath + "/" + packagePath);
    }

    TrackerManager.GetInstance().LoadTrackerData();
}

※ 오브젝트 패키지(3dpkg)는 AR SDK 6.1.0부터 사용가능합니다.
※ Visual Slam Tool 5.1.0 이상에서 생성된 3dmap만 3dpkg로 패키징할 수 있습니다.
※ Object Tracker에는 3dpkg 1개만 추가가능합니다.

맵 추가 / 교체

  1. Visual SLAM Tool을 이용하여 맵 파일을 생성합니다.

  2. 전송 받은 맵 파일을 원하는 경로에 복사합니다.

  3. 맵을 설정합니다.

  4. AddTrackerData (), LoadTrackerData () 를 통해 새로운 맵을 로드할 수 있으며, RemoveTrackerData()를 통해 로드된 맵을 삭제할 수 있습니다.

  5. 3dmap은 최대 3개까지 로드할 수 있으며, 로드된 3개의 맵은 한번에 하나씩 추적가능합니다. 동시에 추적되지 않습니다.

Tracker 시작 / 종료

맵을 로딩한 후 Tracker를 시작 / 종료하려면 다음 코드를 참고하세요.

>ObjectTrackerSample.cs

void Update()
{
    ...
    if (!startTrackerDone)
    {
        TrackerManager.GetInstance().StartTracker(TrackerManager.TRACKER_TYPE_OBJECT);
        ...
    }
    ...
}

void OnApplicationPause(bool pause)
{
    ...
    TrackerManager.GetInstance().StopTracker();
    ...
}

void OnDestroy()
{
    TrackerManager.GetInstance().StopTracker();
    TrackerManager.GetInstance().DestroyTracker();
    ...
}

Tracking 정보 이용

Tracking 정보를 이용하려면 다음 코드를 참고하세요.

>ObjectTrackerSample.cs

void Update()
{
    ...
    TrackingState state = TrackerManager.GetInstance().UpdateTrackingState();
    TrackingResult trackingResult = state.GetTrackingResult(); 

    for (int i = 0; i < trackingResult.GetCount(); i++)
    {
        Trackable trackable = trackingResult.GetTrackable(i);

        if (!objectTrackablesMap.ContainsKey(trackable.GetName()))
        {
            return;
        }

        objectTrackablesMap[trackable.GetName()].OnTrackSuccess(trackable.GetId(), trackable.GetName(), trackable.GetPose());
    }
}

ObjectTrackable(ObjectTrackableBehavior)를 사용하지 않을 경우에는 OnTrackFail() 대신 renderer, collider를 disable하고, OnTrackSuccess() 대신 renderer, collider를 enable, pose를 trackable의 pose로 세팅하는 코드로 교체하면 됩니다.

다음 코드를 참고하세요.

>ObjectTrackerSample.cs

void Update()
{
    foreach (var trackableGameObject in trackableGameObjects)
    {
        Renderer[] rendererComponents = trackableGameObject.GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = trackableGameObject.GetComponentsInChildren<Collider>(true);

        // Disable renderer
        foreach (Renderer component in rendererComponents)
        {
            component.enabled = false;
        }

        // Disable collider
        foreach (Collider component in colliderComponents)
        {
            component.enabled = false;
        }
    }
    
    TrackingState state = TrackerManager.GetInstance().UpdateTrackingState();
    TrackingResult trackingResult = state.GetTrackingResult(); 

    for (int i = 0; i < trackingResult.GetCount(); i++)
    {
        Trackable trackable = trackingResult.GetTrackable(i);
        string trackableName = trackable.GetName();
        
        GameObject trackableGameObject = ... // Get gameObject by trackableName

        Renderer[] rendererComponents = trackableGameObject.GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = trackableGameObject.GetComponentsInChildren<Collider>(true);

        // Enable renderers
        foreach (Renderer component in rendererComponents)
        {
            component.enabled = true;
        }

        // Enable colliders
        foreach (Collider component in colliderComponents)
        {
            component.enabled = true;
        }

        // set pose
        Matrix4x4 poseMatrix = trackable.GetPose();
        trackableGameObject.transform.position = MatrixUtils.PositionFromMatrix(poseMatrix);
        trackableGameObject.transform.rotation = MatrixUtils.QuaternionFromMatrix(poseMatrix);
        trackableGameObject.transform.localScale = MatrixUtils.ScaleFromMatrix(poseMatrix);
    }
}

Tracking 모드 변경

Object Tracker는 NORMAL_TRACKING, EXTENDED_TRACKING 모드가 있습니다.

기본 설정은 EXTENDED_TRACKING 모드 입니다.

  • EXTENDED_TRACKING: 학습한 오브젝트를 넘어서 주변 환경까지 실시간으로 학습하여 확장 추적합니다. 현재 카메라 프레임에 오브젝트의 특징점이 충분히 잡히지 않을 때에도 주변 환경을 통해 오브젝트의 위치를 추정할 수 있습니다.
TrackerManager.GetInstance().SetTrackingOption(TrackerManager.TrackingOption.EXTENDED_TRACKING);
  • NORMAL_TRACKING: 학습한 오브젝트만 추적합니다.
TrackerManager.GetInstance().SetTrackingOption(TrackerManager.TrackingOption.NORMAL_TRACKING);