-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding the yolov8_brake_detection node for brake lights classification
- Loading branch information
Showing
13 changed files
with
275 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
cmake_minimum_required(VERSION 3.5) | ||
project(yolov8_brake_detection) | ||
|
||
# Dependencies | ||
find_package(ament_cmake REQUIRED) | ||
find_package(rclpy REQUIRED) | ||
find_package(rosidl_default_generators REQUIRED) | ||
|
||
# Specify message files | ||
rosidl_generate_interfaces(${PROJECT_NAME} | ||
"msg/BrakeStatus.msg" | ||
) | ||
|
||
# Python scripts | ||
install( | ||
PROGRAMS | ||
yolov8_node.py | ||
yolov8_predict_node.py | ||
DESTINATION lib/${PROJECT_NAME} | ||
) | ||
|
||
# Install other package files | ||
ament_package() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?xml version="1.0"?> | ||
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> | ||
<package format="3"> | ||
<name>yolov8_brake_detection</name> | ||
<version>0.0.0</version> | ||
<description>This package is responsible for performing brake light detection.</description> | ||
<maintainer email="[email protected]">root</maintainer> | ||
<license>Apache-2.0</license> | ||
|
||
<depend>sensor_msgs</depend> | ||
<build_depend>rosidl_default_generators</build_depend> | ||
<build_depend>std_msgs</build_depend> | ||
<exec_depend>rclpy</exec_depend> | ||
<exec_depend>std_msgs</exec_depend> | ||
|
||
<test_depend>ament_copyright</test_depend> | ||
<test_depend>ament_flake8</test_depend> | ||
<test_depend>ament_pep257</test_depend> | ||
<test_depend>python3-pytest</test_depend> | ||
|
||
<export> | ||
<build_type>ament_python</build_type> | ||
</export> | ||
</package> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[develop] | ||
script_dir=$base/lib/yolov8_brake_detection | ||
[install] | ||
install_scripts=$base/lib/yolov8_brake_detection |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from setuptools import setup | ||
|
||
package_name = 'yolov8_brake_detection' | ||
|
||
setup( | ||
name=package_name, | ||
version='0.0.1', | ||
packages=[package_name], | ||
install_requires=[ | ||
'setuptools', | ||
'torch', | ||
'opencv-python', | ||
'cv-bridge', | ||
'rclpy', | ||
'sensor_msgs', # Dependencies for brake light detection node | ||
], | ||
data_files=[ | ||
('share/ament_index/resource_index/packages', ['resource/' + package_name]), | ||
('share/' + package_name, ['package.xml']), | ||
], | ||
entry_points={ | ||
'console_scripts': [ | ||
'yolov8_node = yolov8_brake_detection.yolov8_node:main', | ||
], | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Copyright 2015 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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. | ||
|
||
from ament_copyright.main import main | ||
import pytest | ||
|
||
|
||
# Remove the `skip` decorator once the source file(s) have a copyright header | ||
@pytest.mark.skip(reason='No copyright header has been placed in the generated source file.') | ||
@pytest.mark.copyright | ||
@pytest.mark.linter | ||
def test_copyright(): | ||
rc = main(argv=['.', 'test']) | ||
assert rc == 0, 'Found errors' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Copyright 2017 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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. | ||
|
||
from ament_flake8.main import main_with_errors | ||
import pytest | ||
|
||
|
||
@pytest.mark.flake8 | ||
@pytest.mark.linter | ||
def test_flake8(): | ||
rc, errors = main_with_errors(argv=[]) | ||
assert rc == 0, \ | ||
'Found %d code style errors / warnings:\n' % len(errors) + \ | ||
'\n'.join(errors) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Copyright 2015 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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. | ||
|
||
from ament_pep257.main import main | ||
import pytest | ||
|
||
|
||
@pytest.mark.linter | ||
@pytest.mark.pep257 | ||
def test_pep257(): | ||
rc = main(argv=['.', 'test']) | ||
assert rc == 0, 'Found code style errors / warnings' |
Empty file.
Binary file not shown.
21 changes: 21 additions & 0 deletions
21
yolov8_brake_detection/yolov8_brake_detection/rosbag2_2024_12_11-00_42_05/metadata.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
rosbag2_bagfile_information: | ||
version: 5 | ||
storage_identifier: sqlite3 | ||
duration: | ||
nanoseconds: 0 | ||
starting_time: | ||
nanoseconds_since_epoch: 9223372036854775807 | ||
message_count: 0 | ||
topics_with_message_count: | ||
[] | ||
compression_format: "" | ||
compression_mode: "" | ||
relative_file_paths: | ||
- rosbag2_2024_12_11-00_42_05_0.db3 | ||
files: | ||
- path: rosbag2_2024_12_11-00_42_05_0.db3 | ||
starting_time: | ||
nanoseconds_since_epoch: 9223372036854775807 | ||
duration: | ||
nanoseconds: 0 | ||
message_count: 0 |
Binary file added
BIN
+24 KB
...tion/yolov8_brake_detection/rosbag2_2024_12_11-00_42_05/rosbag2_2024_12_11-00_42_05_0.db3
Binary file not shown.
104 changes: 104 additions & 0 deletions
104
yolov8_brake_detection/yolov8_brake_detection/yolov8_node.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import rclpy | ||
from rclpy.node import Node | ||
from sensor_msgs.msg import Image | ||
from cv_bridge import CvBridge | ||
from ultralytics import YOLO | ||
import cv2 | ||
from std_msgs.msg import String, Float32 | ||
|
||
class YOLOv8BrakeDetection(Node): | ||
def __init__(self): | ||
super().__init__('yolov8_brake_detection') | ||
|
||
# Declare the parameter for the camera topic name | ||
self.declare_parameter('image_topic', '/cameras/camera0') | ||
topic_name = self.get_parameter('image_topic').get_parameter_value().string_value | ||
|
||
# Create a subscription to the image topic | ||
self.subscription = self.create_subscription( | ||
Image, | ||
topic_name, # Use the topic name from the parameter | ||
self.image_callback, | ||
10 | ||
) | ||
|
||
# Publisher for brake detection results (status as string) | ||
self.publisher = self.create_publisher(String, 'brake_detection_results', 10) | ||
# Publisher for confidence score as a float | ||
self.confidence_publisher = self.create_publisher(Float32, 'brake_detection_confidence', 10) | ||
|
||
# Initialize CvBridge for converting ROS Image to OpenCV image | ||
self.bridge = CvBridge() | ||
|
||
# Load the YOLOv8 model | ||
model_path = '/navigator/ros2_ws/src/yolov8_brake_detection/yolov8_brake_detection/best.pt' | ||
try: | ||
self.get_logger().info(f"Loading YOLO model from: {model_path}") | ||
self.model = YOLO(model_path) | ||
self.get_logger().info("YOLOv8 model loaded successfully.") | ||
except Exception as e: | ||
self.get_logger().error(f"Failed to load YOLOv8 model: {e}") | ||
raise e | ||
|
||
def image_callback(self, msg): | ||
try: | ||
# Convert ROS Image message to OpenCV image | ||
cv_image = self.bridge.imgmsg_to_cv2(msg, desired_encoding='bgr8') | ||
|
||
# Run inference with YOLOv8 | ||
results = self.model(cv_image) | ||
|
||
# Process the results (detection boxes, classes, and confidence) | ||
for detection in results: | ||
class_name = detection['class'] # Update as per YOLO's output format | ||
confidence = detection['confidence'] | ||
|
||
# Publish the brake status | ||
if class_name == 'car_BrakeOn': | ||
self.publish_brake_status("Brake On") | ||
print(f"Detected Brakes On") | ||
|
||
elif class_name == 'car_BrakeOff': | ||
self.publish_brake_status("Brake Off") | ||
print(f"Detected Brakes Off") | ||
|
||
except Exception as e: | ||
self.get_logger().error(f"Error processing image: {e}") | ||
|
||
def publish_brake_status(self, status): | ||
try: | ||
# Publish brake status as a string | ||
message = String() | ||
message.data = status | ||
self.publisher.publish(message) | ||
self.get_logger().info(f"Published brake status: {status}") | ||
|
||
except Exception as e: | ||
self.get_logger().error(f"Failed to publish brake status: {e}") | ||
|
||
def publish_confidence(self, confidence): | ||
try: | ||
# Publish confidence score as a float | ||
confidence_message = Float32() | ||
confidence_message.data = confidence | ||
self.confidence_publisher.publish(confidence_message) | ||
self.get_logger().info(f"Published confidence: {confidence:.2f}") | ||
|
||
except Exception as e: | ||
self.get_logger().error(f"Failed to publish confidence score: {e}") | ||
|
||
def main(args=None): | ||
rclpy.init(args=args) | ||
|
||
# Initialize the YOLOv8BrakeDetection node | ||
node = YOLOv8BrakeDetection() | ||
|
||
# Spin the node to process incoming messages | ||
rclpy.spin(node) | ||
|
||
# Clean up and shut down | ||
node.destroy_node() | ||
rclpy.shutdown() | ||
|
||
if __name__ == '__main__': | ||
main() |