From bb722045251cc5917feff1940f5535d80ccc211f Mon Sep 17 00:00:00 2001 From: Ashish Date: Wed, 22 Apr 2026 17:07:30 +0200 Subject: [PATCH 01/16] Refactor: add new package called pipeline_end_detector --- .vscode/settings.json | 11 +++ .../pipeline_end_detector/CMakeLists.txt | 51 ++++++++++ .../config/pipeline_end_detector_config.yaml | 10 ++ .../pipeline_end_detector_node.hpp | 27 ++++++ .../launch/pipeline_end_detector.launch.py | 37 ++++++++ .../pipeline_end_detector/package.xml | 23 +++++ .../pipeline_end_detector/src/main.cpp | 10 ++ .../src/pipeline_end_detector_node.cpp | 92 +++++++++++++++++++ 8 files changed, 261 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt create mode 100644 mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml create mode 100644 mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp create mode 100644 mission/tacc/pipeline_inspection/pipeline_end_detector/launch/pipeline_end_detector.launch.py create mode 100644 mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml create mode 100644 mission/tacc/pipeline_inspection/pipeline_end_detector/src/main.cpp create mode 100644 mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..80e2124 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "ROS2.distro": "humble", + "python.autoComplete.extraPaths": [ + "/opt/ros/humble/lib/python3.10/site-packages", + "/opt/ros/humble/local/lib/python3.10/dist-packages" + ], + "python.analysis.extraPaths": [ + "/opt/ros/humble/lib/python3.10/site-packages", + "/opt/ros/humble/local/lib/python3.10/dist-packages" + ] +} \ No newline at end of file diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt b/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt new file mode 100644 index 0000000..8b11ebd --- /dev/null +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.8) +project(pipeline_end_detector) + +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 20) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(std_msgs REQUIRED) +find_package(std_srvs REQUIRED) + +include_directories(include) + +add_executable(pipeline_end_detector_node + src/main.cpp + src/pipeline_end_detector_node.cpp +) + +target_include_directories(pipeline_end_detector_node + PRIVATE + $ +) + +ament_target_dependencies(pipeline_end_detector_node + rclcpp + std_msgs + std_srvs +) + +install( + TARGETS pipeline_end_detector_node + DESTINATION lib/${PROJECT_NAME} +) + +install( + DIRECTORY include/ + DESTINATION include +) + +install(DIRECTORY + launch + config + DESTINATION share/${PROJECT_NAME}/ +) + +ament_package() diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml b/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml new file mode 100644 index 0000000..358e304 --- /dev/null +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml @@ -0,0 +1,10 @@ +/**: + ros__parameters: + # Number of consecutive detections required before triggering the service call + detection_threshold: 10 + topics: + # Topic published by the end-of-pipeline detector model (std_msgs/UInt8) + # Non-zero value means "end of pipeline detected" + detection: "end_of_pipeline/detection" + # Service name of the pipeline inspection FSM trigger + end_of_pipeline_service: "pipeline_inspection_fsm/pipeline_finished" diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp new file mode 100644 index 0000000..d55afa8 --- /dev/null +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +namespace pipeline_end_detector { + +class PipelineEndDetectorNode : public rclcpp::Node { +public: + explicit PipelineEndDetectorNode(const rclcpp::NodeOptions& options); + +private: + void declare_parameters(); + void setup_pubsub(); + void detection_callback(const std_msgs::msg::UInt8::SharedPtr msg); + void call_end_of_pipeline_service(); + + rclcpp::Subscription::SharedPtr detection_sub_; + rclcpp::Client::SharedPtr end_of_pipeline_client_; + + int consecutive_detections_{0}; + int detection_threshold_{0}; + bool service_called_{false}; +}; + +} // namespace pipeline_end_detector diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/launch/pipeline_end_detector.launch.py b/mission/tacc/pipeline_inspection/pipeline_end_detector/launch/pipeline_end_detector.launch.py new file mode 100644 index 0000000..c3f3ea9 --- /dev/null +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/launch/pipeline_end_detector.launch.py @@ -0,0 +1,37 @@ +import os + +from ament_index_python.packages import get_package_share_directory +from auv_setup.launch_arg_common import ( + declare_drone_and_namespace_args, + resolve_drone_and_namespace, +) +from launch import LaunchDescription +from launch.actions import OpaqueFunction +from launch_ros.actions import Node + + +def launch_setup(context, *args, **kwargs): + _, namespace = resolve_drone_and_namespace(context) + + config = os.path.join( + get_package_share_directory('pipeline_end_detector'), + 'config', + 'pipeline_end_detector_config.yaml', + ) + + node = Node( + package='pipeline_end_detector', + executable='pipeline_end_detector_node', + name='pipeline_end_detector_node', + namespace=namespace, + parameters=[config], + output='screen', + ) + + return [node] + + +def generate_launch_description() -> LaunchDescription: + return LaunchDescription( + declare_drone_and_namespace_args() + [OpaqueFunction(function=launch_setup)] + ) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml b/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml new file mode 100644 index 0000000..68539ee --- /dev/null +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml @@ -0,0 +1,23 @@ + + + + pipeline_end_detector + 0.0.0 + + Subscribes to the end-of-pipeline detection topic and, after a configurable + number of consecutive detections, triggers a service call to the pipeline + inspection FSM to signal that the pipeline has ended. + + vortex + MIT + + ament_cmake + + rclcpp + std_msgs + std_srvs + + + ament_cmake + + diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/main.cpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/main.cpp new file mode 100644 index 0000000..276f00b --- /dev/null +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/main.cpp @@ -0,0 +1,10 @@ +#include +#include "pipeline_end_detector/pipeline_end_detector_node.hpp" + +int main(int argc, char* argv[]) { + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared( + rclcpp::NodeOptions())); + rclcpp::shutdown(); + return 0; +} diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp new file mode 100644 index 0000000..9aae5c6 --- /dev/null +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp @@ -0,0 +1,92 @@ +#include "pipeline_end_detector/pipeline_end_detector_node.hpp" + +namespace pipeline_end_detector { + +PipelineEndDetectorNode::PipelineEndDetectorNode( + const rclcpp::NodeOptions& options) + : rclcpp::Node("pipeline_end_detector_node", options) { + declare_parameters(); + + detection_threshold_ = + static_cast(get_parameter("detection_threshold").as_int()); + + setup_pubsub(); + + RCLCPP_INFO(get_logger(), + "PipelineEndDetectorNode started. threshold=%d, service='%s'", + detection_threshold_, + get_parameter("topics.end_of_pipeline_service").as_string().c_str()); +} + +void PipelineEndDetectorNode::declare_parameters() { + declare_parameter("topics.detection", + "end_of_pipeline/detection"); + declare_parameter("topics.end_of_pipeline_service", + "pipeline_inspection_fsm/pipeline_finished"); + declare_parameter("detection_threshold", 10); +} + +void PipelineEndDetectorNode::setup_pubsub() { + detection_sub_ = create_subscription( + get_parameter("topics.detection").as_string(), + rclcpp::QoS(10), + std::bind(&PipelineEndDetectorNode::detection_callback, this, + std::placeholders::_1)); + + end_of_pipeline_client_ = create_client( + get_parameter("topics.end_of_pipeline_service").as_string()); +} + +void PipelineEndDetectorNode::detection_callback( + const std_msgs::msg::UInt8::SharedPtr msg) { + if (service_called_) { + return; + } + + if (msg->data > 0) { + ++consecutive_detections_; + RCLCPP_DEBUG(get_logger(), "Consecutive detections: %d / %d", + consecutive_detections_, detection_threshold_); + } else { + if (consecutive_detections_ > 0) { + RCLCPP_DEBUG(get_logger(), + "Detection streak broken, resetting counter."); + } + consecutive_detections_ = 0; + } + + if (consecutive_detections_ >= detection_threshold_) { + call_end_of_pipeline_service(); + } +} + +void PipelineEndDetectorNode::call_end_of_pipeline_service() { + if (!end_of_pipeline_client_->service_is_ready()) { + RCLCPP_WARN(get_logger(), + "End-of-pipeline service not available, skipping call."); + return; + } + + service_called_ = true; + + auto request = std::make_shared(); + auto future = end_of_pipeline_client_->async_send_request( + request, + [this](rclcpp::Client::SharedFuture result) { + const auto& response = result.get(); + if (response->success) { + RCLCPP_INFO(get_logger(), + "End-of-pipeline service call succeeded: %s", + response->message.c_str()); + } else { + RCLCPP_ERROR(get_logger(), + "End-of-pipeline service call failed: %s", + response->message.c_str()); + // Allow retrying on next detection streak + service_called_ = false; + consecutive_detections_ = 0; + } + }); +} + +} // namespace pipeline_end_detector From e65aee92f5d6e7acbc08b1f5c5a8b2b5208ab812 Mon Sep 17 00:00:00 2001 From: Ashish Date: Wed, 22 Apr 2026 17:48:08 +0200 Subject: [PATCH 02/16] feat: add pipeline_end_detector package for end-of-pipeline FSM signalling Subscribes to /classification_output (std_msgs/UInt8), counts consecutive Class 1 detections, and calls pipeline_inspection_fsm/pipeline_finished (std_srvs/Trigger) once the configurable threshold is reached. --- .../pipeline_end_detector/README.md | 50 +++++++++++++++++++ .../config/pipeline_end_detector_config.yaml | 4 +- .../src/pipeline_end_detector_node.cpp | 3 +- 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 mission/tacc/pipeline_inspection/pipeline_end_detector/README.md diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/README.md b/mission/tacc/pipeline_inspection/pipeline_end_detector/README.md new file mode 100644 index 0000000..89298c0 --- /dev/null +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/README.md @@ -0,0 +1,50 @@ +# Pipeline End Detector + +A ROS2 node that subscribes to the end-of-pipeline classification output and, after a configurable number of consecutive detections, sends a trigger service call to the pipeline inspection FSM to signal that the pipeline has ended. + +## Overview + +The node listens to a `std_msgs/UInt8` topic published by the end-of-pipeline classifier: + +- `data == 1` — Class 1: end of pipeline detected +- `data == 0` — Class 0: continue following + +Once `detection_threshold` consecutive `1`s are received, the node calls the `pipeline_inspection_fsm/pipeline_finished` service. If the call fails, the counter resets and the node retries on the next streak. + +## ROS2 Interface + +### Subscriptions + +| Topic | Type | Description | +|---|---|---| +| `classification_output` | `std_msgs/UInt8` | End-of-pipeline classification output | + +### Service Clients + +| Service | Type | Description | +|---|---|---| +| `pipeline_inspection_fsm/pipeline_finished` | `std_srvs/Trigger` | Signals the FSM that the pipeline has ended | + +## Configuration + +### `pipeline_end_detector_config.yaml` + +```yaml +detection_threshold: 10 # consecutive detections required before triggering +topics: + detection: "classification_output" + end_of_pipeline_service: "pipeline_inspection_fsm/pipeline_finished" +``` + +## Running + +```bash +ros2 run pipeline_end_detector pipeline_end_detector_node \ + --ros-args --params-file path/to/pipeline_end_detector_config.yaml +``` + +Or via the launch file: + +```bash +ros2 launch pipeline_end_detector pipeline_end_detector.launch.py +``` diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml b/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml index 358e304..3a1ed6d 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml @@ -4,7 +4,7 @@ detection_threshold: 10 topics: # Topic published by the end-of-pipeline detector model (std_msgs/UInt8) - # Non-zero value means "end of pipeline detected" - detection: "end_of_pipeline/detection" + # data == 1 → Class 1: end of pipeline | data == 0 → Class 0: continue following + detection: "classification_output" # Service name of the pipeline inspection FSM trigger end_of_pipeline_service: "pipeline_inspection_fsm/pipeline_finished" diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp index 9aae5c6..591035d 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp @@ -20,7 +20,7 @@ PipelineEndDetectorNode::PipelineEndDetectorNode( void PipelineEndDetectorNode::declare_parameters() { declare_parameter("topics.detection", - "end_of_pipeline/detection"); + "classification_output"); declare_parameter("topics.end_of_pipeline_service", "pipeline_inspection_fsm/pipeline_finished"); declare_parameter("detection_threshold", 10); @@ -82,7 +82,6 @@ void PipelineEndDetectorNode::call_end_of_pipeline_service() { RCLCPP_ERROR(get_logger(), "End-of-pipeline service call failed: %s", response->message.c_str()); - // Allow retrying on next detection streak service_called_ = false; consecutive_detections_ = 0; } From b1307ea6dbf07ac7978d23a42b70fc6400050386 Mon Sep 17 00:00:00 2001 From: Ashish Date: Wed, 22 Apr 2026 17:51:28 +0200 Subject: [PATCH 03/16] run pre commit --- .../pipeline_end_detector_node.hpp | 4 ++-- .../pipeline_end_detector/src/main.cpp | 5 +++-- .../src/pipeline_end_detector_node.cpp | 17 ++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp index d55afa8..1572b68 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp @@ -7,10 +7,10 @@ namespace pipeline_end_detector { class PipelineEndDetectorNode : public rclcpp::Node { -public: + public: explicit PipelineEndDetectorNode(const rclcpp::NodeOptions& options); -private: + private: void declare_parameters(); void setup_pubsub(); void detection_callback(const std_msgs::msg::UInt8::SharedPtr msg); diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/main.cpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/main.cpp index 276f00b..8f2f03d 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/main.cpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/main.cpp @@ -3,8 +3,9 @@ int main(int argc, char* argv[]) { rclcpp::init(argc, argv); - rclcpp::spin(std::make_shared( - rclcpp::NodeOptions())); + rclcpp::spin( + std::make_shared( + rclcpp::NodeOptions())); rclcpp::shutdown(); return 0; } diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp index 591035d..7662e1a 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp @@ -12,24 +12,23 @@ PipelineEndDetectorNode::PipelineEndDetectorNode( setup_pubsub(); - RCLCPP_INFO(get_logger(), - "PipelineEndDetectorNode started. threshold=%d, service='%s'", - detection_threshold_, - get_parameter("topics.end_of_pipeline_service").as_string().c_str()); + RCLCPP_INFO( + get_logger(), + "PipelineEndDetectorNode started. threshold=%d, service='%s'", + detection_threshold_, + get_parameter("topics.end_of_pipeline_service").as_string().c_str()); } void PipelineEndDetectorNode::declare_parameters() { - declare_parameter("topics.detection", - "classification_output"); + declare_parameter("topics.detection", "classification_output"); declare_parameter("topics.end_of_pipeline_service", - "pipeline_inspection_fsm/pipeline_finished"); + "pipeline_inspection_fsm/pipeline_finished"); declare_parameter("detection_threshold", 10); } void PipelineEndDetectorNode::setup_pubsub() { detection_sub_ = create_subscription( - get_parameter("topics.detection").as_string(), - rclcpp::QoS(10), + get_parameter("topics.detection").as_string(), rclcpp::QoS(10), std::bind(&PipelineEndDetectorNode::detection_callback, this, std::placeholders::_1)); From 6b2538dae433699b26ef6f240511328890bc27cb Mon Sep 17 00:00:00 2001 From: Ashish Date: Wed, 22 Apr 2026 17:55:18 +0200 Subject: [PATCH 04/16] sadasd --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 80e2124..1ae91b4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,4 +8,4 @@ "/opt/ros/humble/lib/python3.10/site-packages", "/opt/ros/humble/local/lib/python3.10/dist-packages" ] -} \ No newline at end of file +} From 84537cf619a574665f260a6e9635f0dd6a3facb1 Mon Sep 17 00:00:00 2001 From: Andreas Kluge Svendsrud <89779148+kluge7@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:36:02 +0200 Subject: [PATCH 05/16] Delete .vscode/settings.json --- .vscode/settings.json | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 1ae91b4..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "ROS2.distro": "humble", - "python.autoComplete.extraPaths": [ - "/opt/ros/humble/lib/python3.10/site-packages", - "/opt/ros/humble/local/lib/python3.10/dist-packages" - ], - "python.analysis.extraPaths": [ - "/opt/ros/humble/lib/python3.10/site-packages", - "/opt/ros/humble/local/lib/python3.10/dist-packages" - ] -} From e8c32247d1acf3fe9a3ffbafd3c7952901f8c882 Mon Sep 17 00:00:00 2001 From: Ashish Date: Fri, 24 Apr 2026 15:14:54 +0200 Subject: [PATCH 06/16] Fix: use vortex utils for QoS and changes requested as per the PR --- .../pipeline_end_detector/CMakeLists.txt | 2 ++ .../pipeline_end_detector/pipeline_end_detector_node.hpp | 9 ++++++--- .../pipeline_end_detector/package.xml | 3 ++- .../src/pipeline_end_detector_node.cpp | 5 ++++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt b/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt index 8b11ebd..2ee1ba8 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt @@ -13,6 +13,7 @@ find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) find_package(std_srvs REQUIRED) +find_package(vortex_utils_ros REQUIRED) include_directories(include) @@ -30,6 +31,7 @@ ament_target_dependencies(pipeline_end_detector_node rclcpp std_msgs std_srvs + vortex_utils_ros ) install( diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp index 1572b68..d2777c2 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp @@ -19,9 +19,12 @@ class PipelineEndDetectorNode : public rclcpp::Node { rclcpp::Subscription::SharedPtr detection_sub_; rclcpp::Client::SharedPtr end_of_pipeline_client_; - int consecutive_detections_{0}; - int detection_threshold_{0}; - bool service_called_{false}; + int consecutive_detections_{ + 0}; // number of consecutive Class 1 detections so far + int detection_threshold; // number of consecutive detections required to + // trigger the service call + bool service_called_{ + false}; // prevents the service from being called more than once }; } // namespace pipeline_end_detector diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml b/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml index 68539ee..cccad5b 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml @@ -8,7 +8,7 @@ number of consecutive detections, triggers a service call to the pipeline inspection FSM to signal that the pipeline has ended. - vortex + vortex MIT ament_cmake @@ -16,6 +16,7 @@ rclcpp std_msgs std_srvs + vortex_utils_ros ament_cmake diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp index 7662e1a..e5da679 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp @@ -1,5 +1,7 @@ #include "pipeline_end_detector/pipeline_end_detector_node.hpp" +#include "vortex/utils/ros/qos_profiles.hpp" + namespace pipeline_end_detector { PipelineEndDetectorNode::PipelineEndDetectorNode( @@ -27,8 +29,9 @@ void PipelineEndDetectorNode::declare_parameters() { } void PipelineEndDetectorNode::setup_pubsub() { + const auto sensor_qos = vortex::utils::qos_profiles::reliable_profile(10); detection_sub_ = create_subscription( - get_parameter("topics.detection").as_string(), rclcpp::QoS(10), + get_parameter("topics.detection").as_string(), sensor_qos, std::bind(&PipelineEndDetectorNode::detection_callback, this, std::placeholders::_1)); From a0859b532b1a6d08c364c901eaf18c11e345a1d6 Mon Sep 17 00:00:00 2001 From: Ashish Date: Fri, 24 Apr 2026 15:28:43 +0200 Subject: [PATCH 07/16] feat: shutdown node after service call --- .../pipeline_end_detector/src/pipeline_end_detector_node.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp index e5da679..f2f5a92 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp @@ -80,6 +80,7 @@ void PipelineEndDetectorNode::call_end_of_pipeline_service() { RCLCPP_INFO(get_logger(), "End-of-pipeline service call succeeded: %s", response->message.c_str()); + rclcpp::shutdown(); } else { RCLCPP_ERROR(get_logger(), "End-of-pipeline service call failed: %s", From 2f92bc5717815405c2dd601c5e3b49cdbb78f124 Mon Sep 17 00:00:00 2001 From: Ashish Date: Fri, 24 Apr 2026 15:34:30 +0200 Subject: [PATCH 08/16] fix: declare transitive deps geometry_msgs and vortex_msgs required by vortex_utils_ros --- .../pipeline_inspection/pipeline_end_detector/CMakeLists.txt | 2 ++ .../tacc/pipeline_inspection/pipeline_end_detector/package.xml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt b/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt index 2ee1ba8..c703e25 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/CMakeLists.txt @@ -13,6 +13,8 @@ find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) find_package(std_srvs REQUIRED) +find_package(geometry_msgs REQUIRED) +find_package(vortex_msgs REQUIRED) find_package(vortex_utils_ros REQUIRED) include_directories(include) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml b/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml index cccad5b..5dfccf8 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/package.xml @@ -16,6 +16,8 @@ rclcpp std_msgs std_srvs + geometry_msgs + vortex_msgs vortex_utils_ros From fdcea70c121b9c68e7bcbc63bfb89aedabc92d19 Mon Sep 17 00:00:00 2001 From: Ashish Date: Fri, 24 Apr 2026 15:42:04 +0200 Subject: [PATCH 09/16] Small fix in naming of parameter --- .../pipeline_end_detector/pipeline_end_detector_node.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp index d2777c2..f3a0907 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp @@ -20,9 +20,9 @@ class PipelineEndDetectorNode : public rclcpp::Node { rclcpp::Client::SharedPtr end_of_pipeline_client_; int consecutive_detections_{ - 0}; // number of consecutive Class 1 detections so far - int detection_threshold; // number of consecutive detections required to - // trigger the service call + 0}; // number of consecutive Class 1 detections so far + int detection_threshold_; // number of consecutive detections required to + // trigger the service call bool service_called_{ false}; // prevents the service from being called more than once }; From e3cc2663540f3386cf2da0692a0d4924a660687d Mon Sep 17 00:00:00 2001 From: Ashish Date: Fri, 24 Apr 2026 15:53:01 +0200 Subject: [PATCH 10/16] feat: gate detection on FSM start signal via service server --- .../pipeline_end_detector_node.hpp | 6 +++++ .../src/pipeline_end_detector_node.cpp | 23 ++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp index f3a0907..95cc536 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp @@ -15,14 +15,20 @@ class PipelineEndDetectorNode : public rclcpp::Node { void setup_pubsub(); void detection_callback(const std_msgs::msg::UInt8::SharedPtr msg); void call_end_of_pipeline_service(); + void start_detection_callback( + const std_srvs::srv::Trigger::Request::SharedPtr request, + std_srvs::srv::Trigger::Response::SharedPtr response); rclcpp::Subscription::SharedPtr detection_sub_; rclcpp::Client::SharedPtr end_of_pipeline_client_; + rclcpp::Service::SharedPtr start_detection_server_; int consecutive_detections_{ 0}; // number of consecutive Class 1 detections so far int detection_threshold_; // number of consecutive detections required to // trigger the service call + bool detection_active_{ + false}; // set to true when FSM signals pipeline following has started bool service_called_{ false}; // prevents the service from being called more than once }; diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp index f2f5a92..3bf422c 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp @@ -16,15 +16,18 @@ PipelineEndDetectorNode::PipelineEndDetectorNode( RCLCPP_INFO( get_logger(), - "PipelineEndDetectorNode started. threshold=%d, service='%s'", + "PipelineEndDetectorNode started. threshold=%d, awaiting activation on " + "'%s'", detection_threshold_, - get_parameter("topics.end_of_pipeline_service").as_string().c_str()); + get_parameter("topics.start_detection_service").as_string().c_str()); } void PipelineEndDetectorNode::declare_parameters() { declare_parameter("topics.detection", "classification_output"); declare_parameter("topics.end_of_pipeline_service", "pipeline_inspection_fsm/pipeline_finished"); + declare_parameter("topics.start_detection_service", + "pipeline_end_detector/start_detection"); declare_parameter("detection_threshold", 10); } @@ -37,11 +40,25 @@ void PipelineEndDetectorNode::setup_pubsub() { end_of_pipeline_client_ = create_client( get_parameter("topics.end_of_pipeline_service").as_string()); + + start_detection_server_ = create_service( + get_parameter("topics.start_detection_service").as_string(), + std::bind(&PipelineEndDetectorNode::start_detection_callback, this, + std::placeholders::_1, std::placeholders::_2)); +} + +void PipelineEndDetectorNode::start_detection_callback( + const std_srvs::srv::Trigger::Request::SharedPtr /*request*/, + std_srvs::srv::Trigger::Response::SharedPtr response) { + detection_active_ = true; + response->success = true; + response->message = "Pipeline end detection activated."; + RCLCPP_INFO(get_logger(), "Pipeline following started — detection active."); } void PipelineEndDetectorNode::detection_callback( const std_msgs::msg::UInt8::SharedPtr msg) { - if (service_called_) { + if (!detection_active_ || service_called_) { return; } From 5315356105fab566e9a5a65a6bf5fdfd422dac9c Mon Sep 17 00:00:00 2001 From: Ashish Date: Fri, 24 Apr 2026 16:02:43 +0200 Subject: [PATCH 11/16] ci: retrigger CI From dcaf6c284698c02dd3b9239ed0ac1662a1294179 Mon Sep 17 00:00:00 2001 From: Ashish Date: Fri, 24 Apr 2026 16:12:52 +0200 Subject: [PATCH 12/16] chore: comment out pending yasmin pin in dependencies.repos --- dependencies.repos | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dependencies.repos b/dependencies.repos index 116cec4..8aacff0 100644 --- a/dependencies.repos +++ b/dependencies.repos @@ -5,3 +5,8 @@ repositories: vortex-utils: type: git url: https://github.com/vortexntnu/vortex-utils.git +# Pending decision — pin yasmin to avoid breaking CI on upstream updates +# yasmin: +# type: git +# url: https://github.com/uleroboticsgroup/yasmin.git +# version: 5.0.0 From 802cdaaaa48e50ee5f70b0ea0a438cd97c26b965 Mon Sep 17 00:00:00 2001 From: ashishagain Date: Fri, 24 Apr 2026 17:09:53 +0200 Subject: [PATCH 13/16] Clean up dependencies.repos by removing yasmin Removed commented-out section for yasmin dependency. --- dependencies.repos | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dependencies.repos b/dependencies.repos index 8aacff0..116cec4 100644 --- a/dependencies.repos +++ b/dependencies.repos @@ -5,8 +5,3 @@ repositories: vortex-utils: type: git url: https://github.com/vortexntnu/vortex-utils.git -# Pending decision — pin yasmin to avoid breaking CI on upstream updates -# yasmin: -# type: git -# url: https://github.com/uleroboticsgroup/yasmin.git -# version: 5.0.0 From 55de71d3670310ac20a798eae6de80ec8cb0cf15 Mon Sep 17 00:00:00 2001 From: Ashish Bhardwaj Date: Tue, 28 Apr 2026 15:11:36 +0200 Subject: [PATCH 14/16] fix: Default values and topics/service declared in config --- .../config/pipeline_end_detector_config.yaml | 2 ++ .../src/pipeline_end_detector_node.cpp | 10 ++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml b/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml index 3a1ed6d..7988aba 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/config/pipeline_end_detector_config.yaml @@ -8,3 +8,5 @@ detection: "classification_output" # Service name of the pipeline inspection FSM trigger end_of_pipeline_service: "pipeline_inspection_fsm/pipeline_finished" + # Service name to activate detection on this node + start_detection_service: "pipeline_end_detector/start_detection" diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp index 3bf422c..b719e07 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/src/pipeline_end_detector_node.cpp @@ -23,12 +23,10 @@ PipelineEndDetectorNode::PipelineEndDetectorNode( } void PipelineEndDetectorNode::declare_parameters() { - declare_parameter("topics.detection", "classification_output"); - declare_parameter("topics.end_of_pipeline_service", - "pipeline_inspection_fsm/pipeline_finished"); - declare_parameter("topics.start_detection_service", - "pipeline_end_detector/start_detection"); - declare_parameter("detection_threshold", 10); + declare_parameter("topics.detection"); + declare_parameter("topics.end_of_pipeline_service"); + declare_parameter("topics.start_detection_service"); + declare_parameter("detection_threshold"); } void PipelineEndDetectorNode::setup_pubsub() { From 9b2bd798bb1cd980215b1bd3cb425f86071c35ac Mon Sep 17 00:00:00 2001 From: Ashish Bhardwaj Date: Tue, 28 Apr 2026 15:13:18 +0200 Subject: [PATCH 15/16] Docs: explaination of class 1 detections --- .../pipeline_end_detector/pipeline_end_detector_node.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp index 95cc536..78464f4 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp @@ -24,7 +24,7 @@ class PipelineEndDetectorNode : public rclcpp::Node { rclcpp::Service::SharedPtr start_detection_server_; int consecutive_detections_{ - 0}; // number of consecutive Class 1 detections so far + 0}; // number of consecutive Class 1 (end of pipeline) detections so far int detection_threshold_; // number of consecutive detections required to // trigger the service call bool detection_active_{ From 8ff5b5676869486f54d52e629a21f2818a0825ee Mon Sep 17 00:00:00 2001 From: Ashish Bhardwaj Date: Tue, 28 Apr 2026 15:26:30 +0200 Subject: [PATCH 16/16] ran pre-commit --- .../pipeline_end_detector/pipeline_end_detector_node.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp index 78464f4..400d4e8 100644 --- a/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp +++ b/mission/tacc/pipeline_inspection/pipeline_end_detector/include/pipeline_end_detector/pipeline_end_detector_node.hpp @@ -23,8 +23,8 @@ class PipelineEndDetectorNode : public rclcpp::Node { rclcpp::Client::SharedPtr end_of_pipeline_client_; rclcpp::Service::SharedPtr start_detection_server_; - int consecutive_detections_{ - 0}; // number of consecutive Class 1 (end of pipeline) detections so far + int consecutive_detections_{0}; // number of consecutive Class 1 (end of + // pipeline) detections so far int detection_threshold_; // number of consecutive detections required to // trigger the service call bool detection_active_{