fake_object_recognition.cpp
Go to the documentation of this file.
00001 
00018 #include "fake_object_recognition.h"
00019 #include <rapidxml.hpp>
00020 #include <rapidxml_utils.hpp>
00021 #include <ros/package.h>
00022 #include <boost/algorithm/string/predicate.hpp>
00023 #include <boost/lexical_cast.hpp>
00024 #include <boost/algorithm/string.hpp>
00025 #include "rating.h"
00026 #include "error_simulation.h"
00027 #include <unistd.h>
00028 #include <algorithm>
00029 //Eigen
00030 #include <Eigen/Geometry>
00031 
00032 #include "asr_object_database/ObjectMetaData.h"
00033 #include "ApproxMVBB/ComputeApproxMVBB.hpp"
00034 
00035 namespace fake_object_recognition {
00036 
00037 FakeObjectRecognition::FakeObjectRecognition() : nh_(NODE_NAME), config_changed_(false), recognition_released_(true) {
00038     ROS_DEBUG("Initialize process");
00039     nh_.getParam("fovx", fovx_); // Field of view in x.
00040     nh_.getParam("fovy", fovy_); // Field of view in y.
00041     nh_.getParam("ncp", ncp_); // Near clipping plane of fustrum.
00042     nh_.getParam("fcp", fcp_); // Far clipping plane of fustrum.
00043     nh_.getParam("frame_world", frame_world_);
00044     nh_.getParam("frame_camera_left", frame_camera_left_);
00045     nh_.getParam("frame_camera_right", frame_camera_right_);
00046     nh_.getParam("config_file_path", config_file_path_);
00047     nh_.getParam("output_rec_objects_topic", output_rec_objects_topic_);
00048     nh_.getParam("output_rec_marker_topic", output_rec_markers_topic_);
00049     nh_.getParam("output_constellation_topic", output_constellation_marker_topic_);
00050     nh_.getParam("output_normals_topic", output_normals_topic_);
00051     nh_.getParam("rating_threshold_d", rating_threshold_d_);
00052     nh_.getParam("rating_threshold_x", rating_threshold_x_);
00053     nh_.getParam("rating_threshold_y", rating_threshold_y_);
00054     nh_.getParam("timer_duration", timer_duration_);
00055 
00056     reconfigure_server_.setCallback(boost::bind(&FakeObjectRecognition::configCallback, this, _1, _2));
00057 
00058     get_recognizer_service_ = nh_.advertiseService(GET_RECOGNIZER_SERVICE_NAME, &FakeObjectRecognition::processGetRecognizerRequest, this);
00059     release_recognizer_service_ = nh_.advertiseService(RELEASE_RECOGNIZER_SERVICE_NAME, &FakeObjectRecognition::processReleaseRecognizerRequest, this);
00060 
00061     get_all_recognizers_service_ = nh_.advertiseService(GET_ALL_RECOGNIZERS_SERVICE_NAME, &FakeObjectRecognition::processGetAllRecognizersRequest, this);
00062     clear_all_recognizers_service_ = nh_.advertiseService(CLEAR_ALL_RECOGNIZERS_SERVICE_NAME, &FakeObjectRecognition::processClearAllRecognizers, this);
00063 
00064     recognized_objects_pub_ = nh_.advertise<asr_msgs::AsrObject>(output_rec_objects_topic_, 1);
00065     recognized_objects_marker_pub_ = nh_.advertise<visualization_msgs::Marker>(output_rec_markers_topic_, 1);
00066     generated_constellation_marker_pub_ = nh_.advertise<visualization_msgs::Marker>(output_constellation_marker_topic_, 1);
00067     object_normals_pub_ = nh_.advertise<visualization_msgs::MarkerArray>(output_normals_topic_, 100);
00068 
00069     timer_ = nh_.createTimer(ros::Duration(timer_duration_), &FakeObjectRecognition::timerCallback, this);
00070 
00071     //Only used here to visualize object constellation. The rest (errors etc) is done at first doRecognition() call.
00072     loadObjects();
00073 
00074     // initialize bounding boxes and normals:
00075     ROS_DEBUG_STREAM("Initializing object bounding boxes and normals");
00076     // Set up service to get normals:
00077     ros::service::waitForService("/asr_object_database/object_meta_data");
00078     object_metadata_service_client_ = nh_.serviceClient<asr_object_database::ObjectMetaData>("/asr_object_database/object_meta_data");
00079     // Set bounding box corner point filename:
00080     bb_corners_file_name_ = ros::package::getPath("asr_fake_object_recognition") + "/config/bounding_box_corners.xml";
00081     // Set object databse package name:
00082     object_database_name_ = "asr_object_database";
00083 
00084     for (std::vector<ObjectConfig>::iterator iter = objects_.begin(); iter != objects_.end(); ++iter) {
00085        if (normals_.find(iter->getType()) == normals_.end()) {    // if normals of object type not yet initialized
00086            ROS_DEBUG_STREAM("Initializing normals of object type " << iter->getType());
00087            normals_[iter->getType()] = getNormals(*iter);
00088            ROS_DEBUG_STREAM("Found " << normals_[iter->getType()].size() << " normals. Normals initialized.");
00089        }
00090        if (bounding_box_corners_.find(iter->getType()) == bounding_box_corners_.end()) { // if bounding box corners of object type not yet initialized
00091            ROS_DEBUG_STREAM("Initializing bounding box of object type " << iter->getType());
00092            std::array<geometry_msgs::Point, 8> corner_points;
00093            if (!getBBfromFile(corner_points, iter->getType())) { // No corners were found in file: calculate and write them to file
00094                corner_points = calculateBB(*iter);
00095            }
00096            bounding_box_corners_[iter->getType()] = corner_points;
00097            ROS_DEBUG_STREAM("Found " << bounding_box_corners_[iter->getType()].size() << " bounding box corner points. Bounding box initialized.");
00098         }
00099     }
00100     ROS_INFO("Recognition is initially released");
00101 }
00102 
00103 void FakeObjectRecognition::loadObjects() {
00104     objects_.clear();
00105 
00106     std::string xml_path;
00107     if (boost::starts_with(config_file_path_, ".")) //if path starts with a point, assume it's a relative path.
00108     {
00109         xml_path = ros::package::getPath("asr_fake_object_recognition") + config_file_path_.substr(1);
00110     }
00111     else //Otherwise use it as an absolute path
00112     {
00113         xml_path = config_file_path_;
00114     }
00115     ROS_DEBUG_STREAM("Path to objects.xml: " << xml_path);
00116 
00117     try {
00118         rapidxml::file<> xmlFile(xml_path.c_str());
00119         rapidxml::xml_document<> doc;
00120         doc.parse<0>(xmlFile.data());
00121 
00122         rapidxml::xml_node<> *root_node = doc.first_node();
00123         if (root_node) {
00124             rapidxml::xml_node<> *child_node = root_node->first_node();
00125             while (child_node) {
00126                 rapidxml::xml_attribute<> *type_attribute = child_node->first_attribute("type");
00127                 rapidxml::xml_attribute<> *id_attribute = child_node->first_attribute("id");
00128                 rapidxml::xml_attribute<> *mesh_attribute = child_node->first_attribute("mesh");
00129                 rapidxml::xml_attribute<> *angles_attribute = child_node->first_attribute("angles");
00130                 if (type_attribute && id_attribute && mesh_attribute && angles_attribute) {
00131                     std::string type = type_attribute->value();
00132                     std::string mesh = mesh_attribute->value();
00133                     std::string id = id_attribute->value();
00134                     std::string pose_string = child_node->value();
00135                     std::string angles = angles_attribute->value();
00136                     geometry_msgs::Pose pose;
00137                     if (parsePoseString(pose_string, pose, " ,", angles)) {
00138                         objects_.push_back(ObjectConfig(type, id, pose, mesh));
00139                     }
00140                 }
00141                 child_node = child_node->next_sibling();
00142             }
00143         }
00144     } catch(std::runtime_error err) {
00145         ROS_DEBUG_STREAM("Can't parse xml-file. Runtime error: " << err.what());
00146     } catch (rapidxml::parse_error err) {
00147         ROS_DEBUG_STREAM("Can't parse xml-file Parse error: " << err.what());
00148     }
00149 
00150 }
00151 
00152 
00153 bool FakeObjectRecognition::parsePoseString(std::string pose_in, geometry_msgs::Pose &pose_out, std::string delim, std::string angles) {
00154     std::vector<std::string> strvec;
00155 
00156     boost::algorithm::trim_if(pose_in, boost::algorithm::is_any_of(delim));
00157     boost::algorithm::split(strvec, pose_in, boost::algorithm::is_any_of(delim), boost::algorithm::token_compress_on);
00158     if (strvec.size() == 6 || strvec.size() == 7) {
00159         try {
00160             pose_out.position.x = boost::lexical_cast<double>(strvec[0]);
00161             pose_out.position.y = boost::lexical_cast<double>(strvec[1]);
00162             pose_out.position.z = boost::lexical_cast<double>(strvec[2]);
00163 
00164             if(angles == "quaternion" && strvec.size() == 7)
00165             {
00166                 pose_out.orientation.w = boost::lexical_cast<double>(strvec[3]);
00167                 pose_out.orientation.x = boost::lexical_cast<double>(strvec[4]);
00168                 pose_out.orientation.y = boost::lexical_cast<double>(strvec[5]);
00169                 pose_out.orientation.z = boost::lexical_cast<double>(strvec[6]);
00170             }
00171             else if(angles == "euler" && strvec.size() == 6)
00172             {
00173                 double euler0,euler1,euler2;
00174                 euler0 = boost::lexical_cast<double>(strvec[3]);
00175                 euler1 = boost::lexical_cast<double>(strvec[4]);
00176                 euler2 = boost::lexical_cast<double>(strvec[5]);
00177 
00178                 Eigen::Matrix3d rotationMatrix;
00179                 rotationMatrix = Eigen::AngleAxisd(euler0 * (M_PI / 180), Eigen::Vector3d::UnitX())
00180                         * Eigen::AngleAxisd(euler1 * (M_PI / 180), Eigen::Vector3d::UnitY())
00181                         * Eigen::AngleAxisd(euler2 * (M_PI / 180), Eigen::Vector3d::UnitZ());
00182 
00183                 Eigen::Quaternion<double> result(rotationMatrix);
00184                 pose_out.orientation.w = result.w();
00185                 pose_out.orientation.x = result.x();
00186                 pose_out.orientation.y = result.y();
00187                 pose_out.orientation.z = result.z();
00188             }
00189             else
00190             {
00191                 ROS_ERROR("Invalid XML syntax.");
00192                 nh_.shutdown();
00193             }
00194 
00195             return true;
00196         } catch (boost::bad_lexical_cast err) {
00197             ROS_DEBUG_STREAM("Can't cast node-value. Cast error: " << err.what());
00198         }
00199     }
00200     return false;
00201 }
00202 
00203 bool FakeObjectRecognition::processGetRecognizerRequest(GetRecognizer::Request &req, GetRecognizer::Response &res) {
00204     ROS_DEBUG("Get recognizer request");
00205     if(std::find(objects_to_rec_.begin(), objects_to_rec_.end(), req.object_type_name) != objects_to_rec_.end()) {
00206         ROS_DEBUG("Requested object is already in list of recognizable objects");
00207     } else {
00208         ROS_DEBUG("Add requested object to recognizable object list");
00209         objects_to_rec_.push_back(req.object_type_name);
00210         recognition_released_ = false;
00211     }
00212     return true;
00213 }
00214 
00215 bool FakeObjectRecognition::processReleaseRecognizerRequest(ReleaseRecognizer::Request &req, ReleaseRecognizer::Response &res) {
00216     ROS_DEBUG("Release recognizer request");
00217     objects_to_rec_.erase(std::remove(objects_to_rec_.begin(), objects_to_rec_.end(), req.object_type_name), objects_to_rec_.end());
00218     if (!(objects_to_rec_.size() > 0)) {
00219         recognition_released_ = true;
00220     }
00221     return true;
00222 }
00223 
00224 bool FakeObjectRecognition::processGetAllRecognizersRequest(GetAllRecognizers::Request &req, GetAllRecognizers::Response &res) {
00225     ROS_DEBUG("Get all recognizers request");
00226 
00227     objects_to_rec_.clear();
00228     for(std::vector<ObjectConfig>::iterator objectIt = objects_.begin(); objectIt != objects_.end(); objectIt++){
00229         ROS_DEBUG_STREAM("Adding objects " << objectIt->getType() << " to recognizable list");
00230         objects_to_rec_.push_back(objectIt->getType());
00231 
00232     }
00233 
00234     recognition_released_ = false;
00235     return true;
00236 
00237 }
00238 
00239 bool FakeObjectRecognition::processClearAllRecognizers(ClearAllRecognizers::Request &req, ClearAllRecognizers::Response &res) {
00240     ROS_DEBUG("Clear all recognizers request");
00241     objects_to_rec_.clear();
00242     recognition_released_ = true;
00243     return true;
00244 }
00245 
00246 void FakeObjectRecognition::timerCallback(const ros::TimerEvent& event) {
00247     for (std::vector<ObjectConfig>::iterator iter = objects_.begin(); iter != objects_.end(); ++iter) {
00248         //Generating marker for each object that is present in config file.
00249         asr_msgs::AsrObjectPtr asr_msg = createAsrMessage(*iter, iter->getPose(), frame_world_);
00250         generated_constellation_marker_pub_.publish(createMarker(asr_msg, iter - objects_.begin(), 2 * timer_duration_, true));
00251                 // Generating normal markers for each object.
00252         visualization_msgs::MarkerArray::Ptr normal_markers = createNormalMarker(*iter, (iter - objects_.begin()) * 100, 10 * timer_duration_);
00253         object_normals_pub_.publish(normal_markers); // can have up to 100 normals
00254     }
00255     if (!recognition_released_) {
00256         doRecognition();
00257     }
00258 }
00259 
00260 void FakeObjectRecognition::configCallback(FakeObjectRecognitionConfig &config, uint32_t level) {
00261     config_changed_ = true;
00262     config_ = config;
00263 }
00264 
00265 void FakeObjectRecognition::doRecognition() {
00266     ROS_INFO("Do recognition");
00267     // React to changed config:
00268     if (config_changed_) {
00269         ROS_DEBUG("Configuration change");
00270         ROS_DEBUG("Load Objects");
00271         if (config_file_path_ != config_.config_file_path) {
00272             ROS_INFO_STREAM("Path to config file has changed. Recognition is released");
00273             config_file_path_ = config_.config_file_path;
00274             objects_to_rec_.clear();
00275             recognition_released_ = true;
00276             return;
00277         }
00278         loadObjects();
00279         err_sim_ = ErrorSimulation(config_.use_pose_invalidation, config_.use_position_noise, config_.use_orientation_noise);
00280         err_sim_.setProbPoseInval(config_.prob_pose_invalidation);
00281         err_sim_.setPoseNoiseDistMean(config_.pos_noise_normal_dist_mean);
00282         err_sim_.setPoseNoiseDistDev(config_.pos_noise_normal_dist_dev);
00283         err_sim_.setOrXNoiseDistMean(config_.or_x_noise_normal_dist_mean);
00284         err_sim_.setOrXNoiseDistDev(config_.or_x_noise_normal_dist_dev);
00285         err_sim_.setOrYNoiseDistMean(config_.or_y_noise_normal_dist_mean);
00286         err_sim_.setOrYNoiseDistDev(config_.or_y_noise_normal_dist_dev);
00287         err_sim_.setOrZNoiseDistMean(config_.or_z_noise_normal_dist_mean);
00288         err_sim_.setOrZNoiseDistDev(config_.or_z_noise_normal_dist_dev);
00289         config_changed_ = false;
00290     }
00291     // Print all loaded objects to debug stream:
00292     std::string recognizable_objects;
00293     std::string objects_to_rec;
00294     for (std::vector<ObjectConfig>::iterator iter = objects_.begin(); iter != objects_.end(); ++iter) {
00295         recognizable_objects += iter->getType() + " ";
00296     }
00297     ROS_DEBUG_STREAM("All recognizable objects: " << recognizable_objects);
00298     // Print all Objects for which recognition has been requested (via processGetRecognizerRequest or processGetAllRecognizersRequest) to debug stream:
00299     for (std::vector<std::string>::iterator iter = objects_to_rec_.begin(); iter != objects_to_rec_.end(); ++iter) {
00300         objects_to_rec += *iter + " ";
00301     }
00302     ROS_DEBUG_STREAM("Objects to recognize: " << objects_to_rec);
00303 
00304     for (std::vector<ObjectConfig>::iterator iter = objects_.begin(); iter != objects_.end(); ++iter) {             // for all loaded (recognizable) objects:
00305         if(std::find(objects_to_rec_.begin(), objects_to_rec_.end(), iter->getType()) == objects_to_rec_.end()) {   // unless end of vector of requested objects is reached:
00306             continue;
00307         }
00308         ROS_INFO_STREAM("Current object: '" << iter->getType() << "'");
00309         geometry_msgs::Pose pose_left;
00310         geometry_msgs::Pose pose_right;
00311 
00312         std::array<geometry_msgs::Point, 8> bounding_box = bounding_box_corners_[iter->getType()]; // Bounding box, given as corner points relative to object frame
00313         std::array<geometry_msgs::Point, 8> bb_left;
00314         std::array<geometry_msgs::Point, 8> bb_right;
00315 
00316         std::vector<geometry_msgs::Point> normals = normals_[iter->getType()]; // Object normals
00317         std::vector<geometry_msgs::Point> normals_left;
00318         std::vector<geometry_msgs::Point> normals_right;
00319 
00320         try {
00321             if (config_.use_camera_pose) { // If camera pose is used:
00322                 ROS_DEBUG_STREAM("Transform into camera frame");
00323 
00324                 pose_left = transformFrame((*iter).getPose(), frame_world_, frame_camera_left_);
00325                 pose_right = transformFrame((*iter).getPose(), frame_world_, frame_camera_right_);
00326 
00327                 ROS_DEBUG_STREAM("Pose left: " << pose_left.position.x << " " << pose_left.position.y << " " << pose_left.position.z << " " << pose_left.orientation.w << " " << pose_left.orientation.x << " " << pose_left.orientation.y << " " << pose_left.orientation.z << " ");
00328                 ROS_DEBUG_STREAM("Pose right: " << pose_right.position.x << " " << pose_right.position.y << " " << pose_right.position.z << " " << pose_right.orientation.w << " " << pose_right.orientation.x << " " << pose_right.orientation.y << " " << pose_right.orientation.z << " ");
00329 
00330                 pose_left = err_sim_.addNoiseToOrientation(err_sim_.addNoiseToPosition(pose_left));
00331                 pose_right = err_sim_.addNoiseToOrientation(err_sim_.addNoiseToPosition(pose_right));
00332 
00333                 ROS_DEBUG_STREAM("Pose left (with errors): " << pose_left.position.x << " " << pose_left.position.y << " " << pose_left.position.z << " " << pose_left.orientation.w << " " << pose_left.orientation.x << " " << pose_left.orientation.y << " " << pose_left.orientation.z << " ");
00334                 ROS_DEBUG_STREAM("Pose right (with errors): " << pose_right.position.x << " " << pose_right.position.y << " " << pose_right.position.z << " " << pose_right.orientation.w << " " << pose_right.orientation.x << " " << pose_right.orientation.y << " " << pose_right.orientation.z << " ");
00335 
00336                 // for bounding box and normals transformation:
00337                 Eigen::Quaterniond rot_left(pose_left.orientation.w, pose_left.orientation.x, pose_left.orientation.y, pose_left.orientation.z);
00338                 Eigen::Quaterniond rot_right(pose_right.orientation.w, pose_right.orientation.x, pose_right.orientation.y, pose_right.orientation.z);
00339                 // Transform bounding box corner points:
00340                 ROS_DEBUG_STREAM("Transform " << bounding_box.size() << " bounding box corner points.");
00341                 Eigen::Vector3d trans_left(pose_left.position.x, pose_left.position.y, pose_left.position.z);
00342                 Eigen::Vector3d trans_right(pose_right.position.x, pose_right.position.y, pose_right.position.z);
00343                 bb_left = transformPoints(bounding_box, rot_left, trans_left);
00344                 bb_right = transformPoints(bounding_box, rot_right, trans_right);
00345 
00346                 //Transform normals (Rotate according to object pose):
00347                 ROS_DEBUG_STREAM("Transform " << normals.size() << " normals.");
00348                 normals_left = transformPoints(normals, rot_left, Eigen::Vector3d(0.0, 0.0, 0.0));
00349                 normals_right = transformPoints(normals, rot_right, Eigen::Vector3d(0.0, 0.0, 0.0));
00350             } else {
00351                 ROS_DEBUG_STREAM("Camera pose is not used");
00352             }
00353         } catch (tf2::LookupException &exc) {
00354             ROS_DEBUG_STREAM("Lookup exception at doRecognition: " << exc.what());
00355             continue;
00356         } catch (tf2::ExtrapolationException &exc) {
00357             ROS_DEBUG_STREAM("Extrapolation exception at doRecognition: " << exc.what());
00358             continue;
00359         } catch (tf2::InvalidArgumentException &exc) {
00360             ROS_DEBUG_STREAM("Invalid argument exception at doRecognition: " << exc.what());
00361             continue;
00362         } catch (tf2::ConnectivityException &exc) {
00363             ROS_DEBUG_STREAM("Connectivity exception at doRecognition: " << exc.what());
00364             continue;
00365         }
00366 
00367         //if (!(config_.use_camera_pose) || objectIsVisible(pose_left, pose_right)) { // old way of doing the following
00368         if (!(config_.use_camera_pose) || objectIsVisible(bb_left, bb_right, pose_left, pose_right, normals_left, normals_right)) { // If camera pose is not used OR camera pose is used and objectIsVisible() returns true:
00369             ROS_INFO_STREAM("Object '" << (*iter).getType() << "' was found");
00370             asr_msgs::AsrObjectPtr asr_msg;
00371             if (!(config_.use_camera_pose)) {
00372                 asr_msg = createAsrMessage(*iter, iter->getPose(), frame_world_);
00373             } else {
00374                 asr_msg = createAsrMessage(*iter, pose_left, frame_camera_left_);
00375             }
00376             recognized_objects_pub_.publish(asr_msg);
00377             recognized_objects_marker_pub_.publish(createMarker(asr_msg, iter - objects_.begin(), 10 * timer_duration_));
00378         }
00379     }
00380     ROS_INFO("---------------------------------- \n");
00381 }
00382 
00383 geometry_msgs::Pose FakeObjectRecognition::transformFrame(const geometry_msgs::Pose &pose, const std::string &frame_from, const std::string &frame_to) {
00384     //lookup transform to get latest timestamp
00385     tf::StampedTransform transform;
00386     listener_.lookupTransform(frame_from, frame_to, ros::Time(0), transform);
00387 
00388     geometry_msgs::PoseStamped stamped_in;
00389     stamped_in.header.frame_id = frame_from;
00390     stamped_in.header.stamp = transform.stamp_;
00391     stamped_in.pose.position = pose.position;
00392     stamped_in.pose.orientation = pose.orientation;
00393 
00394     geometry_msgs::PoseStamped stamped_out;
00395     listener_.transformPose(frame_to, stamped_in, stamped_out);
00396 
00397     geometry_msgs::Pose result;
00398     result.position = stamped_out.pose.position;
00399     result.orientation = stamped_out.pose.orientation;
00400 
00401     return result;
00402 }
00403 // Currently not used anymore:
00404 bool FakeObjectRecognition::objectIsVisible(const geometry_msgs::Pose &pose_left, const geometry_msgs::Pose &pose_right) {
00405     Rating rating(fovx_, fovy_, ncp_, fcp_);
00406     bool pose_inval = err_sim_.poseInvalidation();
00407     if (!pose_inval) {ROS_DEBUG("Pose is invalid (simulated error)");}
00408 
00409     bool rating_result = false;
00410     ROS_DEBUG("Rating in left camera:");
00411     bool left_rating = rating.ratePose(pose_left, rating_threshold_d_, rating_threshold_x_, rating_threshold_y_);
00412     ROS_DEBUG("Rating in left camera:");
00413     bool right_rating = rating.ratePose(pose_right,  rating_threshold_d_, rating_threshold_x_, rating_threshold_y_);
00414 
00415     switch(config_.frustum_mode) {
00416     case 1: rating_result = left_rating | right_rating; ROS_DEBUG("Rating left and right pose (OR)"); break;
00417     case 2: rating_result = left_rating; ROS_DEBUG("Rating left pose only"); break;
00418     case 3: rating_result = right_rating; ROS_DEBUG("Rating right pose only"); break;
00419     default: rating_result = left_rating & right_rating; ROS_DEBUG("Rating left and right pose (AND)");
00420     }
00421 
00422     
00423     if (rating_result && pose_inval) {
00424         return true;
00425     }
00426     return false;
00427 }
00428 // Currently used:
00429 bool FakeObjectRecognition::objectIsVisible(const std::array<geometry_msgs::Point, 8> &bb_left, const std::array<geometry_msgs::Point, 8> &bb_right,
00430                                             const geometry_msgs::Pose &pose_left, const geometry_msgs::Pose &pose_right,
00431                                             const std::vector<geometry_msgs::Point> &normals_left, const std::vector<geometry_msgs::Point> &normals_right) {
00432     Rating rating(fovx_, fovy_, ncp_, fcp_);
00433     bool pose_inval = err_sim_.poseInvalidation();
00434     if (!pose_inval) {ROS_DEBUG("Pose is invalid (simulated error)");}
00435 
00436     bool rating_result = false;
00437     bool left_rating = rating.rateBBandNormal(pose_left, bb_left, normals_left, rating_threshold_);
00438     bool right_rating = rating.rateBBandNormal(pose_right, bb_right, normals_right, rating_threshold_);
00439 
00440 
00441     switch(config_.frustum_mode) {
00442     case 1: rating_result = left_rating | right_rating; ROS_DEBUG("Rating left and right pose (OR)"); break;
00443     case 2: rating_result = left_rating; ROS_DEBUG("Rating left pose only"); break;
00444     case 3: rating_result = right_rating; ROS_DEBUG("Rating right pose only"); break;
00445     default: rating_result = left_rating & right_rating; ROS_DEBUG("Rating left and right pose (AND)");
00446     }
00447 
00448 
00449     if (rating_result && pose_inval) {
00450         return true;
00451     }
00452     return false;
00453 }
00454 
00455 asr_msgs::AsrObjectPtr FakeObjectRecognition::createAsrMessage(const ObjectConfig &object_config, const geometry_msgs::Pose &pose, const std::string &frame_id) {
00456     asr_msgs::AsrObjectPtr object;
00457     object.reset(new asr_msgs::AsrObject());
00458 
00459     std_msgs::Header header;
00460     header.frame_id = frame_id;
00461     header.stamp = ros::Time::now();
00462     object->header = header;
00463     object->providedBy = "fake_object_recognition";
00464 
00465     geometry_msgs::PoseWithCovariance pose_covariance;
00466     pose_covariance.pose.position.x = pose.position.x;
00467     pose_covariance.pose.position.y = pose.position.y;
00468     pose_covariance.pose.position.z = pose.position.z;
00469     pose_covariance.pose.orientation.w = pose.orientation.w;
00470     pose_covariance.pose.orientation.x = pose.orientation.x;
00471     pose_covariance.pose.orientation.y = pose.orientation.y;
00472     pose_covariance.pose.orientation.z = pose.orientation.z;
00473 
00474     for(unsigned int i = 0; i < pose_covariance.covariance.size(); i++) {
00475         pose_covariance.covariance.at(i) = 0.0f;
00476     }
00477     object->sampledPoses.push_back(pose_covariance);
00478 
00479     // Bounding Box:
00480     boost::array< ::geometry_msgs::Point_<std::allocator<void> > , 8> bounding_box;
00481     std::array<geometry_msgs::Point, 8> object_bb = bounding_box_corners_[object_config.getType()];
00482     for (unsigned int i = 0; i < 8; i++) {
00483         bounding_box[i] = object_bb.at(i);
00484     }
00485     object->boundingBox = bounding_box;
00486 
00487     if(object_config.getId() == std::string("0"))
00488     {
00489         object->colorName = "textured";
00490     }
00491     else
00492     {
00493         object->color = getMeshColor(object_config.getId());
00494     }
00495     object->type = object_config.getType();
00496 
00497     object->identifier = object_config.getId();
00498     object->meshResourcePath = object_config.getMeshName();
00499 
00500     //object->sizeConfidence = pose_rec->getResults().at(results_index)->getScore3D();
00501     //object->typeConfidence = pose_rec->getResults().at(results_index)->getScore2D();
00502 
00503     return object;
00504 }
00505 
00506 visualization_msgs::Marker FakeObjectRecognition::createMarker(const asr_msgs::AsrObjectPtr &object, int id, int lifetime, bool use_col_init) {
00507     visualization_msgs::Marker marker;
00508     marker.header = object->header;
00509     marker.id = id;
00510     marker.action = visualization_msgs::Marker::ADD;
00511     marker.pose.position = object->sampledPoses.front().pose.position;
00512     marker.pose.orientation = object->sampledPoses.front().pose.orientation;
00513 
00514     if (use_col_init) {
00515         marker.color = createColorRGBA(0.0, 0.0, 1.0, 0.4);
00516         marker.ns = "Available objects";
00517     } else {
00518         marker.color = getMeshColor(object->identifier);
00519         marker.ns = "Recognition results";
00520     }
00521 
00522     marker.scale.x = 0.001;
00523     marker.scale.y = 0.001;
00524     marker.scale.z = 0.001;
00525 
00526     marker.mesh_use_embedded_materials = true;
00527     marker.type = visualization_msgs::Marker::MESH_RESOURCE;
00528     marker.mesh_resource = object->meshResourcePath;
00529     marker.lifetime = ros::Duration(lifetime);
00530 
00531     return marker;
00532 }
00533 
00534 
00535 /* only working because the shape-based recognizer sets the observedId with the object color */
00536 std_msgs::ColorRGBA FakeObjectRecognition::getMeshColor(std::string observed_id)
00537 {
00538     std_msgs::ColorRGBA retColor = FakeObjectRecognition::createColorRGBA(0.0, 0.0, 0.0, 0.0);
00539 
00540     if (( observed_id.length() == 12 ) && ( observed_id.find_first_not_of("0123456789") == std::string::npos )) {
00541         float rgba[4];
00542         bool isColor = true;
00543         try {
00544             for (int i = 0; i <= 3; i++) {
00545                 std::string temp;
00546                 temp = observed_id.substr( (i * 3), 3 );
00547                 rgba[i] = std::stof(temp) / 100.0;
00548             }
00549         } catch (std::invalid_argument& ia) {
00550             ROS_DEBUG_STREAM(ia.what());
00551             isColor = false;
00552         }
00553 
00554         if(isColor) {
00555             retColor = FakeObjectRecognition::createColorRGBA(rgba[0], rgba[1], rgba[2], 1.0);
00556         }
00557     }
00558     return retColor;
00559 }
00560 
00561 std_msgs::ColorRGBA FakeObjectRecognition::createColorRGBA(float red, float green, float blue, float alpha) {
00562     std_msgs::ColorRGBA color;
00563 
00564     color.r = red;
00565     color.g = green;
00566     color.b = blue;
00567     color.a = alpha;
00568 
00569     return color;
00570 }
00571 
00572 std::vector<geometry_msgs::Point> FakeObjectRecognition::transformPoints(std::vector<geometry_msgs::Point> points_list, Eigen::Quaterniond rotation, Eigen::Vector3d translation) {
00573     std::vector<geometry_msgs::Point> result_list = points_list;
00574     rotation.normalize();
00575     Eigen::Matrix3d rot_mat = rotation.toRotationMatrix();
00576     for (unsigned int i = 0; i < points_list.size(); i++) {
00577         Eigen::Vector3d current_point = Eigen::Vector3d(points_list.at(i).x, points_list.at(i).y, points_list.at(i).z);
00578         current_point = rot_mat * current_point;
00579         current_point += translation;
00580         result_list.at(i) = createPoint(current_point.x(), current_point.y(), current_point.z());
00581     }
00582     return result_list;
00583 }
00584 
00585 std::array<geometry_msgs::Point, 8> FakeObjectRecognition::transformPoints(std::array<geometry_msgs::Point, 8> points_list, Eigen::Quaterniond rotation, Eigen::Vector3d translation) {
00586     std::vector<geometry_msgs::Point> points_vector;
00587     for (unsigned int i = 0; i < points_list.size(); i++) {
00588         points_vector.push_back(points_list.at(i));
00589     }
00590     points_vector = transformPoints(points_vector, rotation, translation);
00591     std::array<geometry_msgs::Point, 8> result_array;
00592     for (unsigned int i = 0; i < result_array.size(); i++) {
00593         result_array.at(i) = points_vector.at(i);
00594     }
00595     return result_array;
00596 }
00597 
00598 visualization_msgs::MarkerArray::Ptr FakeObjectRecognition::createNormalMarker(const ObjectConfig &object, int id, int lifetime) {
00599     // Visualize normals (similar to next_best_view VisualizationsHelper.hpp, MarkerHelper.cpp:
00600     visualization_msgs::MarkerArray::Ptr objectNormalsMarkerArrayPtr;
00601 
00602     Eigen::Matrix<float, 4, 1> color = Eigen::Matrix<float, 4, 1>(1.0, 1.0, 0.0, 1.0);
00603     Eigen::Matrix<float, 3, 1> scale = Eigen::Matrix<float, 3, 1>(0.005, 0.01, 0.005);
00604     std::string ns = "ObjectNormals";
00605 
00606     // create common arrow marker:
00607     visualization_msgs::Marker objectNormalMarker;
00608     objectNormalMarker.header.frame_id = "/map";
00609     objectNormalMarker.lifetime = ros::Duration(lifetime);
00610     objectNormalMarker.ns = ns;
00611     objectNormalMarker.action = visualization_msgs::Marker::ADD;
00612 
00613     objectNormalMarker.type = visualization_msgs::Marker::ARROW;
00614     objectNormalMarker.pose.position = createPoint(0, 0, 0);
00615     objectNormalMarker.pose.orientation.x = 0.0;
00616     objectNormalMarker.pose.orientation.y = 0.0;
00617     objectNormalMarker.pose.orientation.z = 0.0;
00618     objectNormalMarker.pose.orientation.w = 1.0;
00619     // the model size unit is mm
00620     objectNormalMarker.scale.x = scale[0];
00621     objectNormalMarker.scale.y = scale[1];
00622     objectNormalMarker.scale.z = scale[2];
00623 
00624     objectNormalMarker.color.r = color[0];
00625     objectNormalMarker.color.g = color[1];
00626     objectNormalMarker.color.b = color[2];
00627     objectNormalMarker.color.a = color[3];
00628 
00629     objectNormalsMarkerArrayPtr = boost::make_shared<visualization_msgs::MarkerArray>();
00630     // transform normals into world frame
00631     std::vector<geometry_msgs::Point> normals = normals_[object.getType()];
00632     geometry_msgs::Pose object_pose = object.getPose();
00633     Eigen::Quaterniond rotation(object_pose.orientation.w, object_pose.orientation.x, object_pose.orientation.y, object_pose.orientation.z);
00634     normals = transformPoints(normals, rotation, Eigen::Vector3d(0.0, 0.0, 0.0));
00635     for(unsigned int i = 0; i < normals_[object.getType()].size(); i++) {
00636         geometry_msgs::Point start = object.getPose().position;
00637         geometry_msgs::Point end;
00638         end = createPoint(0.07 * normals.at(i).x, 0.07 * normals.at(i).y, 0.07 * normals.at(i).z);
00639         end.x += start.x;
00640         end.y += start.y;
00641         end.z += start.z;
00642         // Set individual parts of objectNormalMarker:
00643         objectNormalMarker.header.stamp = ros::Time();
00644         objectNormalMarker.id = id + i;
00645 
00646         objectNormalMarker.points = std::vector<geometry_msgs::Point>(); // Reset objectNormalMarker.points
00647         objectNormalMarker.points.push_back(start);
00648         objectNormalMarker.points.push_back(end);
00649 
00650         objectNormalsMarkerArrayPtr->markers.push_back(objectNormalMarker);
00651     }
00652     return objectNormalsMarkerArrayPtr;
00653 }
00654 
00655 std::vector<geometry_msgs::Point> FakeObjectRecognition::getNormals(const ObjectConfig &object) {
00656     // init normals: (similar to next_best_view ObjectHelper.h)
00657     std::vector<geometry_msgs::Point> temp_normals = std::vector<geometry_msgs::Point>();
00658 
00659     // Takes the mesh file path and cuts off the beginning ("package://asr_object_database/rsc/databases/")
00660     // and everything after the next "_", leaving only the recognizer name of the object.
00661     std::vector<std::string> strvec;
00662     std::string in = object.getMeshName();
00663     boost::algorithm::trim_if(in, boost::algorithm::is_any_of("_/"));
00664     boost::algorithm::split(strvec, in, boost::algorithm::is_any_of("_/"));
00665     ROS_DEBUG_STREAM("Recognizer name of object: " << strvec.at(7));
00666     std::string recognizer = strvec.at(7);
00667 
00668     // Get the object's meta data containing the normals:
00669     asr_object_database::ObjectMetaData objectMetaData;
00670     objectMetaData.request.object_type = object.getType();
00671     objectMetaData.request.recognizer = recognizer;
00672 
00673     if (!object_metadata_service_client_.exists()) { ROS_DEBUG_STREAM("/asr_object_database/object_meta_data service is not available"); }
00674     else {
00675         object_metadata_service_client_.call(objectMetaData);
00676         if (!objectMetaData.response.is_valid) { ROS_DEBUG_STREAM("objectMetadata response is not valid for object type " << object.getType()); }
00677         else { temp_normals = objectMetaData.response.normal_vectors; }
00678     }
00679     return temp_normals; // temp_normals: Empty if no normals were found (if some objects don't have any).
00680 }
00681 
00682 bool FakeObjectRecognition::getBBfromFile(std::array<geometry_msgs::Point, 8> &result, std::string object_type) {
00683     // init bounding box:
00684      // open config/bounding_box_corners.xml and check whether the corners for the respective object have already been calculated and stored there:
00685      ROS_DEBUG_STREAM("Looking for bounding box corner points in " << bb_corners_file_name_);
00686      std::string corners_string;
00687      if (std::ifstream(bb_corners_file_name_)) {
00688          try {
00689              rapidxml::file<> xmlFile(bb_corners_file_name_.c_str());
00690              rapidxml::xml_document<> doc;
00691              doc.parse<0>(xmlFile.data());
00692              rapidxml::xml_node<> *root_node = doc.first_node();
00693              if (root_node) {
00694                  rapidxml::xml_node<> *child_node = root_node->first_node();
00695                  while (child_node) {
00696                      rapidxml::xml_attribute<> *type_attribute = child_node->first_attribute("type");
00697                      if (type_attribute) {
00698                          if (object_type == type_attribute->value()) {
00699                              rapidxml::xml_node<> *bb_corners_node = child_node->first_node();
00700                              if (bb_corners_node) {
00701                                  corners_string = bb_corners_node->value();
00702                              }
00703                              else {
00704                                  ROS_DEBUG_STREAM("Could not find values in node with attribute type = \"" << object_type << "\"");
00705                              }
00706                              break;
00707                          }
00708                      }
00709                      child_node = child_node->next_sibling();
00710                  }
00711              }
00712          } catch(std::runtime_error err) {
00713              ROS_DEBUG_STREAM("Can't parse xml-file. Runtime error: " << err.what());
00714          } catch (rapidxml::parse_error err) {
00715              ROS_DEBUG_STREAM("Can't parse xml-file Parse error: " << err.what());
00716          }
00717      }
00718      else {
00719          ROS_DEBUG_STREAM("File " << bb_corners_file_name_ << " does not exist. Will be created when calculating new bounding box corners.");
00720      }
00721      std::array<geometry_msgs::Point, 8> corner_points;
00722      if (corners_string.length() > 0) { // Bounding box corners were found
00723          // get the floats from the input file:
00724          std::stringstream cornerstream;
00725          cornerstream.str(corners_string);
00726          std::string corner_coord;
00727          std::vector<float> coord_list;
00728          try {
00729              while (std::getline(cornerstream, corner_coord, ' ')) {
00730                  coord_list.push_back(std::stof(corner_coord));
00731              }
00732          } catch (std::invalid_argument& ia) {
00733              ROS_DEBUG_STREAM(ia.what());
00734              coord_list = std::vector<float>(); // return empty list: try to calculate new corner points instead
00735          }
00736          unsigned int j = 0;
00737          for (unsigned int i = 0; i <= coord_list.size() - 3; i+=3) {
00738              corner_points.at(j) = createPoint(coord_list.at(i), coord_list.at(i+1), coord_list.at(i+2));
00739              j++;
00740          }
00741      }
00742      else {
00743          return false;
00744      }
00745      result = corner_points;
00746      return true;
00747 }
00748 
00749 std::array<geometry_msgs::Point, 8> FakeObjectRecognition::calculateBB(const ObjectConfig &object) {
00750     /* Takes a .dae file, parses it, and finds position vertices of the mesh if available.
00751     * Uses the vertices as input for ApproxMVBB, which calculates an approximated Minimum Volume Bounding Box.
00752     * Then the 8 corner points of the bouding box are calculated and transformed into the object frame.
00753     * Finally, they are scaled with 0.001 so the measurements are in m.
00754     * The points appear in the list in the following order (like in pbd_msgs/PbdObject.msg):
00755     *     4-----5          z
00756     *    /|    /|         /              x right
00757     *   / |   / |        /               y down
00758     *  0-----1  |       /-------x        z forwar
00759     *  |  |  |  |       |
00760     *  |  6--|--7       |
00761     *  | /   | /        |
00762     *  |/         |/         y
00763     *  2-----3
00764     * If no bounding box could be found, a vector containing only the object's center 8 times is used.
00765     * Result is written to file bb_corners_file_name_.*/
00766     // Get mesh input file:
00767     std::string to_cut = "package://" + object_database_name_;
00768     unsigned int length_to_cut = to_cut.length();
00769     std::string mesh_path = ros::package::getPath(object_database_name_) + object.getMeshName().substr(length_to_cut); // cuts off "package://asr_object_database" from object's meshName
00770     ROS_DEBUG_STREAM("Looking for mesh in: " << mesh_path);
00771 
00772     // Parse the input file:
00773     std::string vertices;
00774     try {
00775         rapidxml::file<> xmlFile(mesh_path.c_str());
00776         rapidxml::xml_document<> doc;
00777         doc.parse<0>(xmlFile.data());
00778         rapidxml::xml_node<> *collada_node = doc.first_node("COLLADA");
00779         if (!collada_node) ROS_DEBUG_STREAM("Could not find node " << "COLLADA");
00780         else {
00781             rapidxml::xml_node<> *lib_geom_node = collada_node->first_node("library_geometries");
00782             if (!lib_geom_node) ROS_DEBUG_STREAM("Could not find node " << "library_geometries");
00783             else {
00784                 rapidxml::xml_node<> *geom_node = lib_geom_node->first_node("geometry");
00785                 if (!geom_node) ROS_DEBUG_STREAM("Could not find node " << "geometry");
00786                 else {
00787                     rapidxml::xml_node<> *mesh_node = geom_node->first_node("mesh");
00788                     if (!mesh_node) ROS_DEBUG_STREAM("Could not find node " << "mesh");
00789                     else {
00790                         rapidxml::xml_node<> *source_node = mesh_node->first_node("source");
00791                         while (source_node) {
00792                             rapidxml::xml_attribute<> *name_attribute = source_node->first_attribute("name");
00793                             std::string name;
00794                             if (name_attribute) {
00795                                 name = name_attribute->value();
00796                                 if (name == "position") {
00797                                     rapidxml::xml_node<> *f_array_node = source_node->first_node("float_array");
00798                                     if (!f_array_node) ROS_DEBUG_STREAM("Could not find node " << "float_array");
00799                                     else {
00800                                         rapidxml::xml_node<> *array_node = f_array_node->first_node();
00801                                         if (!array_node) ROS_DEBUG_STREAM("Could not find node " << "containing the position array");
00802                                         else {
00803                                             vertices = array_node->value();
00804                                             break;
00805                                         }
00806                                     }
00807                                 }
00808                             }
00809                             source_node = source_node->next_sibling("source");
00810                         }
00811                         if (!source_node) ROS_DEBUG_STREAM("Could not find node " << "source with name position and position array");
00812                     }
00813                 }
00814             }
00815         }
00816     } catch(std::runtime_error err) {
00817         ROS_DEBUG_STREAM("Can't parse xml-file. Runtime error: " << err.what());
00818     } catch (rapidxml::parse_error err) {
00819         ROS_DEBUG_STREAM("Can't parse xml-file Parse error: " << err.what());
00820     }
00821 
00822     // get the floats from the input file's mesh-source node with name="positions":
00823     std::stringstream vertstream;
00824     vertstream.str(vertices);
00825     std::vector<float> vertex_list;
00826     std::string vertex_coord;
00827     float sum = 0.0;
00828     try {
00829         while (std::getline(vertstream, vertex_coord, ' ')) {
00830             float value= std::stof(vertex_coord);
00831             sum += std::abs(value);
00832             vertex_list.push_back(value);
00833         }
00834     } catch (std::invalid_argument& ia) {
00835             ROS_DEBUG_STREAM(ia.what());
00836             sum = 0.0; // set sum to 0 to invalidate all vertices found so far and use center point instead
00837     }
00838 
00839     // Set the minimum and maximum coordinates to 0 first
00840     float min_x, min_y, min_z, max_x, max_y, max_z;
00841     min_x = min_y = min_z = max_x = max_y = max_z = 0.0;
00842 
00843     ROS_DEBUG_STREAM("Calculating approximated oriented bounding box");
00844     ApproxMVBB::OOBB bb;
00845 
00846     if (sum > 0.0) { // not all vertices were 0. Otherwise the center of the object (0.0) is used instead of the bounding box.
00847         // Put the floats into Matrix for ApproxMVBB:
00848         ApproxMVBB::Matrix3Dyn points(3,vertex_list.size()/3);
00849         unsigned int j = 0;
00850         for (unsigned int i = 0; i <= vertex_list.size() - 3; i+=3) {
00851             points(0,j) = vertex_list.at(i);
00852             points(1,j) = vertex_list.at(i+1);
00853             points(2,j) = vertex_list.at(i+2);
00854                 j++;
00855             }
00856 
00857             // Calculate bounding box:
00858             bb = ApproxMVBB::approximateMVBB(points,0.001,500,5,0,5);
00859 
00860             ApproxMVBB::Matrix33 A_KI = bb.m_q_KI.matrix().transpose();
00861             for(unsigned int i = 0;  i < points.cols(); ++i) {
00862                 bb.unite(A_KI*points.col(i));
00863             }
00864 
00865             // Calculate all corner points in OOBB frame:
00866             ApproxMVBB::Vector3 min_point = bb.m_minPoint;
00867             ApproxMVBB::Vector3 max_point = bb.m_maxPoint;
00868             min_x = min_point.x();
00869             min_y = min_point.y();
00870             min_z = min_point.z();
00871             max_x = max_point.x();
00872             max_y = max_point.y();
00873             max_z = max_point.z();
00874     }
00875 
00876     // Set the corner points:
00877     std::array<ApproxMVBB::Vector3, 8> corners_amvbb;
00878     corners_amvbb.at(0) = ApproxMVBB::Vector3(min_x, min_y, min_z); // 0 - min_point
00879     corners_amvbb.at(1) = ApproxMVBB::Vector3(max_x, min_y, min_z);
00880     corners_amvbb.at(2) = ApproxMVBB::Vector3(min_x, max_y, min_z);
00881     corners_amvbb.at(3) = ApproxMVBB::Vector3(max_x, max_y, min_z);
00882     corners_amvbb.at(4) = ApproxMVBB::Vector3(min_x, min_y, max_z);
00883     corners_amvbb.at(5) = ApproxMVBB::Vector3(max_x, min_y, max_z);
00884     corners_amvbb.at(6) = ApproxMVBB::Vector3(min_x, max_y, max_z);
00885     corners_amvbb.at(7) = ApproxMVBB::Vector3(max_x, max_y, max_z); // 7 - max_point
00886 
00887     // Into object frame and scaled down with 0.001 (measures assumed to be in mm; to m):
00888     if (sum > 0.0) { // see above
00889         for (unsigned int i = 0; i < corners_amvbb.size(); i++) {
00890             corners_amvbb.at(i) = (bb.m_q_KI * corners_amvbb.at(i)) * 0.001;
00891         }
00892     }
00893 
00894     //Transform Vectors into geometry_msgs:
00895     std::array<geometry_msgs::Point, 8> corner_points;
00896     for (unsigned int i = 0; i < corners_amvbb.size(); i++) {
00897         corner_points.at(i) = createPoint(corners_amvbb.at(i).x(), corners_amvbb.at(i).y(), corners_amvbb.at(i).z());
00898     }
00899 
00900     // Writes points into config/bounding_box_corners.xml
00901     try {
00902         std::string corners_string;
00903         for (unsigned int i = 0; i < corner_points.size(); i++) {
00904             corners_string += boost::lexical_cast<std::string>(corner_points.at(i).x) + " " + boost::lexical_cast<std::string>(corner_points.at(i).y) + " "
00905                     + boost::lexical_cast<std::string>(corner_points.at(i).z) + " ";
00906         }
00907         std::string object_node = "<Object type=\"" + object.getType() + "\">" + corners_string + "</Object>";
00908         std::ifstream ifile;
00909         std::ofstream ofile;
00910         // if necessary, create file:
00911         if (!(std::ifstream(bb_corners_file_name_))) { // file does not exists
00912             ROS_DEBUG_STREAM("Could not find file " << bb_corners_file_name_ << ". Creating file.");
00913             ofile.open(bb_corners_file_name_);
00914             if (ofile.is_open()) {
00915                 ofile << "<Objects></Objects>";
00916                 ofile.close();
00917             }
00918             else
00919                 ROS_DEBUG_STREAM("Could not open file " << bb_corners_file_name_);
00920         }
00921 
00922         ifile.open(bb_corners_file_name_);
00923         if (ifile.is_open()) {
00924             std::string old_contents;
00925             std::string line;
00926             while(getline(ifile, line)) {
00927                 old_contents.append(line);
00928             }
00929             ifile.close();
00930             if (old_contents.find("<Objects>") == 0) {
00931                 ofile.open(bb_corners_file_name_);
00932                 if (ofile.is_open()) {
00933                     std::string inner_nodes = old_contents.substr(9); // Cut off "<Objects>" in the beginning.
00934                     ofile << "<Objects>" << object_node << inner_nodes; // Reattach it and write new node behind it, followed by the rest of the old file
00935                     ofile.close();
00936                     ROS_DEBUG_STREAM("Bounding box corner points written to file " << bb_corners_file_name_);
00937                 }
00938             }
00939             else ROS_DEBUG_STREAM("When trying to write bounding box corners to file " << bb_corners_file_name_ << ": Could not find root node " << "<Objects>" << ". Corners not written.");
00940         }
00941         else {
00942             ROS_DEBUG_STREAM("Could not open file " << bb_corners_file_name_ << ". Bounding box corners not written.");
00943         }
00944     } catch(boost::bad_lexical_cast err) {
00945         ROS_DEBUG_STREAM("Can't cast bounding box corner points to string. Cast error: " << err.what());
00946     }
00947 
00948     return corner_points;
00949 }
00950 
00951 geometry_msgs::Point FakeObjectRecognition::createPoint(double x, double y, double z) {
00952     geometry_msgs::Point pt;
00953     pt.x = x;
00954     pt.y = y;
00955     pt.z = z;
00956     return pt;
00957 }
00958 
00959 }
00960 
00961 int main(int argc, char** argv) {
00962 
00963     ros::init (argc, argv, "asr_fake_object_recognition");
00964 
00965     fake_object_recognition::FakeObjectRecognition rec;
00966 
00967     ros::spin();
00968 
00969     return 0;
00970 }
00971 


asr_fake_object_recognition
Author(s): Allgeyer Tobias, Aumann Florian, Borella Jocelyn, Meißner Pascal, Qattan Mohamad
autogenerated on Sat Jun 8 2019 19:15:45