41 #include <boost/algorithm/string.hpp>
44 #include <QColorDialog>
49 #include "ui_topic_select.h"
66 config_widget_(new QWidget()),
83 p.setColor(QPalette::Background, Qt::white);
87 QPalette p3(
ui_.status->palette());
88 p3.setColor(QPalette::Text, Qt::red);
89 ui_.status->setPalette(p3);
92 ui_.min_color->setColor(Qt::white);
93 ui_.max_color->setColor(Qt::black);
95 ui_.color_transformer->addItem(QString(
"Flat Color"), QVariant(0));
97 QObject::connect(
ui_.selecttopic,
101 QObject::connect(
ui_.buttonResetBuffer,
105 QObject::connect(
ui_.topic,
106 SIGNAL(editingFinished()),
109 QObject::connect(
ui_.alpha,
110 SIGNAL(valueChanged(
double)),
113 QObject::connect(
ui_.color_transformer,
114 SIGNAL(currentIndexChanged(
int)),
117 QObject::connect(
ui_.max_color,
118 SIGNAL(colorEdited(
const QColor &)),
121 QObject::connect(
ui_.min_color,
122 SIGNAL(colorEdited(
const QColor &)),
125 QObject::connect(
ui_.minValue,
126 SIGNAL(valueChanged(
double)),
129 QObject::connect(
ui_.maxValue,
130 SIGNAL(valueChanged(
double)),
133 QObject::connect(
ui_.bufferSize,
134 SIGNAL(valueChanged(
int)),
137 QObject::connect(
ui_.pointSize,
138 SIGNAL(valueChanged(
int)),
141 QObject::connect(
ui_.use_rainbow,
142 SIGNAL(stateChanged(
int)),
145 QObject::connect(
ui_.unpack_rgb,
146 SIGNAL(stateChanged(
int)),
149 QObject::connect(
ui_.use_automaxmin,
150 SIGNAL(stateChanged(
int)),
153 QObject::connect(
ui_.max_color,
154 SIGNAL(colorEdited(
const QColor &)),
157 QObject::connect(
ui_.min_color,
158 SIGNAL(colorEdited(
const QColor &)),
161 QObject::connect(
this,
165 QObject::connect(
this,
170 PrintInfo(
"Constructed PointCloud2Plugin");
179 ROS_DEBUG(
"PointCloud2Plugin::ClearHistory()");
187 QPixmap icon(16, 16);
188 icon.fill(Qt::transparent);
190 QPainter painter(&icon);
191 painter.setRenderHint(QPainter::Antialiasing,
true);
195 pen.setCapStyle(Qt::RoundCap);
197 pen.setColor(
ui_.min_color->color());
199 painter.drawPoint(2, 13);
201 pen.setColor(
ui_.min_color->color());
203 painter.drawPoint(4, 6);
205 pen.setColor(
ui_.max_color->color());
207 painter.drawPoint(12, 9);
209 pen.setColor(
ui_.max_color->color());
211 painter.drawPoint(13, 2);
222 scan.transformed =
false;
223 scan.gl_color.clear();
224 scan.gl_point.clear();
251 unsigned int color_transformer =
static_cast<unsigned int>(
ui_.color_transformer->currentIndex());
252 unsigned int transformer_index = color_transformer -1;
255 val = point.
features[transformer_index];
258 if (val >
max_[transformer_index])
260 max_[transformer_index] = val;
263 if (val <
min_[transformer_index])
265 min_[transformer_index] = val;
271 return ui_.min_color->color();
274 if (
ui_.unpack_rgb->isChecked())
276 uint8_t* pixelColor =
reinterpret_cast<uint8_t*
>(&val);
277 return QColor(pixelColor[2], pixelColor[1], pixelColor[0], 255);
284 val = std::max(0.0
f, std::min(val, 1.0
f));
286 if (
ui_.use_automaxmin->isChecked())
292 if (
ui_.use_rainbow->isChecked())
295 int hue = (int)(val * 255.0);
296 return QColor::fromHsl(hue, 255, 127, 255);
300 const QColor min_color =
ui_.min_color->color();
301 const QColor max_color =
ui_.max_color->color();
303 int red, green, blue;
304 red = (int)(val * max_color.red() + ((1.0 - val) * min_color.red()));
305 green = (int)(val * max_color.green() + ((1.0 - val) * min_color.green()));
306 blue = (int)(val * max_color.blue() + ((1.0 - val) * min_color.blue()));
307 return QColor(red, green, blue, 255);
311 inline int32_t
findChannelIndex(
const sensor_msgs::PointCloud2ConstPtr& cloud,
const std::string& channel)
313 for (int32_t i = 0;
static_cast<size_t>(i) < cloud->fields.size(); ++i)
315 if (cloud->fields[i].name == channel)
330 scan.gl_color.clear();
331 scan.gl_color.reserve(scan.points.size()*4);
335 scan.gl_color.push_back( color.red());
336 scan.gl_color.push_back( color.green());
337 scan.gl_color.push_back( color.blue());
338 scan.gl_color.push_back(
static_cast<uint8_t
>(
alpha_ * 255.0 ) );
348 "sensor_msgs/PointCloud2");
350 if (!topic.
name.empty())
352 ui_.topic->setText(QString::fromStdString(topic.
name));
360 std::string topic =
ui_.topic->text().trimmed().toStdString();
432 scan = std::move(
scans_.front() );
446 scan.
color = QColor::fromRgbF(1.0
f, 0.0
f, 0.0
f, 1.0
f);
461 if (xi == -1 || yi == -1 || zi == -1)
468 for (
size_t i = 0; i <
msg->fields.size(); ++i)
471 std::string
name =
msg->fields[i].name;
473 uint32_t offset_value =
msg->fields[i].offset;
474 uint8_t datatype_value =
msg->fields[i].datatype;
475 input.
offset = offset_value;
489 int new_feature_index =
ui_.color_transformer->currentIndex();
490 std::map<std::string, FieldInfo>::const_iterator it;
499 std::string
const field = it->first;
505 new_feature_index = label;
509 ui_.color_transformer->addItem(QString::fromStdString(field), QVariant(label));
514 ui_.color_transformer->setCurrentIndex(new_feature_index);
519 if (!
msg->data.empty())
521 const uint8_t* ptr = &
msg->data.front();
522 const uint32_t point_step =
msg->point_step;
523 const uint32_t xoff =
msg->fields[xi].offset;
524 const uint32_t yoff =
msg->fields[yi].offset;
525 const uint32_t zoff =
msg->fields[zi].offset;
526 const size_t num_points =
msg->data.size() / point_step;
528 scan.
points.resize(num_points);
530 std::vector<FieldInfo> field_infos;
531 field_infos.reserve(num_features);
534 field_infos.push_back(it->second);
538 scan.
gl_point.reserve(num_points*2);
540 scan.
gl_color.reserve(num_points*4);
542 for (
size_t i = 0; i < num_points; i++, ptr += point_step)
544 float x = *
reinterpret_cast<const float*
>(ptr + xoff);
545 float y = *
reinterpret_cast<const float*
>(ptr + yoff);
546 float z = *
reinterpret_cast<const float*
>(ptr + zoff);
551 point.
features.resize(num_features);
553 for (
int count=0; count < field_infos.size(); count++)
560 scan.
gl_point.push_back( transformed_point.getX() );
561 scan.
gl_point.push_back( transformed_point.getY() );
564 scan.
gl_color.push_back( color.red());
565 scan.
gl_color.push_back( color.green());
566 scan.
gl_color.push_back( color.blue());
573 scans_.push_back( std::move(scan) );
584 return *
reinterpret_cast<const int8_t*
>(
data + feature_info.
offset);
588 return *
reinterpret_cast<const int16_t*
>(
data + feature_info.
offset);
590 return *
reinterpret_cast<const uint16_t*
>(
data + feature_info.
offset);
592 return *
reinterpret_cast<const int32_t*
>(
data + feature_info.
offset);
594 return *
reinterpret_cast<const uint32_t*
>(
data + feature_info.
offset);
596 return *
reinterpret_cast<const float*
>(
data + feature_info.
offset);
598 return *
reinterpret_cast<const double*
>(
data + feature_info.
offset);
640 glEnableClientState(GL_VERTEX_ARRAY);
641 glEnableClientState(GL_COLOR_ARRAY);
648 if (scan.transformed && !scan.gl_color.empty())
650 glBindBuffer(GL_ARRAY_BUFFER, scan.point_vbo);
651 glBufferData(GL_ARRAY_BUFFER, scan.gl_point.size() *
sizeof(
float), scan.gl_point.data(), GL_STATIC_DRAW);
652 glVertexPointer( 2, GL_FLOAT, 0, 0);
654 glBindBuffer(GL_ARRAY_BUFFER, scan.color_vbo);
655 glBufferData(GL_ARRAY_BUFFER, scan.gl_color.size() *
sizeof(uint8_t), scan.gl_color.data(), GL_STATIC_DRAW);
656 glColorPointer( 4, GL_UNSIGNED_BYTE, 0, 0);
658 glDrawArrays(GL_POINTS, 0, scan.gl_point.size() / 2 );
662 glDisableClientState(GL_VERTEX_ARRAY);
663 glDisableClientState(GL_COLOR_ARRAY);
664 glBindBuffer(GL_ARRAY_BUFFER, 0);
695 if (!scan.transformed)
700 scan.gl_point.clear();
701 scan.gl_point.reserve(scan.points.size()*2);
703 scan.transformed =
true;
707 scan.gl_point.push_back( transformed_point.getX() );
708 scan.gl_point.push_back( transformed_point.getY() );
713 ROS_WARN(
"Unable to get transform.");
714 scan.transformed =
false;
721 if (
ui_.color_transformer->currentIndex() ==
COLOR_Z)
728 const std::string& path)
733 node[
"topic"] >> topic;
734 ui_.topic->setText(boost::trim_copy(topic).c_str());
744 if (node[
"buffer_size"])
750 if (node[
"color_transformer"])
755 if (node[
"min_color"])
757 std::string min_color_str;
758 node[
"min_color"] >> min_color_str;
759 ui_.min_color->setColor(QColor(min_color_str.c_str()));
762 if (node[
"max_color"])
764 std::string max_color_str;
765 node[
"max_color"] >> max_color_str;
766 ui_.max_color->setColor(QColor(max_color_str.c_str()));
769 if (node[
"value_min"])
775 if (node[
"value_max"])
787 if (node[
"use_rainbow"])
790 node[
"use_rainbow"] >> use_rainbow;
791 ui_.use_rainbow->setChecked(use_rainbow);
794 if (node[
"unpack_rgb"])
797 node[
"unpack_rgb"] >> unpack_rgb;
798 ui_.unpack_rgb->setChecked(unpack_rgb);
804 if (node[
"use_automaxmin"])
807 node[
"use_automaxmin"] >> use_automaxmin;
808 ui_.use_automaxmin->setChecked(use_automaxmin);
818 ROS_DEBUG(
"Color transformer changed to %d", index);
825 bool color_is_flat =
ui_.color_transformer->currentIndex() ==
COLOR_FLAT;
829 ui_.maxColorLabel->hide();
830 ui_.max_color->hide();
831 ui_.minColorLabel->hide();
832 ui_.min_max_color_widget->show();
833 ui_.min_max_value_widget->hide();
834 ui_.use_automaxmin->hide();
835 ui_.use_rainbow->hide();
839 ui_.maxColorLabel->show();
840 ui_.max_color->show();
841 ui_.minColorLabel->show();
842 ui_.min_max_color_widget->setVisible(!
ui_.use_rainbow->isChecked());
843 ui_.min_max_value_widget->setVisible(!
ui_.use_automaxmin->isChecked());
844 ui_.use_automaxmin->show();
845 ui_.use_rainbow->show();
859 alpha_ = std::max(0.0
f, std::min((
float)value, 1.0
f));
863 const std::string& path)
865 emitter << YAML::Key <<
"topic" <<
866 YAML::Value << boost::trim_copy(
ui_.topic->text().toStdString());
867 emitter << YAML::Key <<
"size" <<
868 YAML::Value <<
ui_.pointSize->value();
869 emitter << YAML::Key <<
"buffer_size" <<
870 YAML::Value <<
ui_.bufferSize->value();
871 emitter << YAML::Key <<
"alpha" <<
873 emitter << YAML::Key <<
"color_transformer" <<
874 YAML::Value <<
ui_.color_transformer->currentText().toStdString();
875 emitter << YAML::Key <<
"min_color" <<
876 YAML::Value <<
ui_.min_color->color().name().toStdString();
877 emitter << YAML::Key <<
"max_color" <<
878 YAML::Value <<
ui_.max_color->color().name().toStdString();
879 emitter << YAML::Key <<
"value_min" <<
880 YAML::Value <<
ui_.minValue->value();
881 emitter << YAML::Key <<
"value_max" <<
882 YAML::Value <<
ui_.maxValue->value();
883 emitter << YAML::Key <<
"use_rainbow" <<
884 YAML::Value <<
ui_.use_rainbow->isChecked();
885 emitter << YAML::Key <<
"use_automaxmin" <<
886 YAML::Value <<
ui_.use_automaxmin->isChecked();
887 emitter << YAML::Key <<
"unpack_rgb" <<
888 YAML::Value <<
ui_.unpack_rgb->isChecked();