11#! /usr/bin/env python3
22from copy import deepcopy
3+ from typing import Optional
34
4- import numpy as np
55import rclpy
66from ament_index_python .packages import get_package_share_directory
77from cv_bridge import CvBridge
1010from rclpy .node import Node
1111from sensor_msgs .msg import Image
1212
13- from bitbots_vision .vision_modules import ros_utils , yoeo
13+ from bitbots_vision .vision_modules import debug , ros_utils , yoeo
1414
1515from .params import gen
1616
@@ -48,7 +48,8 @@ def __init__(self) -> None:
4848
4949 self ._sub_image = None
5050
51- self ._vision_components : list [yoeo .IVisionComponent ] = []
51+ self ._vision_components : list [yoeo .AbstractVisionComponent ] = []
52+ self ._debug_image : Optional [debug .DebugImage ] = None
5253
5354 # Setup reconfiguration
5455 gen .declare_params (self )
@@ -85,37 +86,44 @@ def _get_updated_config_with(self, params) -> dict:
8586 def _configure_vision (self , new_config : dict ) -> None :
8687 yoeo .YOEOObjectManager .configure (new_config )
8788
88- self . _set_up_vision_components (new_config )
89- self ._register_subscribers ( new_config )
89+ debug_image = debug . DebugImage (new_config [ "component_debug_image_active" ] )
90+ self ._debug_image = debug_image
9091
91- def _set_up_vision_components (self , new_config : dict ) -> None :
92- self ._vision_components = []
93- self ._vision_components .append (yoeo .YOEOComponent ())
92+ def make_vision_component (
93+ component_class : type [yoeo .AbstractVisionComponent ], ** kwargs
94+ ) -> yoeo .AbstractVisionComponent :
95+ return component_class (
96+ node = self ,
97+ yoeo_handler = yoeo .YOEOObjectManager .get (),
98+ debug_image = debug_image ,
99+ config = new_config ,
100+ ** kwargs ,
101+ )
102+
103+ self ._vision_components = [make_vision_component (yoeo .YOEOComponent )]
94104
95105 if new_config ["component_ball_detection_active" ]:
96- self ._vision_components .append (yoeo .BallDetectionComponent ( self ))
106+ self ._vision_components .append (make_vision_component ( yoeo .BallDetectionComponent ))
97107 if new_config ["component_robot_detection_active" ]:
98- if yoeo .YOEOObjectManager .is_team_color_detection_supported ():
99- self ._vision_components .append (yoeo .RobotDetectionComponent (self ))
100- else :
101- self ._vision_components .append (yoeo .NoTeamColorRobotDetectionComponent (self ))
108+ self ._vision_components .append (
109+ make_vision_component (
110+ yoeo .RobotDetectionComponent ,
111+ team_color_detection_supported = yoeo .YOEOObjectManager .is_team_color_detection_supported (),
112+ )
113+ )
102114 if new_config ["component_goalpost_detection_active" ]:
103- self ._vision_components .append (yoeo .GoalpostDetectionComponent ( self ))
115+ self ._vision_components .append (make_vision_component ( yoeo .GoalpostDetectionComponent ))
104116 if new_config ["component_line_detection_active" ]:
105- self ._vision_components .append (yoeo .LineDetectionComponent ( self ))
117+ self ._vision_components .append (make_vision_component ( yoeo .LineDetectionComponent ))
106118 if new_config ["component_field_detection_active" ]:
107- self ._vision_components .append (yoeo .FieldDetectionComponent ( self ))
119+ self ._vision_components .append (make_vision_component ( yoeo .FieldDetectionComponent ))
108120 if new_config ["component_debug_image_active" ]:
109- self ._vision_components .append (yoeo .DebugImageComponent (self ))
110-
111- for vision_component in self ._vision_components :
112- vision_component .configure (new_config , new_config ["component_debug_image_active" ])
121+ self ._vision_components .append (make_vision_component (yoeo .DebugImageComponent ))
113122
114- def _register_subscribers (self , config : dict ) -> None :
115123 self ._sub_image = ros_utils .create_or_update_subscriber (
116124 self ,
117125 self ._config ,
118- config ,
126+ new_config ,
119127 self ._sub_image ,
120128 "ROS_img_msg_topic" ,
121129 Image ,
@@ -124,24 +132,13 @@ def _register_subscribers(self, config: dict) -> None:
124132
125133 @profile
126134 def _run_vision_pipeline (self , image_msg : Image ) -> None :
127- image = self ._extract_image_from_message (image_msg )
128- if image is None :
129- logger .error ("Vision pipeline - Image content is None" )
130- return
135+ image = self ._cv_bridge .imgmsg_to_cv2 (image_msg , "bgr8" )
131136
132- self ._forward_image_to_components (image )
133- self ._run_components (image_msg )
134-
135- def _extract_image_from_message (self , image_msg : Image ) -> np .ndarray :
136- return self ._cv_bridge .imgmsg_to_cv2 (image_msg , "bgr8" )
137-
138- def _forward_image_to_components (self , image : np .ndarray ) -> None :
139- for vision_component in self ._vision_components :
140- vision_component .set_image (image )
137+ assert self ._debug_image is not None , "Debug image not initialized"
138+ self ._debug_image .set_image (image )
141139
142- def _run_components (self , image_msg : Image ) -> None :
143140 for vision_component in self ._vision_components :
144- vision_component .run (image_msg )
141+ vision_component .run (image , image_msg . header )
145142
146143
147144def main (args = None ):
0 commit comments