3 #include "../qnodedialog.h" 10 #include <QVBoxLayout> 11 #include <QDialogButtonBox> 12 #include <QScrollArea> 13 #include <QPushButton> 15 #include <QRadioButton> 17 #include <std_msgs/Header.h> 18 #include <unordered_map> 19 #include <rosgraph_msgs/Clock.h> 20 #include <QMessageBox> 28 _publish_clock = settings.value(
"TopicPublisherROS/publish_clock",
true ).toBool();
51 if( !
_node && to_enable)
88 if( all_topics.empty() )
return;
90 QDialog* dialog =
new QDialog();
91 dialog->setWindowTitle(
"Select topics to be published");
92 dialog->setMinimumWidth(350);
93 QVBoxLayout* vertical_layout =
new QVBoxLayout();
94 QFormLayout* grid_layout =
new QFormLayout();
96 std::map<std::string, QCheckBox*> checkbox;
98 QFrame* frame =
new QFrame;
100 auto publish_sim_time =
new QRadioButton(
"Keep original timestamp and publish [/clock]");
101 auto publish_real_time =
new QRadioButton(
"Overwrite timestamp [std_msgs/Header/stamp]");
102 QPushButton* select_button =
new QPushButton(
"Select all");
103 QPushButton* deselect_button =
new QPushButton(
"Deselect all");
106 publish_sim_time->setFocusPolicy(Qt::NoFocus);
107 publish_sim_time->setToolTip(
"Publish the topic [/clock].\n" 108 "You might want to set rosparam use_sim_time = true" );
111 publish_real_time->setFocusPolicy(Qt::NoFocus);
112 publish_real_time->setToolTip(
"Pretend it is a new message.\n" 113 "The timestamp of the original message will be overwritten" 114 "with ros::Time::Now()");
116 select_button->setFocusPolicy(Qt::NoFocus);
117 deselect_button->setFocusPolicy(Qt::NoFocus);
119 for (
const auto& topic: all_topics)
121 auto cb =
new QCheckBox(dialog);
125 cb->setChecked(
true );
128 cb->setChecked( filter_it->second );
130 cb->setFocusPolicy(Qt::NoFocus);
131 grid_layout->addRow(
new QLabel( QString::fromStdString(*topic)), cb);
132 checkbox.insert( std::make_pair(*topic, cb) );
133 connect( select_button, &QPushButton::pressed, [cb](){ cb->setChecked(
true);} );
134 connect( deselect_button, &QPushButton::pressed, [cb](){ cb->setChecked(
false);} );
137 frame->setLayout(grid_layout);
139 QScrollArea* scrollArea =
new QScrollArea;
140 scrollArea->setWidget(frame);
142 QDialogButtonBox* buttons =
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
144 QHBoxLayout* select_buttons_layout =
new QHBoxLayout;
145 select_buttons_layout->addWidget( select_button );
146 select_buttons_layout->addWidget( deselect_button );
148 vertical_layout->addWidget( publish_sim_time );
149 vertical_layout->addWidget( publish_real_time );
150 vertical_layout->addWidget(scrollArea);
151 vertical_layout->addLayout(select_buttons_layout);
152 vertical_layout->addWidget( buttons );
154 connect(buttons, SIGNAL(accepted()), dialog, SLOT(accept()));
155 connect(buttons, SIGNAL(rejected()), dialog, SLOT(reject()));
157 dialog->setLayout(vertical_layout);
161 auto result = dialog->exec();
164 if(autoconfirm || dialog->result() == QDialog::Accepted)
167 for(
const auto& it: checkbox )
175 const std::string& topic_name = it->first;
188 settings.setValue(
"TopicPublisherROS/publish_clock",
_publish_clock );
194 std::unordered_map<std::string, geometry_msgs::TransformStamped> transforms;
198 const std::string& topic_name = data_it.first;
207 if( shapeshifter->
getDataType() !=
"tf/tfMessage" &&
208 shapeshifter->
getDataType() !=
"tf2_msgs/TFMessage" )
220 std::vector<uint8_t> raw_buffer;
222 int initial_index = tf_data->
getIndexFromX( current_time - 2.0 );
230 for(
size_t index = std::max(0, initial_index); index <= last_index; index++ )
236 if( isRosbagMessage )
240 raw_buffer.resize( msg_instance.size() );
242 msg_instance.write(ostream);
244 tf::tfMessage tf_msg;
248 for(
const auto& stamped_transform: tf_msg.transforms)
250 const auto& child_id = stamped_transform.child_frame_id;
251 auto it = transforms.find(child_id);
252 if( it == transforms.end())
254 transforms.insert( {stamped_transform.child_frame_id, stamped_transform} );
256 else if( it->second.header.stamp <= stamped_transform.header.stamp)
258 it->second = stamped_transform;
265 std::vector<geometry_msgs::TransformStamped> transforms_vector;
266 transforms_vector.reserve(transforms.size());
269 for(
auto& trans: transforms)
273 trans.second.header.stamp = now;
275 transforms_vector.emplace_back( std::move(trans.second) );
298 const auto& topic_name = msg_instance.
getTopic();
307 std::vector<uint8_t> raw_buffer;
308 raw_buffer.resize( msg_instance.
size() );
310 msg_instance.
write(ostream);
318 if(first_field->type().baseName() ==
"std_msgs/Header")
321 std_msgs::Header
msg;
332 shapeshifted->
read( istream );
334 auto publisher_it =
_publishers.find( topic_name );
338 publisher_it = res.first;
343 publisher.
publish( *shapeshifted );
354 QMessageBox::warning(
nullptr, tr(
"Disconnected!"),
355 "The roscore master cannot be detected.\n" 356 "The publisher will be disabled.");
368 const PlotDataAny& continuous_msgs = data_it->second;
376 const std::string& topic_name = data_it.first;
386 if( shapeshifter->
getDataType() ==
"tf/tfMessage" ||
387 shapeshifter->
getDataType() ==
"tf2_msgs/TFMessage" )
398 const auto& any_value = plot_any.
at(last_index).
y;
409 rosgraph_msgs::Clock clock;
411 clock.clock.fromSec( current_time );
416 qDebug() <<
"error: " << current_time;
428 QMessageBox::warning(
nullptr, tr(
"Disconnected!"),
429 "The roscore master cannot be detected.\n" 430 "The publisher will be disabled.");
440 const PlotDataAny& continuous_msgs = data_it->second;
441 int current_index = continuous_msgs.
getIndexFromX(current_time);
451 const PlotDataAny& consecutive_msg = data_it->second;
455 const auto& any_value = consecutive_msg.
at(index).
y;
460 if( !
toPublish( msg_instance.getTopic() ) )
470 rosgraph_msgs::Clock clock;
471 clock.clock = msg_instance.getTime();
ValueType any_cast(any const &operand)
const ROSMessageInfo * getMessageInfo(const std::string &msg_identifier) const
bool toPublish(const std::string &topic_name)
void filterDialog(bool autoconfirm)
const Point & at(size_t index) const
void publish(const boost::shared_ptr< M > &message) const
QAction * _select_topics_to_publish
int getIndexFromX(Time x) const
virtual void setParentMenu(QMenu *parent_menu, QAction *parent_action)
QAction * _enable_self_action
constexpr pointer data() const noexcept
static RosIntrospectionFactory & get()
const TreeNode< T > * croot() const
void broadcastTF(double current_time)
ros::Publisher _clock_publisher
std::unordered_map< std::string, PlotDataAny > user_defined
constexpr size_type size() const noexcept
void read(Stream &stream)
void serialize(Stream &stream, const T &t)
ros::Publisher advertise(ros::NodeHandle &nh, const std::string &topic, uint32_t queue_size, bool latch=false, const ros::SubscriberStatusCallback &connect_cb=ros::SubscriberStatusCallback()) const
void setParentMenu(QMenu *menu, QAction *action) override
static RosIntrospection::Parser & parser()
static std::vector< const std::string * > getTopicList()
const PlotDataMapRef * _datamap
std::string const & getDataType() const
virtual ~TopicPublisherROS() override
virtual void updateState(double current_time) override
static ros::NodeHandlePtr getNode()
std::unordered_map< std::string, bool > _topics_to_publish
std::map< std::string, ros::Publisher > _publishers
virtual void setEnabled(bool enabled) override
std::string const & getTopic() const
static RosIntrospection::ShapeShifter * getShapeShifter(const std::string &topic_name)
virtual void play(double interval) override
std::unique_ptr< tf::TransformBroadcaster > _tf_publisher
const std::type_info & type() const any_noexcept
void publishAnyMsg(const rosbag::MessageInstance &msg_instance)
void deserialize(Stream &stream, T &t)
void write(Stream &stream) const
virtual void setEnabled(bool enabled)