34 #include <tango_client_api.h>
35 #include <tango_support_api.h>
61 if(point_cloud->num_points>0)
63 app->cloudReceived(cv::Mat(1, point_cloud->num_points, CV_32FC4, point_cloud->points[0]), point_cloud->timestamp);
72 if(color->format == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
74 tangoImage = cv::Mat(color->height, color->width, CV_8UC4, color->data);
76 else if(color->format == TANGO_HAL_PIXEL_FORMAT_YV12)
78 tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
80 else if(color->format == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
82 tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
84 else if(color->format == 35)
86 tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
90 LOGE(
"Not supported color format : %d.", color->format);
93 if(!tangoImage.empty())
95 app->rgbReceived(tangoImage, (
unsigned int)color->format, color->timestamp);
101 if(pose->status_code == TANGO_POSE_VALID)
111 app->tangoEventReceived(event->type, event->event_key, event->event_value);
120 colorCamera_(colorCamera),
121 decimation_(decimation),
122 rawScanPublished_(publishRawScan),
140 double xu,
double yu,
double w,
double w_inverse,
double two_tan_w_div_two,
141 double* xd,
double* yd) {
142 double ru =
sqrt(xu * xu + yu * yu);
148 double rd_div_ru =
std::atan(ru * two_tan_w_div_two) * w_inverse / ru;
149 *xd = xu * rd_div_ru;
150 *yd = yu * rd_div_ru;
162 cv::Mat & mapX, cv::Mat & mapY) {
163 const double &
fx = fisheyeModel.
K().at<
double>(0,0);
164 const double &
fy = fisheyeModel.
K().at<
double>(1,1);
165 const double &
cx = fisheyeModel.
K().at<
double>(0,2);
166 const double &
cy = fisheyeModel.
K().at<
double>(1,2);
167 const double &
w = fisheyeModel.
D().at<
double>(0,0);
168 mapX.create(fisheyeModel.
imageSize(), CV_32FC1);
169 mapY.create(fisheyeModel.
imageSize(), CV_32FC1);
170 LOGD(
"initFisheyeRectificationMap: fx=%f fy=%f, cx=%f, cy=%f, w=%f",
fx,
fy,
cx,
cy,
w);
172 const double fy_inverse = 1.0 /
fy;
173 const double fx_inverse = 1.0 /
fx;
174 const double w_inverse = 1 /
w;
175 const double two_tan_w_div_two = 2.0 *
std::tan(
w * 0.5);
179 for(
int iu = 0; iu < fisheyeModel.
imageHeight(); ++iu) {
180 for (
int ju = 0; ju < fisheyeModel.
imageWidth(); ++ju) {
181 double xu = (ju -
cx) * fx_inverse;
182 double yu = (iu -
cy) * fy_inverse;
185 double jd =
cx + xd *
fx;
186 double id =
cy + yd *
fy;
187 mapX.at<
float>(iu, ju) = jd;
188 mapY.at<
float>(iu, ju) =
id;
199 TangoSupport_initialize(TangoService_getPoseAtTime, TangoService_getCameraIntrinsics);
202 LOGI(
"NativeRTABMap: Setup tango config");
203 tango_config_ = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
206 LOGE(
"NativeRTABMap: Failed to get default config form");
211 bool is_atuo_recovery =
true;
212 int ret = TangoConfig_setBool(
tango_config_,
"config_enable_auto_recovery", is_atuo_recovery);
213 if (
ret != TANGO_SUCCESS)
215 LOGE(
"NativeRTABMap: config_enable_auto_recovery() failed with error code: %d",
ret);
222 ret = TangoConfig_setBool(
tango_config_,
"config_enable_color_camera",
true);
223 if (
ret != TANGO_SUCCESS)
225 LOGE(
"NativeRTABMap: config_enable_color_camera() failed with error code: %d",
ret);
232 if (
ret != TANGO_SUCCESS)
234 LOGE(
"NativeRTABMap: config_enable_depth() failed with error code: %d",
ret);
239 ret = TangoConfig_setInt32(
tango_config_,
"config_depth_mode", TANGO_POINTCLOUD_XYZC);
240 if (
ret != TANGO_SUCCESS)
242 LOGE(
"Failed to set 'depth_mode' configuration flag with error code: %d",
ret);
250 ret = TangoConfig_setBool(
tango_config_,
"config_enable_low_latency_imu_integration",
true);
251 if (
ret != TANGO_SUCCESS)
253 LOGE(
"NativeRTABMap: Failed to enable low latency imu integration.");
273 if (
ret != TANGO_SUCCESS)
275 LOGE(
"NativeRTABMap: get tango core version failed with error code: %d",
ret);
278 LOGI(
"NativeRTABMap: Tango version : %s", tango_core_version);
282 LOGI(
"NativeRTABMap: Setup callbacks");
286 if (
ret != TANGO_SUCCESS)
288 LOGE(
"NativeRTABMap: Failed to connect to point cloud callback with error code: %d",
ret);
293 if (
ret != TANGO_SUCCESS)
295 LOGE(
"NativeRTABMap: Failed to connect to color callback with error code: %d",
ret);
301 TangoCoordinateFramePair pair;
303 pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
304 pair.target = TANGO_COORDINATE_FRAME_DEVICE;
306 if (
ret != TANGO_SUCCESS)
308 LOGE(
"NativeRTABMap: Failed to connect to pose callback with error code: %d",
ret);
315 if (
ret != TANGO_SUCCESS)
317 LOGE(
"PointCloudApp: Failed to connect to event callback with error code: %d",
ret);
322 LOGI(
"NativeRTABMap: Connect to tango service");
324 if (
ret != TANGO_SUCCESS)
326 LOGE(
"NativeRTABMap: Failed to connect to the Tango service with error code: %d",
ret);
331 LOGI(
"NativeRTABMap: Update extrinsics");
332 TangoPoseData pose_data;
333 TangoCoordinateFramePair frame_pair;
340 frame_pair.base = TANGO_COORDINATE_FRAME_DEVICE;
341 frame_pair.target =
colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE;
342 ret = TangoService_getPoseAtTime(0.0, frame_pair, &pose_data);
343 if (
ret != TANGO_SUCCESS)
345 LOGE(
"NativeRTABMap: Failed to get transform between the color camera frame and device frames");
349 pose_data.translation[0],
350 pose_data.translation[1],
351 pose_data.translation[2],
352 pose_data.orientation[0],
353 pose_data.orientation[1],
354 pose_data.orientation[2],
355 pose_data.orientation[3]);
359 TangoCameraIntrinsics color_camera_intrinsics;
360 ret = TangoService_getCameraIntrinsics(
colorCamera_?TANGO_CAMERA_COLOR:TANGO_CAMERA_FISHEYE, &color_camera_intrinsics);
361 if (
ret != TANGO_SUCCESS)
363 LOGE(
"NativeRTABMap: Failed to get the intrinsics for the color camera with error code: %d.",
ret);
367 LOGD(
"Calibration: fx=%f fy=%f cx=%f cy=%f width=%d height=%d",
368 color_camera_intrinsics.fx,
369 color_camera_intrinsics.fy,
370 color_camera_intrinsics.cx,
371 color_camera_intrinsics.cy,
372 color_camera_intrinsics.width,
373 color_camera_intrinsics.height);
375 cv::Mat
K = cv::Mat::eye(3, 3, CV_64FC1);
376 K.at<
double>(0,0) = color_camera_intrinsics.fx;
377 K.at<
double>(1,1) = color_camera_intrinsics.fy;
378 K.at<
double>(0,2) = color_camera_intrinsics.cx;
379 K.at<
double>(1,2) = color_camera_intrinsics.cy;
380 cv::Mat
D = cv::Mat::zeros(1, 5, CV_64FC1);
381 LOGD(
"Calibration type = %d", color_camera_intrinsics.calibration_type);
382 if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_5_PARAMETERS ||
383 color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_EQUIDISTANT)
385 D.at<
double>(0,0) = color_camera_intrinsics.distortion[0];
386 D.at<
double>(0,1) = color_camera_intrinsics.distortion[1];
387 D.at<
double>(0,2) = color_camera_intrinsics.distortion[2];
388 D.at<
double>(0,3) = color_camera_intrinsics.distortion[3];
389 D.at<
double>(0,4) = color_camera_intrinsics.distortion[4];
391 else if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_3_PARAMETERS)
393 D.at<
double>(0,0) = color_camera_intrinsics.distortion[0];
394 D.at<
double>(0,1) = color_camera_intrinsics.distortion[1];
395 D.at<
double>(0,2) = 0.;
396 D.at<
double>(0,3) = 0.;
397 D.at<
double>(0,4) = color_camera_intrinsics.distortion[2];
399 else if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_2_PARAMETERS)
401 D.at<
double>(0,0) = color_camera_intrinsics.distortion[0];
402 D.at<
double>(0,1) = color_camera_intrinsics.distortion[1];
403 D.at<
double>(0,2) = 0.;
404 D.at<
double>(0,3) = 0.;
405 D.at<
double>(0,4) = 0.;
408 cv::Mat
R = cv::Mat::eye(3, 3, CV_64FC1);
411 LOGD(
"Distortion params: %f, %f, %f, %f, %f",
D.at<
double>(0,0),
D.at<
double>(0,1),
D.at<
double>(0,2),
D.at<
double>(0,3),
D.at<
double>(0,4));
413 cv::Size(color_camera_intrinsics.width, color_camera_intrinsics.height),
432 LOGI(
"TangoService_disconnect()");
433 TangoService_disconnect();
434 LOGI(
"TangoService_disconnect() done.");
448 UASSERT(cloud.type() == CV_32FC4);
466 if(
dt >= 0.0 &&
dt < 0.5)
472 double cloudStamp = timestamp;
480 LOGD(
"tangoColorType=%d", tangoColorType);
481 if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
483 cv::cvtColor(tangoImage, rgb, cv::COLOR_RGBA2BGR);
485 else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YV12)
487 cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_YV12);
489 else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
491 cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_NV21);
493 else if(tangoColorType == 35)
495 cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV420sp2GRAY);
499 LOGE(
"Not supported color format : %d.", tangoColorType);
536 TangoPoseData pose_color_image_t1_T_depth_image_t0;
537 if (TangoSupport_calculateRelativePose(
538 rgbStamp,
colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE, cloudStamp,
539 TANGO_COORDINATE_FRAME_CAMERA_DEPTH,
540 &pose_color_image_t1_T_depth_image_t0) == TANGO_SUCCESS)
547 "SynchronizationApplication: Could not find a valid relative pose at "
548 "time for color and "
554 LOGE(
"Very large color to depth error detected (%s)! Ignoring this frame!", colorToDepth.
prettyPrint().c_str());
558 if(!colorToDepth.
isNull())
563 LOGD(
"rgb=%dx%d cloud size=%d", rgb.cols, rgb.rows, (
int)cloud.total());
573 closeROI[0] = depth.cols/4;
574 closeROI[1] = 3*(depth.cols/4);
575 closeROI[2] = depth.rows/4;
576 closeROI[3] = 3*(depth.rows/4);
577 unsigned short minDepthValue=10000;
578 for(
unsigned int i=0;
i<cloud.total(); ++
i)
580 const float *
p = cloud.ptr<
float>(0,
i);
585 scanData.at(oi++) = pt;
588 int pixel_x_l, pixel_y_l, pixel_x_h, pixel_y_h;
590 pixel_x_l =
static_cast<int>((depthModel.
fx()) * (pt.x / pt.z) + depthModel.
cx());
591 pixel_y_l =
static_cast<int>((depthModel.
fy()) * (pt.y / pt.z) + depthModel.
cy());
592 pixel_x_h =
static_cast<int>((depthModel.
fx()) * (pt.x / pt.z) + depthModel.
cx() + 0.5f);
593 pixel_y_h =
static_cast<int>((depthModel.
fy()) * (pt.y / pt.z) + depthModel.
cy() + 0.5f);
594 unsigned short depth_value(pt.z * 1000.0f);
596 if(pixel_x_l>=closeROI[0] && pixel_x_l<closeROI[1] &&
597 pixel_y_l>closeROI[2] && pixel_y_l<closeROI[3] &&
601 if(depth_value < minDepthValue)
603 minDepthValue = depth_value;
607 bool pixelSet =
false;
608 if(pixel_x_l>=0 && pixel_x_l<depth.cols &&
609 pixel_y_l>0 && pixel_y_l<depth.rows &&
612 unsigned short & depthPixel = depth.at<
unsigned short>(pixel_y_l, pixel_x_l);
613 if(depthPixel == 0 || depthPixel > depth_value)
615 depthPixel = depth_value;
619 if(pixel_x_h>=0 && pixel_x_h<depth.cols &&
620 pixel_y_h>0 && pixel_y_h<depth.rows &&
623 unsigned short & depthPixel = depth.at<
unsigned short>(pixel_y_h, pixel_x_h);
624 if(depthPixel == 0 || depthPixel > depth_value)
626 depthPixel = depth_value;
636 if(closePoints > 100)
643 scan = cv::Mat(1, oi, CV_32FC3, scanData.data()).clone();
649 LOGE(
"color to depth pose is null?!? (rgb stamp=%f) (depth stamp=%f)", rgbStamp, cloudStamp);
652 if(!rgb.empty() && !depth.empty())
687 LOGE(
"Could not get depth and rgb images!?!");
696 LOGD(
"process cloud received %fs",
timer.ticks());
704 if(!tangoImage.empty())
732 tangoPose->translation[0],
733 tangoPose->translation[1],
734 tangoPose->translation[2],
735 tangoPose->orientation[0],
736 tangoPose->orientation[1],
737 tangoPose->orientation[2],
738 tangoPose->orientation[3]);
747 TangoPoseData pose_start_service_T_device;
748 TangoCoordinateFramePair frame_pair;
749 frame_pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
750 frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE;
751 TangoErrorType status = TangoService_getPoseAtTime(timestamp, frame_pair, &pose_start_service_T_device);
752 if (status != TANGO_SUCCESS)
755 "PoseData: Failed to get transform between the Start of service and "
756 "device frames at timestamp %lf",
759 if (pose_start_service_T_device.status_code != TANGO_POSE_VALID)
762 "PoseData: Failed to get transform between the Start of service and "
763 "device frames at timestamp %lf",
782 glBindTexture(GL_TEXTURE_EXTERNAL_OES,
textureId_);
783 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
784 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
785 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
786 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
792 double video_overlay_timestamp;
793 TangoErrorType status = TangoService_updateTextureExternalOes(TANGO_CAMERA_COLOR,
textureId_, &video_overlay_timestamp);
795 if (status == TANGO_SUCCESS)
804 TangoDoubleMatrixTransformData matrix_transform;
805 status = TangoSupport_getDoubleMatrixTransformAtTime(
806 video_overlay_timestamp,
807 TANGO_COORDINATE_FRAME_CAMERA_COLOR,
808 TANGO_COORDINATE_FRAME_START_OF_SERVICE,
809 TANGO_SUPPORT_ENGINE_OPENGL,
810 TANGO_SUPPORT_ENGINE_OPENGL,
811 static_cast<TangoSupportRotation
>(
rotation),
813 if (matrix_transform.status_code == TANGO_POSE_VALID)
816 TangoCameraIntrinsics color_camera_intrinsics;
817 int ret = TangoSupport_getCameraIntrinsicsBasedOnDisplayRotation(
819 static_cast<TangoSupportRotation
>(
rotation),
820 &color_camera_intrinsics);
822 if (
ret == TANGO_SUCCESS) {
823 float image_width =
static_cast<float>(color_camera_intrinsics.width);
824 float image_height =
static_cast<float>(color_camera_intrinsics.height);
825 float fx =
static_cast<float>(color_camera_intrinsics.fx);
826 float fy =
static_cast<float>(color_camera_intrinsics.fy);
827 float cx =
static_cast<float>(color_camera_intrinsics.cx);
828 float cy =
static_cast<float>(color_camera_intrinsics.cy);
833 image_width, image_height,
fx,
fy,
cx,
cy, 0.3, 50);
854 UERROR(
"TangoSupport_getCameraIntrinsicsBasedOnDisplayRotation failed!");
859 UERROR(
"TangoSupport_getDoubleMatrixTransformAtTime failed!");
864 UERROR(
"TangoService_updateTextureExternalOes failed!");
874 pose =
data.groundTruth();