Skip to content

Commit 457fe31

Browse files
committed
Adding docstring to class methods
1 parent 5fd5330 commit 457fe31

File tree

5 files changed

+446
-39
lines changed

5 files changed

+446
-39
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ These are the parameters from the [yolo.launch.py](./yolo_bringup/launch/yolo.la
159159
- **input_depth_info_topic**: Camera topic for info data (default: /camera/depth/camera_info)
160160
- **depth_info_reliability**: Reliability for the depth info topic: 0=system default, 1=Reliable, 2=Best Effort (default: 1)
161161
- **target_frame**: frame to transform the 3D boxes (default: base_link)
162-
- **depth_image_units_divisor**: Divisor to convert the depth image into meters (default: 1000)
162+
- **depth_image_units_divisor**: Divisor to convert the depth image into meters. Depends on the camera you are using (default: 1000)
163163
- **use_tracking**: Whether to activate tracking after detection (default: True)
164164
- **use_3d**: Whether to activate 3D detections (default: False)
165165
- **use_debug**: Whether to activate debug node (default: True)

yolo_ros/yolo_ros/debug_node.py

Lines changed: 112 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,36 @@
4444

4545

4646
class DebugNode(LifecycleNode):
47+
"""
48+
ROS 2 Lifecycle Node for visualizing YOLO detections.
49+
50+
This node subscribes to images and detections, rendering bounding boxes,
51+
masks, keypoints, and 3D markers for debugging and visualization purposes.
52+
"""
4753

4854
def __init__(self) -> None:
55+
"""
56+
Initialize the debug node.
57+
58+
Sets up color mapping and declares ROS parameters.
59+
"""
4960
super().__init__("debug_node")
5061

5162
self._class_to_color = {}
5263
self.cv_bridge = CvBridge()
5364

54-
# params
65+
# Params
5566
self.declare_parameter("image_reliability", QoSReliabilityPolicy.BEST_EFFORT)
5667

5768
def on_configure(self, state: LifecycleState) -> TransitionCallbackReturn:
69+
"""
70+
Configure lifecycle callback.
71+
72+
Retrieves parameters and creates publishers for debug visualizations.
73+
74+
@param state Current lifecycle state
75+
@return Transition callback return status
76+
"""
5877
self.get_logger().info(f"[{self.get_name()}] Configuring...")
5978

6079
self.image_qos_profile = QoSProfile(
@@ -66,7 +85,7 @@ def on_configure(self, state: LifecycleState) -> TransitionCallbackReturn:
6685
depth=1,
6786
)
6887

69-
# pubs
88+
# Pubs
7089
self._dbg_pub = self.create_publisher(Image, "dbg_image", 10)
7190
self._bb_markers_pub = self.create_publisher(MarkerArray, "dgb_bb_markers", 10)
7291
self._kp_markers_pub = self.create_publisher(MarkerArray, "dgb_kp_markers", 10)
@@ -77,9 +96,17 @@ def on_configure(self, state: LifecycleState) -> TransitionCallbackReturn:
7796
return TransitionCallbackReturn.SUCCESS
7897

7998
def on_activate(self, state: LifecycleState) -> TransitionCallbackReturn:
99+
"""
100+
Activate lifecycle callback.
101+
102+
Creates subscriptions to image and detection topics with time synchronization.
103+
104+
@param state Current lifecycle state
105+
@return Transition callback return status
106+
"""
80107
self.get_logger().info(f"[{self.get_name()}] Activating...")
81108

82-
# subs
109+
# Subs
83110
self.image_sub = message_filters.Subscriber(
84111
self, Image, "image_raw", qos_profile=self.image_qos_profile
85112
)
@@ -98,6 +125,14 @@ def on_activate(self, state: LifecycleState) -> TransitionCallbackReturn:
98125
return TransitionCallbackReturn.SUCCESS
99126

100127
def on_deactivate(self, state: LifecycleState) -> TransitionCallbackReturn:
128+
"""
129+
Deactivate lifecycle callback.
130+
131+
Destroys subscriptions and cleans up the synchronizer.
132+
133+
@param state Current lifecycle state
134+
@return Transition callback return status
135+
"""
101136
self.get_logger().info(f"[{self.get_name()}] Deactivating...")
102137

103138
self.destroy_subscription(self.image_sub.sub)
@@ -111,6 +146,14 @@ def on_deactivate(self, state: LifecycleState) -> TransitionCallbackReturn:
111146
return TransitionCallbackReturn.SUCCESS
112147

113148
def on_cleanup(self, state: LifecycleState) -> TransitionCallbackReturn:
149+
"""
150+
Cleanup lifecycle callback.
151+
152+
Destroys publishers and cleans up resources.
153+
154+
@param state Current lifecycle state
155+
@return Transition callback return status
156+
"""
114157
self.get_logger().info(f"[{self.get_name()}] Cleaning up...")
115158

116159
self.destroy_publisher(self._dbg_pub)
@@ -123,6 +166,14 @@ def on_cleanup(self, state: LifecycleState) -> TransitionCallbackReturn:
123166
return TransitionCallbackReturn.SUCCESS
124167

125168
def on_shutdown(self, state: LifecycleState) -> TransitionCallbackReturn:
169+
"""
170+
Shutdown lifecycle callback.
171+
172+
Performs final cleanup before node shutdown.
173+
174+
@param state Current lifecycle state
175+
@return Transition callback return status
176+
"""
126177
self.get_logger().info(f"[{self.get_name()}] Shutting down...")
127178
super().on_shutdown(state)
128179
self.get_logger().info(f"[{self.get_name()}] Shutted down")
@@ -134,8 +185,18 @@ def draw_box(
134185
detection: Detection,
135186
color: Tuple[int],
136187
) -> np.ndarray:
188+
"""
189+
Draw a bounding box on the image.
190+
191+
Renders a rotated rectangle with class name, track ID, and confidence score.
192+
193+
@param cv_image OpenCV image to draw on
194+
@param detection Detection message containing box information
195+
@param color RGB color tuple for the box
196+
@return Modified image with drawn bounding box
197+
"""
137198

138-
# get detection info
199+
# Get detection info
139200
class_name = detection.class_name
140201
score = detection.score
141202
box_msg: BoundingBox2D = detection.bbox
@@ -150,7 +211,7 @@ def draw_box(
150211
round(box_msg.center.position.y + box_msg.size.y / 2.0),
151212
)
152213

153-
# define the four corners of the rectangle
214+
# Define the four corners of the rectangle
154215
rect_pts = np.array(
155216
[
156217
[min_pt[0], min_pt[1]],
@@ -160,14 +221,14 @@ def draw_box(
160221
]
161222
)
162223

163-
# calculate the rotation matrix
224+
# Calculate the rotation matrix
164225
rotation_matrix = cv2.getRotationMatrix2D(
165226
(box_msg.center.position.x, box_msg.center.position.y),
166227
-np.rad2deg(box_msg.center.theta),
167228
1.0,
168229
)
169230

170-
# rotate the corners of the rectangle
231+
# Rotate the corners of the rectangle
171232
rect_pts = np.int0(cv2.transform(np.array([rect_pts]), rotation_matrix)[0])
172233

173234
# Draw the rotated rectangle
@@ -176,7 +237,7 @@ def draw_box(
176237
pt2 = tuple(rect_pts[(i + 1) % 4])
177238
cv2.line(cv_image, pt1, pt2, color, 2)
178239

179-
# write text
240+
# Write text
180241
label = f"{class_name}"
181242
label += f" ({track_id})" if track_id else ""
182243
label += " ({:.3f})".format(score)
@@ -192,6 +253,16 @@ def draw_mask(
192253
detection: Detection,
193254
color: Tuple[int],
194255
) -> np.ndarray:
256+
"""
257+
Draw a segmentation mask on the image.
258+
259+
Renders the mask as a semi-transparent filled polygon.
260+
261+
@param cv_image OpenCV image to draw on
262+
@param detection Detection message containing mask information
263+
@param color RGB color tuple for the mask
264+
@return Modified image with drawn mask
265+
"""
195266

196267
mask_msg = detection.mask
197268
mask_array = np.array([[int(ele.x), int(ele.y)] for ele in mask_msg.data])
@@ -211,6 +282,15 @@ def draw_mask(
211282
return cv_image
212283

213284
def draw_keypoints(self, cv_image: np.ndarray, detection: Detection) -> np.ndarray:
285+
"""
286+
Draw keypoints and skeleton on the image.
287+
288+
Renders individual keypoints as circles and connects them with skeleton lines.
289+
290+
@param cv_image OpenCV image to draw on
291+
@param detection Detection message containing keypoint information
292+
@return Modified image with drawn keypoints and skeleton
293+
"""
214294

215295
keypoints_msg = detection.keypoints
216296

@@ -266,6 +346,13 @@ def get_pk_pose(kp_id: int) -> Tuple[int]:
266346
return cv_image
267347

268348
def create_bb_marker(self, detection: Detection, color: Tuple[int]) -> Marker:
349+
"""
350+
Create a 3D bounding box marker for RViz visualization.
351+
352+
@param detection Detection message containing 3D bbox information
353+
@param color RGB color tuple for the marker
354+
@return Marker message for visualization
355+
"""
269356

270357
bbox3d = detection.bbox3d
271358

@@ -300,6 +387,12 @@ def create_bb_marker(self, detection: Detection, color: Tuple[int]) -> Marker:
300387
return marker
301388

302389
def create_kp_marker(self, keypoint: KeyPoint3D) -> Marker:
390+
"""
391+
Create a 3D keypoint marker for RViz visualization.
392+
393+
@param keypoint 3D keypoint to visualize
394+
@return Marker message for visualization
395+
"""
303396

304397
marker = Marker()
305398

@@ -331,14 +424,23 @@ def create_kp_marker(self, keypoint: KeyPoint3D) -> Marker:
331424
return marker
332425

333426
def detections_cb(self, img_msg: Image, detection_msg: DetectionArray) -> None:
427+
"""
428+
Synchronized callback for image and detections.
429+
430+
Processes detections and creates debug visualizations including annotated
431+
images and 3D markers for bounding boxes and keypoints.
432+
433+
@param img_msg Image message
434+
@param detection_msg Detections message
435+
"""
334436
cv_image = self.cv_bridge.imgmsg_to_cv2(img_msg, desired_encoding="bgr8")
335437
bb_marker_array = MarkerArray()
336438
kp_marker_array = MarkerArray()
337439

338440
detection: Detection
339441
for detection in detection_msg.detections:
340442

341-
# random color
443+
# Random color
342444
class_name = detection.class_name
343445

344446
if class_name not in self._class_to_color:
@@ -367,7 +469,7 @@ def detections_cb(self, img_msg: Image, detection_msg: DetectionArray) -> None:
367469
marker.id = len(kp_marker_array.markers)
368470
kp_marker_array.markers.append(marker)
369471

370-
# publish dbg image
472+
# Publish dbg image
371473
self._dbg_pub.publish(
372474
self.cv_bridge.cv2_to_imgmsg(cv_image, encoding="bgr8", header=img_msg.header)
373475
)

0 commit comments

Comments
 (0)