CameraAREngine.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #include "CameraAREngine.h"
29 #include "util.h"
33 #include "rtabmap/core/util2d.h"
34 
35 #include <media/NdkImage.h>
36 
37 namespace rtabmap {
38 
39 
41 // CameraAREngine
43 CameraAREngine::CameraAREngine(void* env, void* context, void* activity, bool smoothing, float upstreamRelocalizationAccThr):
44  CameraMobile(smoothing, upstreamRelocalizationAccThr),
45  env_(env),
46  context_(context),
47  activity_(activity),
48  arInstallRequested_(false)
49 {
50  glGenTextures(1, &textureId_);
51 }
52 
54  // Disconnect ARCore service
55  close();
56 
57  glDeleteTextures(1, &textureId_);
58 }
59 
60 std::string CameraAREngine::getSerial() const
61 {
62  return "AREngine";
63 }
64 
65 bool CameraAREngine::init(const std::string & calibrationFolder, const std::string & cameraName)
66 {
67  close();
68 
69  CameraMobile::init(calibrationFolder, cameraName);
70 
72 
73  HwArInstallStatus install_status;
74  // If install was not yet requested, that means that we are resuming the
75  // activity first time because of explicit user interaction (such as
76  // launching the application)
77  bool user_requested_install = !arInstallRequested_;
78 
79  // === ATTENTION! ATTENTION! ATTENTION! ===
80  // This method can and will fail in user-facing situations. Your
81  // application must handle these cases at least somewhat gracefully. See
82  // HelloAR Java sample code for reasonable behavior.
83  HwArEnginesApk_requestInstall(env_, activity_, user_requested_install, &install_status);
84 
85  switch (install_status)
86  {
87  case HWAR_INSTALL_STATUS_INSTALLED:
88  break;
89  case HWAR_INSTALL_STATUS_INSTALL_REQUESTED:
90  arInstallRequested_ = true;
91  return false;
92  }
93 
94  // === ATTENTION! ATTENTION! ATTENTION! ===
95  // This method can and will fail in user-facing situations. Your
96  // application must handle these cases at least somewhat gracefully. See
97  // HelloAR Java sample code for reasonable behavior.
98  UASSERT(HwArSession_create(env_, context_, &arSession_) == HWAR_SUCCESS);
100 
101  HwArConfig_create(arSession_, &arConfig_);
103 
104  HwArConfig_setFocusMode(arSession_, arConfig_, HWAR_FOCUS_MODE_FIXED);
105  UASSERT(HwArSession_configure(arSession_, arConfig_) == HWAR_SUCCESS);
106 
107  HwArFrame_create(arSession_, &arFrame_);
108  UASSERT(arFrame_);
109 
110  HwArCameraIntrinsics_create(arSession_, &arCameraIntrinsics_); // May fail?!
111  //UASSERT(arCameraIntrinsics_);
112 
113  HwArPose_create(arSession_, nullptr, &arPose_);
114  UASSERT(arPose_);
115 
118  HwArConfig_setUpdateMode(arSession_, arConfig_, HWAR_UPDATE_MODE_BLOCKING);
119 
121 
122  if (HwArSession_resume(arSession_) != HWAR_SUCCESS)
123  {
124  UERROR("Cannot resume camera!");
125  // In a rare case (such as another camera app launching) the camera may be
126  // given to a different app and so may not be available to this app. Handle
127  // this properly and recreate the session at the next iteration.
128  close();
129  return false;
130  }
131 
132  return true;
133 }
134 
136 {
138  if (arCameraIntrinsics_ != nullptr)
139  {
140  HwArCameraIntrinsics_destroy(arSession_, arCameraIntrinsics_);
141  }
142  arCameraIntrinsics_ = nullptr;
143 
144  if(arSession_!= nullptr)
145  {
146  HwArSession_destroy(arSession_);
147  }
148  arSession_ = nullptr;
149 
150  if(arConfig_!= nullptr)
151  {
152  HwArConfig_destroy(arConfig_);
153  }
154  arConfig_ = nullptr;
155 
156  if (arFrame_ != nullptr)
157  {
158  HwArFrame_destroy(arFrame_);
159  }
160  arFrame_ = nullptr;
161 
162  if (arPose_ != nullptr)
163  {
164  HwArPose_destroy(arPose_);
165  }
166  arPose_ = nullptr;
167 
169 }
170 
171 void CameraAREngine::setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height)
172 {
173  CameraMobile::setScreenRotationAndSize(colorCameraToDisplayRotation, width, height);
174  if(arSession_)
175  {
176  int ret = static_cast<int>(colorCameraToDisplayRotation) + 1; // remove 90deg camera rotation
177  if (ret > 3) {
178  ret -= 4;
179  }
180 
181  HwArSession_setDisplayGeometry(arSession_, ret, width, height);
182  }
183 }
184 
186 {
188  //LOGI("Capturing image...");
189 
190  pose.setNull();
192  if(!arSession_)
193  {
194  return data;
195  }
196 
197  if(textureId_ == 0)
198  {
199  glGenTextures(1, &textureId_);
200  glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId_);
201  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
202  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
203  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
204  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
205  }
206  if(textureId_!=0)
207  HwArSession_setCameraTextureName(arSession_, textureId_);
208 
209  // Update session to get current frame and render camera background.
210  if (HwArSession_update(arSession_, arFrame_) != HWAR_SUCCESS) {
211  LOGE("CameraAREngine::captureImage() ArSession_update error");
212  return data;
213  }
214 
215  // If display rotation changed (also includes view size change), we need to
216  // re-query the uv coordinates for the on-screen portion of the camera image.
217  int32_t geometry_changed = 0;
218  HwArFrame_getDisplayGeometryChanged(arSession_, arFrame_, &geometry_changed);
219  if (geometry_changed != 0 || !uvs_initialized_) {
220  HwArFrame_transformDisplayUvCoords(
224  UERROR("uv: (%f,%f) (%f,%f) (%f,%f) (%f,%f)",
230  uvs_initialized_ = true;
231  }
232 
233  HwArCamera* ar_camera;
234  HwArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
235 
236  HwArCamera_getViewMatrix(arSession_, ar_camera, glm::value_ptr(viewMatrix_));
237  HwArCamera_getProjectionMatrix(arSession_, ar_camera,
238  /*near=*/0.1f, /*far=*/100.f,
240 
241  HwArTrackingState camera_tracking_state;
242  HwArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
243 
244  if(camera_tracking_state == HWAR_TRACKING_STATE_TRACKING)
245  {
246  // Get calibration parameters
247  // FIXME: Hard-coded as getting intrinsics with the api fails
248  float fx=492.689667,fy=492.606201, cx=323.594849, cy=234.659744;
249  int32_t camWidth=640, camHeight=480;
250  //HwArCamera_getImageIntrinsics(arSession_, ar_camera, arCameraIntrinsics_);
251  //HwArCameraIntrinsics_getFocalLength(arSession_, arCameraIntrinsics_, &fx, &fy);
252  //HwArCameraIntrinsics_getPrincipalPoint(arSession_, arCameraIntrinsics_, &cx, &cy);
253  //HwArCameraIntrinsics_getImageDimensions(arSession_, arCameraIntrinsics_, &camWidth, &camHeight);
254  LOGI("%f %f %f %f %d %d", fx, fy, cx, cy, camWidth, camHeight);
255 
256  if(fx > 0 && fy > 0 && camWidth > 0 && camHeight > 0 && cx > 0 && cy > 0)
257  {
258  //ArPointCloud * point_cloud;
259  //ArFrame_acquirePointCloud(ar_session_, ar_frame_, &point_cloud);
260 
261  HwArImage * image = nullptr;
262  HwArImage * depthImage = nullptr;
263  HwArStatus statusRgb = HwArFrame_acquireCameraImage(arSession_, arFrame_, &image);
264  HwArStatus statusDepth = HwArFrame_acquireDepthImage(arSession_, arFrame_, &depthImage);
265  if(statusRgb == HWAR_SUCCESS && statusDepth == HWAR_SUCCESS)
266  {
267  int64_t timestamp_ns;
268  HwArFrame_getTimestamp(arSession_, arFrame_, &timestamp_ns);
269 
270  int planeCount;
271  uint8_t *imageData = nullptr;
272  int len = 0;
273  int stride;
274  int width;
275  int height;
276  const AImage* ndkImageRGB;
277  HwArImage_getNdkImage(image, &ndkImageRGB);
278 
279  AImage_getNumberOfPlanes(ndkImageRGB, &planeCount);
280  AImage_getWidth(ndkImageRGB, &width);
281  AImage_getHeight(ndkImageRGB, &height);
282  AImage_getPlaneRowStride(ndkImageRGB, 0, &stride);
283  AImage_getPlaneData(ndkImageRGB, 0, &imageData, &len);
284  LOGI("RGB: width=%d, height=%d, bytes=%d stride=%d planeCount=%d", width, height, len, stride, planeCount);
285 
286  cv::Mat outputRGB;
287  if(imageData != nullptr && len>0)
288  {
289  cv::cvtColor(cv::Mat(height+height/2, width, CV_8UC1, (void*)imageData), outputRGB, cv::COLOR_YUV2BGR_NV21);
290  }
291 
292  //Depth
293  const AImage* ndkImageDepth;
294  HwArImage_getNdkImage(depthImage, &ndkImageDepth);
295  AImage_getNumberOfPlanes(ndkImageDepth, &planeCount);
296  AImage_getWidth(ndkImageDepth, &width);
297  AImage_getHeight(ndkImageDepth, &height);
298  AImage_getPlaneRowStride(ndkImageDepth, 0, &stride);
299  AImage_getPlaneData(ndkImageDepth, 0, &imageData, &len);
300  LOGI("Depth: width=%d, height=%d, bytes=%d stride=%d planeCount=%d", width, height, len, stride, planeCount);
301 
302  cv::Mat outputDepth(height, width, CV_16UC1);
303  uint16_t *dataShort = (uint16_t *)imageData;
304  for (int y = 0; y < outputDepth.rows; ++y)
305  {
306  for (int x = 0; x < outputDepth.cols; ++x)
307  {
308  uint16_t depthSample = dataShort[y*outputDepth.cols + x];
309  uint16_t depthRange = (depthSample & 0x1FFF); // first 3 bits are confidence
310  outputDepth.at<uint16_t>(y,x) = depthRange;
311  }
312  }
313 
314  if(!outputRGB.empty() && !outputDepth.empty())
315  {
316  double stamp = double(timestamp_ns)/10e8;
317  CameraModel model = CameraModel(fx, fy, cx, cy, deviceTColorCamera_, 0, cv::Size(camWidth, camHeight));
318  data = SensorData(outputRGB, outputDepth, model, 0, stamp);
319 
320  // pose in OpenGL coordinates
321  float pose_raw[7];
322  HwArCamera_getPose(arSession_, ar_camera, arPose_);
323  HwArPose_getPoseRaw(arSession_, arPose_, pose_raw);
324  pose = Transform(pose_raw[4], pose_raw[5], pose_raw[6], pose_raw[0], pose_raw[1], pose_raw[2], pose_raw[3]);
325  if(pose.isNull())
326  {
327  LOGE("CameraAREngine: Pose is null");
328  }
329  else
330  {
332  this->poseReceived(pose, stamp);
333  }
334  }
335  }
336  else
337  {
338  LOGE("CameraAREngine: failed to get rgb image (status=%d %d)", (int)statusRgb, (int)statusDepth);
339  }
340 
341  HwArImage_release(image);
342  HwArImage_release(depthImage);
343  }
344  else
345  {
346  LOGE("Invalid intrinsics!");
347  }
348  }
349 
350  HwArCamera_release(ar_camera);
351  return data;
352 
353 }
354 
355 } /* namespace rtabmap */
rtabmap::SensorData
Definition: SensorData.h:51
rtabmap::CameraAREngine::CameraAREngine
CameraAREngine(void *env, void *context, void *activity, bool smoothing=false, float upstreamRelocalizationAccThr=0.0f)
Definition: CameraAREngine.cpp:43
rtabmap::CameraMobile::close
virtual void close()
Definition: CameraMobile.cpp:86
cy
const double cy
rtabmap::CameraMobile::projectionMatrix_
glm::mat4 projectionMatrix_
Definition: CameraMobile.h:140
ret
int ret
fx
const double fx
rtabmap::CameraAREngine::arPose_
HwArPose * arPose_
Definition: CameraAREngine.h:72
rtabmap::CameraModel
Definition: CameraModel.h:38
rtabmap::CameraAREngine::arSessionMutex_
UMutex arSessionMutex_
Definition: CameraAREngine.h:74
rtabmap::CameraMobile::transformed_uvs_
float transformed_uvs_[8]
Definition: CameraMobile.h:141
rtabmap::CameraMobile::uvs_initialized_
bool uvs_initialized_
Definition: CameraMobile.h:142
int64_t
::int64_t int64_t
rtabmap::CameraAREngine::context_
void * context_
Definition: CameraAREngine.h:66
glm::value_ptr
GLM_FUNC_DECL const genType::value_type * value_ptr(genType const &vec)
y
Matrix3f y
rtabmap::CameraMobile::viewMatrix_
glm::mat4 viewMatrix_
Definition: CameraMobile.h:139
rtabmap::Transform::setNull
void setNull()
Definition: Transform.cpp:152
rtabmap::CameraMobile::deviceTColorCamera_
Transform deviceTColorCamera_
Definition: CameraMobile.h:136
rtabmap::Transform::isNull
bool isNull() const
Definition: Transform.cpp:107
LOGE
#define LOGE(...)
Definition: tango-gl/include/tango-gl/util.h:61
rtabmap::rtabmap_world_T_opengl_world
static const rtabmap::Transform rtabmap_world_T_opengl_world(0.0f, 0.0f,-1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f)
uint16_t
::uint16_t uint16_t
data
int data[]
UScopeMutex
Definition: UMutex.h:157
util3d_transforms.h
rtabmap::CameraAREngine::arFrame_
HwArFrame * arFrame_
Definition: CameraAREngine.h:70
rtabmap::CameraMobile::textureId_
GLuint textureId_
Definition: CameraMobile.h:138
rtabmap::opengl_world_T_rtabmap_world
static const rtabmap::Transform opengl_world_T_rtabmap_world(0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f)
rtabmap::CameraAREngine::arCameraIntrinsics_
HwArCameraIntrinsics * arCameraIntrinsics_
Definition: CameraAREngine.h:71
rtabmap::CameraAREngine::env_
void * env_
Definition: CameraAREngine.h:65
UASSERT
#define UASSERT(condition)
x
x
rtabmap::CameraMobile::init
virtual bool init(const std::string &calibrationFolder=".", const std::string &cameraName="")
Definition: CameraMobile.cpp:76
rtabmap::CameraMobile::opticalRotation
static const rtabmap::Transform opticalRotation
Definition: CameraMobile.h:76
OdometryEvent.h
LOGI
#define LOGI(...)
Definition: tango-gl/include/tango-gl/util.h:53
f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
rtabmap::CameraMobile::poseReceived
void poseReceived(const Transform &pose, double deviceStamp)
Definition: CameraMobile.cpp:175
rtabmap::CameraMobile::setScreenRotationAndSize
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height)
Definition: CameraMobile.h:114
ULogger.h
ULogger class and convenient macros.
rtabmap::CameraAREngine::arInstallRequested_
bool arInstallRequested_
Definition: CameraAREngine.h:73
rtabmap::Transform
Definition: Transform.h:41
util2d.h
uint8_t
::uint8_t uint8_t
rtabmap::CameraAREngine::updateDataOnRender
virtual SensorData updateDataOnRender(Transform &pose)
Definition: CameraAREngine.cpp:185
rtabmap::ScreenRotation
ScreenRotation
Definition: util.h:194
BackgroundRenderer_kVerticesView
static const GLfloat BackgroundRenderer_kVerticesView[]
Definition: background_renderer.h:37
env
rtabmap::CameraAREngine::arConfig_
HwArConfig * arConfig_
Definition: CameraAREngine.h:69
BackgroundRenderer::kNumVertices
static constexpr int kNumVertices
Definition: background_renderer.h:56
rtabmap::CameraMobile
Definition: CameraMobile.h:71
rtabmap::CameraAREngine::setScreenRotationAndSize
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height)
Definition: CameraAREngine.cpp:171
rtabmap::CameraAREngine::close
virtual void close()
Definition: CameraAREngine.cpp:135
rtabmap::CameraAREngine::getSerial
virtual std::string getSerial() const
Definition: CameraAREngine.cpp:60
len
size_t len(handle h)
rtabmap::CameraAREngine::arSession_
HwArSession * arSession_
Definition: CameraAREngine.h:68
false
#define false
Definition: ConvertUTF.c:56
cx
const double cx
rtabmap::CameraAREngine::~CameraAREngine
virtual ~CameraAREngine()
Definition: CameraAREngine.cpp:53
rtabmap
Definition: CameraARCore.cpp:35
rtabmap::CameraAREngine::activity_
void * activity_
Definition: CameraAREngine.h:67
UERROR
#define UERROR(...)
stride
Index stride
util.h
trace.model
model
Definition: trace.py:4
CameraAREngine.h
int32_t
::int32_t int32_t
fy
const double fy
rtabmap::CameraAREngine::init
virtual bool init(const std::string &calibrationFolder=".", const std::string &cameraName="")
Definition: CameraAREngine.cpp:65


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