3 #include <ros/console.h>
4 #include <ros/advertise_service_options.h>
5 #include <ros/node_handle.h>
27 #include <ed_gui_server_msgs/EntityInfos.h>
28 #include <ed_gui_server_msgs/Mesh.h>
30 #include <boost/filesystem.hpp>
32 #include <opencv2/highgui/highgui.hpp>
45 composite->addShape(*shape,
geo::Pose3D(0, 0, 0.7));
48 composite->addShape(*shape,
geo::Pose3D(0, 0, 1.525));
62 for(
unsigned int i = 0; i < vertices.
size(); ++i)
81 unsigned int current_mesh_size = mesh.vertices.size();
82 mesh.vertices.resize(current_mesh_size + triangles.
size() * 9);
83 for(
unsigned int i = 0; i < triangles.
size(); ++i)
90 unsigned int i9 = current_mesh_size + i * 9;
92 mesh.vertices[i9] = v1.
x;
93 mesh.vertices[i9 + 1] = v1.
y;
94 mesh.vertices[i9 + 2] = v1.
z;
95 mesh.vertices[i9 + 3] = v2.
x;
96 mesh.vertices[i9 + 4] = v2.
y;
97 mesh.vertices[i9 + 5] = v2.
z;
98 mesh.vertices[i9 + 6] = v3.
x;
99 mesh.vertices[i9 + 7] = v3.
y;
100 mesh.vertices[i9 + 8] = v3.
z;
110 it != sub_shapes.
end(); ++it)
113 shape->setMesh(it->first->getMesh().getTransformed(it->second.inverse()));
123 msg.id = e->id().str();
124 msg.type = e->type();
125 msg.existence_probability = e->existenceProbability();
126 msg.visual_revision = e->visualRevision();
127 msg.volumes_revision = e->volumesRevision();
129 if (e->hasType(
"person") && e->visualRevision() == 0)
130 msg.visual_revision = 1;
139 msg.has_pose =
false;
146 if (!ch.
points.empty() && e->has_pose())
153 msg.polygon.z_min = ch.
z_min;
154 msg.polygon.z_max = ch.
z_max;
156 unsigned int size = ch.
points.size();
157 msg.polygon.xs.resize(size);
158 msg.polygon.ys.resize(size);
160 for(
unsigned int i = 0; i < size; ++i)
162 msg.polygon.xs[i] = ch.
points[i].x;
163 msg.polygon.ys[i] = ch.
points[i].y;
175 msg.color.r = 255 * r;
176 msg.color.g = 255 * g;
177 msg.color.b = 255 *
b;
183 if (e->hasFlag(
"highlighted"))
191 if (e->hasType(
"person") || e->hasFlag(
"possible_human"))
235 robot_->initialize(robot_name, urdf_rosparam, tf_prefix);
238 ros::NodeHandle nh(
"~/gui");
240 ros::AdvertiseServiceOptions opt_srv_entities =
241 ros::AdvertiseServiceOptions::create<ed_gui_server_msgs::QueryEntities>(
247 ros::AdvertiseServiceOptions opt_srv_meshes =
248 ros::AdvertiseServiceOptions::create<ed_gui_server_msgs::QueryMeshes>(
254 ros::AdvertiseServiceOptions opt_srv_get_entity_info =
255 ros::AdvertiseServiceOptions::create<ed_gui_server_msgs::GetEntityInfo>(
261 ros::AdvertiseServiceOptions opt_srv_interact =
262 ros::AdvertiseServiceOptions::create<ed_gui_server_msgs::Interact>(
268 ros::AdvertiseServiceOptions opt_srv_map =
269 ros::AdvertiseServiceOptions::create<ed_gui_server_msgs::Map>(
273 srv_map_ = nh.advertiseService(opt_srv_map);
275 pub_entities_ = nh.advertise<ed_gui_server_msgs::EntityInfos>(
"entities", 1);
287 ed_gui_server_msgs::EntityInfos entities_msg;
289 entities_msg.header.stamp = ros::Time::now();
290 entities_msg.header.frame_id =
"map";
302 robot_->getEntities(entities_msg.entities);
310 ed_gui_server_msgs::QueryEntities::Response& ros_res)
322 float pos_x = pose.
t.
x;
323 float pos_y = pose.
t.
y;
325 if (ros_req.area_min.x < pos_x && pos_x < ros_req.area_max.x
326 && ros_req.area_min.y < pos_y && pos_y < ros_req.area_max.y)
328 ros_res.entities.push_back(ed_gui_server_msgs::EntityInfo());
329 ed_gui_server_msgs::EntityInfo&
info = ros_res.entities.back();
331 info.id = e->id().str();
332 info.visual_revision = e->visualRevision();
333 info.volumes_revision = e->volumesRevision();
358 rgb_params[0] = cv::IMWRITE_JPEG_QUALITY;
362 if (!cv::imencode(
".jpg",
image, data, rgb_params)) {
363 ROS_ERROR_STREAM(
"[ED Gui Server] RGB image compression failed");
372 params[0] = cv::IMWRITE_PNG_COMPRESSION;
375 if (!cv::imencode(
".png",
image, data, params)) {
376 ROS_ERROR_STREAM(
"[ED Gui Server] PNG image compression failed");
387 ed_gui_server_msgs::GetEntityInfo::Response& ros_res)
394 ros_res.type = e->type();
397 ros_res.affordances.push_back(
"navigate-to");
398 ros_res.affordances.push_back(
"pick-up");
399 ros_res.affordances.push_back(
"place");
405 ss_pose <<
"(" << pose.
t.
x <<
", " << pose.
t.
y <<
", " << pose.
t.
z <<
")";
406 ros_res.property_names.push_back(
"position");
407 ros_res.property_values.push_back(ss_pose.
str());
418 const cv::Mat&
rgb_image = m->image()->getRGBImage();
421 cv::Mat rgb_image_masked(
rgb_image.rows,
rgb_image.cols, CV_8UC3, cv::Scalar(0, 0, 0));
427 const cv::Point2i p(it());
428 rgb_image_masked.at<cv::Vec3b>(p) =
rgb_image.at<cv::Vec3b>(p);
439 min.x =
std::max(0, min.x - ros_req.measurement_image_border);
440 min.y =
std::max(0, min.y - ros_req.measurement_image_border);
453 ed_gui_server_msgs::QueryMeshes::Response& ros_res)
457 if (ros_req.entity_ids.size() != ros_req.visual_requests.size())
460 ss <<
"Number of requested ids(" << ros_req.entity_ids.size() <<
") does not match the number of visual request values (" << ros_req.visual_requests.size() <<
")\n";
461 ros_res.error_msg.append(ss.
str());
462 ros_res.error_msg.append(
"\n");
463 ROS_ERROR_STREAM_NAMED(
"gui_server", ss.
rdbuf());
465 if (ros_req.entity_ids.size() != ros_req.volumes_requests.size())
468 ss <<
"Number of requested ids(" << ros_req.entity_ids.size() <<
") does not match the number of volumes request values (" << ros_req.volumes_requests.size() <<
")";
469 ros_res.error_msg.append(ss.
str());
470 ros_res.error_msg.append(
"\n");
471 ROS_ERROR_STREAM_NAMED(
"gui_server", ss.
rdbuf());
473 if (!ros_res.error_msg.empty())
476 for (
unsigned int i = 0; i < ros_req.entity_ids.size(); ++i)
479 bool visual_needs_update = ros_req.visual_requests[i];
480 bool volumes_needs_update = ros_req.volumes_requests[i];
482 if (!visual_needs_update && !volumes_needs_update)
484 ROS_WARN_STREAM_NAMED(
"gui_server",
"Got request for enity: '" <<
id <<
"', but both visual and volumes request are false");
490 bool robot_entity =
false;
499 ros_res.error_msg +=
"Unknown entity: '" +
id +
"'.\n";
504 ros_res.entity_geometries.push_back(ed_gui_server_msgs::EntityMeshAndVolumes());
505 ed_gui_server_msgs::EntityMeshAndVolumes& entity_geometry = ros_res.entity_geometries.back();
507 if (visual_needs_update)
510 unsigned long visual_revision = 0;
513 visual =
robot_->getShape(
id);
517 ROS_DEBUG_STREAM_NAMED(
"gui_server",
"No visual from robot entity: '" <<
id <<
"'");
522 visual = e->visual();
523 visual_revision = e->visualRevision();
525 if (!visual && e->hasType(
"person"))
529 compensate_z.t.z = -e->pose().t.z;
531 visual = std::make_shared<const geo::Shape>(shape_tr);
537 entity_geometry.id = id;
538 entity_geometry.visual_revision = visual_revision;
543 ROS_DEBUG_STREAM_NAMED(
"gui_server",
"Could not get a visual for entity: '" <<
id <<
"'");
547 if (volumes_needs_update)
551 ROS_ERROR_STREAM_NAMED(
"gui_server",
"Can't get volumes of robot entities. Requested for entity: '" <<
id <<
"'");
555 entity_geometry.id = id;
556 entity_geometry.volumes_revision = e->volumesRevision();
557 for (
const auto& kv: e->volumes())
561 entity_geometry.volumes.
push_back(ed_gui_server_msgs::Volume());
562 ed_gui_server_msgs::Volume& entity_volume = entity_geometry.volumes.back();
563 entity_volume.name = kv.first;
579 ed::ErrorContext errc(
"storeMeasurement", (
"id: '" +
id +
"', type: '" + type +
"'").c_str());
583 char const* home = getenv(
"HOME");
586 boost::filesystem::path dir(
std::string(home) +
"/.ed/measurements/" + type);
587 boost::filesystem::create_directories(dir);
592 ROS_INFO_STREAM(
"Writing entity info to '" << filename <<
"'.");
596 ROS_ERROR_STREAM(
"Entity with id " <<
id <<
" doesn't exist!");
602 ed_gui_server_msgs::Interact::Response& ros_res)
605 ROS_DEBUG_STREAM(
"[ED Gui Server] Received command: " << ros_req.command_yaml);
611 if (params.
value(
"action", action))
613 if (action ==
"store")
616 if (params.
value(
"id",
id) && params.
value(
"type", type))
619 ROS_ERROR_STREAM(
"Please specify an id and a type!");
625 ros_res.result_json =
"{ error: \"" + params.
error() +
"\" }";
630 ros_res.result_json =
"{}";
638 ed_gui_server_msgs::Map::Response& res)
644 bool model_found =
false;
648 if (!e || !e->has_pose())
650 ROS_DEBUG_STREAM_NAMED(
"srvMap",
"Not taking into account entity: " << model);
654 ROS_DEBUG_STREAM_NAMED(
"srvMap",
"Taking into account entity: " << model);
658 minMaxMesh(e->visual()->getBoundingBox().getMesh(), e->pose(), p_min, p_max);
661 else if (e->hasType(
"room") && !e->volumes().empty())
663 for (
const auto& v : e->volumes())
665 minMaxMesh(v.second->getBoundingBox().getMesh(), e->pose(), p_min, p_max);
683 for (
const auto& e_id :
req.entities_in_view)
688 ROS_WARN_STREAM_NAMED(
"srvMap",
"Could not find any of the following entities: " << ss.
str() <<
". All entities will now be taken into account.");
695 if (e->visual() && e->has_pose() && !e->hasFlag(
"self") && (
id.size() < 5 ||
id.substr(
id.size() - 5) !=
"floor"))
697 minMaxMesh(e->visual()->getBoundingBox().getMesh(), e->pose(), p_min, p_max);
699 else if (e->hasType(
"room") && !e->volumes().empty())
701 for (
const auto& v : e->volumes())
702 minMaxMesh(v.second->getBoundingBox().getMesh(), e->pose(), p_min, p_max);
708 p_max.
x *= (p_max.
x>=0) ? 1.01 : 1/1.01;
709 p_max.
y *= (p_max.
y>=0) ? 1.01 : 1/1.01;
710 p_min.
x *= (p_min.
x>=0) ? 1/1.01 : 1.01;
711 p_min.
y *= (p_min.
y>=0) ? 1/1.01 : 1.01;
721 if (range.
y > range.
x)
727 uint width =
req.image_width ?
req.image_width :
static_cast<uint
>(
req.DEFAULT_WIDTH);
728 uint height =
req.image_height ?
req.image_height :
static_cast<uint
>(
req.DEFAULT_HEIGHT);
729 double focal_length =
std::min(width/range.
x, height/range.
y);
732 focal_length * dist, focal_length * dist,
733 width / 2 + 0.5, height / 2 + 0.5,
736 cv::Mat
depth_image = cv::Mat(height, width, CV_32FC1, 0.0);
737 cv::Scalar background_color;
738 if (
req.background ==
req.WHITE)
739 background_color = cv::Scalar(255, 255, 255);
740 else if (
req.background ==
req.BLACK)
741 background_color = cv::Scalar(20, 20, 20);
744 background_color = cv::Scalar(20, 20, 20);
745 cv::Mat
image = cv::Mat(height, width, CV_8UC3, background_color);
750 if (
req.print_labels)
752 const cv::Scalar text_color = cv::Scalar(255, 255, 255) - background_color;
758 if (e->visual() && e->has_pose() && !e->hasFlag(
"self") && (
id.size() < 5 ||
id.substr(
id.size() - 5) !=
"floor"))
764 cv::Size textSize = cv::getTextSize(
id, cv::FONT_HERSHEY_COMPLEX_SMALL, 1, 1, &tmp_baseline);
765 center_cv.x -= textSize.width/2;
766 center_cv.y += textSize.height/2;
767 cv::putText(
image,
id, center_cv, cv::FONT_HERSHEY_COMPLEX_SMALL, 1, text_color, 1);
773 res.pixels_per_meter_width = focal_length;
774 res.pixels_per_meter_height = focal_length;
778 rotate180.
setRPY(M_PI, 0, 0);
784 geo::Vec3 cp_to_tl_image(-
static_cast<double>(width)/2/focal_length, -
static_cast<double>(height)/2/focal_length, 0);
788 res.pose.header.frame_id =
"map";
789 res.pose.header.stamp = ros::Time::now();