10 #include <QDialogButtonBox>
11 #include <QScrollArea>
12 #include <QPushButton>
14 #include <QRadioButton>
15 #include <unordered_map>
16 #include <QMessageBox>
17 #include <tf2_ros/qos.hpp>
18 #include <rosbag2_cpp/types.hpp>
20 #include <rmw/types.h>
25 _context = std::make_shared<rclcpp::Context>();
28 auto exec_args = rclcpp::ExecutorOptions();
30 _executor = std::make_unique<rclcpp::executors::MultiThreadedExecutor>(exec_args, 2);
63 auto publisher_it =
_publishers.find(info.topic_name);
86 if (!
_node && to_enable)
88 auto node_opts = rclcpp::NodeOptions();
90 _node = std::make_shared<rclcpp::Node>(
"plotjuggler", node_opts);
103 const auto any_metadata = metadata_it->second[0].y;
104 _topics_info = std::any_cast<std::vector<TopicInfo>>(any_metadata);
140 const auto any_metadata = metadata_it->second[0].y;
141 _topics_info = std::any_cast<std::vector<TopicInfo>>(any_metadata);
145 dialog->setAttribute(Qt::WA_DeleteOnClose);
146 dialog->
ui()->radioButtonClock->setHidden(
true);
147 dialog->
ui()->radioButtonHeaderStamp->setHidden(
true);
149 std::map<std::string, QCheckBox*> checkbox;
153 const std::string topic_name = info.topic_name;
154 auto cb =
new QCheckBox(dialog);
158 cb->setChecked(
true);
162 cb->setChecked(filter_it->second);
164 cb->setFocusPolicy(Qt::NoFocus);
165 dialog->
ui()->formLayout->addRow(
new QLabel(QString::fromStdString(topic_name)), cb);
166 checkbox.insert(std::make_pair(topic_name, cb));
167 connect(dialog->
ui()->pushButtonSelect, &QPushButton::pressed, [cb]() { cb->setChecked(true); });
168 connect(dialog->
ui()->pushButtonDeselect, &QPushButton::pressed, [cb]() { cb->setChecked(false); });
173 if (dialog->result() == QDialog::Accepted)
176 for (
const auto&
it : checkbox)
187 rcutils_time_point_value_t
Convert(
const builtin_interfaces::msg::Time& stamp)
192 builtin_interfaces::msg::Time
Convert(
const rcutils_time_point_value_t& time_stamp)
194 builtin_interfaces::msg::Time stamp;
195 stamp.sec =
static_cast<int32_t
>(time_stamp /
NSEC_PER_SEC);
196 stamp.nanosec =
static_cast<int32_t
>(time_stamp - (
NSEC_PER_SEC * stamp.sec));
202 using StringPair = std::pair<std::string, std::string>;
204 std::map<StringPair, geometry_msgs::msg::TransformStamped> transforms;
205 std::map<StringPair, geometry_msgs::msg::TransformStamped> static_transforms;
209 const std::string& topic_name = data_it.first;
212 if (topic_name !=
"/tf_static" && topic_name !=
"/tf")
224 auto transforms_ptr = (topic_name ==
"/tf_static") ? & static_transforms : &transforms;
226 std::vector<uint8_t> raw_buffer;
228 int initial_index = tf_data->
getIndexFromX(current_time - 2.0);
230 if (_previous_play_index < last_index && _previous_play_index > initial_index)
235 for (
size_t index = std::max(0, initial_index);
index <= last_index;
index++)
237 const std::any& any_value = tf_data->
at(
index).y;
239 const bool isRosbagMessage = (any_value.type() ==
typeid(
MessageRefPtr));
241 if (!isRosbagMessage)
246 const auto& msg_instance = std::any_cast<MessageRefPtr>(any_value);
248 auto tf_type_support = rosidl_typesupport_cpp::get_message_type_support_handle<tf2_msgs::msg::TFMessage>();
249 tf2_msgs::msg::TFMessage tf_msg;
250 if ( RMW_RET_OK != rmw_deserialize(msg_instance->serialized_data.get(), tf_type_support, &tf_msg) )
252 throw std::runtime_error(
"failed to deserialize TF message");
255 for (
const auto& stamped_transform : tf_msg.transforms)
257 const auto& parent_id = stamped_transform.header.frame_id;
258 const auto& child_id = stamped_transform.child_frame_id;
259 StringPair trans_id = std::make_pair(parent_id, child_id);
260 auto it = transforms_ptr->find(trans_id);
261 if (
it == transforms_ptr->end())
263 transforms_ptr->insert({ trans_id, stamped_transform });
265 else if (
Convert(
it->second.header.stamp) <=
266 Convert(stamped_transform.header.stamp))
268 it->second = stamped_transform;
274 std::vector<geometry_msgs::msg::TransformStamped> transforms_vector;
275 transforms_vector.reserve(transforms_ptr->size());
277 rcutils_time_point_value_t time_stamp;
278 int error = rcutils_system_time_now(&time_stamp);
280 if (
error != RCUTILS_RET_OK)
282 qDebug() <<
"Error getting current time. Error:" << rcutils_get_error_string().str;
285 for (
auto& trans : *transforms_ptr)
287 trans.second.header.stamp =
Convert( time_stamp );
288 transforms_vector.emplace_back(std::move(trans.second));
290 if( transforms_ptr == &transforms ){
321 const std::string& topic_name = data_it.first;
324 if (topic_name ==
"/tf" || topic_name ==
"tf_static")
341 const auto& any_value = plot_any.
at(last_index).y;
345 const auto& msg_instance = std::any_cast<MessageRefPtr>(any_value);
346 publisher_it->second->publish(msg_instance->serialized_data);
363 int current_index = continuous_msgs.
getIndexFromX(current_time);
376 const auto& any_value = consecutive_msg.
at(
index).y;
379 const auto& msg_instance = std::any_cast<MessageRefPtr>(any_value);
381 auto publisher_it =
_publishers.find(msg_instance->topic_name);
387 publisher_it->second->publish(msg_instance->serialized_data);