diff --git a/AreaLearningJava/libs/tango_java_lib.jar b/AreaLearningJava/libs/tango_java_lib.jar index ff61d2f7..497d5073 100644 Binary files a/AreaLearningJava/libs/tango_java_lib.jar and b/AreaLearningJava/libs/tango_java_lib.jar differ diff --git a/AreaLearningJava/src/com/projecttango/experiments/javaarealearning/ALRenderer.java b/AreaLearningJava/src/com/projecttango/experiments/javaarealearning/ALRenderer.java index 1b25ce0c..b5ed969c 100644 --- a/AreaLearningJava/src/com/projecttango/experiments/javaarealearning/ALRenderer.java +++ b/AreaLearningJava/src/com/projecttango/experiments/javaarealearning/ALRenderer.java @@ -30,14 +30,13 @@ import com.projecttango.tangoutils.renderables.Trajectory; /** - * OpenGL rendering class for the AreaLearningActivity API sample. This class manages - * the objects visible in the OpenGL view which are the {@link CameraFrustum}, - * {@link CameraFrustumAndAxis}, {@link Trajectory}, and the {@link Grid}. These - * objects are implemented in the TangoUtils library in the package - * {@link com.projecttango.tangoutils.renderables}. + * OpenGL rendering class for the AreaLearningActivity API sample. This class manages the objects + * visible in the OpenGL view which are the {@link CameraFrustum}, {@link CameraFrustumAndAxis}, + * {@link Trajectory}, and the {@link Grid}. These objects are implemented in the TangoUtils library + * in the package {@link com.projecttango.tangoutils.renderables}. * - * This class receives also handles the user-selected camera view, which can be - * 1st person, 3rd person, or top-down. + * This class receives also handles the user-selected camera view, which can be 1st person, 3rd + * person, or top-down. */ public class ALRenderer extends Renderer implements GLSurfaceView.Renderer { @@ -57,33 +56,32 @@ public void onSurfaceCreated(GL10 gl, EGLConfig config) { mFloorGrid = new Grid(); mCameraFrustumAndAxis = new CameraFrustumAndAxis(); mGreenTrajectory = new Trajectory(3); - mGreenTrajectory.setColor( - new float[] { 0.39f, 0.56f, 0.03f, 1.0f}); + mGreenTrajectory.setColor(new float[] { 0.39f, 0.56f, 0.03f, 1.0f }); mBlueTrajectory = new Trajectory(3); - mBlueTrajectory.setColor( - new float[] { 0.22f, 0.28f, 0.67f, 1.0f}); + mBlueTrajectory.setColor(new float[] { 0.22f, 0.28f, 0.67f, 1.0f }); // Construct the initial view matrix Matrix.setIdentityM(mViewMatrix, 0); Matrix.setLookAtM(mViewMatrix, 0, 5f, 5f, 5f, 0f, 0f, 0f, 0f, 1f, 0f); - mCameraFrustumAndAxis.setModelMatrix(getModelMatCalculator() - .getModelMatrix()); + mCameraFrustumAndAxis.setModelMatrix(getModelMatCalculator().getModelMatrix()); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { GLES20.glViewport(0, 0, width, height); mCameraAspect = (float) width / height; - Matrix.perspectiveM(mProjectionMatrix, 0, THIRD_PERSON_FOV, - mCameraAspect, CAMERA_NEAR, CAMERA_FAR); + Matrix.perspectiveM(mProjectionMatrix, 0, THIRD_PERSON_FOV, mCameraAspect, CAMERA_NEAR, + CAMERA_FAR); } @Override public void onDrawFrame(GL10 gl) { - GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); - mGreenTrajectory.draw(getViewMatrix(), mProjectionMatrix); - mBlueTrajectory.draw(getViewMatrix(), mProjectionMatrix); - mFloorGrid.draw(getViewMatrix(), mProjectionMatrix); - mCameraFrustumAndAxis.draw(getViewMatrix(), mProjectionMatrix); + synchronized (AreaLearningActivity.sharedLock) { + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); + mGreenTrajectory.draw(getViewMatrix(), mProjectionMatrix); + mBlueTrajectory.draw(getViewMatrix(), mProjectionMatrix); + mFloorGrid.draw(getViewMatrix(), mProjectionMatrix); + mCameraFrustumAndAxis.draw(getViewMatrix(), mProjectionMatrix); + } } public CameraFrustum getCameraFrustum() { @@ -97,7 +95,7 @@ public CameraFrustumAndAxis getCameraFrustumAndAxis() { public Trajectory getBlueTrajectory() { return mBlueTrajectory; } - + public Trajectory getGreenTrajectory() { return mGreenTrajectory; } diff --git a/AreaLearningJava/src/com/projecttango/experiments/javaarealearning/AreaLearningActivity.java b/AreaLearningJava/src/com/projecttango/experiments/javaarealearning/AreaLearningActivity.java index f9bc013e..89774870 100644 --- a/AreaLearningJava/src/com/projecttango/experiments/javaarealearning/AreaLearningActivity.java +++ b/AreaLearningJava/src/com/projecttango/experiments/javaarealearning/AreaLearningActivity.java @@ -52,7 +52,8 @@ * and propagation of Tango pose data to OpenGL and Layout views. OpenGL rendering logic is * delegated to the {@link ALRenderer} class. */ -public class AreaLearningActivity extends Activity implements View.OnClickListener, SetNameCommunicator { +public class AreaLearningActivity extends Activity implements View.OnClickListener, + SetNameCommunicator { private static final String TAG = AreaLearningActivity.class.getSimpleName(); private static final int SECONDS_TO_MILLI = 1000; @@ -105,6 +106,11 @@ public class AreaLearningActivity extends Activity implements View.OnClickListen private ALRenderer mRenderer; private GLSurfaceView mGLView; + private TangoPoseData[] mPoses; + private static final int UPDATE_INTERVAL_MS = 100; + private static final DecimalFormat threeDec = new DecimalFormat("00.000"); + public static Object sharedLock = new Object(); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -160,7 +166,6 @@ protected void onCreate(Bundle savedInstanceState) { mRenderer = new ALRenderer(); mGLView.setEGLContextClientVersion(2); mGLView.setRenderer(mRenderer); - mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // Instantiate the Tango service mTango = new Tango(this); @@ -170,6 +175,8 @@ protected void onCreate(Bundle savedInstanceState) { mIsLearningMode = intent.getBooleanExtra(ALStartActivity.USE_AREA_LEARNING, false); mIsConstantSpaceRelocalize = intent.getBooleanExtra(ALStartActivity.LOAD_ADF, false); setTangoConfig(); + mPoses = new TangoPoseData[3]; + startUIThread(); } private void setTangoConfig() { @@ -243,32 +250,85 @@ public void run() { @Override public void onPoseAvailable(TangoPoseData pose) { - - // Update the text views with Pose info. - updateTextViewWith(pose); - float[] translation = pose.getTranslationAsFloats(); - boolean updateRenderer = false; - if (mIsRelocalized) { + // Make sure to have atomic access to Tango Data so that + // render loop doesn't interfere while Pose call back is updating + // the data. + synchronized (sharedLock) { + float[] translation = pose.getTranslationAsFloats(); + boolean updateRenderer = false; + + // Check for Device wrt ADF pose, Device wrt Start of Service pose, + // Start of Service wrt ADF pose(This pose determines if device + // the is relocalized or not). if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_DEVICE) { - updateRenderer = true; - mRenderer.getGreenTrajectory().updateTrajectory(translation); - } - } else { - if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE + mPoses[0] = pose; + if (mAdf2DevicePreviousPoseStatus != pose.statusCode) { + // Set the count to zero when status code changes. + mAdf2DevicePoseCount = 0; + } + mAdf2DevicePreviousPoseStatus = pose.statusCode; + mAdf2DevicePoseCount++; + // Calculate time difference between current and last available Device wrt + // ADF pose. + mAdf2DevicePoseDelta = (pose.timestamp - mAdf2DevicePreviousPoseTimeStamp) + * SECONDS_TO_MILLI; + mAdf2DevicePreviousPoseTimeStamp = pose.timestamp; + if (mIsRelocalized) { + updateRenderer = true; + mRenderer.getGreenTrajectory().updateTrajectory(translation); + } + } else if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_DEVICE) { - updateRenderer = true; - mRenderer.getBlueTrajectory().updateTrajectory(translation); + mPoses[1] = pose; + if (mStart2DevicePreviousPoseStatus != pose.statusCode) { + // Set the count to zero when status code changes. + mStart2DevicePoseCount = 0; + } + mStart2DevicePreviousPoseStatus = pose.statusCode; + mStart2DevicePoseCount++; + // Calculate time difference between current and last available Device wrt + // SS pose. + mStart2DevicePoseDelta = (pose.timestamp - mStart2DevicePreviousPoseTimeStamp) + * SECONDS_TO_MILLI; + mStart2DevicePreviousPoseTimeStamp = pose.timestamp; + if (!mIsRelocalized) { + updateRenderer = true; + + synchronized (mRenderer.getBlueTrajectory()) { + mRenderer.getBlueTrajectory().updateTrajectory(translation); + } + } + } else if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION + && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE) { + mPoses[2] = pose; + if (mAdf2StartPreviousPoseStatus != pose.statusCode) { + // Set the count to zero when status code changes. + mAdf2StartPoseCount = 0; + } + mAdf2StartPreviousPoseStatus = pose.statusCode; + mAdf2StartPoseCount++; + // Calculate time difference between current and last available SS wrt ADF + // pose. + mAdf2StartPoseDelta = (pose.timestamp - mAdf2StartPreviousPoseTimeStamp) + * SECONDS_TO_MILLI; + mAdf2StartPreviousPoseTimeStamp = pose.timestamp; + if (pose.statusCode == TangoPoseData.POSE_VALID) { + mIsRelocalized = true; + // Set the color to green + } else { + mIsRelocalized = false; + // Set the color blue + } } - } - // Update the trajectory, model matrix, and view matrix, then - // render the scene again - if (updateRenderer) { - mRenderer.getModelMatCalculator().updateModelMatrix(translation, - pose.getRotationAsFloats()); - mRenderer.updateViewMatrix(); - mGLView.requestRender(); + // Update the trajectory, model matrix, and view matrix, then + // render the scene again + if (updateRenderer) { + mRenderer.getModelMatCalculator().updateModelMatrix(translation, + pose.getRotationAsFloats()); + mRenderer.updateViewMatrix(); + } } } @@ -328,84 +388,54 @@ public void onSetName(String name, String uuids) { /** * Updates the text view in UI screen with the Pose. Each pose is associated with Target and - * Base Frame. We need to check for that pair ad update our views accordingly. + * Base Frame. We need to check for that pair and update our views accordingly. * * @param pose */ - private void updateTextViewWith(final TangoPoseData pose) { - final DecimalFormat threeDec = new DecimalFormat("0.000"); - runOnUiThread(new Runnable() { - @Override - public void run() { - String translationString = "[" + threeDec.format(pose.translation[0]) + "," - + threeDec.format(pose.translation[1]) + "," - + threeDec.format(pose.translation[2]) + "] "; - - String quaternionString = "[" + threeDec.format(pose.rotation[0]) + "," - + threeDec.format(pose.rotation[1]) + "," - + threeDec.format(pose.rotation[2]) + "," - + threeDec.format(pose.rotation[3]) + "] "; - - if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION - && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_DEVICE) { - if (mAdf2DevicePreviousPoseStatus != pose.statusCode) { - mAdf2DevicePoseCount = 0; - } - mAdf2DevicePreviousPoseStatus = pose.statusCode; - mAdf2DevicePoseCount++; - mAdf2DevicePoseDelta = (pose.timestamp - mAdf2DevicePreviousPoseTimeStamp) - * SECONDS_TO_MILLI; - mAdf2DevicePreviousPoseTimeStamp = pose.timestamp; - mAdf2DeviceTranslationTextView.setText(translationString); - mAdf2DeviceQuatTextView.setText(quaternionString); - mAdf2DevicePoseStatusTextView.setText(getPoseStatus(pose)); - mAdf2DevicePoseCountTextView.setText(Integer.toString(mAdf2DevicePoseCount)); - mAdf2DevicePoseDeltaTextView.setText(threeDec.format(mAdf2DevicePoseDelta)); - } + private void updateTextViews() { + if (mPoses[0] != null + && mPoses[0].baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION + && mPoses[0].targetFrame == TangoPoseData.COORDINATE_FRAME_DEVICE) { + mAdf2DeviceTranslationTextView.setText(getTranslationString(mPoses[0])); + mAdf2DeviceQuatTextView.setText(getQuaternionString(mPoses[0])); + mAdf2DevicePoseStatusTextView.setText(getPoseStatus(mPoses[0])); + mAdf2DevicePoseCountTextView.setText(Integer.toString(mAdf2DevicePoseCount)); + mAdf2DevicePoseDeltaTextView.setText(threeDec.format(mAdf2DevicePoseDelta)); + } - if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE - && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_DEVICE) { - if (mStart2DevicePreviousPoseStatus != pose.statusCode) { - mStart2DevicePoseCount = 0; - } - mStart2DevicePreviousPoseStatus = pose.statusCode; - mStart2DevicePoseCount++; - mStart2DevicePoseDelta = (pose.timestamp - mStart2DevicePreviousPoseTimeStamp) - * SECONDS_TO_MILLI; - mStart2DevicePreviousPoseTimeStamp = pose.timestamp; - mStart2DeviceTranslationTextView.setText(translationString); - mStart2DeviceQuatTextView.setText(quaternionString); - mStart2DevicePoseStatusTextView.setText(getPoseStatus(pose)); - mStart2DevicePoseCountTextView - .setText(Integer.toString(mStart2DevicePoseCount)); - mStart2DevicePoseDeltaTextView.setText(threeDec.format(mStart2DevicePoseDelta)); - } + if (mPoses[1] != null + && mPoses[1].baseFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE + && mPoses[1].targetFrame == TangoPoseData.COORDINATE_FRAME_DEVICE) { + mStart2DeviceTranslationTextView.setText(getTranslationString(mPoses[1])); + mStart2DeviceQuatTextView.setText(getQuaternionString(mPoses[1])); + mStart2DevicePoseStatusTextView.setText(getPoseStatus(mPoses[1])); + mStart2DevicePoseCountTextView.setText(Integer.toString(mStart2DevicePoseCount)); + mStart2DevicePoseDeltaTextView.setText(threeDec.format(mStart2DevicePoseDelta)); + } + + if (mPoses[2] != null + && mPoses[2].baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION + && mPoses[2].targetFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE) { + mAdf2StartTranslationTextView.setText(getTranslationString(mPoses[2])); + mAdf2StartQuatTextView.setText(getQuaternionString(mPoses[2])); + mAdf2StartPoseStatusTextView.setText(getPoseStatus(mPoses[2])); + mAdf2StartPoseCountTextView.setText(Integer.toString(mAdf2StartPoseCount)); + mAdf2StartPoseDeltaTextView.setText(threeDec.format(mAdf2StartPoseDelta)); + } + } + + private String getTranslationString(TangoPoseData pose) { + return "[" + threeDec.format(pose.translation[0]) + "," + + threeDec.format(pose.translation[1]) + "," + threeDec.format(pose.translation[2]) + + "] "; + + } + + private String getQuaternionString(TangoPoseData pose) { + return "[" + threeDec.format(pose.rotation[0]) + "," + threeDec.format(pose.rotation[1]) + + "," + threeDec.format(pose.rotation[2]) + "," + threeDec.format(pose.rotation[3]) + + "] "; - if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION - && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE) { - if (mAdf2StartPreviousPoseStatus != pose.statusCode) { - mAdf2StartPoseCount = 0; - } - mAdf2StartPreviousPoseStatus = pose.statusCode; - mAdf2StartPoseCount++; - mAdf2StartPoseDelta = (pose.timestamp - mAdf2StartPreviousPoseTimeStamp) - * SECONDS_TO_MILLI; - mAdf2StartPreviousPoseTimeStamp = pose.timestamp; - mAdf2StartTranslationTextView.setText(translationString); - mAdf2StartQuatTextView.setText(quaternionString); - mAdf2StartPoseStatusTextView.setText(getPoseStatus(pose)); - mAdf2StartPoseCountTextView.setText(Integer.toString(mAdf2StartPoseCount)); - mAdf2StartPoseDeltaTextView.setText(threeDec.format(mAdf2StartPoseDelta)); - if (pose.statusCode == TangoPoseData.POSE_VALID) { - mIsRelocalized = true; - // Set the color to green - } else { - mIsRelocalized = false; - // Set the color blue - } - } - } - }); } private String getPoseStatus(TangoPoseData pose) { @@ -486,4 +516,40 @@ public void onClick(View v) { public boolean onTouchEvent(MotionEvent event) { return mRenderer.onTouchEvent(event); } + + /** + * Create a separate thread to update Log information on UI at the specified interval of + * UPDATE_INTERVAL_MS. This function also makes sure to have access to the mPoses atomically. + */ + private void startUIThread() { + new Thread(new Runnable() { + @Override + public void run() { + while (true) { + try { + Thread.sleep(UPDATE_INTERVAL_MS); + runOnUiThread(new Runnable() { + @Override + public void run() { + try { + synchronized (sharedLock) { + + if (mPoses == null) { + return; + } else { + updateTextViews(); + } + } + } catch (NullPointerException e) { + e.printStackTrace(); + } + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }).start(); + } } diff --git a/MotionTrackingJava/libs/tango_java_lib.jar b/MotionTrackingJava/libs/tango_java_lib.jar index ff61d2f7..497d5073 100644 Binary files a/MotionTrackingJava/libs/tango_java_lib.jar and b/MotionTrackingJava/libs/tango_java_lib.jar differ diff --git a/MotionTrackingJava/src/com/projecttango/experiments/javamotiontracking/MTGLRenderer.java b/MotionTrackingJava/src/com/projecttango/experiments/javamotiontracking/MTGLRenderer.java index 24db3022..735a18ad 100644 --- a/MotionTrackingJava/src/com/projecttango/experiments/javamotiontracking/MTGLRenderer.java +++ b/MotionTrackingJava/src/com/projecttango/experiments/javamotiontracking/MTGLRenderer.java @@ -75,10 +75,12 @@ public void onSurfaceChanged(GL10 gl, int width, int height) { @Override public void onDrawFrame(GL10 gl) { - GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); - mTrajectory.draw(getViewMatrix(), mProjectionMatrix); - mFloorGrid.draw(getViewMatrix(), mProjectionMatrix); - mCameraFrustumAndAxis.draw(getViewMatrix(), mProjectionMatrix); + synchronized (MotionTrackingActivity.sharedLock) { + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); + mTrajectory.draw(getViewMatrix(), mProjectionMatrix); + mFloorGrid.draw(getViewMatrix(), mProjectionMatrix); + mCameraFrustumAndAxis.draw(getViewMatrix(), mProjectionMatrix); + } } public CameraFrustum getCameraFrustum() { diff --git a/MotionTrackingJava/src/com/projecttango/experiments/javamotiontracking/MotionTrackingActivity.java b/MotionTrackingJava/src/com/projecttango/experiments/javamotiontracking/MotionTrackingActivity.java index 06daea2c..35e23ac9 100644 --- a/MotionTrackingJava/src/com/projecttango/experiments/javamotiontracking/MotionTrackingActivity.java +++ b/MotionTrackingJava/src/com/projecttango/experiments/javamotiontracking/MotionTrackingActivity.java @@ -69,6 +69,10 @@ public class MotionTrackingActivity extends Activity implements View.OnClickList private boolean mIsAutoRecovery; private MTGLRenderer mRenderer; private GLSurfaceView mGLView; + private boolean mIsProcessing = false; + private TangoPoseData mPose; + private static final int UPDATE_INTERVAL_MS = 100; + public static Object sharedLock = new Object(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -106,7 +110,6 @@ protected void onCreate(Bundle savedInstanceState) { mRenderer = new MTGLRenderer(); mGLView.setEGLContextClientVersion(2); mGLView.setRenderer(mRenderer); - mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // Instantiate the Tango service mTango = new Tango(this); @@ -137,7 +140,7 @@ protected void onCreate(Bundle savedInstanceState) { // Display the library version for debug purposes mTangoServiceVersionTextView.setText(mConfig.getString("tango_service_library_version")); - + startUIThread(); } /** @@ -147,8 +150,7 @@ protected void onCreate(Bundle savedInstanceState) { private void setTangoListeners() { // Lock configuration and connect to Tango // Select coordinate frame pair - final ArrayList framePairs = - new ArrayList(); + final ArrayList framePairs = new ArrayList(); framePairs.add(new TangoCoordinateFramePair( TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE, TangoPoseData.COORDINATE_FRAME_DEVICE)); @@ -157,55 +159,30 @@ private void setTangoListeners() { @Override public void onPoseAvailable(final TangoPoseData pose) { - // Log whenever Motion Tracking enters a n invalid state - if (!mIsAutoRecovery && (pose.statusCode == TangoPoseData.POSE_INVALID)) { - Log.w(TAG, "Invalid State"); - } - if (mPreviousPoseStatus != pose.statusCode) { - count = 0; - } - count++; - mPreviousPoseStatus = pose.statusCode; - mDeltaTime = (float) (pose.timestamp - mPreviousTimeStamp) * SECS_TO_MILLISECS; - mPreviousTimeStamp = (float) pose.timestamp; - // Update the OpenGL renderable objects with the new Tango Pose - // data - float[] translation = pose.getTranslationAsFloats(); - mRenderer.getTrajectory().updateTrajectory(translation); - mRenderer.getModelMatCalculator().updateModelMatrix(translation, - pose.getRotationAsFloats()); - mRenderer.updateViewMatrix(); - mGLView.requestRender(); - - // Update the UI with TangoPose information - runOnUiThread(new Runnable() { - @Override - public void run() { - DecimalFormat threeDec = new DecimalFormat("0.000"); - String translationString = "[" + threeDec.format(pose.translation[0]) - + ", " + threeDec.format(pose.translation[1]) + ", " - + threeDec.format(pose.translation[2]) + "] "; - String quaternionString = "[" + threeDec.format(pose.rotation[0]) + ", " - + threeDec.format(pose.rotation[1]) + ", " - + threeDec.format(pose.rotation[2]) + ", " - + threeDec.format(pose.rotation[3]) + "] "; - - // Display pose data on screen in TextViews - mPoseTextView.setText(translationString); - mQuatTextView.setText(quaternionString); - mPoseCountTextView.setText(Integer.toString(count)); - mDeltaTextView.setText(threeDec.format(mDeltaTime)); - if (pose.statusCode == TangoPoseData.POSE_VALID) { - mPoseStatusTextView.setText(R.string.pose_valid); - } else if (pose.statusCode == TangoPoseData.POSE_INVALID) { - mPoseStatusTextView.setText(R.string.pose_invalid); - } else if (pose.statusCode == TangoPoseData.POSE_INITIALIZING) { - mPoseStatusTextView.setText(R.string.pose_initializing); - } else if (pose.statusCode == TangoPoseData.POSE_UNKNOWN) { - mPoseStatusTextView.setText(R.string.pose_unknown); - } + //Make sure to have atomic access to Tango Pose Data so that + //render loop doesn't interfere while Pose call back is updating + // the data. + synchronized (sharedLock) { + mPose = pose; + mDeltaTime = (float) (pose.timestamp - mPreviousTimeStamp) * SECS_TO_MILLISECS; + mPreviousTimeStamp = (float) pose.timestamp; + // Log whenever Motion Tracking enters an invalid state + if (!mIsAutoRecovery && (pose.statusCode == TangoPoseData.POSE_INVALID)) { + Log.w(TAG, "Invalid State"); } - }); + if (mPreviousPoseStatus != pose.statusCode) { + count = 0; + } + count++; + mPreviousPoseStatus = pose.statusCode; + // Update the OpenGL renderable objects with the new Tango Pose + // data + float[] translation = pose.getTranslationAsFloats(); + mRenderer.getTrajectory().updateTrajectory(translation); + mRenderer.getModelMatCalculator().updateModelMatrix(translation, + pose.getRotationAsFloats()); + mRenderer.updateViewMatrix(); + } } @Override @@ -302,7 +279,10 @@ public void onClick(View v) { public boolean onTouchEvent(MotionEvent event) { return mRenderer.onTouchEvent(event); } - + + /** + * Setup the extrinsics of the device. + */ private void setUpExtrinsics() { // Get device to imu matrix. TangoPoseData device2IMUPose = new TangoPoseData(); @@ -322,4 +302,64 @@ private void setUpExtrinsics() { mRenderer.getModelMatCalculator().SetColorCamera2IMUMatrix( color2IMUPose.getTranslationAsFloats(), color2IMUPose.getRotationAsFloats()); } + /** + * Create a separate thread to update Log information on UI at the specified + * interval of UPDATE_INTERVAL_MS. This function also makes sure to have access + * to the mPose atomically. + */ + private void startUIThread() { + new Thread(new Runnable() { + DecimalFormat threeDec = new DecimalFormat("00.000"); + @Override + public void run() { + while (true) { + try { + Thread.sleep(UPDATE_INTERVAL_MS); + runOnUiThread(new Runnable() { + @Override + public void run() { + try { + synchronized (sharedLock) { + if (mPose == null) { + return; + } + + String translationString = "[" + + threeDec.format(mPose.translation[0]) + ", " + + threeDec.format(mPose.translation[1]) + ", " + + threeDec.format(mPose.translation[2]) + "] "; + String quaternionString = "[" + + threeDec.format(mPose.rotation[0]) + ", " + + threeDec.format(mPose.rotation[1]) + ", " + + threeDec.format(mPose.rotation[2]) + ", " + + threeDec.format(mPose.rotation[3]) + "] "; + + // Display pose data on screen in TextViews + mPoseTextView.setText(translationString); + mQuatTextView.setText(quaternionString); + mPoseCountTextView.setText(Integer.toString(count)); + mDeltaTextView.setText(threeDec.format(mDeltaTime)); + if (mPose.statusCode == TangoPoseData.POSE_VALID) { + mPoseStatusTextView.setText(R.string.pose_valid); + } else if (mPose.statusCode == TangoPoseData.POSE_INVALID) { + mPoseStatusTextView.setText(R.string.pose_invalid); + } else if (mPose.statusCode == TangoPoseData.POSE_INITIALIZING) { + mPoseStatusTextView.setText(R.string.pose_initializing); + } else if (mPose.statusCode == TangoPoseData.POSE_UNKNOWN) { + mPoseStatusTextView.setText(R.string.pose_unknown); + } + } + } catch (NullPointerException e) { + e.printStackTrace(); + } + } + }); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }).start(); + } } diff --git a/PointCloudJava/libs/tango_java_lib.jar b/PointCloudJava/libs/tango_java_lib.jar index ff61d2f7..497d5073 100644 Binary files a/PointCloudJava/libs/tango_java_lib.jar and b/PointCloudJava/libs/tango_java_lib.jar differ diff --git a/PointCloudJava/src/com/projecttango/experiments/javapointcloud/PCRenderer.java b/PointCloudJava/src/com/projecttango/experiments/javapointcloud/PCRenderer.java index 1f383778..a639e7fc 100644 --- a/PointCloudJava/src/com/projecttango/experiments/javapointcloud/PCRenderer.java +++ b/PointCloudJava/src/com/projecttango/experiments/javapointcloud/PCRenderer.java @@ -30,16 +30,14 @@ import com.projecttango.tangoutils.renderables.PointCloud; /** - * OpenGL rendering class for the Motion Tracking API sample. This class - * managers the objects visible in the OpenGL view which are the - * {@link CameraFrustum}, {@link PointCloud} and the {@link Grid}. These objects - * are implemented in the TangoUtils library in the package + * OpenGL rendering class for the Motion Tracking API sample. This class managers the objects + * visible in the OpenGL view which are the {@link CameraFrustum}, {@link PointCloud} and the + * {@link Grid}. These objects are implemented in the TangoUtils library in the package * {@link com.projecttango.tangoutils.renderables}. * - * This class receives {@link TangoPose} data from the {@link MotionTracking} - * class and updates the model and view matrices of the {@link Renderable} - * objects appropriately. It also handles the user-selected camera view, which - * can be 1st person, 3rd person, or top-down. + * This class receives {@link TangoPose} data from the {@link MotionTracking} class and updates the + * model and view matrices of the {@link Renderable} objects appropriately. It also handles the + * user-selected camera view, which can be 1st person, 3rd person, or top-down. * */ public class PCRenderer extends Renderer implements GLSurfaceView.Renderer { @@ -62,24 +60,27 @@ public void onSurfaceCreated(GL10 gl, EGLConfig config) { mCameraFrustumAndAxis = new CameraFrustumAndAxis(); Matrix.setIdentityM(mViewMatrix, 0); Matrix.setLookAtM(mViewMatrix, 0, 5f, 5f, 5f, 0f, 0f, 0f, 0f, 1f, 0f); - mCameraFrustumAndAxis.setModelMatrix(getModelMatCalculator() - .getModelMatrix()); + mCameraFrustumAndAxis.setModelMatrix(getModelMatCalculator().getModelMatrix()); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { GLES20.glViewport(0, 0, width, height); mCameraAspect = (float) width / height; - Matrix.perspectiveM(mProjectionMatrix, 0, CAMERA_FOV, mCameraAspect, - CAMERA_NEAR, CAMERA_FAR); + Matrix.perspectiveM(mProjectionMatrix, 0, CAMERA_FOV, mCameraAspect, CAMERA_NEAR, + CAMERA_FAR); } @Override public void onDrawFrame(GL10 gl) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); mGrid.draw(mViewMatrix, mProjectionMatrix); - mPointCloud.draw(mViewMatrix, mProjectionMatrix); - mCameraFrustumAndAxis.draw(mViewMatrix, mProjectionMatrix); + synchronized (PointCloudActivity.depthLock) { + mPointCloud.draw(mViewMatrix, mProjectionMatrix); + } + synchronized (PointCloudActivity.poseLock) { + mCameraFrustumAndAxis.draw(mViewMatrix, mProjectionMatrix); + } } public PointCloud getPointCloud() { diff --git a/PointCloudJava/src/com/projecttango/experiments/javapointcloud/PointCloudActivity.java b/PointCloudJava/src/com/projecttango/experiments/javapointcloud/PointCloudActivity.java index 2b1a0bd5..cb703c4c 100644 --- a/PointCloudJava/src/com/projecttango/experiments/javapointcloud/PointCloudActivity.java +++ b/PointCloudJava/src/com/projecttango/experiments/javapointcloud/PointCloudActivity.java @@ -47,10 +47,9 @@ import java.util.ArrayList; /** - * Main Activity class for the Point Cloud Sample. Handles the connection to the - * {@link Tango} service and propagation of Tango XyzIj data to OpenGL and - * Layout views. OpenGL rendering logic is delegated to the {@link PCrenderer} - * class. + * Main Activity class for the Point Cloud Sample. Handles the connection to the {@link Tango} + * service and propagation of Tango XyzIj data to OpenGL and Layout views. OpenGL rendering logic is + * delegated to the {@link PCrenderer} class. */ public class PointCloudActivity extends Activity implements OnClickListener { @@ -80,12 +79,18 @@ public class PointCloudActivity extends Activity implements OnClickListener { private int count; private int mPreviousPoseStatus; + private int mPointCount; private float mDeltaTime; private float mPosePreviousTimeStamp; private float mXyIjPreviousTimeStamp; private float mCurrentTimeStamp; + private float mPointCloudFrameDelta; private String mServiceVersion; private boolean mIsTangoServiceConnected; + private TangoPoseData mPose; + private static final int UPDATE_INTERVAL_MS = 100; + public static Object poseLock = new Object(); + public static Object depthLock = new Object(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -122,12 +127,10 @@ protected void onCreate(Bundle savedInstanceState) { mGLView = (GLSurfaceView) findViewById(R.id.gl_surface_view); mGLView.setEGLContextClientVersion(2); mGLView.setRenderer(mRenderer); - mGLView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); PackageInfo packageInfo; try { - packageInfo = this.getPackageManager().getPackageInfo( - this.getPackageName(), 0); + packageInfo = this.getPackageManager().getPackageInfo(this.getPackageName(), 0); mApplicationVersionTextView.setText(packageInfo.versionName); } catch (NameNotFoundException e) { e.printStackTrace(); @@ -137,6 +140,7 @@ protected void onCreate(Bundle savedInstanceState) { mServiceVersion = mConfig.getString("tango_service_library_version"); mTangoServiceVersionTextView.setText(mServiceVersion); mIsTangoServiceConnected = false; + startUIThread(); } @Override @@ -146,8 +150,7 @@ protected void onPause() { mTango.disconnect(); mIsTangoServiceConnected = false; } catch (TangoErrorException e) { - Toast.makeText(getApplicationContext(), R.string.TangoError, - Toast.LENGTH_SHORT).show(); + Toast.makeText(getApplicationContext(), R.string.TangoError, Toast.LENGTH_SHORT).show(); } } @@ -169,31 +172,27 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.i(TAG, "Triggered"); // Make sure the request was successful if (resultCode == RESULT_CANCELED) { - Toast.makeText(this, R.string.motiontrackingpermission, - Toast.LENGTH_LONG).show(); + Toast.makeText(this, R.string.motiontrackingpermission, Toast.LENGTH_LONG).show(); finish(); return; } try { setTangoListeners(); } catch (TangoErrorException e) { - Toast.makeText(this, R.string.TangoError, Toast.LENGTH_SHORT) - .show(); + Toast.makeText(this, R.string.TangoError, Toast.LENGTH_SHORT).show(); } catch (SecurityException e) { - Toast.makeText(getApplicationContext(), - R.string.motiontrackingpermission, Toast.LENGTH_SHORT) - .show(); + Toast.makeText(getApplicationContext(), R.string.motiontrackingpermission, + Toast.LENGTH_SHORT).show(); } try { mTango.connect(mConfig); mIsTangoServiceConnected = true; } catch (TangoOutOfDateException e) { - Toast.makeText(getApplicationContext(), - R.string.TangoOutOfDateException, Toast.LENGTH_SHORT) - .show(); - } catch (TangoErrorException e) { - Toast.makeText(getApplicationContext(), R.string.TangoError, + Toast.makeText(getApplicationContext(), R.string.TangoOutOfDateException, Toast.LENGTH_SHORT).show(); + } catch (TangoErrorException e) { + Toast.makeText(getApplicationContext(), R.string.TangoError, Toast.LENGTH_SHORT) + .show(); } setUpExtrinsics(); } @@ -236,12 +235,10 @@ private void setUpExtrinsics() { try { device2IMUPose = mTango.getPoseAtTime(0.0, framePair); } catch (TangoErrorException e) { - Toast.makeText(getApplicationContext(), R.string.TangoError, - Toast.LENGTH_SHORT).show(); + Toast.makeText(getApplicationContext(), R.string.TangoError, Toast.LENGTH_SHORT).show(); } mRenderer.getModelMatCalculator().SetDevice2IMUMatrix( - device2IMUPose.getTranslationAsFloats(), - device2IMUPose.getRotationAsFloats()); + device2IMUPose.getTranslationAsFloats(), device2IMUPose.getRotationAsFloats()); // Set color camera to imu matrix in Model Matrix Calculator. TangoPoseData color2IMUPose = new TangoPoseData(); @@ -251,18 +248,15 @@ private void setUpExtrinsics() { try { color2IMUPose = mTango.getPoseAtTime(0.0, framePair); } catch (TangoErrorException e) { - Toast.makeText(getApplicationContext(), R.string.TangoError, - Toast.LENGTH_SHORT).show(); + Toast.makeText(getApplicationContext(), R.string.TangoError, Toast.LENGTH_SHORT).show(); } mRenderer.getModelMatCalculator().SetColorCamera2IMUMatrix( - color2IMUPose.getTranslationAsFloats(), - color2IMUPose.getRotationAsFloats()); + color2IMUPose.getTranslationAsFloats(), color2IMUPose.getRotationAsFloats()); } private void setTangoListeners() { // Configure the Tango coordinate frame pair - final ArrayList framePairs = - new ArrayList(); + final ArrayList framePairs = new ArrayList(); framePairs.add(new TangoCoordinateFramePair( TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE, TangoPoseData.COORDINATE_FRAME_DEVICE)); @@ -271,108 +265,65 @@ private void setTangoListeners() { @Override public void onPoseAvailable(final TangoPoseData pose) { - mDeltaTime = (float) (pose.timestamp - mPosePreviousTimeStamp) - * SECS_TO_MILLISECS; - mPosePreviousTimeStamp = (float) pose.timestamp; - if (mPreviousPoseStatus != pose.statusCode) { - count = 0; - } - count++; - mPreviousPoseStatus = pose.statusCode; - mRenderer.getModelMatCalculator().updateModelMatrix( - pose.getTranslationAsFloats(), - pose.getRotationAsFloats()); - mRenderer.updateViewMatrix(); - mGLView.requestRender(); - // Update the UI with TangoPose information - runOnUiThread(new Runnable() { - @Override - public void run() { - DecimalFormat threeDec = new DecimalFormat("0.000"); - String translationString = "[" - + threeDec.format(pose.translation[0]) + ", " - + threeDec.format(pose.translation[1]) + ", " - + threeDec.format(pose.translation[2]) + "] "; - String quaternionString = "[" - + threeDec.format(pose.rotation[0]) + ", " - + threeDec.format(pose.rotation[1]) + ", " - + threeDec.format(pose.rotation[2]) + ", " - + threeDec.format(pose.rotation[3]) + "] "; - - // Display pose data on screen in TextViews - mPoseTextView.setText(translationString); - mQuatTextView.setText(quaternionString); - mPoseCountTextView.setText(Integer.toString(count)); - mDeltaTextView.setText(threeDec.format(mDeltaTime)); - if (pose.statusCode == TangoPoseData.POSE_VALID) { - mPoseStatusTextView.setText(R.string.pose_valid); - } else if (pose.statusCode == TangoPoseData.POSE_INVALID) { - mPoseStatusTextView.setText(R.string.pose_invalid); - } else if (pose.statusCode == TangoPoseData.POSE_INITIALIZING) { - mPoseStatusTextView - .setText(R.string.pose_initializing); - } else if (pose.statusCode == TangoPoseData.POSE_UNKNOWN) { - mPoseStatusTextView.setText(R.string.pose_unknown); - } + // Make sure to have atomic access to Tango Pose Data so that + // render loop doesn't interfere while Pose call back is updating + // the data. + synchronized (poseLock) { + mPose = pose; + // Calculate the delta time from previous pose. + mDeltaTime = (float) (pose.timestamp - mPosePreviousTimeStamp) + * SECS_TO_MILLISECS; + mPosePreviousTimeStamp = (float) pose.timestamp; + if (mPreviousPoseStatus != pose.statusCode) { + count = 0; } - }); + count++; + mPreviousPoseStatus = pose.statusCode; + mRenderer.getModelMatCalculator().updateModelMatrix( + pose.getTranslationAsFloats(), pose.getRotationAsFloats()); + mRenderer.updateViewMatrix(); + } } @Override public void onXyzIjAvailable(final TangoXyzIjData xyzIj) { - mCurrentTimeStamp = (float) xyzIj.timestamp; - final float frameDelta = (mCurrentTimeStamp - mXyIjPreviousTimeStamp) - * SECS_TO_MILLISECS; - mXyIjPreviousTimeStamp = mCurrentTimeStamp; - byte[] buffer = new byte[xyzIj.xyzCount * 3 * 4]; - FileInputStream fileStream = new FileInputStream( - xyzIj.xyzParcelFileDescriptor.getFileDescriptor()); - try { - fileStream.read(buffer, - xyzIj.xyzParcelFileDescriptorOffset, buffer.length); - fileStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - try { - TangoPoseData pointCloudPose = mTango.getPoseAtTime( - mCurrentTimeStamp, framePairs.get(0)); - - mRenderer.getPointCloud().UpdatePoints(buffer, - xyzIj.xyzCount); - mRenderer.getModelMatCalculator() - .updatePointCloudModelMatrix( - pointCloudPose.getTranslationAsFloats(), - pointCloudPose.getRotationAsFloats()); - mRenderer.getPointCloud().setModelMatrix( - mRenderer.getModelMatCalculator() - .getPointCloudModelMatrixCopy()); - } catch (TangoErrorException e) { - Toast.makeText(getApplicationContext(), - R.string.TangoError, Toast.LENGTH_SHORT).show(); - } catch (TangoInvalidException e) { - Toast.makeText(getApplicationContext(), - R.string.TangoError, Toast.LENGTH_SHORT).show(); - } - - // Must run UI changes on the UI thread. Running in the Tango - // service thread - // will result in an error. - runOnUiThread(new Runnable() { - DecimalFormat threeDec = new DecimalFormat("0.000"); - - @Override - public void run() { - // Display number of points in the point cloud - mPointCountTextView.setText(Integer - .toString(xyzIj.xyzCount)); - mFrequencyTextView.setText("" - + threeDec.format(frameDelta)); - mAverageZTextView.setText("" - + threeDec.format(mRenderer.getPointCloud() - .getAverageZ())); + // Make sure to have atomic access to TangoXyzIjData so that + // render loop doesn't interfere while onXYZijAvailable callback is updating + // the point cloud data. + synchronized (depthLock) { + mCurrentTimeStamp = (float) xyzIj.timestamp; + mPointCloudFrameDelta = (mCurrentTimeStamp - mXyIjPreviousTimeStamp) + * SECS_TO_MILLISECS; + mXyIjPreviousTimeStamp = mCurrentTimeStamp; + mPointCount = xyzIj.xyzCount; + byte[] buffer = new byte[xyzIj.xyzCount * 3 * 4]; + // TODO: Use getXYZBuffer() call instead of parcel file directly. + FileInputStream fileStream = new FileInputStream(xyzIj.xyzParcelFileDescriptor + .getFileDescriptor()); + try { + fileStream.read(buffer, xyzIj.xyzParcelFileDescriptorOffset, buffer.length); + fileStream.close(); + } catch (IOException e) { + e.printStackTrace(); } - }); + try { + TangoPoseData pointCloudPose = mTango.getPoseAtTime(mCurrentTimeStamp, + framePairs.get(0)); + + mRenderer.getPointCloud().UpdatePoints(buffer, xyzIj.xyzCount); + mRenderer.getModelMatCalculator().updatePointCloudModelMatrix( + pointCloudPose.getTranslationAsFloats(), + pointCloudPose.getRotationAsFloats()); + mRenderer.getPointCloud().setModelMatrix( + mRenderer.getModelMatCalculator().getPointCloudModelMatrixCopy()); + } catch (TangoErrorException e) { + Toast.makeText(getApplicationContext(), R.string.TangoError, + Toast.LENGTH_SHORT).show(); + } catch (TangoInvalidException e) { + Toast.makeText(getApplicationContext(), R.string.TangoError, + Toast.LENGTH_SHORT).show(); + } + } } @Override @@ -380,8 +331,7 @@ public void onTangoEvent(final TangoEvent event) { runOnUiThread(new Runnable() { @Override public void run() { - mTangoEventTextView.setText(event.eventKey + ": " - + event.eventValue); + mTangoEventTextView.setText(event.eventKey + ": " + event.eventValue); } }); } @@ -392,4 +342,69 @@ public void onFrameAvailable(int cameraId) { } }); } + + /** + * Create a separate thread to update Log information on UI at the specified interval of + * UPDATE_INTERVAL_MS. This function also makes sure to have access to the mPose atomically. + */ + private void startUIThread() { + new Thread(new Runnable() { + final DecimalFormat threeDec = new DecimalFormat("0.000"); + + @Override + public void run() { + while (true) { + try { + Thread.sleep(UPDATE_INTERVAL_MS); + // Update the UI with TangoPose information + runOnUiThread(new Runnable() { + @Override + public void run() { + synchronized (poseLock) { + if (mPose == null) { + return; + } + String translationString = "[" + + threeDec.format(mPose.translation[0]) + ", " + + threeDec.format(mPose.translation[1]) + ", " + + threeDec.format(mPose.translation[2]) + "] "; + String quaternionString = "[" + + threeDec.format(mPose.rotation[0]) + ", " + + threeDec.format(mPose.rotation[1]) + ", " + + threeDec.format(mPose.rotation[2]) + ", " + + threeDec.format(mPose.rotation[3]) + "] "; + + // Display pose data on screen in TextViews + mPoseTextView.setText(translationString); + mQuatTextView.setText(quaternionString); + mPoseCountTextView.setText(Integer.toString(count)); + mDeltaTextView.setText(threeDec.format(mDeltaTime)); + if (mPose.statusCode == TangoPoseData.POSE_VALID) { + mPoseStatusTextView.setText(R.string.pose_valid); + } else if (mPose.statusCode == TangoPoseData.POSE_INVALID) { + mPoseStatusTextView.setText(R.string.pose_invalid); + } else if (mPose.statusCode == TangoPoseData.POSE_INITIALIZING) { + mPoseStatusTextView.setText(R.string.pose_initializing); + } else if (mPose.statusCode == TangoPoseData.POSE_UNKNOWN) { + mPoseStatusTextView.setText(R.string.pose_unknown); + } + } + synchronized (depthLock) { + // Display number of points in the point cloud + mPointCountTextView.setText(Integer.toString(mPointCount)); + mFrequencyTextView.setText("" + + threeDec.format(mPointCloudFrameDelta)); + mAverageZTextView.setText("" + + threeDec.format(mRenderer.getPointCloud() + .getAverageZ())); + } + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }).start(); + } } diff --git a/PointCloudJava/src/com/projecttango/experiments/javapointcloud/package-info.java b/PointCloudJava/src/com/projecttango/experiments/javapointcloud/package-info.java index 06c2ca36..8e99deae 100644 --- a/PointCloudJava/src/com/projecttango/experiments/javapointcloud/package-info.java +++ b/PointCloudJava/src/com/projecttango/experiments/javapointcloud/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * A sample application to show how to get Point Cloud Data from Project Tango API + * A sample application to show hwo to get Point Cloud Data from Project Tango API * and display in world coordinates of Opengl ES2.0. */ package com.projecttango.experiments.javapointcloud; diff --git a/QuickstartJava/libs/tango_java_lib.jar b/QuickstartJava/libs/tango_java_lib.jar index ff61d2f7..497d5073 100644 Binary files a/QuickstartJava/libs/tango_java_lib.jar and b/QuickstartJava/libs/tango_java_lib.jar differ diff --git a/VideoOverlaySample/libs/tango_java_lib.jar b/VideoOverlaySample/libs/tango_java_lib.jar index ff61d2f7..497d5073 100644 Binary files a/VideoOverlaySample/libs/tango_java_lib.jar and b/VideoOverlaySample/libs/tango_java_lib.jar differ diff --git a/VideoOverlaySample/src/com/projecttango/videooverlaysample/MainActivity.java b/VideoOverlaySample/src/com/projecttango/videooverlaysample/MainActivity.java index 4411ee68..8a3f45d4 100644 --- a/VideoOverlaySample/src/com/projecttango/videooverlaysample/MainActivity.java +++ b/VideoOverlaySample/src/com/projecttango/videooverlaysample/MainActivity.java @@ -20,6 +20,7 @@ import android.app.Activity; import android.content.Intent; import android.os.Bundle; +import android.util.Log; import android.widget.Toast; import com.google.atap.tangoservice.Tango; @@ -69,6 +70,7 @@ private void startCameraPreview() { TangoCameraIntrinsics.TANGO_CAMERA_COLOR); TangoConfig config = mTango.getConfig(TangoConfig.CONFIG_TYPE_DEFAULT); mTango.connect(config); + ArrayList framePairs = new ArrayList(); mTango.connectListener(framePairs, new OnTangoUpdateListener() { @Override @@ -78,7 +80,8 @@ public void onPoseAvailable(TangoPoseData pose) { @Override public void onFrameAvailable(int cameraId) { - if (cameraId == TangoCameraIntrinsics.TANGO_CAMERA_COLOR) { + Log.e("Video Sample", "onFrameAvailable"); + if (cameraId == TangoCameraIntrinsics.TANGO_CAMERA_COLOR) {; tangoCameraPreview.onFrameAvailable(); } }