8 #include <geometry_msgs/PointStamped.h> 9 #include <geometry_msgs/PoseStamped.h> 10 #include <geometry_msgs/QuaternionStamped.h> 11 #include <geometry_msgs/Vector3Stamped.h> 13 #include <eigen_conversions/eigen_msg.h> 15 #include "../core/interaction.h" 16 #include "../core/workspace.h" 18 #include "interactive.h" 22 std::shared_ptr<MeshRenderer> _mesh_renderer;
29 PROPERTY(
double, radius, 0.1, min = 0.0);
30 PROPERTY(std::shared_ptr<Material>, material,
31 std::make_shared<Material>(1, 1, 1));
33 if (_mesh_watcher.changed(radius())) {
35 std::make_shared<Mesh>(makeSphere(16, 8).scale(radius())),
38 MeshDisplayBase::renderSync(context);
48 if (
auto message = topic().message()) {
49 node()->frame(message->header.frame_id);
50 Eigen::Vector3d point;
51 tf::pointMsgToEigen(message->point, point);
52 Eigen::Isometry3d transform;
53 transform.translation() = point;
54 node()->pose(transform);
59 PointDisplayBase::renderSync(context);
68 PROPERTY(std::string, topic);
70 visualization_msgs::InteractiveMarkerInit init;
71 init.markers.push_back(makePointMarker());
74 virtual void publish(
const std::string &frame,
75 const Eigen::Isometry3d &pose)
override {
76 if (_publish_watcher.changed(topic(), frame, poseToArray(pose),
78 geometry_msgs::PointStamped m;
79 tf::pointEigenToMsg(pose.translation(), m.point);
80 m.header.frame_id = frame;
81 _publisher.publish(topic(), m);
91 PROPERTY(
Frame, frame);
94 node()->frame(frame());
95 if (
auto message = topic().message()) {
96 Eigen::Vector3d point;
97 tf::pointMsgToEigen(*message, point);
98 Eigen::Isometry3d transform;
99 transform.translation() = point;
100 node()->pose(transform);
105 PointDisplayBase::renderSync(context);
114 PROPERTY(std::string, topic);
116 visualization_msgs::InteractiveMarkerInit init;
117 init.markers.push_back(makePointMarker());
118 _markers->init(init);
120 virtual void publish(
const std::string &frame,
121 const Eigen::Isometry3d &pose)
override {
122 if (_publish_watcher.changed(topic(), frame, poseToArray(pose),
124 geometry_msgs::Point m;
125 tf::pointEigenToMsg(pose.translation(), m);
126 _publisher.publish(topic(), m);
133 std::shared_ptr<MeshRenderer> _mesh_renderer;
140 PROPERTY(
double, radius, 0.1, min = 0.0);
141 PROPERTY(
double, length, 1.0, min = 0.0);
142 PROPERTY(std::shared_ptr<Material>, material,
143 std::make_shared<Material>(1, 1, 1));
145 if (_mesh_watcher.changed(length(), radius())) {
147 std::make_shared<Mesh>(makeAxes(length(), radius(), 24)), material());
149 MeshDisplayBase::renderSync(context);
156 PROPERTY(
Frame, frame);
159 node()->frame(frame());
160 if (
auto message = topic().message()) {
161 Eigen::Isometry3d transform;
162 tf::poseMsgToEigen(*message, transform);
163 node()->pose(transform);
168 PoseDisplayBase::renderSync(context);
177 PROPERTY(std::string, topic);
179 visualization_msgs::InteractiveMarkerInit init;
180 init.markers.push_back(makePoseMarker());
181 _markers->init(init);
183 virtual void publish(
const std::string &frame,
184 const Eigen::Isometry3d &pose)
override {
185 if (_publish_watcher.changed(topic(), frame, poseToArray(pose),
187 geometry_msgs::Pose m;
188 tf::poseEigenToMsg(pose, m);
189 _publisher.publish(topic(), m);
199 if (
auto message = topic().message()) {
200 node()->frame(message->header.frame_id);
201 Eigen::Isometry3d transform;
202 tf::poseMsgToEigen(message->pose, transform);
203 node()->pose(transform);
208 PoseDisplayBase::renderSync(context);
217 PROPERTY(std::string, topic);
219 visualization_msgs::InteractiveMarkerInit init;
220 init.markers.push_back(makePoseMarker());
221 _markers->init(init);
223 virtual void publish(
const std::string &frame,
224 const Eigen::Isometry3d &pose)
override {
225 if (_publish_watcher.changed(topic(), frame, poseToArray(pose),
227 geometry_msgs::PoseStamped m;
228 tf::poseEigenToMsg(pose, m.pose);
229 m.header.frame_id = frame;
230 _publisher.publish(topic(), m);
239 PROPERTY(
Frame, frame);
242 node()->frame(frame());
243 if (
auto message = topic().message()) {
244 Eigen::Quaterniond quat;
245 tf::quaternionMsgToEigen(*message, quat);
246 node()->pose(Eigen::Isometry3d(quat));
251 PoseDisplayBase::renderSync(context);
260 PROPERTY(std::string, topic);
262 visualization_msgs::InteractiveMarkerInit init;
263 init.markers.push_back(makeRotationMarker());
264 _markers->init(init);
266 virtual void publish(
const std::string &frame,
267 const Eigen::Isometry3d &pose)
override {
268 if (_publish_watcher.changed(topic(), frame, poseToArray(pose),
270 geometry_msgs::Quaternion m;
271 tf::quaternionEigenToMsg(Eigen::Quaterniond(pose.linear()), m);
272 _publisher.publish(topic(), m);
283 if (
auto message = topic().message()) {
284 Eigen::Quaterniond quat;
285 tf::quaternionMsgToEigen(message->quaternion, quat);
286 node()->pose(Eigen::Isometry3d(quat));
291 PoseDisplayBase::renderSync(context);
300 PROPERTY(std::string, topic);
302 visualization_msgs::InteractiveMarkerInit init;
303 init.markers.push_back(makeRotationMarker());
304 _markers->init(init);
306 virtual void publish(
const std::string &frame,
307 const Eigen::Isometry3d &pose)
override {
308 if (_publish_watcher.changed(topic(), frame, poseToArray(pose),
310 geometry_msgs::QuaternionStamped m;
311 tf::quaternionEigenToMsg(Eigen::Quaterniond(pose.linear()), m.quaternion);
312 m.header.frame_id = frame;
313 _publisher.publish(topic(), m);
323 std::condition_variable condition;
324 std::weak_ptr<GeometryPublisherDisplayBase> display;
325 volatile bool exit_flag =
false;
327 std::shared_ptr<Data> _data;
331 std::unique_lock<std::mutex> lock(_data->mutex);
332 _data->exit_flag =
true;
333 _data->condition.notify_all();
335 virtual void refresh()
override {
337 auto data = _data = std::make_shared<Data>();
340 std::thread([data]() {
341 LOG_DEBUG(
"start publisher thread");
342 auto t = std::chrono::steady_clock::now();
344 t += std::chrono::seconds(1);
346 std::unique_lock<std::mutex> lock(data->mutex);
348 if (data->exit_flag) {
349 LOG_DEBUG(
"exit publisher thread");
352 if (std::chrono::steady_clock::now() >= t) {
355 data->condition.wait_until(lock, t);
358 if (
auto me = data->display.lock()) {
368 virtual void publish() = 0;
373 std::shared_ptr<MeshRenderer> _line_renderer, _tip_renderer;
376 Vector3Node(
const std::shared_ptr<Material> &material) {
377 _line_renderer = create<MeshRenderer>(
378 std::make_shared<Mesh>(
379 makeCylinder(16).scale(1, 1, 0.5).translate(0, 0, 0.5)),
381 _tip_renderer = create<MeshRenderer>(
382 std::make_shared<Mesh>(makeCone(16).scale(1, 1, 1).translate(0, 0, 0)),
385 void setVector(
const Eigen::Vector3d &vector,
double arrow_length,
386 double arrow_radius) {
387 double length = arrow_length * vector.norm();
389 std::max(1e-6, std::min(length * 0.5, arrow_radius * 4));
390 double tip_radius = tip_length * 0.5;
391 double line_length = std::max(1e-6, length - tip_length);
392 double line_radius = tip_length * 0.25;
393 Eigen::Vector3d z = vector.normalized();
394 Eigen::Vector3d y = z.unitOrthogonal();
395 Eigen::Vector3d x = y.cross(z).normalized();
397 Eigen::Affine3d transform;
398 transform.setIdentity();
399 transform.linear().col(0) = x * line_radius;
400 transform.linear().col(1) = y * line_radius;
401 transform.linear().col(2) = z * line_length;
402 _line_renderer->pose(transform);
405 Eigen::Affine3d transform;
406 transform.setIdentity();
407 transform.linear().col(0) = x * tip_radius;
408 transform.linear().col(1) = y * tip_radius;
409 transform.linear().col(2) = z * tip_length;
410 transform.translation() = z * line_length;
411 _tip_renderer->pose(transform);
417 std::shared_ptr<Vector3Node> _node;
420 void _setVector(
const Eigen::Vector3d &vector) {
421 _node->setVector(vector, length(), radius());
425 PROPERTY(
double, radius, 0.1, min = 0.0);
426 PROPERTY(
double, length, 1.0, min = 0.0);
427 PROPERTY(std::shared_ptr<Material>, material,
428 std::make_shared<Material>(1, 1, 1));
429 virtual void refresh()
override {
432 MeshDisplayBase::refresh();
441 PROPERTY(
Frame, frame);
444 node()->frame(frame());
445 if (
auto message = topic().message()) {
446 Eigen::Vector3d vector;
447 tf::vectorMsgToEigen(*message, vector);
453 Vector3DisplayBase::renderSync(context);
459 std::shared_ptr<Vector3Node> _node;
461 double _interaction_factor = 1;
464 PROPERTY(
Frame, frame);
465 PROPERTY(Eigen::Vector3d, vector);
466 PROPERTY(
double, radius, 0.1, min = 0.0);
467 PROPERTY(
double, length, 1.0, min = 0.0);
468 PROPERTY(std::shared_ptr<Material>, material,
469 std::make_shared<Material>(1, 1, 1));
471 if (_watcher.changed(vector().x(), vector().y(), vector().z())) {
474 _node->setVector(vector(), length(), radius());
475 _node->frame(frame());
476 GeometryPublisherDisplayBase::renderSync(context);
478 virtual void refresh()
override {
481 GeometryPublisherDisplayBase::refresh();
484 virtual bool interact(
const Interaction &interaction)
override {
485 if (GeometryPublisherDisplayBase::interact(interaction)) {
488 Eigen::Affine3d inverse_pose = _node->framePose().inverse();
489 if (interaction.pressed) {
490 _interaction_factor =
493 std::min(1.0, vector().normalized().dot(
494 inverse_pose * interaction.begin.point) /
495 (vector().norm() * length()))) /
498 vector() += (inverse_pose * interaction.current.point -
499 inverse_pose * interaction.previous.point) *
510 PROPERTY(std::string, topic);
511 virtual void publish()
override {
512 Eigen::Vector3d v = vector();
513 geometry_msgs::Vector3 m;
514 tf::vectorEigenToMsg(v, m);
515 _publisher.publish(topic(), m);
524 PROPERTY(std::string, topic);
525 virtual void publish()
override {
526 Eigen::Vector3d v = vector();
527 geometry_msgs::Vector3Stamped m;
528 tf::vectorEigenToMsg(v, m.vector);
529 m.header.frame_id = frame().name();
530 _publisher.publish(topic(), m);
541 if (
auto message = topic().message()) {
542 node()->frame(message->header.frame_id);
543 Eigen::Vector3d vector;
544 tf::vectorMsgToEigen(message->vector, vector);
550 Vector3DisplayBase::renderSync(context);