tango_3d_reconstruction_helper.cpp
Go to the documentation of this file.
00001 // Copyright 2017 Intermodalics All Rights Reserved.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      http://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
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   // Configure the color camera intrinsics to be used with updates to the mesh.
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   // Get latest point cloud.
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   // Get latest image.
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     // Get updated mesh segment indices.
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     // Extract Tango mesh from updated index.
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     // Make mesh marker from tango mesh.
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     // Free tango mesh once we are finished with it.
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 } // namespace tango_3d_reconstruction_helper


tango_ros_native
Author(s):
autogenerated on Thu Jun 6 2019 19:49:54