34 #include <tango_client_api.h> 35 #include <tango_support_api.h> 49 if(app->
isRunning() && point_cloud->num_points>0)
51 app->
cloudReceived(cv::Mat(1, point_cloud->num_points, CV_32FC4, point_cloud->points[0]), point_cloud->timestamp);
61 if(color->format == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
63 tangoImage = cv::Mat(color->height, color->width, CV_8UC4, color->data);
65 else if(color->format == TANGO_HAL_PIXEL_FORMAT_YV12)
67 tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
69 else if(color->format == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
71 tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
73 else if(color->format == 35)
75 tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
79 LOGE(
"Not supported color format : %d.", color->format);
82 if(!tangoImage.empty())
84 app->
rgbReceived(tangoImage, (
unsigned int)color->format, color->timestamp);
91 if(pose->status_code == TANGO_POSE_VALID)
110 colorCamera_(colorCamera),
111 decimation_(decimation),
112 rawScanPublished_(publishRawScan),
131 double xu,
double yu,
double w,
double w_inverse,
double two_tan_w_div_two,
132 double* xd,
double* yd) {
133 double ru =
sqrt(xu * xu + yu * yu);
135 if (w < epsilon || ru < epsilon) {
139 double rd_div_ru =
std::atan(ru * two_tan_w_div_two) * w_inverse / ru;
140 *xd = xu * rd_div_ru;
141 *yd = yu * rd_div_ru;
153 cv::Mat & mapX, cv::Mat & mapY) {
154 const double & fx = fisheyeModel.
K().at<
double>(0,0);
155 const double & fy = fisheyeModel.
K().at<
double>(1,1);
156 const double & cx = fisheyeModel.
K().at<
double>(0,2);
157 const double & cy = fisheyeModel.
K().at<
double>(1,2);
158 const double & w = fisheyeModel.
D().at<
double>(0,0);
159 mapX.create(fisheyeModel.
imageSize(), CV_32FC1);
160 mapY.create(fisheyeModel.
imageSize(), CV_32FC1);
161 LOGD(
"initFisheyeRectificationMap: fx=%f fy=%f, cx=%f, cy=%f, w=%f", fx, fy, cx, cy, w);
163 const double fy_inverse = 1.0 / fy;
164 const double fx_inverse = 1.0 / fx;
165 const double w_inverse = 1 / w;
166 const double two_tan_w_div_two = 2.0 *
std::tan(w * 0.5);
170 for(
int iu = 0; iu < fisheyeModel.
imageHeight(); ++iu) {
171 for (
int ju = 0; ju < fisheyeModel.
imageWidth(); ++ju) {
172 double xu = (ju - cx) * fx_inverse;
173 double yu = (iu - cy) * fy_inverse;
175 applyFovModel(xu, yu, w, w_inverse, two_tan_w_div_two, &xd, &yd);
176 double jd = cx + xd * fx;
177 double id = cy + yd * fy;
178 mapX.at<
float>(iu, ju) = jd;
179 mapY.at<
float>(iu, ju) =
id;
188 TangoSupport_initialize(TangoService_getPoseAtTime, TangoService_getCameraIntrinsics);
191 LOGI(
"NativeRTABMap: Setup tango config");
192 tango_config_ = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
195 LOGE(
"NativeRTABMap: Failed to get default config form");
200 bool is_atuo_recovery =
true;
201 int ret = TangoConfig_setBool(
tango_config_,
"config_enable_auto_recovery", is_atuo_recovery);
202 if (ret != TANGO_SUCCESS)
204 LOGE(
"NativeRTABMap: config_enable_auto_recovery() failed with error code: %d", ret);
211 ret = TangoConfig_setBool(
tango_config_,
"config_enable_color_camera",
true);
212 if (ret != TANGO_SUCCESS)
214 LOGE(
"NativeRTABMap: config_enable_color_camera() failed with error code: %d", ret);
220 ret = TangoConfig_setBool(
tango_config_,
"config_enable_depth",
true);
221 if (ret != TANGO_SUCCESS)
223 LOGE(
"NativeRTABMap: config_enable_depth() failed with error code: %d", ret);
228 ret = TangoConfig_setInt32(
tango_config_,
"config_depth_mode", TANGO_POINTCLOUD_XYZC);
229 if (ret != TANGO_SUCCESS)
231 LOGE(
"Failed to set 'depth_mode' configuration flag with error code: %d", ret);
239 ret = TangoConfig_setBool(
tango_config_,
"config_enable_low_latency_imu_integration",
true);
240 if (ret != TANGO_SUCCESS)
242 LOGE(
"NativeRTABMap: Failed to enable low latency imu integration.");
261 ret = TangoConfig_getString(
tango_config_,
"tango_service_library_version", tango_core_version, kVersionStringLength);
262 if (ret != TANGO_SUCCESS)
264 LOGE(
"NativeRTABMap: get tango core version failed with error code: %d", ret);
267 LOGI(
"NativeRTABMap: Tango version : %s", tango_core_version);
271 LOGI(
"NativeRTABMap: Setup callbacks");
275 if (ret != TANGO_SUCCESS)
277 LOGE(
"NativeRTABMap: Failed to connect to point cloud callback with error code: %d", ret);
282 if (ret != TANGO_SUCCESS)
284 LOGE(
"NativeRTABMap: Failed to connect to color callback with error code: %d", ret);
290 TangoCoordinateFramePair pair;
292 pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
293 pair.target = TANGO_COORDINATE_FRAME_DEVICE;
295 if (ret != TANGO_SUCCESS)
297 LOGE(
"NativeRTABMap: Failed to connect to pose callback with error code: %d", ret);
304 if (ret != TANGO_SUCCESS)
306 LOGE(
"PointCloudApp: Failed to connect to event callback with error code: %d", ret);
311 LOGI(
"NativeRTABMap: Connect to tango service");
313 if (ret != TANGO_SUCCESS)
315 LOGE(
"NativeRTABMap: Failed to connect to the Tango service with error code: %d", ret);
320 LOGI(
"NativeRTABMap: Update extrinsics");
321 TangoPoseData pose_data;
322 TangoCoordinateFramePair frame_pair;
329 frame_pair.base = TANGO_COORDINATE_FRAME_DEVICE;
330 frame_pair.target =
colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE;
331 ret = TangoService_getPoseAtTime(0.0, frame_pair, &pose_data);
332 if (ret != TANGO_SUCCESS)
334 LOGE(
"NativeRTABMap: Failed to get transform between the color camera frame and device frames");
338 pose_data.translation[0],
339 pose_data.translation[1],
340 pose_data.translation[2],
341 pose_data.orientation[0],
342 pose_data.orientation[1],
343 pose_data.orientation[2],
344 pose_data.orientation[3]);
348 TangoCameraIntrinsics color_camera_intrinsics;
349 ret = TangoService_getCameraIntrinsics(
colorCamera_?TANGO_CAMERA_COLOR:TANGO_CAMERA_FISHEYE, &color_camera_intrinsics);
350 if (ret != TANGO_SUCCESS)
352 LOGE(
"NativeRTABMap: Failed to get the intrinsics for the color camera with error code: %d.", ret);
356 LOGD(
"Calibration: fx=%f fy=%f cx=%f cy=%f width=%d height=%d",
357 color_camera_intrinsics.fx,
358 color_camera_intrinsics.fy,
359 color_camera_intrinsics.cx,
360 color_camera_intrinsics.cy,
361 color_camera_intrinsics.width,
362 color_camera_intrinsics.height);
364 cv::Mat K = cv::Mat::eye(3, 3, CV_64FC1);
365 K.at<
double>(0,0) = color_camera_intrinsics.fx;
366 K.at<
double>(1,1) = color_camera_intrinsics.fy;
367 K.at<
double>(0,2) = color_camera_intrinsics.cx;
368 K.at<
double>(1,2) = color_camera_intrinsics.cy;
369 cv::Mat D = cv::Mat::zeros(1, 5, CV_64FC1);
370 LOGD(
"Calibration type = %d", color_camera_intrinsics.calibration_type);
371 if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_5_PARAMETERS ||
372 color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_EQUIDISTANT)
374 D.at<
double>(0,0) = color_camera_intrinsics.distortion[0];
375 D.at<
double>(0,1) = color_camera_intrinsics.distortion[1];
376 D.at<
double>(0,2) = color_camera_intrinsics.distortion[2];
377 D.at<
double>(0,3) = color_camera_intrinsics.distortion[3];
378 D.at<
double>(0,4) = color_camera_intrinsics.distortion[4];
380 else if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_3_PARAMETERS)
382 D.at<
double>(0,0) = color_camera_intrinsics.distortion[0];
383 D.at<
double>(0,1) = color_camera_intrinsics.distortion[1];
384 D.at<
double>(0,2) = 0.;
385 D.at<
double>(0,3) = 0.;
386 D.at<
double>(0,4) = color_camera_intrinsics.distortion[2];
388 else if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_2_PARAMETERS)
390 D.at<
double>(0,0) = color_camera_intrinsics.distortion[0];
391 D.at<
double>(0,1) = color_camera_intrinsics.distortion[1];
392 D.at<
double>(0,2) = 0.;
393 D.at<
double>(0,3) = 0.;
394 D.at<
double>(0,4) = 0.;
397 cv::Mat R = cv::Mat::eye(3, 3, CV_64FC1);
400 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));
402 cv::Size(color_camera_intrinsics.width, color_camera_intrinsics.height),
404 deviceTColorCamera_);
411 LOGI(
"deviceTColorCameraRtabmap =%s", deviceTColorCamera_.prettyPrint().c_str());
421 LOGI(
"TangoService_disconnect()");
422 TangoService_disconnect();
423 LOGI(
"TangoService_disconnect() done.");
437 UASSERT(cloud.type() == CV_32FC4);
454 if(dt >= 0.0 && dt < 0.5)
456 bool notify =
cloud_.empty();
471 if(this->
isRunning() && !tangoImage.empty())
499 tangoPose->translation[0],
500 tangoPose->translation[1],
501 tangoPose->translation[2],
502 tangoPose->orientation[0],
503 tangoPose->orientation[1],
504 tangoPose->orientation[2],
505 tangoPose->orientation[3]);
514 TangoPoseData pose_start_service_T_device;
515 TangoCoordinateFramePair frame_pair;
516 frame_pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
517 frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE;
518 TangoErrorType status = TangoService_getPoseAtTime(timestamp, frame_pair, &pose_start_service_T_device);
519 if (status != TANGO_SUCCESS)
522 "PoseData: Failed to get transform between the Start of service and " 523 "device frames at timestamp %lf",
526 if (pose_start_service_T_device.status_code != TANGO_POSE_VALID)
529 "PoseData: Failed to get transform between the Start of service and " 530 "device frames at timestamp %lf",
551 LOGE(
"Not received any frames since 2 seconds, try to restart the camera again.");
557 UERROR(
"cloud and image were set!?");
571 double cloudStamp = 0.0;
572 double rgbStamp = 0.0;
573 int tangoColorType = 0;
589 LOGD(
"tangoColorType=%d", tangoColorType);
590 if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
592 cv::cvtColor(tangoImage, rgb, CV_RGBA2BGR);
594 else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YV12)
596 cv::cvtColor(tangoImage, rgb, CV_YUV2BGR_YV12);
598 else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
600 cv::cvtColor(tangoImage, rgb, CV_YUV2BGR_NV21);
602 else if(tangoColorType == 35)
604 cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV420sp2GRAY);
608 LOGE(
"Not supported color format : %d.", tangoColorType);
644 TangoPoseData pose_color_image_t1_T_depth_image_t0;
645 if (TangoSupport_calculateRelativePose(
646 rgbStamp,
colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE, cloudStamp,
647 TANGO_COORDINATE_FRAME_CAMERA_DEPTH,
648 &pose_color_image_t1_T_depth_image_t0) == TANGO_SUCCESS)
655 "SynchronizationApplication: Could not find a valid relative pose at " 656 "time for color and " 662 LOGE(
"Very large color to depth error detected (%s)! Ignoring this frame!", colorToDepth.
prettyPrint().c_str());
666 if(!colorToDepth.
isNull())
671 LOGD(
"rgb=%dx%d cloud size=%d", rgb.cols, rgb.rows, (
int)cloud.total());
681 closeROI[0] = depth.cols/4;
682 closeROI[1] = 3*(depth.cols/4);
683 closeROI[2] = depth.rows/4;
684 closeROI[3] = 3*(depth.rows/4);
685 unsigned short minDepthValue=10000;
686 for(
unsigned int i=0; i<cloud.total(); ++i)
688 float * p = cloud.ptr<
float>(0,i);
693 scanData.at(oi++) = pt;
696 int pixel_x_l, pixel_y_l, pixel_x_h, pixel_y_h;
698 pixel_x_l =
static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx());
699 pixel_y_l =
static_cast<int>((depthModel.fy()) * (pt.y / pt.z) + depthModel.cy());
700 pixel_x_h =
static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx() + 0.5f);
701 pixel_y_h =
static_cast<int>((depthModel.fy()) * (pt.y / pt.z) + depthModel.cy() + 0.5f);
702 unsigned short depth_value(pt.z * 1000.0f);
704 if(pixel_x_l>=closeROI[0] && pixel_x_l<closeROI[1] &&
705 pixel_y_l>closeROI[2] && pixel_y_l<closeROI[3] &&
709 if(depth_value < minDepthValue)
711 minDepthValue = depth_value;
715 bool pixelSet =
false;
716 if(pixel_x_l>=0 && pixel_x_l<depth.cols &&
717 pixel_y_l>0 && pixel_y_l<depth.rows &&
720 unsigned short & depthPixel = depth.at<
unsigned short>(pixel_y_l, pixel_x_l);
721 if(depthPixel == 0 || depthPixel > depth_value)
723 depthPixel = depth_value;
727 if(pixel_x_h>=0 && pixel_x_h<depth.cols &&
728 pixel_y_h>0 && pixel_y_h<depth.rows &&
731 unsigned short & depthPixel = depth.at<
unsigned short>(pixel_y_h, pixel_x_h);
732 if(depthPixel == 0 || depthPixel > depth_value)
734 depthPixel = depth_value;
744 if(closePoints > 100)
751 scan = cv::Mat(1, oi, CV_32FC3, scanData.data()).clone();
757 LOGE(
"color to depth pose is null?!? (rgb stamp=%f) (depth stamp=%f)", rgbStamp, cloudStamp);
760 if(!rgb.empty() && !depth.empty())
793 LOGE(
"Could not get depth and rgb images!?!");
virtual SensorData captureImage(CameraInfo *info=0)
static const rtabmap::Transform tango_device_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)
cv::Mat fisheyeRectifyMapY_
void cloudReceived(const cv::Mat &cloud, double timestamp)
const cv::Size & imageSize() const
static const rtabmap::Transform rtabmap_world_T_tango_world(0.0f, 1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f)
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
void onTangoEventAvailableRouter(void *context, const TangoEvent *event)
virtual bool init(const std::string &calibrationFolder=".", const std::string &cameraName="")
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
const Transform & getOriginOffset() const
const float maxDepthError
GLM_FUNC_DECL genType e()
bool acquire(int n=1, int ms=0)
void poseReceived(const Transform &pose)
cv::Mat fisheyeRectifyMapX_
const int scanDownsampling
void post(UEvent *event, bool async=true) const
GLM_FUNC_DECL bool isNull(detail::tmat2x2< T, P > const &m, T const &epsilon)
#define UASSERT(condition)
Transform deviceTColorCamera_
const int kVersionStringLength
virtual std::string getSerial() const
cv::Mat RTABMAP_EXP decimate(const cv::Mat &image, int d)
GLM_FUNC_DECL genType atan(genType const &y, genType const &x)
CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing)
void tangoEventReceived(int type, const char *key, const char *value)
GLM_FUNC_DECL genType tan(genType const &angle)
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)
void onPoseAvailableRouter(void *context, const TangoPoseData *pose)
cv::Mat RTABMAP_EXP fillDepthHoles(const cv::Mat &depth, int maximumHoleSize=1, float errorRatio=0.02f)
ULogger class and convenient macros.
void onFrameAvailableRouter(void *context, TangoCameraId id, const TangoImageBuffer *color)
void initFisheyeRectificationMap(const CameraModel &fisheyeModel, cv::Mat &mapX, cv::Mat &mapY)
void rgbReceived(const cv::Mat &tangoImage, int type, double timestamp)
void onPointCloudAvailableRouter(void *context, const TangoPointCloud *point_cloud)
static LaserScan backwardCompatibility(const cv::Mat &oldScanFormat, int maxPoints=0, int maxRange=0, const Transform &localTransform=Transform::getIdentity())
void applyFovModel(double xu, double yu, double w, double w_inverse, double two_tan_w_div_two, double *xd, double *yd)
CameraModel scaled(double scale) const
const Transform & localTransform() const
rtabmap::Transform getPoseAtTimestamp(double timestamp)
rtabmap::Transform tangoPoseToTransform(const TangoPoseData *tangoPose) const