Skip to content

Commit 9db48b5

Browse files
committed
feat: add trigger by service
Signed-off-by: tanaka3 <ttatcoder@outlook.jp>
1 parent 8c92d17 commit 9db48b5

File tree

8 files changed

+112
-28
lines changed

8 files changed

+112
-28
lines changed

common/tier4_screen_capture_rviz_plugin/package.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
<build_depend>autoware_cmake</build_depend>
1313

14+
<depend>libopencv-dev</depend>
1415
<depend>libqt5-core</depend>
1516
<depend>libqt5-gui</depend>
1617
<depend>libqt5-widgets</depend>
1718
<depend>qtbase5-dev</depend>
1819
<depend>rclcpp</depend>
1920
<depend>rviz_common</depend>
2021
<depend>rviz_rendering</depend>
21-
<depend>libopencv-dev</depend>
22+
<depend>std_srvs</depend>
2223
<test_depend>ament_lint_auto</test_depend>
2324
<test_depend>autoware_lint_common</test_depend>
2425

common/tier4_screen_capture_rviz_plugin/src/screen_capture_panel.cpp

+76-24
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
#include <filesystem>
2121
#include <iostream>
2222

23+
using std::placeholders::_1;
24+
using std::placeholders::_2;
25+
2326
void setFormatDate(QLabel * line, double time)
2427
{
2528
char buffer[128];
@@ -47,13 +50,13 @@ AutowareScreenCapturePanel::AutowareScreenCapturePanel(QWidget * parent)
4750
// video capture
4851
auto * video_cap_layout = new QHBoxLayout;
4952
{
50-
capture_to_mp4_button_ptr_ = new QPushButton("Capture To Video");
53+
capture_to_mp4_button_ptr_ = new QPushButton("Capture Screen");
5154
connect(capture_to_mp4_button_ptr_, SIGNAL(clicked()), this, SLOT(onClickVideoCapture()));
5255
capture_hz_ = new QSpinBox();
53-
capture_hz_->setRange(1, 2);
54-
capture_hz_->setValue(1);
56+
capture_hz_->setRange(1, 10);
57+
capture_hz_->setValue(10);
5558
capture_hz_->setSingleStep(1);
56-
connect(capture_hz_, SIGNAL(valueChanged(int)), this, SLOT(onRateChanged(int)));
59+
connect(capture_hz_, SIGNAL(valueChanged(int)), this, SLOT(onRateChanged()));
5760
// video cap layout
5861
video_cap_layout->addWidget(capture_to_mp4_button_ptr_);
5962
video_cap_layout->addWidget(capture_hz_);
@@ -74,11 +77,25 @@ AutowareScreenCapturePanel::AutowareScreenCapturePanel(QWidget * parent)
7477
state_ = State::WAITING_FOR_CAPTURE;
7578
}
7679

80+
void AutowareScreenCapturePanel::onCaptureTrigger(
81+
[[maybe_unused]] const std::shared_ptr<std_srvs::srv::Trigger::Request> req,
82+
const std::shared_ptr<std_srvs::srv::Trigger::Response> res)
83+
{
84+
onClickVideoCapture();
85+
res->success = true;
86+
res->message = stateToString(state_);
87+
}
88+
7789
void AutowareScreenCapturePanel::onInitialize()
7890
{
79-
rviz_ros_node_ = getDisplayContext()->getRosNodeAbstraction();
91+
raw_node_ = this->getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node();
92+
capture_service_ = raw_node_->create_service<std_srvs::srv::Trigger>(
93+
"/debug/service/capture_screen",
94+
std::bind(&AutowareScreenCapturePanel::onCaptureTrigger, this, _1, _2));
8095
}
8196

97+
void AutowareScreenCapturePanel::onRateChanged() {}
98+
8299
void AutowareScreenCapturePanel::onClickScreenCapture()
83100
{
84101
const std::string time_text = "capture/" + ros_time_label_->text().toStdString();
@@ -87,24 +104,24 @@ void AutowareScreenCapturePanel::onClickScreenCapture()
87104
return;
88105
}
89106

90-
void AutowareScreenCapturePanel::convertPNGImagesToMP4() {
91-
cv::VideoCapture capture(root_folder_+ "/%06d.png", cv::CAP_IMAGES);
107+
void AutowareScreenCapturePanel::convertPNGImagesToMP4()
108+
{
109+
cv::VideoCapture capture(root_folder_ + "/%06d.png", cv::CAP_IMAGES);
92110
if (!capture.isOpened()) {
93111
return;
94112
}
95-
int fourcc = cv::VideoWriter::fourcc('m', 'p', '4', 'v'); // mp4
113+
int fourcc = cv::VideoWriter::fourcc('m', 'p', '4', 'v'); // mp4
96114
cv::VideoWriter writer;
97-
cv::Size size = cv::Size(1280,720);
98-
writer.open("capture/" + root_folder_ + ".mp4", fourcc, 1, size);
99-
cv::Mat image, resized;
115+
cv::Size size = cv::Size(1280, 720);
116+
writer.open("capture/" + root_folder_ + ".mp4", fourcc, capture_hz_->value(), size);
117+
cv::Mat image;
100118
while (true) {
101119
capture >> image;
102120
if (image.empty()) {
103121
break;
104122
}
105123
// need to resize for fixed frame video
106-
cv::resize(image,resized,size);
107-
writer << resized;
124+
writer << image;
108125
cv::waitKey(0);
109126
}
110127
capture.release();
@@ -116,6 +133,18 @@ void AutowareScreenCapturePanel::convertPNGImagesToMP4() {
116133
void AutowareScreenCapturePanel::onClickVideoCapture()
117134
{
118135
const int clock = static_cast<int>(1e3 / capture_hz_->value());
136+
try {
137+
const QWidgetList top_level_widgets = QApplication::topLevelWidgets();
138+
for (QWidget * widget : top_level_widgets) {
139+
QMainWindow * main_window_candidate = qobject_cast<QMainWindow *>(widget);
140+
if (main_window_candidate) {
141+
main_window_ = main_window_candidate;
142+
}
143+
}
144+
} catch (...) {
145+
return;
146+
}
147+
if (!main_window_) return;
119148
switch (state_) {
120149
case State::WAITING_FOR_CAPTURE:
121150
// initialize setting
@@ -129,16 +158,12 @@ void AutowareScreenCapturePanel::onClickVideoCapture()
129158
capture_timer_->start(clock);
130159
state_ = State::CAPTURING;
131160
break;
132-
case State::CAPTURING:
133-
{
134-
capture_timer_->stop();
135-
}
161+
case State::CAPTURING: {
162+
capture_timer_->stop();
163+
}
136164
capture_to_mp4_button_ptr_->setText("writing to video");
137165
capture_to_mp4_button_ptr_->setStyleSheet("background-color: #FFFF00;");
138166
convertPNGImagesToMP4();
139-
state_ = State::FINALIZED;
140-
break;
141-
case State::FINALIZED:
142167
capture_to_mp4_button_ptr_->setText("waiting for capture");
143168
capture_to_mp4_button_ptr_->setStyleSheet("background-color: #00FF00;");
144169
state_ = State::WAITING_FOR_CAPTURE;
@@ -152,15 +177,42 @@ void AutowareScreenCapturePanel::onTimer()
152177
std::stringstream count_text;
153178
count_text << std::setw(6) << std::setfill('0') << counter_;
154179
const std::string file = root_folder_ + "/" + count_text.str() + ".png";
155-
getDisplayContext()->getViewManager()->getRenderPanel()->getRenderWindow()->captureScreenShot(
156-
file);
180+
if (!main_window_) return;
181+
try {
182+
// this is deprecated but only way to capture nicely
183+
QPixmap original_pixmap = QPixmap::grabWindow(main_window_->winId());
184+
QString format = "png";
185+
QString file_name = QString::fromStdString(file);
186+
if (!file_name.isEmpty())
187+
original_pixmap.scaled(width_, height_).save(file_name, format.toLatin1().constData());
188+
} catch (std::exception & e) {
189+
std::cout << e.what() << std::endl;
190+
}
157191
counter_++;
158192
}
159193

160194
void AutowareScreenCapturePanel::update()
161195
{
162-
setFormatDate(
163-
ros_time_label_, rviz_ros_node_.lock()->get_raw_node()->get_clock()->now().seconds());
196+
setFormatDate(ros_time_label_, raw_node_->get_clock()->now().seconds());
197+
}
198+
199+
void AutowareScreenCapturePanel::save(rviz_common::Config config) const
200+
{
201+
Panel::save(config);
202+
config.mapSetValue("width", &width_);
203+
config.mapSetValue("height", &height_);
204+
}
205+
206+
void AutowareScreenCapturePanel::load(const rviz_common::Config & config)
207+
{
208+
Panel::load(config);
209+
if (!config.mapGetFloat("width", &width_)) width_ = 1280;
210+
if (!config.mapGetFloat("height", &height_)) height_ = 720;
211+
}
212+
213+
AutowareScreenCapturePanel::~AutowareScreenCapturePanel()
214+
{
215+
std::filesystem::remove_all(root_folder_);
164216
}
165217

166218
#include <pluginlib/class_list_macros.hpp>

common/tier4_screen_capture_rviz_plugin/src/screen_capture_panel.hpp

+34-3
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,30 @@
1616
#define SCREEN_CAPTURE_PANEL_HPP_
1717

1818
// Qt
19+
#include <QApplication>
20+
#include <QDesktopWidget>
21+
#include <QDir>
22+
#include <QFileDialog>
1923
#include <QHBoxLayout>
2024
#include <QLabel>
2125
#include <QLineEdit>
26+
#include <QMainWindow>
2227
#include <QPushButton>
28+
#include <QScreen>
2329
#include <QSpinBox>
2430
#include <QTimer>
2531

2632
// rviz
33+
#include <opencv2/opencv.hpp>
2734
#include <rviz_common/display_context.hpp>
2835
#include <rviz_common/panel.hpp>
2936
#include <rviz_common/render_panel.hpp>
3037
#include <rviz_common/ros_integration/ros_node_abstraction_iface.hpp>
3138
#include <rviz_common/view_manager.hpp>
3239
#include <rviz_rendering/render_window.hpp>
3340

34-
#include <opencv2/opencv.hpp>
41+
// ros
42+
#include <std_srvs/srv/trigger.hpp>
3543

3644
#include <memory>
3745
#include <string>
@@ -44,30 +52,53 @@ class AutowareScreenCapturePanel : public rviz_common::Panel
4452

4553
public:
4654
explicit AutowareScreenCapturePanel(QWidget * parent = nullptr);
55+
~AutowareScreenCapturePanel();
4756
void update();
4857
void onInitialize() override;
4958
void createWallTimer();
5059
void onTimer();
5160
void convertPNGImagesToMP4();
61+
void save(rviz_common::Config config) const override;
62+
void load(const rviz_common::Config & config) override;
63+
void onCaptureTrigger(
64+
const std::shared_ptr<std_srvs::srv::Trigger::Request> req,
65+
const std::shared_ptr<std_srvs::srv::Trigger::Response> res);
5266

5367
public Q_SLOTS:
5468
void onClickScreenCapture();
5569
void onClickCaptureToVideo();
5670
void onClickVideoCapture();
71+
void onRateChanged();
5772

5873
private:
5974
QLabel * ros_time_label_;
6075
QPushButton * screen_capture_button_ptr_;
6176
QPushButton * capture_to_mp4_button_ptr_;
6277
QSpinBox * capture_hz_;
6378
QTimer * capture_timer_;
64-
enum class State { WAITING_FOR_CAPTURE, CAPTURING, FINALIZED };
79+
QMainWindow * main_window_;
80+
enum class State { WAITING_FOR_CAPTURE, CAPTURING };
6581
State state_;
6682
std::string root_folder_;
6783
size_t counter_;
84+
bool is_capture_;
85+
float width_;
86+
float height_;
87+
88+
std::string stateToString(const State & state)
89+
{
90+
if (state == State::WAITING_FOR_CAPTURE) {
91+
return "waiting for capture";
92+
}
93+
if (state == State::CAPTURING) {
94+
return "capturing";
95+
}
96+
return "";
97+
}
6898

6999
protected:
70-
rviz_common::ros_integration::RosNodeAbstractionIface::WeakPtr rviz_ros_node_;
100+
rclcpp::Service<std_srvs::srv::Trigger>::SharedPtr capture_service_;
101+
rclcpp::Node::SharedPtr raw_node_;
71102
};
72103

73104
#endif // SCREEN_CAPTURE_PANEL_HPP_

perception/lidar_apollo_instance_segmentation/COLCON_IGNORE

Whitespace-only changes.

perception/lidar_centerpoint/COLCON_IGNORE

Whitespace-only changes.

perception/tensorrt_yolo/COLCON_IGNORE

Whitespace-only changes.

perception/traffic_light_classifier/COLCON_IGNORE

Whitespace-only changes.

perception/traffic_light_ssd_fine_detector/COLCON_IGNORE

Whitespace-only changes.

0 commit comments

Comments
 (0)