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;
197 TangoSupport_initialize(TangoService_getPoseAtTime, TangoService_getCameraIntrinsics);
200 LOGI(
"NativeRTABMap: Setup tango config");
201 tango_config_ = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
204 LOGE(
"NativeRTABMap: Failed to get default config form");
209 bool is_atuo_recovery =
true;
210 int ret = TangoConfig_setBool(
tango_config_,
"config_enable_auto_recovery", is_atuo_recovery);
211 if (
ret != TANGO_SUCCESS)
213 LOGE(
"NativeRTABMap: config_enable_auto_recovery() failed with error code: %d",
ret);
220 ret = TangoConfig_setBool(
tango_config_,
"config_enable_color_camera",
true);
221 if (
ret != TANGO_SUCCESS)
223 LOGE(
"NativeRTABMap: config_enable_color_camera() failed with error code: %d",
ret);
230 if (
ret != TANGO_SUCCESS)
232 LOGE(
"NativeRTABMap: config_enable_depth() failed with error code: %d",
ret);
237 ret = TangoConfig_setInt32(
tango_config_,
"config_depth_mode", TANGO_POINTCLOUD_XYZC);
238 if (
ret != TANGO_SUCCESS)
240 LOGE(
"Failed to set 'depth_mode' configuration flag with error code: %d",
ret);
248 ret = TangoConfig_setBool(
tango_config_,
"config_enable_low_latency_imu_integration",
true);
249 if (
ret != TANGO_SUCCESS)
251 LOGE(
"NativeRTABMap: Failed to enable low latency imu integration.");
271 if (
ret != TANGO_SUCCESS)
273 LOGE(
"NativeRTABMap: get tango core version failed with error code: %d",
ret);
276 LOGI(
"NativeRTABMap: Tango version : %s", tango_core_version);
280 LOGI(
"NativeRTABMap: Setup callbacks");
284 if (
ret != TANGO_SUCCESS)
286 LOGE(
"NativeRTABMap: Failed to connect to point cloud callback with error code: %d",
ret);
291 if (
ret != TANGO_SUCCESS)
293 LOGE(
"NativeRTABMap: Failed to connect to color callback with error code: %d",
ret);
299 TangoCoordinateFramePair pair;
301 pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
302 pair.target = TANGO_COORDINATE_FRAME_DEVICE;
304 if (
ret != TANGO_SUCCESS)
306 LOGE(
"NativeRTABMap: Failed to connect to pose callback with error code: %d",
ret);
313 if (
ret != TANGO_SUCCESS)
315 LOGE(
"PointCloudApp: Failed to connect to event callback with error code: %d",
ret);
320 LOGI(
"NativeRTABMap: Connect to tango service");
322 if (
ret != TANGO_SUCCESS)
324 LOGE(
"NativeRTABMap: Failed to connect to the Tango service with error code: %d",
ret);
329 LOGI(
"NativeRTABMap: Update extrinsics");
330 TangoPoseData pose_data;
331 TangoCoordinateFramePair frame_pair;
338 frame_pair.base = TANGO_COORDINATE_FRAME_DEVICE;
339 frame_pair.target =
colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE;
340 ret = TangoService_getPoseAtTime(0.0, frame_pair, &pose_data);
341 if (
ret != TANGO_SUCCESS)
343 LOGE(
"NativeRTABMap: Failed to get transform between the color camera frame and device frames");
347 pose_data.translation[0],
348 pose_data.translation[1],
349 pose_data.translation[2],
350 pose_data.orientation[0],
351 pose_data.orientation[1],
352 pose_data.orientation[2],
353 pose_data.orientation[3]);
357 TangoCameraIntrinsics color_camera_intrinsics;
358 ret = TangoService_getCameraIntrinsics(
colorCamera_?TANGO_CAMERA_COLOR:TANGO_CAMERA_FISHEYE, &color_camera_intrinsics);
359 if (
ret != TANGO_SUCCESS)
361 LOGE(
"NativeRTABMap: Failed to get the intrinsics for the color camera with error code: %d.",
ret);
365 LOGD(
"Calibration: fx=%f fy=%f cx=%f cy=%f width=%d height=%d",
366 color_camera_intrinsics.fx,
367 color_camera_intrinsics.fy,
368 color_camera_intrinsics.cx,
369 color_camera_intrinsics.cy,
370 color_camera_intrinsics.width,
371 color_camera_intrinsics.height);
373 cv::Mat
K = cv::Mat::eye(3, 3, CV_64FC1);
374 K.at<
double>(0,0) = color_camera_intrinsics.fx;
375 K.at<
double>(1,1) = color_camera_intrinsics.fy;
376 K.at<
double>(0,2) = color_camera_intrinsics.cx;
377 K.at<
double>(1,2) = color_camera_intrinsics.cy;
378 cv::Mat
D = cv::Mat::zeros(1, 5, CV_64FC1);
379 LOGD(
"Calibration type = %d", color_camera_intrinsics.calibration_type);
380 if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_5_PARAMETERS ||
381 color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_EQUIDISTANT)
383 D.at<
double>(0,0) = color_camera_intrinsics.distortion[0];
384 D.at<
double>(0,1) = color_camera_intrinsics.distortion[1];
385 D.at<
double>(0,2) = color_camera_intrinsics.distortion[2];
386 D.at<
double>(0,3) = color_camera_intrinsics.distortion[3];
387 D.at<
double>(0,4) = color_camera_intrinsics.distortion[4];
389 else if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_3_PARAMETERS)
391 D.at<
double>(0,0) = color_camera_intrinsics.distortion[0];
392 D.at<
double>(0,1) = color_camera_intrinsics.distortion[1];
393 D.at<
double>(0,2) = 0.;
394 D.at<
double>(0,3) = 0.;
395 D.at<
double>(0,4) = color_camera_intrinsics.distortion[2];
397 else if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_2_PARAMETERS)
399 D.at<
double>(0,0) = color_camera_intrinsics.distortion[0];
400 D.at<
double>(0,1) = color_camera_intrinsics.distortion[1];
401 D.at<
double>(0,2) = 0.;
402 D.at<
double>(0,3) = 0.;
403 D.at<
double>(0,4) = 0.;
406 cv::Mat
R = cv::Mat::eye(3, 3, CV_64FC1);
409 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));
411 cv::Size(color_camera_intrinsics.width, color_camera_intrinsics.height),
430 LOGI(
"TangoService_disconnect()");
431 TangoService_disconnect();
432 LOGI(
"TangoService_disconnect() done.");
446 UASSERT(cloud.type() == CV_32FC4);
464 if(
dt >= 0.0 &&
dt < 0.5)
470 double cloudStamp = timestamp;
478 LOGD(
"tangoColorType=%d", tangoColorType);
479 if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
481 cv::cvtColor(tangoImage, rgb, cv::COLOR_RGBA2BGR);
483 else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YV12)
485 cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_YV12);
487 else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
489 cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_NV21);
491 else if(tangoColorType == 35)
493 cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV420sp2GRAY);
497 LOGE(
"Not supported color format : %d.", tangoColorType);
534 TangoPoseData pose_color_image_t1_T_depth_image_t0;
535 if (TangoSupport_calculateRelativePose(
536 rgbStamp,
colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE, cloudStamp,
537 TANGO_COORDINATE_FRAME_CAMERA_DEPTH,
538 &pose_color_image_t1_T_depth_image_t0) == TANGO_SUCCESS)
545 "SynchronizationApplication: Could not find a valid relative pose at "
546 "time for color and "
552 LOGE(
"Very large color to depth error detected (%s)! Ignoring this frame!", colorToDepth.
prettyPrint().c_str());
556 if(!colorToDepth.
isNull())
561 LOGD(
"rgb=%dx%d cloud size=%d", rgb.cols, rgb.rows, (
int)cloud.total());
571 closeROI[0] = depth.cols/4;
572 closeROI[1] = 3*(depth.cols/4);
573 closeROI[2] = depth.rows/4;
574 closeROI[3] = 3*(depth.rows/4);
575 unsigned short minDepthValue=10000;
576 for(
unsigned int i=0;
i<cloud.total(); ++
i)
578 const float *
p = cloud.ptr<
float>(0,
i);
583 scanData.at(oi++) = pt;
586 int pixel_x_l, pixel_y_l, pixel_x_h, pixel_y_h;
588 pixel_x_l =
static_cast<int>((depthModel.
fx()) * (pt.x / pt.z) + depthModel.
cx());
589 pixel_y_l =
static_cast<int>((depthModel.
fy()) * (pt.y / pt.z) + depthModel.
cy());
590 pixel_x_h =
static_cast<int>((depthModel.
fx()) * (pt.x / pt.z) + depthModel.
cx() + 0.5f);
591 pixel_y_h =
static_cast<int>((depthModel.
fy()) * (pt.y / pt.z) + depthModel.
cy() + 0.5f);
592 unsigned short depth_value(pt.z * 1000.0f);
594 if(pixel_x_l>=closeROI[0] && pixel_x_l<closeROI[1] &&
595 pixel_y_l>closeROI[2] && pixel_y_l<closeROI[3] &&
599 if(depth_value < minDepthValue)
601 minDepthValue = depth_value;
605 bool pixelSet =
false;
606 if(pixel_x_l>=0 && pixel_x_l<depth.cols &&
607 pixel_y_l>0 && pixel_y_l<depth.rows &&
610 unsigned short & depthPixel = depth.at<
unsigned short>(pixel_y_l, pixel_x_l);
611 if(depthPixel == 0 || depthPixel > depth_value)
613 depthPixel = depth_value;
617 if(pixel_x_h>=0 && pixel_x_h<depth.cols &&
618 pixel_y_h>0 && pixel_y_h<depth.rows &&
621 unsigned short & depthPixel = depth.at<
unsigned short>(pixel_y_h, pixel_x_h);
622 if(depthPixel == 0 || depthPixel > depth_value)
624 depthPixel = depth_value;
634 if(closePoints > 100)
641 scan = cv::Mat(1, oi, CV_32FC3, scanData.data()).clone();
647 LOGE(
"color to depth pose is null?!? (rgb stamp=%f) (depth stamp=%f)", rgbStamp, cloudStamp);
650 if(!rgb.empty() && !depth.empty())
691 LOGE(
"Could not get depth and rgb images!?!");
700 LOGD(
"process cloud received %fs",
timer.ticks());
708 if(!tangoImage.empty())
736 tangoPose->translation[0],
737 tangoPose->translation[1],
738 tangoPose->translation[2],
739 tangoPose->orientation[0],
740 tangoPose->orientation[1],
741 tangoPose->orientation[2],
742 tangoPose->orientation[3]);
751 TangoPoseData pose_start_service_T_device;
752 TangoCoordinateFramePair frame_pair;
753 frame_pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
754 frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE;
755 TangoErrorType status = TangoService_getPoseAtTime(timestamp, frame_pair, &pose_start_service_T_device);
756 if (status != TANGO_SUCCESS)
759 "PoseData: Failed to get transform between the Start of service and "
760 "device frames at timestamp %lf",
763 if (pose_start_service_T_device.status_code != TANGO_POSE_VALID)
766 "PoseData: Failed to get transform between the Start of service and "
767 "device frames at timestamp %lf",
786 glBindTexture(GL_TEXTURE_EXTERNAL_OES,
textureId_);
787 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
788 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
789 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
790 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
796 double video_overlay_timestamp;
797 TangoErrorType status = TangoService_updateTextureExternalOes(TANGO_CAMERA_COLOR,
textureId_, &video_overlay_timestamp);
799 if (status == TANGO_SUCCESS)
808 TangoDoubleMatrixTransformData matrix_transform;
809 status = TangoSupport_getDoubleMatrixTransformAtTime(
810 video_overlay_timestamp,
811 TANGO_COORDINATE_FRAME_CAMERA_COLOR,
812 TANGO_COORDINATE_FRAME_START_OF_SERVICE,
813 TANGO_SUPPORT_ENGINE_OPENGL,
814 TANGO_SUPPORT_ENGINE_OPENGL,
815 static_cast<TangoSupportRotation
>(
rotation),
817 if (matrix_transform.status_code == TANGO_POSE_VALID)
820 TangoCameraIntrinsics color_camera_intrinsics;
821 int ret = TangoSupport_getCameraIntrinsicsBasedOnDisplayRotation(
823 static_cast<TangoSupportRotation
>(
rotation),
824 &color_camera_intrinsics);
826 if (
ret == TANGO_SUCCESS) {
827 float image_width =
static_cast<float>(color_camera_intrinsics.width);
828 float image_height =
static_cast<float>(color_camera_intrinsics.height);
829 float fx =
static_cast<float>(color_camera_intrinsics.fx);
830 float fy =
static_cast<float>(color_camera_intrinsics.fy);
831 float cx =
static_cast<float>(color_camera_intrinsics.cx);
832 float cy =
static_cast<float>(color_camera_intrinsics.cy);
841 image_width, image_height,
fx,
fy,
cx,
cy, 0.3, 50);
862 UERROR(
"TangoSupport_getCameraIntrinsicsBasedOnDisplayRotation failed!");
867 UERROR(
"TangoSupport_getDoubleMatrixTransformAtTime failed!");
872 UERROR(
"TangoService_updateTextureExternalOes failed!");
882 pose =
data.groundTruth();