ARCoreSharedCamera.java
Go to the documentation of this file.
1 package com.introlab.rtabmap;
2 
3 import java.nio.ByteBuffer;
4 import java.nio.FloatBuffer;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.EnumSet;
8 import java.util.List;
9 import java.util.concurrent.atomic.AtomicBoolean;
10 
11 import com.google.ar.core.Anchor;
12 import com.google.ar.core.Camera;
13 import com.google.ar.core.CameraConfig;
14 import com.google.ar.core.CameraConfigFilter;
15 import com.google.ar.core.CameraIntrinsics;
16 import com.google.ar.core.Config;
17 import com.google.ar.core.Coordinates2d;
18 import com.google.ar.core.Frame;
19 import com.google.ar.core.PointCloud;
20 import com.google.ar.core.Pose;
21 import com.google.ar.core.Session;
22 import com.google.ar.core.SharedCamera;
23 import com.google.ar.core.TrackingState;
24 import com.google.ar.core.exceptions.CameraNotAvailableException;
25 import com.google.ar.core.exceptions.NotYetAvailableException;
26 import com.google.ar.core.exceptions.UnavailableException;
27 
28 import android.content.Context;
29 import android.graphics.ImageFormat;
30 import android.hardware.camera2.CameraAccessException;
31 import android.hardware.camera2.CameraCaptureSession;
32 import android.hardware.camera2.CameraCharacteristics;
33 import android.hardware.camera2.CameraDevice;
34 import android.hardware.camera2.CameraManager;
35 import android.hardware.camera2.CameraMetadata;
36 import android.hardware.camera2.CaptureFailure;
37 import android.hardware.camera2.CaptureRequest;
38 import android.hardware.camera2.TotalCaptureResult;
39 import android.media.Image;
40 import android.opengl.GLES20;
41 import android.opengl.GLSurfaceView;
42 import android.os.Handler;
43 import android.os.HandlerThread;
44 import android.support.annotation.NonNull;
45 import android.util.Log;
46 import android.view.Surface;
47 import android.widget.Toast;
48 
49 public class ARCoreSharedCamera {
50 
51  public static final String TAG = ARCoreSharedCamera.class.getSimpleName();
52 
53  private static final float[] QUAD_COORDS =
54  new float[] {
55  -1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f,
56  };
57 
58  private static RTABMapActivity mActivity;
60  mActivity = c;
61  }
62 
63  // Depth TOF Image.
64  // Use 240 * 180 for now, hardcoded for Huawei P30 Pro
65  private int depthWidth = 640;
66  private int depthHeight = 480;
67 
68  // GL Surface used to draw camera preview image.
69  public GLSurfaceView surfaceView;
70 
71  // ARCore session that supports camera sharing.
72  private Session sharedSession;
73 
74  private Pose odomPose = Pose.IDENTITY;
75 
76  // Camera capture session. Used by both non-AR and AR modes.
77  private CameraCaptureSession captureSession;
78 
79  // Reference to the camera system service.
80  private CameraManager cameraManager;
81 
82  // Camera device. Used by both non-AR and AR modes.
83  private CameraDevice cameraDevice;
84 
85  // Looper handler thread.
86  private HandlerThread backgroundThread;
87  // Looper handler.
88  private Handler backgroundHandler;
89 
90  // ARCore shared camera instance, obtained from ARCore session that supports sharing.
91  private SharedCamera sharedCamera;
92 
93  private Toast mToast = null;
94 
95  // Camera ID for the camera used by ARCore.
96  private String cameraId;
97  private String depthCameraId;
98 
101  private float[] depthIntrinsics = null;
102 
103  private AtomicBoolean mReady = new AtomicBoolean(false);
104 
105  // Camera preview capture request builder
106  private CaptureRequest.Builder previewCaptureRequestBuilder;
107 
108  private int cameraTextureId = -1;
109  private boolean firstFrameReceived = false;
110 
111  // Image reader that continuously processes CPU images.
113  private boolean mTOFAvailable = false;
114 
115  ByteBuffer mPreviousDepth = null;
116  double mPreviousDepthStamp = 0.0;
117  ByteBuffer mPreviousDepth2 = null;
118  double mPreviousDepthStamp2 = 0.0;
119 
120  public boolean isDepthSupported() {return mTOFAvailable;}
121 
122  public void setToast(Toast toast)
123  {
124  mToast = toast;
125  }
126 
127  // Camera device state callback.
128  private final CameraDevice.StateCallback cameraDeviceCallback =
129  new CameraDevice.StateCallback() {
130  @Override
131  public void onOpened(@NonNull CameraDevice cameraDevice) {
132  Log.d(TAG, "Camera device ID " + cameraDevice.getId() + " opened.");
135  }
136 
137  @Override
138  public void onClosed(@NonNull CameraDevice cameraDevice) {
139  Log.d(TAG, "Camera device ID " + cameraDevice.getId() + " closed.");
140  ARCoreSharedCamera.this.cameraDevice = null;
141  }
142 
143  @Override
144  public void onDisconnected(@NonNull CameraDevice cameraDevice) {
145  Log.w(TAG, "Camera device ID " + cameraDevice.getId() + " disconnected.");
146  cameraDevice.close();
147  ARCoreSharedCamera.this.cameraDevice = null;
148  }
149 
150  @Override
151  public void onError(@NonNull CameraDevice cameraDevice, int error) {
152  Log.e(TAG, "Camera device ID " + cameraDevice.getId() + " error " + error);
153  cameraDevice.close();
154  ARCoreSharedCamera.this.cameraDevice = null;
155  }
156  };
157 
158  // Repeating camera capture session state callback.
159  CameraCaptureSession.StateCallback cameraCaptureCallback =
160  new CameraCaptureSession.StateCallback() {
161 
162  // Called when the camera capture session is first configured after the app
163  // is initialized, and again each time the activity is resumed.
164  @Override
165  public void onConfigured(@NonNull CameraCaptureSession session) {
166  Log.d(TAG, "Camera capture session configured.");
167  captureSession = session;
169  }
170 
171  @Override
172  public void onSurfacePrepared(
173  @NonNull CameraCaptureSession session, @NonNull Surface surface) {
174  Log.d(TAG, "Camera capture surface prepared.");
175  }
176 
177  @Override
178  public void onReady(@NonNull CameraCaptureSession session) {
179  Log.d(TAG, "Camera capture session ready.");
180  }
181 
182  @Override
183  public void onActive(@NonNull CameraCaptureSession session) {
184  Log.d(TAG, "Camera capture session active.");
185  resumeARCore();
186  }
187 
188  @Override
189  public void onClosed(@NonNull CameraCaptureSession session) {
190  Log.d(TAG, "Camera capture session closed.");
191  }
192 
193  @Override
194  public void onConfigureFailed(@NonNull CameraCaptureSession session) {
195  Log.e(TAG, "Failed to configure camera capture session.");
196  }
197  };
198 
199  // Repeating camera capture session capture callback.
200  private final CameraCaptureSession.CaptureCallback captureSessionCallback =
201  new CameraCaptureSession.CaptureCallback() {
202 
203  @Override
204  public void onCaptureCompleted(
205  @NonNull CameraCaptureSession session,
206  @NonNull CaptureRequest request,
207  @NonNull TotalCaptureResult result) {
208  //Log.i(TAG, "onCaptureCompleted");
209  }
210 
211  //@Override // android 23
212  public void onCaptureBufferLost(
213  @NonNull CameraCaptureSession session,
214  @NonNull CaptureRequest request,
215  @NonNull Surface target,
216  long frameNumber) {
217  Log.e(TAG, "onCaptureBufferLost: " + frameNumber);
218  }
219 
220  @Override
221  public void onCaptureFailed(
222  @NonNull CameraCaptureSession session,
223  @NonNull CaptureRequest request,
224  @NonNull CaptureFailure failure) {
225  Log.e(TAG, "onCaptureFailed: " + failure.getFrameNumber() + " " + failure.getReason());
226  }
227 
228  @Override
229  public void onCaptureSequenceAborted(
230  @NonNull CameraCaptureSession session, int sequenceId) {
231  Log.e(TAG, "onCaptureSequenceAborted: " + sequenceId + " " + session);
232  }
233  };
234 
235  private void resumeARCore() {
236  // Ensure that session is valid before triggering ARCore resume. Handles the case where the user
237  // manually uninstalls ARCore while the app is paused and then resumes.
238  if (sharedSession == null) {
239  return;
240  }
241 
242  try {
243  Log.i(TAG, "Resume ARCore.");
244  // Resume ARCore.
245  sharedSession.resume();
246  // Set capture session callback while in AR mode.
248  } catch (CameraNotAvailableException e) {
249  Log.e(TAG, "Failed to resume ARCore session", e);
250  return;
251  }
252 
253  }
254 
255 
256  // Called when starting non-AR mode or switching to non-AR mode.
257  // Also called when app starts in AR mode, or resumes in AR mode.
258  private void setRepeatingCaptureRequest() {
259  try {
260  captureSession.setRepeatingRequest(
262  } catch (CameraAccessException e) {
263  Log.e(TAG, "Failed to set repeating request", e);
264  }
265  }
266 
267 
268  private void createCameraPreviewSession() {
269  Log.e(TAG, "createCameraPreviewSession: " + "starting camera preview session.");
270  try {
271  // Note that isGlAttached will be set to true in AR mode in onDrawFrame().
272  sharedSession.setCameraTextureName(cameraTextureId);
273 
274  // Create an ARCore compatible capture request using `TEMPLATE_RECORD`.
275  previewCaptureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
276 
277  // Build surfaces list, starting with ARCore provided surfaces.
278  List<Surface> surfaceList = sharedCamera.getArCoreSurfaces();
279  Log.e(TAG, " createCameraPreviewSession: " + "surfaceList: sharedCamera.getArCoreSurfaces(): " + surfaceList.size());
280 
281  // Add a CPU image reader surface. On devices that don't support CPU image access, the image
282  // may arrive significantly later, or not arrive at all.
283  if (mTOFAvailable && cameraId.compareTo(depthCameraId) == 0) surfaceList.add(mTOFImageReader.imageReader.getSurface());
284  // Surface list should now contain three surfacemReadymReadys:
285  // 0. sharedCamera.getSurfaceTexture()
286  // 1. …
287  // 2. depthImageReader.getSurface()
288 
289  // Add ARCore surfaces and CPU image surface targets.
290  for (Surface surface : surfaceList) {
291  previewCaptureRequestBuilder.addTarget(surface);
292  }
293 
294  // Wrap our callback in a shared camera callback.
295  CameraCaptureSession.StateCallback wrappedCallback = sharedCamera.createARSessionStateCallback(cameraCaptureCallback, backgroundHandler);
296 
297  // Create camera capture session for camera preview using ARCore wrapped callback.
298  cameraDevice.createCaptureSession(surfaceList, wrappedCallback, backgroundHandler);
299 
300  mReady.set(true);
301  } catch (CameraAccessException e) {
302  Log.e(TAG, "CameraAccessException", e);
303  }
304  }
305 
306  // Start background handler thread, used to run callbacks without blocking UI thread.
307  private void startBackgroundThread() {
308  backgroundThread = new HandlerThread("sharedCameraBackground");
309  backgroundThread.start();
310  backgroundHandler = new Handler(backgroundThread.getLooper());
312  }
313 
314  // Stop background handler thread.
315  private void stopBackgroundThread() {
316  if (backgroundThread != null) {
317  backgroundThread.quitSafely();
318  try {
319  backgroundThread.join();
320  backgroundThread = null;
321  backgroundHandler = null;
322  } catch (InterruptedException e) {
323  Log.e(TAG, "Interrupted while trying to join background handler thread", e);
324  }
325  }
327  }
328 
336  private static boolean contains(int[] modes, int mode) {
337  if (modes == null) {
338  return false;
339  }
340  for (int i : modes) {
341  if (i == mode) {
342  return true;
343  }
344  }
345  return false;
346  }
347 
348  // Perform various checks, then open camera device and create CPU image reader.
349  public boolean openCamera() {
350 
351  close();
352 
354 
355  if(cameraTextureId == -1)
356  {
357  int[] textures = new int[1];
358  GLES20.glGenTextures(1, textures, 0);
359  cameraTextureId = textures[0];
360  }
361 
362  Log.v(TAG, "Perform various checks, then open camera device and create CPU image reader.");
363  // Don't open camera if already opened.
364  if (cameraDevice != null) {
365  return false;
366  }
367 
368  if (sharedSession == null) {
369  try {
370  // Create ARCore session that supports camera sharing.
371  sharedSession = new Session(mActivity, EnumSet.of(Session.Feature.SHARED_CAMERA));
372  } catch (UnavailableException e) {
373  Log.e(TAG, "Failed to create ARCore session that supports camera sharing", e);
374  return false;
375  }
376 
377  // First obtain the session handle before getting the list of various camera configs.
378  // Create filter here with desired fps filters.
379  CameraConfigFilter cameraConfigFilter = new CameraConfigFilter(sharedSession);
380  CameraConfig[] cameraConfigs = sharedSession.getSupportedCameraConfigs(cameraConfigFilter).toArray(new CameraConfig[0]);
381  Log.i(TAG, "Size of supported CameraConfigs list is " + cameraConfigs.length);
382 
383  // Determine the highest and lowest CPU resolutions.
384  int highestResolutionIndex=-1;
385  int highestResolution = 0;
386  for(int i=0; i<cameraConfigs.length; ++i)
387  {
388  Log.i(TAG, "Camera ID: " + cameraConfigs[i].getCameraId());
389  Log.i(TAG, "Resolution: " + cameraConfigs[i].getImageSize().getWidth() + "x" + cameraConfigs[i].getImageSize().getHeight());
390  if(highestResolution == 0 || highestResolution < cameraConfigs[i].getImageSize().getWidth())
391  {
392  highestResolutionIndex = i;
393  highestResolution = cameraConfigs[i].getImageSize().getWidth();
394  }
395  }
396  if(highestResolutionIndex>=0)
397  {
398  //Log.i(TAG, "Setting camera resolution to " + cameraConfigs[highestResolutionIndex].getImageSize().getWidth() + "x" + cameraConfigs[highestResolutionIndex].getImageSize().getHeight());
399  //FIXME: Can we make it work to use HD rgb images? To avoid this error "CaptureRequest contains unconfigured Input/Output Surface!"
400  //sharedSession.setCameraConfig(cameraConfigs[highestResolutionIndex]);
401  }
402 
403  // Enable auto focus mode while ARCore is running.
404  Config config = sharedSession.getConfig();
405  config.setFocusMode(Config.FocusMode.FIXED);
406  config.setUpdateMode(Config.UpdateMode.BLOCKING);
407  config.setPlaneFindingMode(Config.PlaneFindingMode.DISABLED);
408  config.setLightEstimationMode(Config.LightEstimationMode.DISABLED);
409  config.setCloudAnchorMode(Config.CloudAnchorMode.DISABLED);
410  sharedSession.configure(config);
411 
412  }
413 
414  // Store the ARCore shared camera reference.
415  sharedCamera = sharedSession.getSharedCamera();
416  // Store the ID of the camera used by ARCore.
417  cameraId = sharedSession.getCameraConfig().getCameraId();
418 
419  Log.d(TAG, "Shared camera ID: " + cameraId);
420 
421  mTOFAvailable = false;
422 
423  // Store a reference to the camera system service.
424  cameraManager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
425 
426  depthCameraId = null;
427  // show all cameras
428  try {
429  // Find a CameraDevice that supports DEPTH16 captures, and configure state.
430  for (String tmpCameraId : cameraManager.getCameraIdList()) {
431  CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(tmpCameraId);
432 
433  Log.i(TAG, "Camera " + tmpCameraId + " extrinsics:");
434 
435  float[] translation = characteristics.get(CameraCharacteristics.LENS_POSE_TRANSLATION);
436  if(translation != null)
437  {
438  Log.i(TAG, String.format("Translation (x,y,z): %f,%f,%f", translation[0], translation[1], translation[2]));
439  }
440  float[] rotation = characteristics.get(CameraCharacteristics.LENS_POSE_ROTATION);
441  if(rotation != null)
442  {
443  Log.i(TAG, String.format("Rotation (qx,qy,qz,qw): %f,%f,%f,%f", rotation[0], rotation[1], rotation[2], rotation[3]));
444  }
445 
446  if(tmpCameraId.compareTo(cameraId)==0 && translation!=null && rotation!=null)
447  {
449  Log.i(TAG,"Set rgb extrinsics!");
450  }
451 
452  if (!contains(characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES), CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) ||
453  characteristics.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_FRONT) {
454  continue;
455  }
456  Log.i(TAG, "Camera " + tmpCameraId + " has depth output available");
457 
458  depthCameraId = tmpCameraId;
459  if(translation!=null && rotation != null)
460  {
462  Log.i(TAG,"Set depth extrinsics!");
463  }
464  depthIntrinsics = characteristics.get(CameraCharacteristics.LENS_INTRINSIC_CALIBRATION);
465  Log.i(TAG, String.format("Intrinsics (fx,fy,cx,cy,s): %f,%f,%f,%f,%f",
466  depthIntrinsics[0],
467  depthIntrinsics[1],
468  depthIntrinsics[2],
469  depthIntrinsics[3],
470  depthIntrinsics[4]));
471  }
472  } catch (CameraAccessException e) {
473  e.printStackTrace();
474  }
475  if(rgbExtrinsics == null)
476  {
477  float[] translation = {0,0,0};
478  float[] rotation = {0,0,0,1};
480  }
481  if(depthExtrinsics == null)
482  {
484  }
485 
486  if(depthCameraId != null)
487  {
488  ArrayList<String> resolutions = getResolutions(mActivity, depthCameraId, ImageFormat.DEPTH16);
489  if (resolutions != null) {
490  float[] newDepthIntrinsics = null;
491  int largestWidth = 0;
492  for( String temp : resolutions) {
493  Log.i(TAG, "DEPTH16 resolution: " + temp);
494  depthWidth = Integer.parseInt(temp.split("x")[0]);
495  depthHeight = Integer.parseInt(temp.split("x")[1]);
496  if(depthIntrinsics != null)
497  {
498  if(depthIntrinsics[0] != 0)
499  {
500  if(largestWidth == 0 && depthWidth>largestWidth)
501  {
502  largestWidth = depthWidth; // intrinsics should match this resolution
503  }
504  // Samsung Galaxy Note10+: take smallest resolution and match the intrinsics
505  if(depthWidth < largestWidth)
506  {
507  float scale = (float)depthWidth/(float)largestWidth;
508  newDepthIntrinsics = depthIntrinsics.clone();
509  newDepthIntrinsics[0] *= scale;
510  newDepthIntrinsics[1] *= scale;
511  newDepthIntrinsics[2] *= scale;
512  newDepthIntrinsics[3] *= scale;
513  }
514  }
515  else if(depthWidth ==240 && depthHeight==180)
516  {
517  // Huawei P30 Pro: only 240x180 is working
518  break;
519  }
520  }
521  }
522  if (resolutions.size()>0) {
523  mTOFAvailable = true;
524  if(newDepthIntrinsics!=null) {
525  depthIntrinsics = newDepthIntrinsics;
526  }
527  }
528  }
529  }
530  Log.i(TAG, "TOF_available: " + mTOFAvailable);
531 
532  // Color CPU Image.
533  // Use the currently configured CPU image size.
534  //Size desiredCPUImageSize = sharedSession.getCameraConfig().getImageSize();
535 
537 
538  // When ARCore is running, make sure it also updates our CPU image surface.
539  if (mTOFAvailable && cameraId.compareTo(depthCameraId) == 0) {
540  sharedCamera.setAppSurfaces(this.cameraId, Arrays.asList(mTOFImageReader.imageReader.getSurface()));
541  }
542 
543  try {
544 
545  // Wrap our callback in a shared camera callback.
546  CameraDevice.StateCallback wrappedCallback = sharedCamera.createARDeviceStateCallback(cameraDeviceCallback, backgroundHandler);
547 
548  // Open the camera device using the ARCore wrapped callback.
549  cameraManager.openCamera(cameraId, wrappedCallback, backgroundHandler);
550 
551  if(mTOFAvailable && cameraId.compareTo(depthCameraId) != 0)
552  {
554  }
555 
556  } catch (CameraAccessException e) {
557  Log.e(TAG, "Failed to open camera", e);
558  return false;
559  } catch (IllegalArgumentException e) {
560  Log.e(TAG, "Failed to open camera", e);
561  return false;
562  } catch (SecurityException e) {
563  Log.e(TAG, "Failed to open camera", e);
564  return false;
565  }
566 
567  return true;
568  }
569 
570  public static void rotationMatrixToQuaternion(float[] R, float[] q) {
571  final float m00 = R[0];
572  final float m10 = R[1];
573  final float m20 = R[2];
574  final float m01 = R[4];
575  final float m11 = R[5];
576  final float m21 = R[6];
577  final float m02 = R[8];
578  final float m12 = R[9];
579  final float m22 = R[10];
580 
581  float tr = m00 + m11 + m22;
582 
583  if (tr > 0) {
584  float S = (float) Math.sqrt(tr + 1.0) * 2; // S=4*qw
585  q[0] = 0.25f * S;/* w w w.j ava 2s.co m*/
586  q[1] = (m21 - m12) / S;
587  q[2] = (m02 - m20) / S;
588  q[3] = (m10 - m01) / S;
589  } else if ((m00 > m11) & (m00 > m22)) {
590  float S = (float) Math.sqrt(1.0 + m00 - m11 - m22) * 2; //
591  // S=4*q[1]
592  q[0] = (m21 - m12) / S;
593  q[1] = 0.25f * S;
594  q[2] = (m01 + m10) / S;
595  q[3] = (m02 + m20) / S;
596  } else if (m11 > m22) {
597  float S = (float) Math.sqrt(1.0 + m11 - m00 - m22) * 2; //
598  // S=4*q[2]
599  q[0] = (m02 - m20) / S;
600  q[1] = (m01 + m10) / S;
601  q[2] = 0.25f * S;
602  q[3] = (m12 + m21) / S;
603  } else {
604  float S = (float) Math.sqrt(1.0 + m22 - m00 - m11) * 2; //
605  // S=4*q[3]
606  q[0] = (m10 - m01) / S;
607  q[1] = (m02 + m20) / S;
608  q[2] = (m12 + m21) / S;
609  q[3] = 0.25f * S;
610  }
611 
612  }
613 
614 
615  // Close the camera device.
616  public void close() {
617  Log.w(TAG, "close()");
618 
619  if (sharedSession != null) {
620  sharedSession.close();
621  sharedSession = null;
622  }
623 
624  if (captureSession != null) {
625  captureSession.close();
626  captureSession = null;
627  }
628  if (cameraDevice != null) {
629  cameraDevice.close();
630  cameraDevice = null;
631  }
632 
634  firstFrameReceived = false;
635 
636  if(cameraTextureId>=0)
637  {
638  GLES20.glDeleteTextures(1, new int[] {cameraTextureId}, 0);
639  }
640 
642  }
643 
644  public void setDisplayGeometry(int rotation, int width, int height)
645  {
646  if(sharedSession!=null)
647  sharedSession.setDisplayGeometry(rotation, width, height);
648  }
649 
650  /*************************************************** ONDRAWFRAME ARCORE ************************************************************* */
651  // Draw frame when in AR mode. Called on the GL thread.
652  public void updateGL() throws CameraNotAvailableException {
653 
654  if(!mReady.get() || sharedSession == null)
655  {
656  return;
657  }
658 
659  if (mTOFAvailable && mTOFImageReader.frameCount == 0) return;
660 
661  // Perform ARCore per-frame update.
662  Frame frame = null;
663  try {
664  frame = sharedSession.update();
665  } catch (Exception e) {
666  e.printStackTrace();
667  return;
668  }
669 
670  Camera camera = null;
671  if (frame != null) {
672  camera = frame.getCamera();
673  }else
674  {
675  Log.e(TAG, String.format("frame.getCamera() null!"));
676  return;
677  }
678 
679  if (camera == null) {
680  Log.e(TAG, String.format("camera is null!"));
681  return;
682  }
683  boolean lost = false;
684  if (camera.getTrackingState() != TrackingState.TRACKING) {
685  final String trackingState = camera.getTrackingState().toString();
686  Log.e(TAG, String.format("Tracking lost! state=%s", trackingState));
687  // This will force a new session on the next frame received
688  lost = true;
689  mActivity.runOnUiThread(new Runnable() {
690  public void run() {
691  if(mToast!=null && firstFrameReceived)
692  {
693  String msg = "Tracking lost! If you are mapping, you will need to relocalize before continuing.";
694  if(mToast.getView() == null || !mToast.getView().isShown())
695  {
696  mToast.makeText(mActivity.getApplicationContext(),
697  msg, Toast.LENGTH_LONG).show();
698  }
699  else
700  {
701  mToast.setText(msg);
702  }
703  }
704  }
705  });
706  }
707 
708  if (frame.getTimestamp() != 0) {
709  Pose pose = camera.getPose();
710  double stamp = (double)frame.getTimestamp()/10e8;
711  CameraIntrinsics intrinsics = camera.getImageIntrinsics();
712  try{
713  Image image = frame.acquireCameraImage();
714  if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("frame=%d vs image=%d", frame.getTimestamp(), image.getTimestamp()));
715  PointCloud cloud = frame.acquirePointCloud();
716  FloatBuffer points = cloud.getPoints();
717 
718  if (image.getFormat() != ImageFormat.YUV_420_888) {
719  throw new IllegalArgumentException(
720  "Expected image in YUV_420_888 format, got format " + image.getFormat());
721  }
722 
724  {
725  for(int i =0;i<image.getPlanes().length;++i)
726  {
727  Log.d(TAG, String.format("Plane[%d] pixel stride = %d, row stride = %d", i, image.getPlanes()[i].getPixelStride(), image.getPlanes()[i].getRowStride()));
728  }
729  }
730 
731  float[] fl = intrinsics.getFocalLength();
732  float[] pp = intrinsics.getPrincipalPoint();
733  if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("fx=%f fy=%f cx=%f cy=%f", fl[0], fl[1], pp[0], pp[1]));
734 
735  ByteBuffer y = image.getPlanes()[0].getBuffer().asReadOnlyBuffer();
736  ByteBuffer u = image.getPlanes()[1].getBuffer().asReadOnlyBuffer();
737  ByteBuffer v = image.getPlanes()[2].getBuffer().asReadOnlyBuffer();
738 
739  if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("RGB %dx%d len=%dbytes format=%d stamp=%f",
740  image.getWidth(), image.getHeight(), y.limit(), image.getFormat(), stamp));
741 
742  float[] texCoord = new float[8];
743  frame.transformCoordinates2d(
744  Coordinates2d.OPENGL_NORMALIZED_DEVICE_COORDINATES,
745  QUAD_COORDS,
746  Coordinates2d.IMAGE_NORMALIZED,
747  texCoord);
748 
749  float[] p = new float[16];
750  camera.getProjectionMatrix(p, 0, 0.1f, 100.0f);
751 
752  float[] viewMatrix = new float[16];
753  camera.getDisplayOrientedPose().inverse().toMatrix(viewMatrix, 0);
754  float[] quat = new float[4];
755  rotationMatrixToQuaternion(viewMatrix, quat);
756 
757 
758  if(mTOFAvailable)
759  {
760  ByteBuffer depth;
761  double depthStamp;
762  synchronized (mTOFImageReader) {
764  depthStamp = (double)mTOFImageReader.timestamp/10e8;
765  }
766 
767  if(mPreviousDepth == null)
768  {
769  mPreviousDepth = depth;
770  mPreviousDepthStamp = depthStamp;
771  }
772  if(mPreviousDepth2 == null)
773  {
774  mPreviousDepth2 = depth;
775  mPreviousDepthStamp2 = depthStamp;
776  }
777 
778  if(!RTABMapActivity.DISABLE_LOG) Log.d(TAG, String.format("Depth %dx%d len=%dbytes format=%d stamp=%f previous=%f rgb=%f",
779  mTOFImageReader.WIDTH, mTOFImageReader.HEIGHT, depth.limit(), ImageFormat.DEPTH16, depthStamp, mPreviousDepthStamp, stamp));
780 
783  lost?0:pose.tx(), lost?0:pose.ty(), lost?0:pose.tz(), lost?0:pose.qx(), lost?0:pose.qy(), lost?0:pose.qz(), lost?0:pose.qw(),
784  fl[0], fl[1], pp[0], pp[1],
788  stamp,
789  depthStamp<=stamp?depthStamp:mPreviousDepthStamp<=stamp?mPreviousDepthStamp:mPreviousDepthStamp2,
790  y, u, v, y.limit(), image.getWidth(), image.getHeight(), image.getFormat(),
791  depthStamp<=stamp?depth:mPreviousDepthStamp<=stamp?mPreviousDepth:mPreviousDepth2,
792  depthStamp<=stamp?depth.limit():mPreviousDepthStamp<=stamp?mPreviousDepth.limit():mPreviousDepth2.limit(),
793  mTOFImageReader.WIDTH, mTOFImageReader.HEIGHT, ImageFormat.DEPTH16,
794  points, points.limit()/4,
795  viewMatrix[12], viewMatrix[13], viewMatrix[14], quat[1], quat[2], quat[3], quat[0],
796  p[0], p[5], p[8], p[9], p[10], p[11], p[14],
797  texCoord[0],texCoord[1],texCoord[2],texCoord[3],texCoord[4],texCoord[5],texCoord[6],texCoord[7]);
798 
799  // triple buffer in case delay of rgb frame is > 60 ms
800  if(depthStamp != mPreviousDepthStamp)
801  {
802  mPreviousDepthStamp2 = mPreviousDepthStamp;
803  mPreviousDepth2 = mPreviousDepth;
804  mPreviousDepthStamp = depthStamp;
805  mPreviousDepth = depth;
806  }
807  }
808  else
809  {
812  lost?0:pose.tx(), lost?0:pose.ty(), lost?0:pose.tz(), lost?0:pose.qx(), lost?0:pose.qy(), lost?0:pose.qz(), lost?0:pose.qw(),
813  fl[0], fl[1], pp[0], pp[1],
815  stamp,
816  y, u, v, y.limit(), image.getWidth(), image.getHeight(), image.getFormat(),
817  points, points.limit()/4,
818  viewMatrix[12], viewMatrix[13], viewMatrix[14], quat[1], quat[2], quat[3], quat[0],
819  p[0], p[5], p[8], p[9], p[10], p[11], p[14],
820  texCoord[0],texCoord[1],texCoord[2],texCoord[3],texCoord[4],texCoord[5],texCoord[6],texCoord[7]);
821  }
822 
823  firstFrameReceived = !lost;
824  image.close();
825  cloud.close();
826 
827  } catch (NotYetAvailableException e) {
828 
829  }
830  }
831  }
832 
833  /********************************************************************************************************************* */
834  /*************************************************** End ************************************************************* */
835  /********************************************************************************************************************* */
836 
837 
838  public ArrayList<String> getResolutions (Context context, String cameraId, int imageFormat){
839  Log.v(TAG, "getResolutions: cameraId:" + cameraId + " imageFormat: " + imageFormat);
840 
841  ArrayList<String> output = new ArrayList<String>();
842  try {
843  CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
844  CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
845 
846  for (android.util.Size s : characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(imageFormat)) {
847  output.add(s.getWidth() + "x" + s.getHeight());
848  }
849  } catch (Exception e) {
850  e.printStackTrace();
851  }
852  return output;
853  }
854 
855 }
com.introlab.rtabmap.ARCoreSharedCamera.firstFrameReceived
boolean firstFrameReceived
Definition: ARCoreSharedCamera.java:109
glm::length
GLM_FUNC_DECL genType::value_type length(genType const &x)
com.introlab.rtabmap.ARCoreSharedCamera.createCameraPreviewSession
void createCameraPreviewSession()
Definition: ARCoreSharedCamera.java:268
run
void run(class_loader::ClassLoader *loader)
com.introlab.rtabmap.TOF_ImageReader.backgroundHandler
Handler backgroundHandler
Definition: TOF_ImageReader.java:39
s
RealScalar s
Pose
Pose2 Pose
com.introlab.rtabmap.ARCoreSharedCamera.cameraId
String cameraId
Definition: ARCoreSharedCamera.java:96
com.introlab.rtabmap.ARCoreSharedCamera.rgbExtrinsics
Pose rgbExtrinsics
Definition: ARCoreSharedCamera.java:99
com.introlab.rtabmap.ARCoreSharedCamera.captureSession
CameraCaptureSession captureSession
Definition: ARCoreSharedCamera.java:77
c
Scalar Scalar * c
glm::quat
highp_quat quat
Quaternion of default single-precision floating-point numbers.
Definition: fwd.hpp:68
com.introlab.rtabmap.ARCoreSharedCamera.captureSessionCallback
final CameraCaptureSession.CaptureCallback captureSessionCallback
Definition: ARCoreSharedCamera.java:200
com.introlab.rtabmap.ARCoreSharedCamera.depthIntrinsics
float[] depthIntrinsics
Definition: ARCoreSharedCamera.java:101
com.introlab.rtabmap.TOF_ImageReader.imageReader
ImageReader imageReader
Definition: TOF_ImageReader.java:32
com.introlab.rtabmap.ARCoreSharedCamera.startBackgroundThread
void startBackgroundThread()
Definition: ARCoreSharedCamera.java:307
com.introlab.rtabmap.RTABMapLib.postOdometryEventDepth
static native void postOdometryEventDepth(long nativeApplication, float x, float y, float z, float qx, float qy, float qz, float qw, float rgb_fx, float rgb_fy, float rgb_cx, float rgb_cy, float depth_fx, float depth_fy, float depth_cx, float depth_cy, float rgbFrameX, float rgbFrameY, float rgbFrameZ, float rgbFrameQX, float rgbFrameQY, float rgbFrameQZ, float rgbFrameQW, float depthFrameX, float depthFrameY, float depthFrameZ, float depthFrameQX, float depthFrameQY, float depthFrameQZ, float depthFrameQW, double rgbStamp, double depthStamp, ByteBuffer yPlane, ByteBuffer uPlane, ByteBuffer vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat, ByteBuffer depth, int depthLen, int depthWidth, int depthHeight, int depthFormat, FloatBuffer points, int pointsLen, float vx, float vy, float vz, float vqx, float vqy, float vqz, float vqw, float p00, float p11, float p02, float p12, float p22, float p32, float p23, float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7)
com.introlab.rtabmap.ARCoreSharedCamera.sharedSession
Session sharedSession
Definition: ARCoreSharedCamera.java:72
com.introlab.rtabmap.ARCoreSharedCamera.backgroundHandler
Handler backgroundHandler
Definition: ARCoreSharedCamera.java:88
y
Matrix3f y
com.introlab.rtabmap.ARCoreSharedCamera.sharedCamera
SharedCamera sharedCamera
Definition: ARCoreSharedCamera.java:91
com.introlab.rtabmap.TOF_ImageReader.timestamp
long timestamp
Definition: TOF_ImageReader.java:34
com.introlab.rtabmap.ARCoreSharedCamera.surfaceView
GLSurfaceView surfaceView
Definition: ARCoreSharedCamera.java:69
com.introlab.rtabmap.TOF_ImageReader.frameCount
int frameCount
Definition: TOF_ImageReader.java:33
com.introlab.rtabmap.ARCoreSharedCamera.depthWidth
int depthWidth
Definition: ARCoreSharedCamera.java:65
com.introlab.rtabmap.ARCoreSharedCamera.mTOFAvailable
boolean mTOFAvailable
Definition: ARCoreSharedCamera.java:113
com.introlab.rtabmap.ARCoreSharedCamera.contains
static boolean contains(int[] modes, int mode)
Definition: ARCoreSharedCamera.java:336
com.introlab.rtabmap.TOF_ImageReader.startBackgroundThread
void startBackgroundThread()
Definition: TOF_ImageReader.java:244
com.introlab.rtabmap.TOF_ImageReader.close
void close()
Definition: TOF_ImageReader.java:55
com.introlab.rtabmap.TOF_ImageReader.HEIGHT
int HEIGHT
Definition: TOF_ImageReader.java:30
mode
const DiscreteKey mode
com.introlab.rtabmap.RTABMapLib
Definition: RTABMapLib.java:15
com.introlab.rtabmap.ARCoreSharedCamera.stopBackgroundThread
void stopBackgroundThread()
Definition: ARCoreSharedCamera.java:315
com.introlab.rtabmap.ARCoreSharedCamera.depthExtrinsics
Pose depthExtrinsics
Definition: ARCoreSharedCamera.java:100
com.introlab.rtabmap.ARCoreSharedCamera.setToast
void setToast(Toast toast)
Definition: ARCoreSharedCamera.java:122
translation
translation
com.introlab.rtabmap.TOF_ImageReader.WIDTH
int WIDTH
Definition: TOF_ImageReader.java:29
scale
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics scale
q
EIGEN_DEVICE_FUNC const Scalar & q
com.introlab.rtabmap.ARCoreSharedCamera.mActivity
static RTABMapActivity mActivity
Definition: ARCoreSharedCamera.java:58
com.introlab.rtabmap.ARCoreSharedCamera.resumeARCore
void resumeARCore()
Definition: ARCoreSharedCamera.java:235
com.introlab.rtabmap.RTABMapActivity.DISABLE_LOG
static boolean DISABLE_LOG
Definition: RTABMapActivity.java:114
com.introlab.rtabmap.ARCoreSharedCamera.openCamera
boolean openCamera()
Definition: ARCoreSharedCamera.java:349
com.introlab.rtabmap.TOF_ImageReader.depth16_raw
ByteBuffer depth16_raw
Definition: TOF_ImageReader.java:41
com.introlab.rtabmap.ARCoreSharedCamera.close
void close()
Definition: ARCoreSharedCamera.java:616
com.introlab.rtabmap.ARCoreSharedCamera.setRepeatingCaptureRequest
void setRepeatingCaptureRequest()
Definition: ARCoreSharedCamera.java:258
target
target
com.introlab.rtabmap.ARCoreSharedCamera.getResolutions
ArrayList< String > getResolutions(Context context, String cameraId, int imageFormat)
Definition: ARCoreSharedCamera.java:838
com.introlab.rtabmap.ARCoreSharedCamera.mReady
AtomicBoolean mReady
Definition: ARCoreSharedCamera.java:103
error
void error(const char *str)
com.introlab.rtabmap.ARCoreSharedCamera.setDisplayGeometry
void setDisplayGeometry(int rotation, int width, int height)
Definition: ARCoreSharedCamera.java:644
p
Point3_ p(2)
com.introlab.rtabmap.ARCoreSharedCamera.cameraDevice
CameraDevice cameraDevice
Definition: ARCoreSharedCamera.java:83
com.introlab.rtabmap.RTABMapActivity.nativeApplication
static long nativeApplication
Definition: RTABMapActivity.java:110
com.introlab.rtabmap.ARCoreSharedCamera.mTOFImageReader
TOF_ImageReader mTOFImageReader
Definition: ARCoreSharedCamera.java:112
com.introlab.rtabmap.ARCoreSharedCamera.rotationMatrixToQuaternion
static void rotationMatrixToQuaternion(float[] R, float[] q)
Definition: ARCoreSharedCamera.java:570
com.introlab.rtabmap.ARCoreSharedCamera.ARCoreSharedCamera
ARCoreSharedCamera(RTABMapActivity c)
Definition: ARCoreSharedCamera.java:59
f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
com.introlab.rtabmap.ARCoreSharedCamera.TAG
static final String TAG
Definition: ARCoreSharedCamera.java:51
com.introlab.rtabmap.TOF_ImageReader.createImageReader
void createImageReader(int width, int height)
Definition: TOF_ImageReader.java:206
com.introlab.rtabmap.ARCoreSharedCamera.cameraTextureId
int cameraTextureId
Definition: ARCoreSharedCamera.java:108
com.introlab.rtabmap.ARCoreSharedCamera.cameraManager
CameraManager cameraManager
Definition: ARCoreSharedCamera.java:80
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
com.introlab.rtabmap.ARCoreSharedCamera.depthHeight
int depthHeight
Definition: ARCoreSharedCamera.java:66
com.introlab.rtabmap.TOF_ImageReader.stopBackgroundThread
void stopBackgroundThread()
Definition: TOF_ImageReader.java:251
com.introlab.rtabmap.ARCoreSharedCamera.odomPose
Pose odomPose
Definition: ARCoreSharedCamera.java:74
com.introlab.rtabmap.ARCoreSharedCamera.cameraDeviceCallback
final CameraDevice.StateCallback cameraDeviceCallback
Definition: ARCoreSharedCamera.java:128
glm::rotation
GLM_FUNC_DECL detail::tquat< T, P > rotation(detail::tvec3< T, P > const &orig, detail::tvec3< T, P > const &dest)
com.introlab.rtabmap.ARCoreSharedCamera.updateGL
void updateGL()
Definition: ARCoreSharedCamera.java:652
camera
Camera camera(Pose3(Rot3().retract(Vector3(0.1, 0.2, 0.3)), Point3(0, 5, 0)), Cal3Bundler0(1, 0, 0))
com.introlab.rtabmap.ARCoreSharedCamera.depthCameraId
String depthCameraId
Definition: ARCoreSharedCamera.java:97
com
v
Array< int, Dynamic, 1 > v
Camera
PinholePose< Cal3_S2 > Camera
com.introlab.rtabmap.ARCoreSharedCamera.previewCaptureRequestBuilder
CaptureRequest.Builder previewCaptureRequestBuilder
Definition: ARCoreSharedCamera.java:106
com.introlab.rtabmap.ARCoreSharedCamera
Definition: ARCoreSharedCamera.java:49
com.introlab.rtabmap.ARCoreSharedCamera.mToast
Toast mToast
Definition: ARCoreSharedCamera.java:93
float
float
com.introlab.rtabmap.ARCoreSharedCamera.isDepthSupported
boolean isDepthSupported()
Definition: ARCoreSharedCamera.java:120
com.introlab.rtabmap.ARCoreSharedCamera.backgroundThread
HandlerThread backgroundThread
Definition: ARCoreSharedCamera.java:86
com.introlab.rtabmap.ARCoreSharedCamera.QUAD_COORDS
static final float[] QUAD_COORDS
Definition: ARCoreSharedCamera.java:53
com.introlab.rtabmap.RTABMapLib.postOdometryEvent
static native void postOdometryEvent(long nativeApplication, float x, float y, float z, float qx, float qy, float qz, float qw, float rgb_fx, float rgb_fy, float rgb_cx, float rgb_cy, float rgbFrameX, float rgbFrameY, float rgbFrameZ, float rgbFrameQX, float rgbFrameQY, float rgbFrameQZ, float rgbFrameQW, double stamp, ByteBuffer yPlane, ByteBuffer uPlane, ByteBuffer vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat, FloatBuffer points, int pointsLen, float vx, float vy, float vz, float vqx, float vqy, float vqz, float vqw, float p00, float p11, float p02, float p12, float p22, float p32, float p23, float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7)
com.introlab.rtabmap.TOF_ImageReader.cameraDeviceCallback
final CameraDevice.StateCallback cameraDeviceCallback
Definition: TOF_ImageReader.java:74
com.introlab.rtabmap.TOF_ImageReader
Definition: TOF_ImageReader.java:25
config
config
i
int i
result
RESULT & result
S
S
msg
msg
R
R
com.introlab.rtabmap.RTABMapActivity
Definition: RTABMapActivity.java:107


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sun Dec 1 2024 03:42:41