diff --git a/CMakeLists.txt b/CMakeLists.txt index a292b75..58a397b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,22 +22,58 @@ find_package(shisen_cpp REQUIRED) find_package(sensor_msgs REQUIRED) find_package(cv_bridge REQUIRED) +find_package(Protobuf CONFIG REQUIRED) +message(STATUS "Using protobuf ${Protobuf_VERSION}") + +# Find gRPC installation +# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation. +find_package(gRPC CONFIG REQUIRED) +message(STATUS "Using gRPC ${gRPC_VERSION}") + add_library(${PROJECT_NAME} SHARED + "src/${PROJECT_NAME}/config/grpc/config.cpp" + "src/${PROJECT_NAME}/config/grpc/call_data_get_color_setting.cpp" + "src/${PROJECT_NAME}/config/grpc/call_data_save_color_setting.cpp" + "src/${PROJECT_NAME}/config/grpc/call_data_set_color_setting.cpp" + "src/${PROJECT_NAME}/config/utils/config.cpp" "src/${PROJECT_NAME}/detector/color_detector.cpp" "src/${PROJECT_NAME}/detector/dnn_detector.cpp" "src/${PROJECT_NAME}/detector/lbp_detector.cpp" "src/${PROJECT_NAME}/node/ninshiki_cpp_node.cpp" "src/${PROJECT_NAME}/utils/color.cpp" "src/${PROJECT_NAME}/utils/contours.cpp" - "src/${PROJECT_NAME}/utils/circle.cpp" - "src/${PROJECT_NAME}/node/ninshiki_cpp_node.cpp" - "src/${PROJECT_NAME}/utils/utils.cpp") + "src/${PROJECT_NAME}/utils/utils.cpp" +) + +add_library(${PROJECT_NAME}_exported SHARED + "src/${PROJECT_NAME}/detector/color_detector.cpp" + "src/${PROJECT_NAME}/detector/dnn_detector.cpp" + "src/${PROJECT_NAME}/detector/lbp_detector.cpp" + "src/${PROJECT_NAME}/utils/color.cpp" + "src/${PROJECT_NAME}/utils/contours.cpp" + "src/${PROJECT_NAME}/utils/utils.cpp" +) target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + $) + +target_include_directories(${PROJECT_NAME}_exported PUBLIC $ $) ament_target_dependencies(${PROJECT_NAME} + keisan + ninshiki_interfaces + OpenCV + rclcpp + shisen_cpp + sensor_msgs + cv_bridge + gRPC) + +ament_target_dependencies(${PROJECT_NAME}_exported keisan ninshiki_interfaces OpenCV @@ -46,13 +82,28 @@ ament_target_dependencies(${PROJECT_NAME} sensor_msgs cv_bridge) +target_link_libraries(${PROJECT_NAME} + gRPC::grpc++_reflection + gRPC::grpc++ +) + install(DIRECTORY "include" DESTINATION ".") install(TARGETS ${PROJECT_NAME} - EXPORT export_${PROJECT_NAME} +EXPORT export_${PROJECT_NAME} + ARCHIVE DESTINATION "lib" + LIBRARY DESTINATION "lib" + RUNTIME DESTINATION "bin" + INCLUDES DESTINATION "include") + +install(TARGETS ${PROJECT_NAME}_exported +EXPORT export_${PROJECT_NAME}_exported ARCHIVE DESTINATION "lib" LIBRARY DESTINATION "lib" - RUNTIME DESTINATION "bin") + RUNTIME DESTINATION "bin" + INCLUDES DESTINATION "include") + +target_compile_options(${PROJECT_NAME} PRIVATE -fPIC) add_executable(detector "src/ninshiki_cpp_detector.cpp") target_include_directories(detector PUBLIC @@ -78,5 +129,5 @@ ament_export_dependencies( sensor_msgs cv_bridge) ament_export_include_directories("include") -ament_export_libraries(${PROJECT_NAME}) +ament_export_libraries(${PROJECT_NAME}_exported) ament_package() diff --git a/include/ninshiki_cpp/config/grpc/call_data.hpp b/include/ninshiki_cpp/config/grpc/call_data.hpp new file mode 100644 index 0000000..18ede9c --- /dev/null +++ b/include/ninshiki_cpp/config/grpc/call_data.hpp @@ -0,0 +1,87 @@ +// Copyright (c) 2024 Ichiro ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef __NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_HPP__ +#define __NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_HPP__ + +#include "ninshiki_cpp/config/grpc/call_data_base.hpp" +#include "ninshiki_interfaces/ninshiki.grpc.pb.h" +#include "ninshiki_interfaces/ninshiki.pb.h" +#include "grpc/support/log.h" +#include "grpcpp/grpcpp.h" + +namespace ninshiki_cpp +{ +template +class CallData : public CallDataBase +{ +public: + CallData( + ninshiki_interfaces::proto::Config::AsyncService * service, grpc::ServerCompletionQueue * cq, + const std::string & path); + + void Proceed(); + +protected: + virtual void AddNextToCompletionQueue() = 0; + + enum CallStatus { CREATE, PROCESS, FINISH }; + + CallStatus status_; // The current serving state. + + ninshiki_interfaces::proto::Config::AsyncService * service_; + + const std::string path_; + + grpc::ServerCompletionQueue * cq_; + grpc::ServerContext ctx_; + ConfigRequest request_; + ConfigReply reply_; + grpc::ServerAsyncResponseWriter responder_; +}; + +template +CallData::CallData( + ninshiki_interfaces::proto::Config::AsyncService * service, grpc::ServerCompletionQueue * cq, + const std::string & path) +: status_(CREATE), service_(service), cq_(cq), responder_(&ctx_), path_(path) +{ +} + +template +void CallData::Proceed() +{ + if (status_ == CREATE) { + status_ = PROCESS; + WaitForRequest(); + } else if (status_ == PROCESS) { + AddNextToCompletionQueue(); + HandleRequest(); + status_ = FINISH; + responder_.Finish(reply_, grpc::Status::OK, this); + } else { + GPR_ASSERT(status_ == FINISH); + delete this; + } +} + +} // namespace ninshiki_cpp + +#endif // __NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_HPP__ diff --git a/include/ninshiki_cpp/utils/circle.hpp b/include/ninshiki_cpp/config/grpc/call_data_base.hpp similarity index 67% rename from include/ninshiki_cpp/utils/circle.hpp rename to include/ninshiki_cpp/config/grpc/call_data_base.hpp index 4f5d914..d7e0e80 100644 --- a/include/ninshiki_cpp/utils/circle.hpp +++ b/include/ninshiki_cpp/config/grpc/call_data_base.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021 ICHIRO ITS +// Copyright (c) 2024 Ichiro ITS // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -18,32 +18,20 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#ifndef NINSHIKI_CPP__UTILS__CIRCLE_HPP_ -#define NINSHIKI_CPP__UTILS__CIRCLE_HPP_ +#ifndef NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_BASE_HPP_ +#define NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_BASE_HPP_ -#include -#include - -namespace ninshiki_cpp::utils +namespace ninshiki_cpp { - -class Circle +class CallDataBase { -private: - - cv::Point2f center; - float radius; - public: + virtual void Proceed() = 0; - Circle(const std::vector & contour); - - void draw(cv::Mat & image, int line_size) const; - - const cv::Point2f & get_center() const; - const float get_radius() const; +protected: + virtual void WaitForRequest() = 0; + virtual void HandleRequest() = 0; }; +} // namespace ninshiki_cpp -} // namespace ninshiki_cpp::utils - -#endif // NINSHIKI_CPP__UTILS__CIRCLES_HPP_ +#endif // NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_BASE_HPP_ diff --git a/include/ninshiki_cpp/config/grpc/call_data_get_color_setting.hpp b/include/ninshiki_cpp/config/grpc/call_data_get_color_setting.hpp new file mode 100644 index 0000000..ff46e38 --- /dev/null +++ b/include/ninshiki_cpp/config/grpc/call_data_get_color_setting.hpp @@ -0,0 +1,43 @@ +// Copyright (c) 2024 Ichiro ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_GET_COLOR_SETTING_HPP__ +#define NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_GET_COLOR_SETTING_HPP__ + +#include + +namespace ninshiki_cpp +{ +class CallDataGetColorSetting +: CallData +{ +public: + CallDataGetColorSetting( + ninshiki_interfaces::proto::Config::AsyncService * service, grpc::ServerCompletionQueue * cq, + const std::string & path); + +protected: + void AddNextToCompletionQueue() override; + void WaitForRequest() override; + void HandleRequest() override; +}; +} // namespace ninshiki_cpp + +#endif // NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_GET_COLOR_SETTING_HPP__ diff --git a/include/ninshiki_cpp/config/grpc/call_data_save_color_setting.hpp b/include/ninshiki_cpp/config/grpc/call_data_save_color_setting.hpp new file mode 100644 index 0000000..966a66e --- /dev/null +++ b/include/ninshiki_cpp/config/grpc/call_data_save_color_setting.hpp @@ -0,0 +1,45 @@ +// Copyright (c) 2024 Ichiro ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_SAVE_COLOR_SETTING_HPP__ +#define NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_SAVE_COLOR_SETTING_HPP__ + +#include +#include + +namespace ninshiki_cpp +{ +class CallDataSaveColorSetting +: CallData +{ +public: + CallDataSaveColorSetting( + ninshiki_interfaces::proto::Config::AsyncService * service, grpc::ServerCompletionQueue * cq, + const std::string & path); + +protected: + void AddNextToCompletionQueue() override; + void WaitForRequest() override; + void HandleRequest() override; +}; + +} // namespace ninshiki_cpp + +#endif // NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_SAVE_COLOR_SETTING_HPP__ diff --git a/include/ninshiki_cpp/config/grpc/call_data_set_color_setting.hpp b/include/ninshiki_cpp/config/grpc/call_data_set_color_setting.hpp new file mode 100644 index 0000000..f7bf63c --- /dev/null +++ b/include/ninshiki_cpp/config/grpc/call_data_set_color_setting.hpp @@ -0,0 +1,48 @@ +// Copyright (c) 2024 Ichiro ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef NINSHIKI_CPP_CONFIG__GRPC__CALL_DATA_SET_COLOR_SETTING_HPP__ +#define NINSHIKI_CPP_CONFIG__GRPC__CALL_DATA_SET_COLOR_SETTING_HPP__ + +#include +#include +#include +#include + +namespace ninshiki_cpp +{ +class CallDataSetColorSetting +: CallData +{ +public: + CallDataSetColorSetting( + ninshiki_interfaces::proto::Config::AsyncService * service, grpc::ServerCompletionQueue * cq, + const std::string & path, std::shared_ptr color_detection); + using ColorDetector = ninshiki_cpp::detector::ColorDetector; + +protected: + void AddNextToCompletionQueue() override; + void WaitForRequest() override; + void HandleRequest() override; + std::shared_ptr color_detection_; +}; +} // namespace ninshiki_cpp + +#endif // NINSHIKI_CPP__CONFIG__GRPC__CALL_DATA_SET_COLOR_SETTING_HPP__ diff --git a/include/ninshiki_cpp/config/grpc/config.hpp b/include/ninshiki_cpp/config/grpc/config.hpp new file mode 100644 index 0000000..65a7463 --- /dev/null +++ b/include/ninshiki_cpp/config/grpc/config.hpp @@ -0,0 +1,57 @@ +// Copyright (c) 2024 Ichiro ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef NINSHIKI_CPP__CONFIG__GRPC__CONFIG_HPP_ +#define NINSHIKI_CPP__CONFIG__GRPC__CONFIG_HPP_ + +#include +#include +#include +#include + +#include +#include + +namespace ninshiki_cpp +{ +class ConfigGrpc +{ +public: + explicit ConfigGrpc(); + explicit ConfigGrpc(const std::string & path); + using ColorDetector = detector::ColorDetector; + + ~ConfigGrpc(); + + void Run(const std::string & path, std::shared_ptr color_detection); + +private: + std::string path; + static void SignIntHandler(int signum); + + static inline std::unique_ptr cq_; + static inline std::unique_ptr server_; + std::thread thread_; + ninshiki_interfaces::proto::Config::AsyncService service_; +}; + +} // namespace ninshiki_cpp + +#endif // NINSHIKI_CPP__CONFIG__GRPC__CONFIG_HPP_ diff --git a/src/ninshiki_cpp/utils/circle.cpp b/include/ninshiki_cpp/config/utils/config.hpp similarity index 65% rename from src/ninshiki_cpp/utils/circle.cpp rename to include/ninshiki_cpp/config/utils/config.hpp index 57cdb36..9a90cfa 100644 --- a/src/ninshiki_cpp/utils/circle.cpp +++ b/include/ninshiki_cpp/config/utils/config.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021 ICHIRO ITS +// Copyright (c) 2024 Ichiro ITS // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -18,30 +18,30 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "ninshiki_cpp/utils/circle.hpp" +#ifndef NINSHIKI_CPP__CONFIG__UTILS__CONFIG_HPP_ +#define NINSHIKI_CPP__CONFIG__UTILS__CONFIG_HPP_ -namespace ninshiki_cpp::utils -{ +#include -Circle::Circle(const std::vector & contour) -: center(cv::Point2f(-1, -1)), radius(0.0) -{ - cv::minEnclosingCircle(contour, center, radius); -} +#include +#include +#include -void Circle::draw(cv::Mat & image, int line_size) const +namespace ninshiki_cpp { - cv::circle(image, center, radius, cv::Scalar(0, 255, 238), line_size); -} - -const cv::Point2f & Circle::get_center() const +class Config { - return center; -} +public: + explicit Config(const std::string & path); -const float Circle::get_radius() const -{ - return radius; -} + std::string get_color_setting(const std::string & key) const; + void save_color_setting(const nlohmann::json & color_data); + nlohmann::json get_grpc_config() const; + +private: + std::string path; +}; + +} // namespace ninshiki_cpp -} // namespace ninshiki_cpp::utils +#endif // NINSHIKI_CPP__CONFIG__UTILS__CONFIG_HPP_ diff --git a/include/ninshiki_cpp/detector/color_detector.hpp b/include/ninshiki_cpp/detector/color_detector.hpp index 3e37935..964a125 100644 --- a/include/ninshiki_cpp/detector/color_detector.hpp +++ b/include/ninshiki_cpp/detector/color_detector.hpp @@ -51,6 +51,7 @@ class ColorDetector : public Detector bool load_configuration() {load_configuration(config_path);} bool save_configuration(); bool sync_configuration(); + void configure_color_setting(utils::Color color); cv::Mat classify(cv::Mat input); cv::Mat classify_gray(cv::Mat input); diff --git a/include/ninshiki_cpp/node/ninshiki_cpp_node.hpp b/include/ninshiki_cpp/node/ninshiki_cpp_node.hpp index 75730cd..d944a9e 100644 --- a/include/ninshiki_cpp/node/ninshiki_cpp_node.hpp +++ b/include/ninshiki_cpp/node/ninshiki_cpp_node.hpp @@ -29,6 +29,7 @@ #include #include "rclcpp/rclcpp.hpp" +#include "ninshiki_cpp/config/grpc/config.hpp" #include "sensor_msgs/msg/image.hpp" #include "ninshiki_cpp/detector/color_detector.hpp" #include "ninshiki_cpp/detector/detector.hpp" @@ -48,13 +49,10 @@ class NinshikiCppNode using LBPDetector = ninshiki_cpp::detector::LBPDetector; NinshikiCppNode( - rclcpp::Node::SharedPtr node, - int frequency, shisen_cpp::Options options); - void publish(); - void set_detection( - std::shared_ptr dnn_detection, - std::shared_ptr color_detection, + rclcpp::Node::SharedPtr node, int frequency, shisen_cpp::Options options, std::string path, + std::shared_ptr dnn_detection, std::shared_ptr color_detection, std::shared_ptr lbp_detection); + void publish(); private: using Contours = ninshiki_interfaces::msg::Contours; @@ -68,6 +66,8 @@ class NinshikiCppNode rclcpp::Publisher::SharedPtr color_segmentation_publisher; rclcpp::Subscription::SharedPtr image_subscriber; + ConfigGrpc config_grpc; + std::shared_ptr dnn_detection; std::shared_ptr color_detection; std::shared_ptr lbp_detection; @@ -75,6 +75,8 @@ class NinshikiCppNode cv::Mat received_frame; cv::Mat hsv_frame; + std::string path; + static std::string get_node_prefix(); }; diff --git a/src/ninshiki_cpp/config/grpc/call_data_get_color_setting.cpp b/src/ninshiki_cpp/config/grpc/call_data_get_color_setting.cpp new file mode 100644 index 0000000..6ffa1e6 --- /dev/null +++ b/src/ninshiki_cpp/config/grpc/call_data_get_color_setting.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2024 Ichiro ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include +#include +#include +#include +#include + +namespace ninshiki_cpp +{ +CallDataGetColorSetting::CallDataGetColorSetting( + ninshiki_interfaces::proto::Config::AsyncService * service, grpc::ServerCompletionQueue * cq, + const std::string & path) +: CallData(service, cq, path) +{ + Proceed(); +} + +void CallDataGetColorSetting::AddNextToCompletionQueue() +{ + new CallDataGetColorSetting(service_, cq_, path_); +} + +void CallDataGetColorSetting::WaitForRequest() +{ + service_->RequestGetColorSetting(&ctx_, &request_, &responder_, cq_, cq_, this); +} + +void CallDataGetColorSetting::HandleRequest() +{ + Config config(path_); + reply_.set_json_color(config.get_color_setting("color")); + RCLCPP_INFO(rclcpp::get_logger("Get config"), "config has been sent!"); +} +} // namespace ninshiki_cpp diff --git a/src/ninshiki_cpp/config/grpc/call_data_save_color_setting.cpp b/src/ninshiki_cpp/config/grpc/call_data_save_color_setting.cpp new file mode 100644 index 0000000..1e18d4b --- /dev/null +++ b/src/ninshiki_cpp/config/grpc/call_data_save_color_setting.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2024 Ichiro ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include +#include +#include +#include +#include +#include + +namespace ninshiki_cpp +{ +CallDataSaveColorSetting::CallDataSaveColorSetting( + ninshiki_interfaces::proto::Config::AsyncService * service, grpc::ServerCompletionQueue * cq, + const std::string & path) +: CallData(service, cq, path) +{ + Proceed(); +} + +void CallDataSaveColorSetting::AddNextToCompletionQueue() +{ + new CallDataSaveColorSetting(service_, cq_, path_); +} + +void CallDataSaveColorSetting::WaitForRequest() +{ + service_->RequestSaveColorSetting(&ctx_, &request_, &responder_, cq_, cq_, this); +} + +void CallDataSaveColorSetting::HandleRequest() +{ + Config config(path_); + try { + std::string json_string = request_.json_color(); + nlohmann::json color_data = nlohmann::json::parse(json_string); + + config.save_color_setting(color_data); + RCLCPP_INFO(rclcpp::get_logger("Save config"), "config has been saved!"); + } catch (nlohmann::json::exception & e) { + RCLCPP_ERROR(rclcpp::get_logger("Save config"), e.what()); + } +} +} // namespace ninshiki_cpp diff --git a/src/ninshiki_cpp/config/grpc/call_data_set_color_setting.cpp b/src/ninshiki_cpp/config/grpc/call_data_set_color_setting.cpp new file mode 100644 index 0000000..e7e4c0f --- /dev/null +++ b/src/ninshiki_cpp/config/grpc/call_data_set_color_setting.cpp @@ -0,0 +1,70 @@ +// Copyright (c) 2024 Ichiro ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include +#include +#include +#include +#include + +namespace ninshiki_cpp +{ +CallDataSetColorSetting::CallDataSetColorSetting( + ninshiki_interfaces::proto::Config::AsyncService * service, grpc::ServerCompletionQueue * cq, + const std::string & path, std::shared_ptr color_detection) +: CallData(service, cq, path), color_detection_(color_detection) +{ + Proceed(); +} + +void CallDataSetColorSetting::AddNextToCompletionQueue() +{ + new CallDataSetColorSetting(service_, cq_, path_, color_detection_); +} + +void CallDataSetColorSetting::WaitForRequest() +{ + service_->RequestSetColorSetting(&ctx_, &request_, &responder_, cq_, cq_, this); +} + +void CallDataSetColorSetting::HandleRequest() +{ + Config config(path_); + try { + utils::Color color( + request_.name(), + request_.min_hue(), + request_.max_hue(), + request_.min_saturation(), + request_.max_saturation(), + request_.min_value(), + request_.max_value() + ); + + color_detection_->configure_color_setting(color); + + RCLCPP_INFO( + rclcpp::get_logger("Set color config"), "color setting config has been applied!" + ); + } catch (nlohmann::json::exception e) { + RCLCPP_ERROR(rclcpp::get_logger("Set config"), e.what()); + } +} +} // namespace ninshiki_cpp diff --git a/src/ninshiki_cpp/config/grpc/config.cpp b/src/ninshiki_cpp/config/grpc/config.cpp new file mode 100644 index 0000000..31805a6 --- /dev/null +++ b/src/ninshiki_cpp/config/grpc/config.cpp @@ -0,0 +1,85 @@ +// Copyright (c) 2024 ICHIRO ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using grpc::ServerBuilder; +using namespace std::chrono_literals; + +namespace ninshiki_cpp +{ +ConfigGrpc::ConfigGrpc() {} +ConfigGrpc::ConfigGrpc(const std::string & path) : path(path) {} + +ConfigGrpc::~ConfigGrpc() +{ + server_->Shutdown(); + cq_->Shutdown(); +} + +void ConfigGrpc::SignIntHandler(int signum) +{ + server_->Shutdown(); + cq_->Shutdown(); + exit(signum); +} + +void ConfigGrpc::Run(const std::string & path, std::shared_ptr color_detection) +{ + Config config(path); + std::string server_address = + absl::StrFormat("0.0.0.0:%d", config.get_grpc_config()["port"].get()); + + ServerBuilder builder; + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterService(&service_); + + cq_ = builder.AddCompletionQueue(); + server_ = builder.BuildAndStart(); + std::cout << "Server listening on " << server_address << std::endl; + + signal(SIGINT, SignIntHandler); + thread_ = std::thread([&path, &color_detection, this]() { + new CallDataGetColorSetting(&service_, cq_.get(), path); + new CallDataSaveColorSetting(&service_, cq_.get(), path); + new CallDataSetColorSetting(&service_, cq_.get(), path, color_detection); + void * tag; // uniquely identifies a request. + bool ok = true; + while (true) { + this->cq_->Next(&tag, &ok); + if (ok) { + static_cast(tag)->Proceed(); + } + } + }); + std::this_thread::sleep_for(200ms); +} + +} // namespace ninshiki_cpp diff --git a/src/ninshiki_cpp/config/utils/config.cpp b/src/ninshiki_cpp/config/utils/config.cpp new file mode 100644 index 0000000..24407e2 --- /dev/null +++ b/src/ninshiki_cpp/config/utils/config.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2024 Ichiro ITS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include +#include + +#include +#include +#include + + +namespace ninshiki_cpp +{ +Config::Config(const std::string & path) : path(path) {} + +std::string Config::get_color_setting(const std::string & key) const +{ + if (key == "color") { + std::ifstream color_file(path + "color_classifier.json"); + nlohmann::json color_data = nlohmann::json::parse(color_file); + return color_data.dump(); + } + + return ""; +} + +nlohmann::json Config::get_grpc_config() const +{ + std::ifstream grpc_file(path + "grpc.json"); + nlohmann::json grpc_data = nlohmann::json::parse(grpc_file); + grpc_file.close(); + return grpc_data; +} + +void Config::save_color_setting(const nlohmann::json & color_data) +{ + std::ofstream color_file(path + "color_classifier.json", std::ios::out | std::ios::trunc); + color_file << std::setw(2) << color_data << std::endl; + color_file.close(); +} + +} // namespace ninshiki_cpp diff --git a/src/ninshiki_cpp/detector/color_detector.cpp b/src/ninshiki_cpp/detector/color_detector.cpp index 673333e..a129c79 100644 --- a/src/ninshiki_cpp/detector/color_detector.cpp +++ b/src/ninshiki_cpp/detector/color_detector.cpp @@ -132,6 +132,22 @@ bool ColorDetector::sync_configuration() return true; } +void ColorDetector::configure_color_setting(utils::Color color) +{ + for (auto & item : colors) { + if (item.name == color.name) { + item.min_hue = color.min_hue; + item.max_hue = color.max_hue; + item.min_saturation = color.min_saturation; + item.max_saturation = color.max_saturation; + item.min_value = color.min_value; + item.max_value = color.max_value; + + break; + } + } +} + cv::Mat ColorDetector::classify(cv::Mat input) { int h_min = (min_hue * 255) / 360; diff --git a/src/ninshiki_cpp/node/ninshiki_cpp_node.cpp b/src/ninshiki_cpp/node/ninshiki_cpp_node.cpp index 58c02f2..bb2dfbc 100644 --- a/src/ninshiki_cpp/node/ninshiki_cpp_node.cpp +++ b/src/ninshiki_cpp/node/ninshiki_cpp_node.cpp @@ -30,9 +30,10 @@ namespace ninshiki_cpp::node { NinshikiCppNode::NinshikiCppNode( - rclcpp::Node::SharedPtr node, - int frequency, shisen_cpp::Options options) -: node(node), dnn_detection(nullptr), color_detection(nullptr), lbp_detection(nullptr) + rclcpp::Node::SharedPtr node, int frequency, shisen_cpp::Options options, std::string path, + std::shared_ptr dnn_detection, std::shared_ptr color_detection, + std::shared_ptr lbp_detection) +: node(node), path(path), dnn_detection(dnn_detection), color_detection(color_detection), lbp_detection(lbp_detection) { detected_object_publisher = node->create_publisher( get_node_prefix() + "/dnn_detection", 10); @@ -55,6 +56,9 @@ NinshikiCppNode::NinshikiCppNode( } } ); + + config_grpc.Run(path, color_detection); + RCLCPP_INFO(rclcpp::get_logger("GrpcServers"), "grpc running"); } void NinshikiCppNode::publish() @@ -75,16 +79,6 @@ void NinshikiCppNode::publish() lbp_detection->detection_result.detected_objects.clear(); } -void NinshikiCppNode::set_detection( - std::shared_ptr dnn_detection, - std::shared_ptr color_detection, - std::shared_ptr lbp_detection) -{ - this->dnn_detection = dnn_detection; - this->color_detection = color_detection; - this->lbp_detection = lbp_detection; -} - std::string NinshikiCppNode::get_node_prefix() { return "ninshiki_cpp"; diff --git a/src/ninshiki_cpp_detector.cpp b/src/ninshiki_cpp_detector.cpp index 23cc588..2bebff6 100644 --- a/src/ninshiki_cpp_detector.cpp +++ b/src/ninshiki_cpp_detector.cpp @@ -108,8 +108,6 @@ int main(int argc, char ** argv) } auto node = std::make_shared("ninshiki_cpp"); - auto ninshiki_cpp_node = std::make_shared( - node, frequency, options); auto dnn_detection = std::make_shared(gpu, myriad); auto color_detection = std::make_shared(); @@ -117,7 +115,8 @@ int main(int argc, char ** argv) color_detection->load_configuration(path); - ninshiki_cpp_node->set_detection(dnn_detection, color_detection, lbp_detection); + auto ninshiki_cpp_node = std::make_shared( + node, frequency, options, path, dnn_detection, color_detection, lbp_detection); rclcpp::spin(node); rclcpp::shutdown();