From 662046241655137b3302d8ab9f67a7e1faf8c772 Mon Sep 17 00:00:00 2001 From: Ar-Ray-code Date: Sat, 6 Apr 2024 22:50:13 +0900 Subject: [PATCH] add emptybutton --- button_rviz_plugin/CMakeLists.txt | 40 ++++++ button_rviz_plugin/package.xml | 21 ++++ button_rviz_plugin/plugins_description.xml | 5 + button_rviz_plugin/src/button_handler.hpp | 83 +++++++++++++ button_rviz_plugin/src/button_panel.cpp | 136 +++++++++++++++++++++ button_rviz_plugin/src/button_panel.hpp | 55 +++++++++ 6 files changed, 340 insertions(+) create mode 100644 button_rviz_plugin/CMakeLists.txt create mode 100644 button_rviz_plugin/package.xml create mode 100644 button_rviz_plugin/plugins_description.xml create mode 100644 button_rviz_plugin/src/button_handler.hpp create mode 100644 button_rviz_plugin/src/button_panel.cpp create mode 100644 button_rviz_plugin/src/button_panel.hpp diff --git a/button_rviz_plugin/CMakeLists.txt b/button_rviz_plugin/CMakeLists.txt new file mode 100644 index 0000000..a4ff67b --- /dev/null +++ b/button_rviz_plugin/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.8) +project(button_rviz_plugin) + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rviz_common REQUIRED) +find_package(rviz_rendering REQUIRED) + +set(CMAKE_AUTOMOC ON) + +add_library(${PROJECT_NAME} SHARED + src/button_panel.cpp +) +ament_target_dependencies(${PROJECT_NAME} + rviz_common + rviz_rendering +) +install(TARGETS + ${PROJECT_NAME} + EXPORT ${PROJECT_NAME} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + INCLUDES DESTINATION include +) + +pluginlib_export_plugin_description_file(rviz_common plugins_description.xml) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + set(ament_cmake_copyright_FOUND TRUE) + set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +ament_package() diff --git a/button_rviz_plugin/package.xml b/button_rviz_plugin/package.xml new file mode 100644 index 0000000..20b584c --- /dev/null +++ b/button_rviz_plugin/package.xml @@ -0,0 +1,21 @@ + + + + button_rviz_plugin + 0.0.0 + button rviz plugin for CoRE_viewer + Ar-Ray-code + MIT + + ament_cmake + + rviz_common + rviz_rendering + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/button_rviz_plugin/plugins_description.xml b/button_rviz_plugin/plugins_description.xml new file mode 100644 index 0000000..2f24c4f --- /dev/null +++ b/button_rviz_plugin/plugins_description.xml @@ -0,0 +1,5 @@ + + + button panel + + \ No newline at end of file diff --git a/button_rviz_plugin/src/button_handler.hpp b/button_rviz_plugin/src/button_handler.hpp new file mode 100644 index 0000000..71d1ba0 --- /dev/null +++ b/button_rviz_plugin/src/button_handler.hpp @@ -0,0 +1,83 @@ +// Copyright 2024 StrayedCats. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include + +namespace button_rviz_plugin +{ +class ButtonHandler +{ +public: + ButtonHandler(void) {} + + void setRosNodePtr(const rclcpp::Node::SharedPtr node_ptr) + { + node_ptr_ = node_ptr; + } + + bool initializePublisher(const std::string topic_name) + { + if (topic_name == "") { + return false; + } + button_publisher_ = + node_ptr_->create_publisher(topic_name, 10); + return true; + } + + void finalizePublisher(void) + { + button_publisher_.reset(); + } + + void publishButton(bool button) + { + if (button) + { + std_msgs::msg::Empty msg; + button_publisher_->publish(msg); + } + } + + std::vector getEmptyTopicList(void) const + { + return getTopicList("std_msgs/msg/Empty"); + } + +private: + std::vector getTopicList(const std::string type_name) const + { + std::map> topic_map = node_ptr_->get_topic_names_and_types(); + + std::vector output; + for (auto pair : topic_map) { + for (auto s : pair.second) { + if (s == type_name) { + output.push_back(pair.first); + break; + } + } + } + return output; + } + + rclcpp::Node::SharedPtr node_ptr_; + rclcpp::Publisher::SharedPtr button_publisher_; +}; + +} // namespace button_rviz_plugin diff --git a/button_rviz_plugin/src/button_panel.cpp b/button_rviz_plugin/src/button_panel.cpp new file mode 100644 index 0000000..9bdef5b --- /dev/null +++ b/button_rviz_plugin/src/button_panel.cpp @@ -0,0 +1,136 @@ +// Copyright 2024 StrayedCats. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "button_panel.hpp" + +#include +#include + +#include +#include +#include + +namespace button_rviz_plugin +{ +EmptyButton::EmptyButton(QWidget * parent) +: rviz_common::Panel(parent) +{ + QVBoxLayout * layout = new QVBoxLayout; + + QHBoxLayout * layout_1st = new QHBoxLayout; + enable_check_ = new QCheckBox("Enable"); + layout_1st->addWidget(enable_check_); + topic_combo_ = new QComboBox(); + topic_combo_->setEditable(true); + layout_1st->addWidget(topic_combo_); + // layout->addLayout(layout_1st); + + // QHBoxLayout * layout_3rd = new QHBoxLayout; + a_button_ = new QPushButton("click"); + layout_1st->addWidget(a_button_); + layout->addLayout(layout_1st); + + setLayout(layout); + + interval_timer_ = new QTimer(this); + + connect(interval_timer_, &QTimer::timeout, this, &EmptyButton::onTick); + connect(enable_check_, &QCheckBox::stateChanged, this, &EmptyButton::onCheckChange); + connect(a_button_, &QPushButton::clicked, this, &EmptyButton::onClickA); + + interval_timer_->start(100); +} + +void EmptyButton::onInitialize() +{ + button_handler_.setRosNodePtr( + this->getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node()); + updateTopicList(); +} + +void EmptyButton::onCheckChange(int state) +{ + if (state == Qt::Checked) { + std::string topic_name = topic_combo_->currentText().toStdString(); + bool ret = button_handler_.initializePublisher(topic_name); + if (!ret) { + return; + } + is_active_ = true; + } else { + button_handler_.finalizePublisher(); + is_active_ = false; + updateTopicList(); + } +} + +void EmptyButton::onClickA() +{ + a_clicked_ = true; +} + +void EmptyButton::onTick() +{ + if (is_active_) { + button_handler_.publishButton(a_clicked_); + a_clicked_ = false; + } +} + +void EmptyButton::save(rviz_common::Config config) const +{ + rviz_common::Panel::save(config); + config.mapSetValue("BaseTopic", topic_combo_->currentText()); + config.mapSetValue("Checked", enable_check_->isChecked()); +} + +void EmptyButton::load(const rviz_common::Config & config) +{ + rviz_common::Panel::load(config); + QString tmp_text; + bool tmp_bool; + if (config.mapGetString("BaseTopic", &tmp_text)) { + topic_combo_->setCurrentText(tmp_text); + } + if (config.mapGetBool("Checked", &tmp_bool)) { + enable_check_->setChecked(tmp_bool); + } +} + +void EmptyButton::updateTopicList(void) +{ + std::string previous_topic_name = topic_combo_->currentText().toStdString(); + auto topic_list = button_handler_.getEmptyTopicList(); + topic_combo_->clear(); + int same_topic_index = -1; + for (auto t : topic_list) { + topic_combo_->addItem(t.c_str()); + if (t == previous_topic_name) { + same_topic_index = topic_combo_->count() - 1; + } + } + + if (previous_topic_name != "") { + if (same_topic_index < 0) { + topic_combo_->addItem(previous_topic_name.c_str()); + same_topic_index = topic_combo_->count() - 1; + } + topic_combo_->setCurrentIndex(same_topic_index); + } +} + +} // namespace button_rviz_plugin + +#include +PLUGINLIB_EXPORT_CLASS(button_rviz_plugin::EmptyButton, rviz_common::Panel) diff --git a/button_rviz_plugin/src/button_panel.hpp b/button_rviz_plugin/src/button_panel.hpp new file mode 100644 index 0000000..e3f6e04 --- /dev/null +++ b/button_rviz_plugin/src/button_panel.hpp @@ -0,0 +1,55 @@ +// Copyright 2024 StrayedCats. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include + +#ifndef Q_MOC_RUN +#include "button_handler.hpp" +#include +#endif + +namespace button_rviz_plugin +{ + +class EmptyButton : public rviz_common::Panel +{ + Q_OBJECT + +public: + EmptyButton(QWidget * parent = nullptr); + void onInitialize() override; + void load(const rviz_common::Config & config) override; + void save(rviz_common::Config config) const override; + +public Q_SLOTS: + void onCheckChange(int state); + void onClickA(void); + void onTick(void); + +private: + void updateTopicList(void); + + ButtonHandler button_handler_{}; + QCheckBox * enable_check_; + QComboBox * topic_combo_; + QPushButton * a_button_; + QTimer * interval_timer_; + bool is_active_{false}; + bool a_clicked_{false}; +}; + +} // namespace button_rviz_plugin