@@ -69,6 +69,10 @@ public class MotionTrackingActivity extends Activity implements View.OnClickList
6969 private boolean mIsAutoRecovery ;
7070 private MTGLRenderer mRenderer ;
7171 private GLSurfaceView mGLView ;
72+ private boolean mIsProcessing = false ;
73+ private TangoPoseData mPose ;
74+ private static final int UPDATE_INTERVAL_MS = 100 ;
75+ public static Object sharedLock = new Object ();
7276
7377 @ Override
7478 protected void onCreate (Bundle savedInstanceState ) {
@@ -106,7 +110,6 @@ protected void onCreate(Bundle savedInstanceState) {
106110 mRenderer = new MTGLRenderer ();
107111 mGLView .setEGLContextClientVersion (2 );
108112 mGLView .setRenderer (mRenderer );
109- mGLView .setRenderMode (GLSurfaceView .RENDERMODE_WHEN_DIRTY );
110113
111114 // Instantiate the Tango service
112115 mTango = new Tango (this );
@@ -137,7 +140,7 @@ protected void onCreate(Bundle savedInstanceState) {
137140
138141 // Display the library version for debug purposes
139142 mTangoServiceVersionTextView .setText (mConfig .getString ("tango_service_library_version" ));
140-
143+ startUIThread ();
141144 }
142145
143146 /**
@@ -147,8 +150,7 @@ protected void onCreate(Bundle savedInstanceState) {
147150 private void setTangoListeners () {
148151 // Lock configuration and connect to Tango
149152 // Select coordinate frame pair
150- final ArrayList <TangoCoordinateFramePair > framePairs =
151- new ArrayList <TangoCoordinateFramePair >();
153+ final ArrayList <TangoCoordinateFramePair > framePairs = new ArrayList <TangoCoordinateFramePair >();
152154 framePairs .add (new TangoCoordinateFramePair (
153155 TangoPoseData .COORDINATE_FRAME_START_OF_SERVICE ,
154156 TangoPoseData .COORDINATE_FRAME_DEVICE ));
@@ -157,55 +159,30 @@ private void setTangoListeners() {
157159
158160 @ Override
159161 public void onPoseAvailable (final TangoPoseData pose ) {
160- // Log whenever Motion Tracking enters a n invalid state
161- if (!mIsAutoRecovery && (pose .statusCode == TangoPoseData .POSE_INVALID )) {
162- Log .w (TAG , "Invalid State" );
163- }
164- if (mPreviousPoseStatus != pose .statusCode ) {
165- count = 0 ;
166- }
167- count ++;
168- mPreviousPoseStatus = pose .statusCode ;
169- mDeltaTime = (float ) (pose .timestamp - mPreviousTimeStamp ) * SECS_TO_MILLISECS ;
170- mPreviousTimeStamp = (float ) pose .timestamp ;
171- // Update the OpenGL renderable objects with the new Tango Pose
172- // data
173- float [] translation = pose .getTranslationAsFloats ();
174- mRenderer .getTrajectory ().updateTrajectory (translation );
175- mRenderer .getModelMatCalculator ().updateModelMatrix (translation ,
176- pose .getRotationAsFloats ());
177- mRenderer .updateViewMatrix ();
178- mGLView .requestRender ();
179-
180- // Update the UI with TangoPose information
181- runOnUiThread (new Runnable () {
182- @ Override
183- public void run () {
184- DecimalFormat threeDec = new DecimalFormat ("0.000" );
185- String translationString = "[" + threeDec .format (pose .translation [0 ])
186- + ", " + threeDec .format (pose .translation [1 ]) + ", "
187- + threeDec .format (pose .translation [2 ]) + "] " ;
188- String quaternionString = "[" + threeDec .format (pose .rotation [0 ]) + ", "
189- + threeDec .format (pose .rotation [1 ]) + ", "
190- + threeDec .format (pose .rotation [2 ]) + ", "
191- + threeDec .format (pose .rotation [3 ]) + "] " ;
192-
193- // Display pose data on screen in TextViews
194- mPoseTextView .setText (translationString );
195- mQuatTextView .setText (quaternionString );
196- mPoseCountTextView .setText (Integer .toString (count ));
197- mDeltaTextView .setText (threeDec .format (mDeltaTime ));
198- if (pose .statusCode == TangoPoseData .POSE_VALID ) {
199- mPoseStatusTextView .setText (R .string .pose_valid );
200- } else if (pose .statusCode == TangoPoseData .POSE_INVALID ) {
201- mPoseStatusTextView .setText (R .string .pose_invalid );
202- } else if (pose .statusCode == TangoPoseData .POSE_INITIALIZING ) {
203- mPoseStatusTextView .setText (R .string .pose_initializing );
204- } else if (pose .statusCode == TangoPoseData .POSE_UNKNOWN ) {
205- mPoseStatusTextView .setText (R .string .pose_unknown );
206- }
162+ //Make sure to have atomic access to Tango Pose Data so that
163+ //render loop doesn't interfere while Pose call back is updating
164+ // the data.
165+ synchronized (sharedLock ) {
166+ mPose = pose ;
167+ mDeltaTime = (float ) (pose .timestamp - mPreviousTimeStamp ) * SECS_TO_MILLISECS ;
168+ mPreviousTimeStamp = (float ) pose .timestamp ;
169+ // Log whenever Motion Tracking enters an invalid state
170+ if (!mIsAutoRecovery && (pose .statusCode == TangoPoseData .POSE_INVALID )) {
171+ Log .w (TAG , "Invalid State" );
207172 }
208- });
173+ if (mPreviousPoseStatus != pose .statusCode ) {
174+ count = 0 ;
175+ }
176+ count ++;
177+ mPreviousPoseStatus = pose .statusCode ;
178+ // Update the OpenGL renderable objects with the new Tango Pose
179+ // data
180+ float [] translation = pose .getTranslationAsFloats ();
181+ mRenderer .getTrajectory ().updateTrajectory (translation );
182+ mRenderer .getModelMatCalculator ().updateModelMatrix (translation ,
183+ pose .getRotationAsFloats ());
184+ mRenderer .updateViewMatrix ();
185+ }
209186 }
210187
211188 @ Override
@@ -302,7 +279,10 @@ public void onClick(View v) {
302279 public boolean onTouchEvent (MotionEvent event ) {
303280 return mRenderer .onTouchEvent (event );
304281 }
305-
282+
283+ /**
284+ * Setup the extrinsics of the device.
285+ */
306286 private void setUpExtrinsics () {
307287 // Get device to imu matrix.
308288 TangoPoseData device2IMUPose = new TangoPoseData ();
@@ -322,4 +302,64 @@ private void setUpExtrinsics() {
322302 mRenderer .getModelMatCalculator ().SetColorCamera2IMUMatrix (
323303 color2IMUPose .getTranslationAsFloats (), color2IMUPose .getRotationAsFloats ());
324304 }
305+ /**
306+ * Create a separate thread to update Log information on UI at the specified
307+ * interval of UPDATE_INTERVAL_MS. This function also makes sure to have access
308+ * to the mPose atomically.
309+ */
310+ private void startUIThread () {
311+ new Thread (new Runnable () {
312+ DecimalFormat threeDec = new DecimalFormat ("00.000" );
313+ @ Override
314+ public void run () {
315+ while (true ) {
316+ try {
317+ Thread .sleep (UPDATE_INTERVAL_MS );
318+ runOnUiThread (new Runnable () {
319+ @ Override
320+ public void run () {
321+ try {
322+ synchronized (sharedLock ) {
323+ if (mPose == null ) {
324+ return ;
325+ }
326+
327+ String translationString = "["
328+ + threeDec .format (mPose .translation [0 ]) + ", "
329+ + threeDec .format (mPose .translation [1 ]) + ", "
330+ + threeDec .format (mPose .translation [2 ]) + "] " ;
331+ String quaternionString = "["
332+ + threeDec .format (mPose .rotation [0 ]) + ", "
333+ + threeDec .format (mPose .rotation [1 ]) + ", "
334+ + threeDec .format (mPose .rotation [2 ]) + ", "
335+ + threeDec .format (mPose .rotation [3 ]) + "] " ;
336+
337+ // Display pose data on screen in TextViews
338+ mPoseTextView .setText (translationString );
339+ mQuatTextView .setText (quaternionString );
340+ mPoseCountTextView .setText (Integer .toString (count ));
341+ mDeltaTextView .setText (threeDec .format (mDeltaTime ));
342+ if (mPose .statusCode == TangoPoseData .POSE_VALID ) {
343+ mPoseStatusTextView .setText (R .string .pose_valid );
344+ } else if (mPose .statusCode == TangoPoseData .POSE_INVALID ) {
345+ mPoseStatusTextView .setText (R .string .pose_invalid );
346+ } else if (mPose .statusCode == TangoPoseData .POSE_INITIALIZING ) {
347+ mPoseStatusTextView .setText (R .string .pose_initializing );
348+ } else if (mPose .statusCode == TangoPoseData .POSE_UNKNOWN ) {
349+ mPoseStatusTextView .setText (R .string .pose_unknown );
350+ }
351+ }
352+ } catch (NullPointerException e ) {
353+ e .printStackTrace ();
354+ }
355+ }
356+ });
357+
358+ } catch (InterruptedException e ) {
359+ e .printStackTrace ();
360+ }
361+ }
362+ }
363+ }).start ();
364+ }
325365}
0 commit comments