19 #include <rapidxml.hpp> 20 #include <rapidxml_utils.hpp> 22 #include <boost/algorithm/string/predicate.hpp> 23 #include <boost/lexical_cast.hpp> 24 #include <boost/algorithm/string.hpp> 30 #include <Eigen/Geometry> 32 #include "asr_object_database/ObjectMetaData.h" 33 #include "ApproxMVBB/ComputeApproxMVBB.hpp" 84 for (std::vector<ObjectConfig>::iterator iter =
objects_.begin(); iter !=
objects_.end(); ++iter) {
88 ROS_DEBUG_STREAM(
"Found " << normals_[iter->getType()].size() <<
" normals. Normals initialized.");
91 ROS_DEBUG_STREAM(
"Initializing bounding box of object type " << iter->getType());
92 std::array<geometry_msgs::Point, 8> corner_points;
100 ROS_INFO(
"Recognition is initially released");
106 std::string xml_path;
118 rapidxml::file<> xmlFile(xml_path.c_str());
119 rapidxml::xml_document<> doc;
120 doc.parse<0>(xmlFile.data());
122 rapidxml::xml_node<> *root_node = doc.first_node();
124 rapidxml::xml_node<> *child_node = root_node->first_node();
126 rapidxml::xml_attribute<> *type_attribute = child_node->first_attribute(
"type");
127 rapidxml::xml_attribute<> *id_attribute = child_node->first_attribute(
"id");
128 rapidxml::xml_attribute<> *mesh_attribute = child_node->first_attribute(
"mesh");
129 rapidxml::xml_attribute<> *angles_attribute = child_node->first_attribute(
"angles");
130 if (type_attribute && id_attribute && mesh_attribute && angles_attribute) {
131 std::string type = type_attribute->value();
132 std::string mesh = mesh_attribute->value();
133 std::string
id = id_attribute->value();
134 std::string pose_string = child_node->value();
135 std::string
angles = angles_attribute->value();
136 geometry_msgs::Pose pose;
141 child_node = child_node->next_sibling();
144 }
catch(std::runtime_error err) {
146 }
catch (rapidxml::parse_error err) {
154 std::vector<std::string> strvec;
156 boost::algorithm::trim_if(pose_in, boost::algorithm::is_any_of(delim));
157 boost::algorithm::split(strvec, pose_in, boost::algorithm::is_any_of(delim), boost::algorithm::token_compress_on);
158 if (strvec.size() == 6 || strvec.size() == 7) {
160 pose_out.position.x = boost::lexical_cast<
double>(strvec[0]);
161 pose_out.position.y = boost::lexical_cast<
double>(strvec[1]);
162 pose_out.position.z = boost::lexical_cast<
double>(strvec[2]);
164 if(angles ==
"quaternion" && strvec.size() == 7)
166 pose_out.orientation.w = boost::lexical_cast<
double>(strvec[3]);
167 pose_out.orientation.x = boost::lexical_cast<
double>(strvec[4]);
168 pose_out.orientation.y = boost::lexical_cast<
double>(strvec[5]);
169 pose_out.orientation.z = boost::lexical_cast<
double>(strvec[6]);
171 else if(angles ==
"euler" && strvec.size() == 6)
173 double euler0,euler1,euler2;
174 euler0 = boost::lexical_cast<
double>(strvec[3]);
175 euler1 = boost::lexical_cast<
double>(strvec[4]);
176 euler2 = boost::lexical_cast<
double>(strvec[5]);
178 Eigen::Matrix3d rotationMatrix;
179 rotationMatrix = Eigen::AngleAxisd(euler0 * (M_PI / 180), Eigen::Vector3d::UnitX())
180 * Eigen::AngleAxisd(euler1 * (M_PI / 180), Eigen::Vector3d::UnitY())
181 * Eigen::AngleAxisd(euler2 * (M_PI / 180), Eigen::Vector3d::UnitZ());
183 Eigen::Quaternion<double> result(rotationMatrix);
184 pose_out.orientation.w = result.w();
185 pose_out.orientation.x = result.x();
186 pose_out.orientation.y = result.y();
187 pose_out.orientation.z = result.z();
196 }
catch (boost::bad_lexical_cast err) {
206 ROS_DEBUG(
"Requested object is already in list of recognizable objects");
208 ROS_DEBUG(
"Add requested object to recognizable object list");
225 ROS_DEBUG(
"Get all recognizers request");
228 for(std::vector<ObjectConfig>::iterator objectIt =
objects_.begin(); objectIt !=
objects_.end(); objectIt++){
229 ROS_DEBUG_STREAM(
"Adding objects " << objectIt->getType() <<
" to recognizable list");
240 ROS_DEBUG(
"Clear all recognizers request");
247 for (std::vector<ObjectConfig>::iterator iter =
objects_.begin(); iter !=
objects_.end(); ++iter) {
272 ROS_INFO_STREAM(
"Path to config file has changed. Recognition is released");
292 std::string recognizable_objects;
293 std::string objects_to_rec;
294 for (std::vector<ObjectConfig>::iterator iter =
objects_.begin(); iter !=
objects_.end(); ++iter) {
295 recognizable_objects += iter->getType() +
" ";
300 objects_to_rec += *iter +
" ";
304 for (std::vector<ObjectConfig>::iterator iter =
objects_.begin(); iter !=
objects_.end(); ++iter) {
309 geometry_msgs::Pose pose_left;
310 geometry_msgs::Pose pose_right;
313 std::array<geometry_msgs::Point, 8> bb_left;
314 std::array<geometry_msgs::Point, 8> bb_right;
316 std::vector<geometry_msgs::Point> normals =
normals_[iter->getType()];
317 std::vector<geometry_msgs::Point> normals_left;
318 std::vector<geometry_msgs::Point> normals_right;
327 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 <<
" ");
328 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 <<
" ");
333 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 <<
" ");
334 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 <<
" ");
337 Eigen::Quaterniond rot_left(pose_left.orientation.w, pose_left.orientation.x, pose_left.orientation.y, pose_left.orientation.z);
338 Eigen::Quaterniond rot_right(pose_right.orientation.w, pose_right.orientation.x, pose_right.orientation.y, pose_right.orientation.z);
340 ROS_DEBUG_STREAM(
"Transform " << bounding_box.size() <<
" bounding box corner points.");
341 Eigen::Vector3d trans_left(pose_left.position.x, pose_left.position.y, pose_left.position.z);
342 Eigen::Vector3d trans_right(pose_right.position.x, pose_right.position.y, pose_right.position.z);
347 ROS_DEBUG_STREAM(
"Transform " << normals.size() <<
" normals.");
348 normals_left =
transformPoints(normals, rot_left, Eigen::Vector3d(0.0, 0.0, 0.0));
349 normals_right =
transformPoints(normals, rot_right, Eigen::Vector3d(0.0, 0.0, 0.0));
357 ROS_DEBUG_STREAM(
"Extrapolation exception at doRecognition: " << exc.what());
360 ROS_DEBUG_STREAM(
"Invalid argument exception at doRecognition: " << exc.what());
363 ROS_DEBUG_STREAM(
"Connectivity exception at doRecognition: " << exc.what());
368 if (!(
config_.use_camera_pose) ||
objectIsVisible(bb_left, bb_right, pose_left, pose_right, normals_left, normals_right)) {
370 asr_msgs::AsrObjectPtr asr_msg;
371 if (!(
config_.use_camera_pose)) {
380 ROS_INFO(
"---------------------------------- \n");
388 geometry_msgs::PoseStamped stamped_in;
389 stamped_in.header.frame_id = frame_from;
390 stamped_in.header.stamp = transform.
stamp_;
391 stamped_in.pose.position = pose.position;
392 stamped_in.pose.orientation = pose.orientation;
394 geometry_msgs::PoseStamped stamped_out;
397 geometry_msgs::Pose result;
398 result.position = stamped_out.pose.position;
399 result.orientation = stamped_out.pose.orientation;
407 if (!pose_inval) {
ROS_DEBUG(
"Pose is invalid (simulated error)");}
409 bool rating_result =
false;
416 case 1: rating_result = left_rating | right_rating;
ROS_DEBUG(
"Rating left and right pose (OR)");
break;
417 case 2: rating_result = left_rating;
ROS_DEBUG(
"Rating left pose only");
break;
418 case 3: rating_result = right_rating;
ROS_DEBUG(
"Rating right pose only");
break;
419 default: rating_result = left_rating & right_rating;
ROS_DEBUG(
"Rating left and right pose (AND)");
423 if (rating_result && pose_inval) {
430 const geometry_msgs::Pose &pose_left,
const geometry_msgs::Pose &pose_right,
431 const std::vector<geometry_msgs::Point> &normals_left,
const std::vector<geometry_msgs::Point> &normals_right) {
434 if (!pose_inval) {
ROS_DEBUG(
"Pose is invalid (simulated error)");}
436 bool rating_result =
false;
442 case 1: rating_result = left_rating | right_rating;
ROS_DEBUG(
"Rating left and right pose (OR)");
break;
443 case 2: rating_result = left_rating;
ROS_DEBUG(
"Rating left pose only");
break;
444 case 3: rating_result = right_rating;
ROS_DEBUG(
"Rating right pose only");
break;
445 default: rating_result = left_rating & right_rating;
ROS_DEBUG(
"Rating left and right pose (AND)");
449 if (rating_result && pose_inval) {
456 asr_msgs::AsrObjectPtr object;
457 object.reset(
new asr_msgs::AsrObject());
459 std_msgs::Header header;
460 header.frame_id = frame_id;
462 object->header = header;
463 object->providedBy =
"fake_object_recognition";
465 geometry_msgs::PoseWithCovariance pose_covariance;
466 pose_covariance.pose.position.x = pose.position.x;
467 pose_covariance.pose.position.y = pose.position.y;
468 pose_covariance.pose.position.z = pose.position.z;
469 pose_covariance.pose.orientation.w = pose.orientation.w;
470 pose_covariance.pose.orientation.x = pose.orientation.x;
471 pose_covariance.pose.orientation.y = pose.orientation.y;
472 pose_covariance.pose.orientation.z = pose.orientation.z;
474 for(
unsigned int i = 0; i < pose_covariance.covariance.size(); i++) {
475 pose_covariance.covariance.at(i) = 0.0f;
477 object->sampledPoses.push_back(pose_covariance);
480 boost::array< ::geometry_msgs::Point_<std::allocator<void> > , 8> bounding_box;
482 for (
unsigned int i = 0; i < 8; i++) {
483 bounding_box[i] = object_bb.at(i);
485 object->boundingBox = bounding_box;
487 if(object_config.
getId() == std::string(
"0"))
489 object->colorName =
"textured";
495 object->type = object_config.
getType();
497 object->identifier = object_config.
getId();
498 object->meshResourcePath = object_config.
getMeshName();
507 visualization_msgs::Marker marker;
508 marker.header =
object->header;
510 marker.action = visualization_msgs::Marker::ADD;
511 marker.pose.position =
object->sampledPoses.front().pose.position;
512 marker.pose.orientation =
object->sampledPoses.front().pose.orientation;
516 marker.ns =
"Available objects";
519 marker.ns =
"Recognition results";
522 marker.scale.x = 0.001;
523 marker.scale.y = 0.001;
524 marker.scale.z = 0.001;
526 marker.mesh_use_embedded_materials =
true;
527 marker.type = visualization_msgs::Marker::MESH_RESOURCE;
528 marker.mesh_resource =
object->meshResourcePath;
540 if (( observed_id.length() == 12 ) && ( observed_id.find_first_not_of(
"0123456789") == std::string::npos )) {
544 for (
int i = 0; i <= 3; i++) {
546 temp = observed_id.substr( (i * 3), 3 );
547 rgba[i] = std::stof(temp) / 100.0;
549 }
catch (std::invalid_argument& ia) {
562 std_msgs::ColorRGBA color;
573 std::vector<geometry_msgs::Point> result_list = points_list;
574 rotation.normalize();
575 Eigen::Matrix3d rot_mat = rotation.toRotationMatrix();
576 for (
unsigned int i = 0; i < points_list.size(); i++) {
577 Eigen::Vector3d current_point = Eigen::Vector3d(points_list.at(i).x, points_list.at(i).y, points_list.at(i).z);
578 current_point = rot_mat * current_point;
579 current_point += translation;
580 result_list.at(i) =
createPoint(current_point.x(), current_point.y(), current_point.z());
586 std::vector<geometry_msgs::Point> points_vector;
587 for (
unsigned int i = 0; i < points_list.size(); i++) {
588 points_vector.push_back(points_list.at(i));
591 std::array<geometry_msgs::Point, 8> result_array;
592 for (
unsigned int i = 0; i < result_array.size(); i++) {
593 result_array.at(i) = points_vector.at(i);
600 visualization_msgs::MarkerArray::Ptr objectNormalsMarkerArrayPtr;
602 Eigen::Matrix<float, 4, 1> color = Eigen::Matrix<float, 4, 1>(1.0, 1.0, 0.0, 1.0);
603 Eigen::Matrix<float, 3, 1> scale = Eigen::Matrix<float, 3, 1>(0.005, 0.01, 0.005);
604 std::string ns =
"ObjectNormals";
607 visualization_msgs::Marker objectNormalMarker;
608 objectNormalMarker.header.frame_id =
"/map";
610 objectNormalMarker.ns = ns;
611 objectNormalMarker.action = visualization_msgs::Marker::ADD;
613 objectNormalMarker.type = visualization_msgs::Marker::ARROW;
614 objectNormalMarker.pose.position =
createPoint(0, 0, 0);
615 objectNormalMarker.pose.orientation.x = 0.0;
616 objectNormalMarker.pose.orientation.y = 0.0;
617 objectNormalMarker.pose.orientation.z = 0.0;
618 objectNormalMarker.pose.orientation.w = 1.0;
620 objectNormalMarker.scale.x = scale[0];
621 objectNormalMarker.scale.y = scale[1];
622 objectNormalMarker.scale.z = scale[2];
624 objectNormalMarker.color.r = color[0];
625 objectNormalMarker.color.g = color[1];
626 objectNormalMarker.color.b = color[2];
627 objectNormalMarker.color.a = color[3];
629 objectNormalsMarkerArrayPtr = boost::make_shared<visualization_msgs::MarkerArray>();
631 std::vector<geometry_msgs::Point> normals =
normals_[
object.getType()];
632 geometry_msgs::Pose object_pose =
object.getPose();
633 Eigen::Quaterniond rotation(object_pose.orientation.w, object_pose.orientation.x, object_pose.orientation.y, object_pose.orientation.z);
634 normals =
transformPoints(normals, rotation, Eigen::Vector3d(0.0, 0.0, 0.0));
635 for(
unsigned int i = 0; i <
normals_[
object.getType()].size(); i++) {
636 geometry_msgs::Point start =
object.getPose().position;
637 geometry_msgs::Point end;
638 end =
createPoint(0.07 * normals.at(i).x, 0.07 * normals.at(i).y, 0.07 * normals.at(i).z);
643 objectNormalMarker.header.stamp =
ros::Time();
644 objectNormalMarker.id =
id + i;
646 objectNormalMarker.points = std::vector<geometry_msgs::Point>();
647 objectNormalMarker.points.push_back(start);
648 objectNormalMarker.points.push_back(end);
650 objectNormalsMarkerArrayPtr->markers.push_back(objectNormalMarker);
652 return objectNormalsMarkerArrayPtr;
657 std::vector<geometry_msgs::Point> temp_normals = std::vector<geometry_msgs::Point>();
661 std::vector<std::string> strvec;
662 std::string in =
object.getMeshName();
663 boost::algorithm::trim_if(in, boost::algorithm::is_any_of(
"_/"));
664 boost::algorithm::split(strvec, in, boost::algorithm::is_any_of(
"_/"));
666 std::string recognizer = strvec.at(7);
669 asr_object_database::ObjectMetaData objectMetaData;
670 objectMetaData.request.object_type =
object.getType();
671 objectMetaData.request.recognizer = recognizer;
676 if (!objectMetaData.response.is_valid) {
ROS_DEBUG_STREAM(
"objectMetadata response is not valid for object type " <<
object.getType()); }
677 else { temp_normals = objectMetaData.response.normal_vectors; }
686 std::string corners_string;
690 rapidxml::xml_document<> doc;
691 doc.parse<0>(xmlFile.data());
692 rapidxml::xml_node<> *root_node = doc.first_node();
694 rapidxml::xml_node<> *child_node = root_node->first_node();
696 rapidxml::xml_attribute<> *type_attribute = child_node->first_attribute(
"type");
697 if (type_attribute) {
698 if (object_type == type_attribute->value()) {
699 rapidxml::xml_node<> *bb_corners_node = child_node->first_node();
700 if (bb_corners_node) {
701 corners_string = bb_corners_node->value();
704 ROS_DEBUG_STREAM(
"Could not find values in node with attribute type = \"" << object_type <<
"\"");
709 child_node = child_node->next_sibling();
712 }
catch(std::runtime_error err) {
714 }
catch (rapidxml::parse_error err) {
721 std::array<geometry_msgs::Point, 8> corner_points;
722 if (corners_string.length() > 0) {
724 std::stringstream cornerstream;
725 cornerstream.str(corners_string);
726 std::string corner_coord;
727 std::vector<float> coord_list;
729 while (std::getline(cornerstream, corner_coord,
' ')) {
730 coord_list.push_back(std::stof(corner_coord));
732 }
catch (std::invalid_argument& ia) {
734 coord_list = std::vector<float>();
737 for (
unsigned int i = 0; i <= coord_list.size() - 3; i+=3) {
738 corner_points.at(j) =
createPoint(coord_list.at(i), coord_list.at(i+1), coord_list.at(i+2));
745 result = corner_points;
768 unsigned int length_to_cut = to_cut.length();
773 std::string vertices;
775 rapidxml::file<> xmlFile(mesh_path.c_str());
776 rapidxml::xml_document<> doc;
777 doc.parse<0>(xmlFile.data());
778 rapidxml::xml_node<> *collada_node = doc.first_node(
"COLLADA");
781 rapidxml::xml_node<> *lib_geom_node = collada_node->first_node(
"library_geometries");
782 if (!lib_geom_node)
ROS_DEBUG_STREAM(
"Could not find node " <<
"library_geometries");
784 rapidxml::xml_node<> *geom_node = lib_geom_node->first_node(
"geometry");
787 rapidxml::xml_node<> *mesh_node = geom_node->first_node(
"mesh");
790 rapidxml::xml_node<> *source_node = mesh_node->first_node(
"source");
791 while (source_node) {
792 rapidxml::xml_attribute<> *name_attribute = source_node->first_attribute(
"name");
794 if (name_attribute) {
795 name = name_attribute->value();
796 if (name ==
"position") {
797 rapidxml::xml_node<> *f_array_node = source_node->first_node(
"float_array");
798 if (!f_array_node)
ROS_DEBUG_STREAM(
"Could not find node " <<
"float_array");
800 rapidxml::xml_node<> *array_node = f_array_node->first_node();
801 if (!array_node)
ROS_DEBUG_STREAM(
"Could not find node " <<
"containing the position array");
803 vertices = array_node->value();
809 source_node = source_node->next_sibling(
"source");
811 if (!source_node)
ROS_DEBUG_STREAM(
"Could not find node " <<
"source with name position and position array");
816 }
catch(std::runtime_error err) {
818 }
catch (rapidxml::parse_error err) {
823 std::stringstream vertstream;
824 vertstream.str(vertices);
825 std::vector<float> vertex_list;
826 std::string vertex_coord;
829 while (std::getline(vertstream, vertex_coord,
' ')) {
830 float value= std::stof(vertex_coord);
831 sum += std::abs(value);
832 vertex_list.push_back(value);
834 }
catch (std::invalid_argument& ia) {
840 float min_x, min_y, min_z, max_x, max_y, max_z;
841 min_x = min_y = min_z = max_x = max_y = max_z = 0.0;
848 ApproxMVBB::Matrix3Dyn points(3,vertex_list.size()/3);
850 for (
unsigned int i = 0; i <= vertex_list.size() - 3; i+=3) {
851 points(0,j) = vertex_list.at(i);
852 points(1,j) = vertex_list.at(i+1);
853 points(2,j) = vertex_list.at(i+2);
858 bb = ApproxMVBB::approximateMVBB(points,0.001,500,5,0,5);
860 ApproxMVBB::Matrix33 A_KI = bb.m_q_KI.matrix().transpose();
861 for(
unsigned int i = 0; i < points.cols(); ++i) {
862 bb.unite(A_KI*points.col(i));
866 ApproxMVBB::Vector3 min_point = bb.m_minPoint;
867 ApproxMVBB::Vector3 max_point = bb.m_maxPoint;
868 min_x = min_point.x();
869 min_y = min_point.y();
870 min_z = min_point.z();
871 max_x = max_point.x();
872 max_y = max_point.y();
873 max_z = max_point.z();
877 std::array<ApproxMVBB::Vector3, 8> corners_amvbb;
878 corners_amvbb.at(0) = ApproxMVBB::Vector3(min_x, min_y, min_z);
879 corners_amvbb.at(1) = ApproxMVBB::Vector3(max_x, min_y, min_z);
880 corners_amvbb.at(2) = ApproxMVBB::Vector3(min_x, max_y, min_z);
881 corners_amvbb.at(3) = ApproxMVBB::Vector3(max_x, max_y, min_z);
882 corners_amvbb.at(4) = ApproxMVBB::Vector3(min_x, min_y, max_z);
883 corners_amvbb.at(5) = ApproxMVBB::Vector3(max_x, min_y, max_z);
884 corners_amvbb.at(6) = ApproxMVBB::Vector3(min_x, max_y, max_z);
885 corners_amvbb.at(7) = ApproxMVBB::Vector3(max_x, max_y, max_z);
889 for (
unsigned int i = 0; i < corners_amvbb.size(); i++) {
890 corners_amvbb.at(i) = (bb.m_q_KI * corners_amvbb.at(i)) * 0.001;
895 std::array<geometry_msgs::Point, 8> corner_points;
896 for (
unsigned int i = 0; i < corners_amvbb.size(); i++) {
897 corner_points.at(i) =
createPoint(corners_amvbb.at(i).x(), corners_amvbb.at(i).y(), corners_amvbb.at(i).z());
902 std::string corners_string;
903 for (
unsigned int i = 0; i < corner_points.size(); i++) {
904 corners_string += boost::lexical_cast<std::string>(corner_points.at(i).x) +
" " + boost::lexical_cast<std::string>(corner_points.at(i).y) +
" " 905 + boost::lexical_cast<std::string>(corner_points.at(i).z) +
" ";
907 std::string object_node =
"<Object type=\"" +
object.getType() +
"\">" + corners_string +
"</Object>";
914 if (ofile.is_open()) {
915 ofile <<
"<Objects></Objects>";
923 if (ifile.is_open()) {
924 std::string old_contents;
926 while(getline(ifile, line)) {
927 old_contents.append(line);
930 if (old_contents.find(
"<Objects>") == 0) {
932 if (ofile.is_open()) {
933 std::string inner_nodes = old_contents.substr(9);
934 ofile <<
"<Objects>" << object_node << inner_nodes;
944 }
catch(boost::bad_lexical_cast err) {
945 ROS_DEBUG_STREAM(
"Can't cast bounding box corner points to string. Cast error: " << err.what());
948 return corner_points;
952 geometry_msgs::Point pt;
961 int main(
int argc,
char** argv) {
963 ros::init (argc, argv,
"asr_fake_object_recognition");
bool processReleaseRecognizerRequest(ReleaseRecognizer::Request &req, ReleaseRecognizer::Response &res)
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
bool objectIsVisible(const geometry_msgs::Pose &pose_left, const geometry_msgs::Pose &pose_right)
Checks whether an object is currently visible.
std::string getMeshName() const
Return the mesh path of the object.
void configCallback(FakeObjectRecognitionConfig &config, uint32_t level)
The callback function which is called when the configuration has changed.
void setOrZNoiseDistMean(double or_z_noise_dist_mean)
Sets the mean value of the normal distribution used by the orientation error generation (z-axis) ...
double rating_threshold_x_
std::array< geometry_msgs::Point, 8 > calculateBB(const ObjectConfig &object)
calculate approximated oriented bounding box of the object represented by its corner points ...
static const std::string GET_ALL_RECOGNIZERS_SERVICE_NAME("get_all_recognizers")
void publish(const boost::shared_ptr< M > &message) const
This class is used to simulate typical errors of an object recognition system.
int main(int argc, char **argv)
std::string output_normals_topic_
geometry_msgs::Pose transformFrame(const geometry_msgs::Pose &pose, const std::string &frame_from, const std::string &frame_to)
Transforms a given pose from one frame to another.
void setProbPoseInval(double prob_pose_inval)
Set the probability of the pose invalidation.
geometry_msgs::Point createPoint(double x, double y, double z)
creates a Point geometry_msg with the given coordinates
ros::ServiceServer clear_all_recognizers_service_
std::string config_file_path_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::vector< geometry_msgs::Point > transformPoints(std::vector< geometry_msgs::Point > points_list, Eigen::Quaterniond rotation, Eigen::Vector3d translation)
Transforms points locally (as opposed to via a ROS service call in transformFrame) ...
bool call(MReq &req, MRes &res)
bool processGetAllRecognizersRequest(GetAllRecognizers::Request &req, GetAllRecognizers::Response &res)
visualization_msgs::MarkerArray::Ptr createNormalMarker(const ObjectConfig &object, int id, int lifetime)
publishes normal markers (yellow arrows) for all objects in the configuration
void setOrZNoiseDistDev(double or_z_noise_dist_dev)
Sets the standard deviation value of the normal distribution used by the orientation error generation...
FakeObjectRecognitionConfig config_
FakeObjectRecognition()
The constructor of this class.
This class is used to rate an object's pose based on the current camera position. ...
ros::ServiceServer release_recognizer_service_
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
bool parsePoseString(std::string pose_in, geometry_msgs::Pose &pose_out, std::string delim, std::string angles)
This function parses the string containing the pose of an entry in the object-config-file.
bool recognition_released_
std::vector< geometry_msgs::Point > getNormals(const ObjectConfig &object)
get Normals of the object through the object_database/object_meta_data service
bool rateBBandNormal(const geometry_msgs::Pose &object_pose, const std::array< geometry_msgs::Point, 8 > &bounding_box, const std::vector< geometry_msgs::Point > &normals, double threshold)
Rates an objects visibility based on its bounding box and its normals.
std::string object_database_name_
ros::ServiceServer get_recognizer_service_
geometry_msgs::Pose addNoiseToOrientation(const geometry_msgs::Pose &pose)
Adds error values to the given pose (orientation only)
ROSCPP_DECL void spin(Spinner &spinner)
void setOrYNoiseDistDev(double or_y_noise_dist_dev)
Sets the standard deviation value of the normal distribution used by the orientation error generation...
std::map< std::string, std::vector< geometry_msgs::Point > > normals_
void setOrXNoiseDistMean(double or_x_noise_dist_mean)
Sets the mean value of the normal distribution used by the orientation error generation (x-axis) ...
std::string bb_corners_file_name_
bool processClearAllRecognizers(ClearAllRecognizers::Request &req, ClearAllRecognizers::Response &res)
std::vector< std::string > objects_to_rec_
std::map< std::string, std::array< geometry_msgs::Point, 8 > > bounding_box_corners_
static const std::string CLEAR_ALL_RECOGNIZERS_SERVICE_NAME("clear_all_recognizers")
void loadObjects()
This function loads the objects of the object-config-file.
double rating_threshold_d_
void setOrYNoiseDistMean(double or_y_noise_dist_mean)
Sets the mean value of the normal distribution used by the orientation error generation (y-axis) ...
static std_msgs::ColorRGBA createColorRGBA(float red, float green, float blue, float alpha)
Creates a std_msgs::ColorRGBA-message from the given values.
std::string frame_camera_left_
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
std::vector< ObjectConfig > objects_
static const std::string RELEASE_RECOGNIZER_SERVICE_NAME("release_recognizer")
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool poseInvalidation()
Invalidates a pose by the probability member of this class.
void doRecognition()
This function is called whenever objects shall be recognized.
#define ROS_DEBUG_STREAM(args)
ROSLIB_DECL std::string getPath(const std::string &package_name)
ros::Publisher object_normals_pub_
ros::Publisher generated_constellation_marker_pub_
static std_msgs::ColorRGBA getMeshColor(std::string observed_id)
Returns the color of a mesh based on the object's id (Only creates a color if it is an object of the ...
std::string output_rec_objects_topic_
std::string output_rec_markers_topic_
#define ROS_INFO_STREAM(args)
void timerCallback(const ros::TimerEvent &event)
The callback function of the timer.
dynamic_reconfigure::Server< FakeObjectRecognitionConfig > reconfigure_server_
static const std::string GET_RECOGNIZER_SERVICE_NAME("get_recognizer")
bool getParam(const std::string &key, std::string &s) const
void setPoseNoiseDistMean(double pos_noise_dist_mean)
Sets the mean value of the normal distribution used by the position error generation.
This class is used to save information about an available object.
visualization_msgs::Marker createMarker(const asr_msgs::AsrObjectPtr &object, int id, int lifetime, bool use_col_init=false)
Creates a visualization marker for a found object.
std::string getId() const
Return the id of the object.
asr_msgs::AsrObjectPtr createAsrMessage(const ObjectConfig &object_config, const geometry_msgs::Pose &pose, const std::string &frame_id)
Creates a AsrObject-message for a found object.
bool ratePose(const geometry_msgs::Pose &pose, double threshold_d, double threshold_x, double threshold_y)
Return whether a pose is visible in the camera frustum based on the distance and angle rating...
double rating_threshold_y_
std::string frame_camera_right_
ros::ServiceClient object_metadata_service_client_
geometry_msgs::Pose addNoiseToPosition(const geometry_msgs::Pose &pose)
Adds error values to the given pose (position only)
void setPoseNoiseDistDev(double pos_noise_dist_dev)
Sets the standard deviation value of the normal distribution used by the position error generation...
static const std::string NODE_NAME("asr_fake_object_recognition")
bool getBBfromFile(std::array< geometry_msgs::Point, 8 > &result, std::string object_type)
try to get bounding box corner points from file.
std::string output_constellation_marker_topic_
ros::Publisher recognized_objects_pub_
The central class of the recognition system used for managing the ros subscriptions, configuration changes, loading of the objects, the recognition itself and the visualisation of the results.
tf::TransformListener listener_
ros::ServiceServer get_all_recognizers_service_
bool processGetRecognizerRequest(GetRecognizer::Request &req, GetRecognizer::Response &res)
std::string getType() const
Return the name of the object.
ros::Publisher recognized_objects_marker_pub_
ROSCPP_DECL bool waitForService(const std::string &service_name, int32_t timeout)
void setOrXNoiseDistDev(double or_x_noise_dist_dev)
Sets the standard deviation value of the normal distribution used by the orientation error generation...