00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "tango_ros_native/tango_3d_reconstruction_helper.h"
00015 #include "tango_ros_native/tango_ros_conversions_helper.h"
00016
00017 #include <glog/logging.h>
00018
00019 namespace tango_3d_reconstruction_helper {
00020 Tango3DR_Status TangoSetup3DRConfig(
00021 const ros::NodeHandle& node_handle, double* t3dr_resolution,
00022 Tango3DR_ReconstructionContext* t3dr_context,
00023 Tango3DR_CameraCalibration* t3dr_color_camera_intrinsics) {
00024 const char* function_name = "TangoRosNodelet::TangoSetup3DRConfig()";
00025
00026 Tango3DR_Config t3dr_config =
00027 Tango3DR_Config_create(TANGO_3DR_CONFIG_RECONSTRUCTION);
00028 Tango3DR_Status result;
00029 const char* resolution = "resolution";
00030 double t3dr_resolution_param;
00031 node_handle.param(TANGO_3DR_RESOLUTION_PARAM_NAME,
00032 t3dr_resolution_param, TANGO_3DR_DEFAULT_RESOLUTION);
00033 *t3dr_resolution = t3dr_resolution_param;
00034 result = Tango3DR_Config_setDouble(t3dr_config, resolution, t3dr_resolution_param);
00035 if (result != TANGO_3DR_SUCCESS) {
00036 LOG(ERROR) << function_name << ", Tango3DR_Config_setDouble "
00037 << resolution << " error: " << result;
00038 return result;
00039 }
00040 const char* generate_color = "generate_color";
00041 result = Tango3DR_Config_setBool(t3dr_config, generate_color, true);
00042 if (result != TANGO_3DR_SUCCESS) {
00043 LOG(ERROR) << function_name << ", Tango3DR_Config_setBool "
00044 << generate_color << " error: " << result;
00045 return result;
00046 }
00047 const char* use_floorplan = "use_floorplan";
00048 result = Tango3DR_Config_setBool(t3dr_config, use_floorplan, true);
00049 if (result != TANGO_3DR_SUCCESS) {
00050 LOG(ERROR) << function_name << ", Tango3DR_Config_setBool "
00051 << use_floorplan << " error: " << result;
00052 return result;
00053 }
00054 const char* use_space_clearing = "use_space_clearing";
00055 bool t3dr_use_space_clearing;
00056 node_handle.param(TANGO_3DR_USE_SPACE_CLEARING_PARAM_NAME,
00057 t3dr_use_space_clearing, TANGO_3DR_DEFAULT_USE_SPACE_CLEARING);
00058 result = Tango3DR_Config_setBool(t3dr_config, use_space_clearing,
00059 t3dr_use_space_clearing);
00060 if (result != TANGO_3DR_SUCCESS) {
00061 LOG(ERROR) << function_name << ", Tango3DR_Config_setBool "
00062 << use_space_clearing << " error: " << result;
00063 return result;
00064 }
00065 const char* min_num_vertices = "min_num_vertices";
00066 int t3dr_min_num_vertices;
00067 node_handle.param(TANGO_3DR_MIN_NUM_VERTICES_PARAM_NAME,
00068 t3dr_min_num_vertices, TANGO_3DR_DEFAULT_MIN_NUM_VERTICES);
00069 result = Tango3DR_Config_setInt32(t3dr_config, min_num_vertices,
00070 t3dr_min_num_vertices);
00071 if (result != TANGO_3DR_SUCCESS) {
00072 LOG(ERROR) << function_name << ", Tango3DR_Config_setInt32 "
00073 << min_num_vertices << " error: " << result;
00074 return result;
00075 }
00076 const char* update_method = "update_method";
00077 int t3dr_update_method;
00078 node_handle.param(TANGO_3DR_UPDATE_METHOD_PARAM_NAME,
00079 t3dr_update_method, TANGO_3DR_DEFAULT_UPDATE_METHOD);
00080 result = Tango3DR_Config_setInt32(t3dr_config, update_method,
00081 t3dr_update_method);
00082 if (result != TANGO_3DR_SUCCESS) {
00083 LOG(ERROR) << function_name << ", Tango3DR_Config_setInt32 "
00084 << update_method << " error: " << result;
00085 return result;
00086 }
00087 const char* max_voxel_weight = "max_voxel_weight";
00088 int t3dr_max_voxel_weight;
00089 node_handle.param(TANGO_3DR_MAX_VOXEL_WEIGHT_PARAM_NAME,
00090 t3dr_max_voxel_weight, TANGO_3DR_DEFAULT_MAX_VOXEL_WEIGHT);
00091 result = Tango3DR_Config_setInt32(t3dr_config, max_voxel_weight,
00092 t3dr_max_voxel_weight);
00093 if (result != TANGO_3DR_SUCCESS) {
00094 LOG(ERROR) << function_name << ", Tango3DR_Config_setInt32 "
00095 << max_voxel_weight << " error: " << result;
00096 return result;
00097 }
00098 const char* floorplan_max_error = "floorplan_max_error";
00099 double t3dr_floorplan_max_error;
00100 node_handle.param(TANGO_3DR_FLOORPLAN_MAX_ERROR_PARAM_NAME,
00101 t3dr_floorplan_max_error, TANGO_3DR_DEFAULT_FLOORPLAN_MAX_ERROR);
00102 result = Tango3DR_Config_setDouble(t3dr_config, floorplan_max_error,
00103 t3dr_floorplan_max_error);
00104 if (result != TANGO_3DR_SUCCESS) {
00105 LOG(ERROR) << function_name << ", Tango3DR_Config_setDouble "
00106 << floorplan_max_error << " error: " << result;
00107 return result;
00108 }
00109
00110 *t3dr_context = Tango3DR_ReconstructionContext_create(t3dr_config);
00111 if (*t3dr_context == nullptr) {
00112 LOG(ERROR) << function_name << ", Tango3DR_ReconstructionContext_create error: "
00113 "Unable to create 3DR context.";
00114 return TANGO_3DR_ERROR;
00115 }
00116
00117 result = Tango3DR_ReconstructionContext_setColorCalibration(
00118 *t3dr_context, t3dr_color_camera_intrinsics);
00119 if (result != TANGO_3DR_SUCCESS) {
00120 LOG(ERROR) << function_name << ", Unable to set color calibration.";
00121 return TANGO_3DR_ERROR;
00122 }
00123 return Tango3DR_Config_destroy(t3dr_config);
00124 }
00125
00126 void UpdateMesh(const Tango3DR_ReconstructionContext& t3dr_context,
00127 TangoSupport_PointCloudManager* point_cloud_manager,
00128 TangoSupport_ImageBufferManager* image_buffer_manager,
00129 Tango3DR_Pose* last_camera_depth_pose,
00130 Tango3DR_Pose* last_camera_color_pose,
00131 Tango3DR_GridIndexArray* t3dr_updated_indices) {
00132
00133 TangoPointCloud* last_point_cloud;
00134 TangoSupport_getLatestPointCloud(point_cloud_manager, &last_point_cloud);
00135 Tango3DR_PointCloud t3dr_depth;
00136 t3dr_depth.timestamp = last_point_cloud->timestamp;
00137 t3dr_depth.num_points = last_point_cloud->num_points;
00138 t3dr_depth.points = reinterpret_cast<Tango3DR_Vector4*>(
00139 last_point_cloud->points);
00140
00141 TangoImageBuffer* last_color_image_buffer;
00142 if (image_buffer_manager != nullptr) {
00143 TangoSupport_getLatestImageBuffer(image_buffer_manager,
00144 &last_color_image_buffer);
00145 Tango3DR_ImageBuffer t3dr_image;
00146 t3dr_image.width = last_color_image_buffer->width;
00147 t3dr_image.height = last_color_image_buffer->height;
00148 t3dr_image.stride = last_color_image_buffer->stride;
00149 t3dr_image.timestamp = last_color_image_buffer->timestamp;
00150 t3dr_image.format = static_cast<Tango3DR_ImageFormatType>(
00151 last_color_image_buffer->format);
00152 t3dr_image.data = last_color_image_buffer->data;
00153
00154 Tango3DR_Status result =
00155 Tango3DR_updateFromPointCloud(t3dr_context, &t3dr_depth, last_camera_depth_pose,
00156 &t3dr_image, last_camera_color_pose,
00157 t3dr_updated_indices);
00158 if (result != TANGO_3DR_SUCCESS) {
00159 LOG(ERROR) << "Tango3DR_updateFromPointCloud failed with error code "
00160 << result;
00161 }
00162 }
00163 }
00164
00165 void ExtractMeshAndConvertToMarkerArray(
00166 const Tango3DR_ReconstructionContext& t3dr_context,
00167 const Tango3DR_GridIndexArray& t3dr_updated_indices,
00168 double time_offset, const std::string& base_frame_id,
00169 visualization_msgs::MarkerArray* mesh_marker_array) {
00170 for (size_t i = 0; i < t3dr_updated_indices.num_indices; ++i) {
00171
00172 Tango3DR_Mesh tango_mesh;
00173 Tango3DR_Status result = Tango3DR_extractMeshSegment(
00174 t3dr_context, t3dr_updated_indices.indices[i], &tango_mesh);
00175 if(result != TANGO_3DR_SUCCESS) {
00176 LOG(ERROR) << "Tango3DR_extractMeshSegment failed.";
00177 continue;
00178 }
00179 if (tango_mesh.num_faces == 0) {
00180 LOG(INFO) << "Empty mesh extracted.";
00181 continue;
00182 }
00183
00184 visualization_msgs::Marker mesh_marker;
00185 tango_ros_conversions_helper::toMeshMarker(t3dr_updated_indices.indices[i],
00186 tango_mesh, time_offset, base_frame_id, &mesh_marker);
00187
00188 result = Tango3DR_Mesh_destroy(&tango_mesh);
00189 if (result != TANGO_3DR_SUCCESS) {
00190 LOG(ERROR) << "Tango3DR_Mesh_destroy failed with error code: "
00191 << result;
00192 }
00193 if (mesh_marker.points.empty()) {
00194 LOG(INFO) << "Empty mesh marker.";
00195 continue;
00196 }
00197 mesh_marker_array->markers.push_back(mesh_marker);
00198 }
00199 }
00200
00201 bool ExtractFloorPlanImageAndConvertToOccupancyGrid(
00202 const Tango3DR_ReconstructionContext& t3dr_context,
00203 double time_offset, const std::string& base_frame_id,
00204 double t3dr_resolution, uint8_t threshold,
00205 nav_msgs::OccupancyGrid* occupancy_grid) {
00206 Tango3DR_Status result = Tango3DR_updateFullFloorplan(t3dr_context);
00207 if (result == TANGO_3DR_SUCCESS) {
00208 Tango3DR_Vector2 origin;
00209 Tango3DR_ImageBuffer image_grid;
00210 result = Tango3DR_extractFullFloorplanImage(
00211 t3dr_context, TANGO_3DR_LAYER_SPACE, &origin, &image_grid);
00212 if (result == TANGO_3DR_SUCCESS) {
00213 tango_ros_conversions_helper::toOccupancyGrid(image_grid, origin,
00214 time_offset, base_frame_id, t3dr_resolution, threshold, occupancy_grid);
00215 } else {
00216 LOG(ERROR) << "Tango3DR_extractFullFloorplanImage failed with error"
00217 "code: " << result;
00218 return false;
00219 }
00220 result = Tango3DR_ImageBuffer_destroy(&image_grid);
00221 if (result != TANGO_3DR_SUCCESS) {
00222 LOG(ERROR) << "Tango3DR_ImageBuffer_destroy failed with error "
00223 "code: " << result;
00224 return false;
00225 }
00226 } else {
00227 LOG(ERROR) << "Tango3DR_updateFullFloorplan failed with error "
00228 "code: " << result;
00229 return false;
00230 }
00231 return true;
00232 }
00233 }