把去年的二维码检测、图生文客户端、锥桶检测v8给加了进来,二维码检测新增深度相机检测
This commit is contained in:
121
keyboard_control.py
Executable file
121
keyboard_control.py
Executable file
@@ -0,0 +1,121 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Keyboard control node for robot chassis.
|
||||||
|
W/S: forward/backward
|
||||||
|
A/D: turn left/right
|
||||||
|
I/K: increase/decrease linear speed
|
||||||
|
J/L: increase/decrease angular speed
|
||||||
|
X: stop
|
||||||
|
Q: quit
|
||||||
|
"""
|
||||||
|
|
||||||
|
import rclpy
|
||||||
|
from rclpy.node import Node
|
||||||
|
from geometry_msgs.msg import Twist
|
||||||
|
import sys
|
||||||
|
import select
|
||||||
|
import termios
|
||||||
|
import tty
|
||||||
|
|
||||||
|
HELP = """
|
||||||
|
========================================
|
||||||
|
Keyboard Control
|
||||||
|
========================================
|
||||||
|
W/S : forward / backward
|
||||||
|
A/D : turn left / turn right
|
||||||
|
I/K : linear speed +/- (step 0.05)
|
||||||
|
J/L : angular speed +/- (step 0.1)
|
||||||
|
X/Space: stop
|
||||||
|
Q : quit
|
||||||
|
========================================
|
||||||
|
Current: lin=%.2f ang=%.2f
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class KeyboardControl(Node):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("keyboard_control")
|
||||||
|
self.pub = self.create_publisher(Twist, "/cmd_vel", 10)
|
||||||
|
|
||||||
|
self.lin_speed = 0.2
|
||||||
|
self.ang_speed = 0.5
|
||||||
|
self.lin_step = 0.05
|
||||||
|
self.ang_step = 0.1
|
||||||
|
|
||||||
|
self.print_help()
|
||||||
|
self.create_timer(0.05, self.read_key)
|
||||||
|
|
||||||
|
def print_help(self):
|
||||||
|
print(HELP % (self.lin_speed, self.ang_speed))
|
||||||
|
|
||||||
|
def get_key(self):
|
||||||
|
fd = sys.stdin.fileno()
|
||||||
|
old = termios.tcgetattr(fd)
|
||||||
|
try:
|
||||||
|
tty.setraw(fd)
|
||||||
|
r, _, _ = select.select([sys.stdin], [], [], 0.05)
|
||||||
|
if r:
|
||||||
|
return sys.stdin.read(1)
|
||||||
|
return None
|
||||||
|
finally:
|
||||||
|
termios.tcsetattr(fd, termios.TCSADRAIN, old)
|
||||||
|
|
||||||
|
def read_key(self):
|
||||||
|
key = self.get_key()
|
||||||
|
if key is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
twist = Twist()
|
||||||
|
|
||||||
|
if key == 'w':
|
||||||
|
twist.linear.x = self.lin_speed
|
||||||
|
elif key == 's':
|
||||||
|
twist.linear.x = -self.lin_speed
|
||||||
|
elif key == 'a':
|
||||||
|
twist.angular.z = self.ang_speed
|
||||||
|
elif key == 'd':
|
||||||
|
twist.angular.z = -self.ang_speed
|
||||||
|
elif key == 'i':
|
||||||
|
self.lin_speed = round(self.lin_speed + self.lin_step, 2)
|
||||||
|
self.print_help()
|
||||||
|
return
|
||||||
|
elif key == 'k':
|
||||||
|
self.lin_speed = round(max(0.0, self.lin_speed - self.lin_step), 2)
|
||||||
|
self.print_help()
|
||||||
|
return
|
||||||
|
elif key == 'j':
|
||||||
|
self.ang_speed = round(self.ang_speed + self.ang_step, 2)
|
||||||
|
self.print_help()
|
||||||
|
return
|
||||||
|
elif key == 'l':
|
||||||
|
self.ang_speed = round(max(0.0, self.ang_speed - self.ang_step), 2)
|
||||||
|
self.print_help()
|
||||||
|
return
|
||||||
|
elif key == 'x' or key == ' ':
|
||||||
|
twist.linear.x = 0.0
|
||||||
|
twist.angular.z = 0.0
|
||||||
|
print("*** STOP ***")
|
||||||
|
elif key == 'q' or ord(key) == 3:
|
||||||
|
twist.linear.x = 0.0
|
||||||
|
twist.angular.z = 0.0
|
||||||
|
self.pub.publish(twist)
|
||||||
|
self.get_logger().info("Quitting...")
|
||||||
|
raise SystemExit
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.pub.publish(twist)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
rclpy.init()
|
||||||
|
try:
|
||||||
|
rclpy.spin(KeyboardControl())
|
||||||
|
except SystemExit:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
rclpy.shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -147,7 +147,7 @@ controller_server_rclcpp_node:
|
|||||||
local_costmap:
|
local_costmap:
|
||||||
local_costmap:
|
local_costmap:
|
||||||
ros__parameters:
|
ros__parameters:
|
||||||
update_frequency: 5.0
|
update_frequency: 1.0
|
||||||
publish_frequency: 2.0
|
publish_frequency: 2.0
|
||||||
transform_tolerance: 0.5
|
transform_tolerance: 0.5
|
||||||
global_frame: odom
|
global_frame: odom
|
||||||
|
|||||||
75
src/qr_detection/CMakeLists.txt
Normal file
75
src/qr_detection/CMakeLists.txt
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
project(qr_detection)
|
||||||
|
|
||||||
|
# Default to C99
|
||||||
|
if(NOT CMAKE_C_STANDARD)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Default to C++14
|
||||||
|
if(NOT CMAKE_CXX_STANDARD)
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Find dependencies
|
||||||
|
find_package(ament_cmake REQUIRED)
|
||||||
|
find_package(rclcpp REQUIRED)
|
||||||
|
find_package(std_msgs REQUIRED)
|
||||||
|
find_package(dnn_node REQUIRED)
|
||||||
|
# find_package(hbm_img_msgs REQUIRED)
|
||||||
|
find_package(sensor_msgs REQUIRED)
|
||||||
|
find_package(ai_msgs REQUIRED)
|
||||||
|
find_package(OpenCV REQUIRED)
|
||||||
|
find_package(geometry_msgs REQUIRED)
|
||||||
|
find_package(rosidl_default_generators REQUIRED)
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(ZBar REQUIRED zbar)
|
||||||
|
|
||||||
|
# rosidl_generate_interfaces(${PROJECT_NAME}
|
||||||
|
# "msg/SampleMessage.msg"
|
||||||
|
# )
|
||||||
|
|
||||||
|
# # Define executables
|
||||||
|
# add_executable(talker src/publisher_hbmem.cpp)
|
||||||
|
# ...
|
||||||
|
|
||||||
|
# add_executable(qr_dete_node src/qr_dete.cpp)
|
||||||
|
# ...
|
||||||
|
|
||||||
|
# install(DIRECTORY
|
||||||
|
# ${PROJECT_SOURCE_DIR}/launch/
|
||||||
|
# DESTINATION share/${PROJECT_NAME}/launch)
|
||||||
|
|
||||||
|
# ---- qr_dete_depth_node (sensor_msgs::Image, no hbmem) ----
|
||||||
|
add_executable(qr_dete_depth_node src/qr_dete_depth.cpp)
|
||||||
|
ament_target_dependencies(qr_dete_depth_node
|
||||||
|
rclcpp
|
||||||
|
std_msgs
|
||||||
|
sensor_msgs
|
||||||
|
geometry_msgs
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(qr_dete_depth_node PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
$<INSTALL_INTERFACE:include>
|
||||||
|
${OpenCV_INCLUDE_DIRS} ${ZBar_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
target_link_libraries(qr_dete_depth_node
|
||||||
|
${OpenCV_LIBS} ${ZBar_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS qr_dete_depth_node
|
||||||
|
DESTINATION lib/${PROJECT_NAME})
|
||||||
|
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
find_package(ament_lint_auto REQUIRED)
|
||||||
|
set(ament_cmake_copyright_FOUND TRUE)
|
||||||
|
set(ament_cmake_cpplint_FOUND TRUE)
|
||||||
|
ament_lint_auto_find_test_dependencies()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ament_package()
|
||||||
37
src/qr_detection/launch/qr_detection.launch.py
Normal file
37
src/qr_detection/launch/qr_detection.launch.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from launch import LaunchDescription
|
||||||
|
from launch.actions import DeclareLaunchArgument
|
||||||
|
from launch.actions import IncludeLaunchDescription
|
||||||
|
from launch_ros.actions import Node
|
||||||
|
from launch.substitutions import TextSubstitution
|
||||||
|
from launch.substitutions import LaunchConfiguration
|
||||||
|
from launch.launch_description_sources import PythonLaunchDescriptionSource
|
||||||
|
from ament_index_python import get_package_share_directory
|
||||||
|
|
||||||
|
def generate_launch_description():
|
||||||
|
nv12_codec_node = IncludeLaunchDescription(
|
||||||
|
PythonLaunchDescriptionSource(
|
||||||
|
os.path.join(
|
||||||
|
get_package_share_directory('hobot_codec'),
|
||||||
|
'launch/hobot_codec_decode.launch.py')),
|
||||||
|
launch_arguments={
|
||||||
|
# 'codec_channel': '2',
|
||||||
|
'codec_in_mode': 'ros',
|
||||||
|
'codec_out_mode': 'shared_mem',
|
||||||
|
'codec_sub_topic': '/image',
|
||||||
|
'codec_pub_topic': '/hbmem_img'
|
||||||
|
}.items()
|
||||||
|
)
|
||||||
|
|
||||||
|
qr_detection_node = Node(
|
||||||
|
package='qr_detection',
|
||||||
|
executable='qr_dete_node',
|
||||||
|
name='qr_dete_node',
|
||||||
|
output='screen'
|
||||||
|
)
|
||||||
|
|
||||||
|
return LaunchDescription([
|
||||||
|
nv12_codec_node,
|
||||||
|
qr_detection_node
|
||||||
|
])
|
||||||
5
src/qr_detection/msg/SampleMessage.msg
Normal file
5
src/qr_detection/msg/SampleMessage.msg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
int32 index
|
||||||
|
uint64 time_stamp
|
||||||
|
uint8[4194304] data
|
||||||
|
|
||||||
|
uint32 MAX_SIZE=4194304
|
||||||
22
src/qr_detection/package.xml
Normal file
22
src/qr_detection/package.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?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>qr_detection</name>
|
||||||
|
<version>0.0.0</version>
|
||||||
|
<description>TODO: Package description</description>
|
||||||
|
<maintainer email="root@todo.todo">root</maintainer>
|
||||||
|
<license>TODO: License declaration</license>
|
||||||
|
|
||||||
|
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||||
|
<build_depend>rosidl_default_generators</build_depend>
|
||||||
|
<exec_depend>rosidl_default_runtime</exec_depend>
|
||||||
|
<member_of_group>rosidl_interface_packages</member_of_group>
|
||||||
|
<depend>rclcpp</depend>
|
||||||
|
|
||||||
|
<test_depend>ament_lint_auto</test_depend>
|
||||||
|
<test_depend>ament_lint_common</test_depend>
|
||||||
|
|
||||||
|
<export>
|
||||||
|
<build_type>ament_cmake</build_type>
|
||||||
|
</export>
|
||||||
|
</package>
|
||||||
70
src/qr_detection/src/publisher_hbmem.cpp
Normal file
70
src/qr_detection/src/publisher_hbmem.cpp
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
#include "qr_detection/msg/sample_message.hpp"
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
class MinimalHbmemPublisher : public rclcpp::Node {
|
||||||
|
public:
|
||||||
|
MinimalHbmemPublisher () : Node("minimal_hbmem_publisher"), count_(0) {
|
||||||
|
// 创建publisher_hbmem,topic为"topic"
|
||||||
|
publisher_ = this->create_publisher_hbmem<qr_detection::msg::SampleMessage>(
|
||||||
|
"topic", rclcpp::SensorDataQoS());
|
||||||
|
|
||||||
|
// 定时器,每隔40毫秒调用一次timer_callback进行消息发送
|
||||||
|
timer_ = this->create_wall_timer(
|
||||||
|
40ms, std::bind(&MinimalHbmemPublisher::timer_callback, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 定时器回调函数
|
||||||
|
void timer_callback() {
|
||||||
|
// 获取要发送的消息
|
||||||
|
auto loanedMsg = publisher_->borrow_loaned_message();
|
||||||
|
// 判断消息是否可用,可能出现获取消息失败导致消息不可用的情况
|
||||||
|
if (loanedMsg.is_valid()) {
|
||||||
|
// 引用方式获取实际的消息
|
||||||
|
auto& msg = loanedMsg.get();
|
||||||
|
|
||||||
|
// 获取当前时间,单位为us
|
||||||
|
auto time_now =
|
||||||
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
|
std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||||
|
|
||||||
|
// 对消息的index和time_stamp进行赋值
|
||||||
|
msg.index = count_;
|
||||||
|
msg.time_stamp = time_now;
|
||||||
|
|
||||||
|
// 打印发送消息
|
||||||
|
RCLCPP_INFO(this->get_logger(), "message: %d", msg.index);
|
||||||
|
publisher_->publish(std::move(loanedMsg));
|
||||||
|
// 注意,发送后,loanedMsg已不可用
|
||||||
|
// 计数器加一
|
||||||
|
count_++;
|
||||||
|
} else {
|
||||||
|
// 获取消息失败,丢弃该消息
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Failed to get LoanMessage!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定时器
|
||||||
|
rclcpp::TimerBase::SharedPtr timer_;
|
||||||
|
|
||||||
|
// hbmem publisher
|
||||||
|
rclcpp::PublisherHbmem<qr_detection::msg::SampleMessage>::SharedPtr publisher_;
|
||||||
|
|
||||||
|
// 计数器
|
||||||
|
size_t count_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
rclcpp::spin(std::make_shared<MinimalHbmemPublisher>());
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
290
src/qr_detection/src/qr_dete.cpp
Normal file
290
src/qr_detection/src/qr_dete.cpp
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
#include <memory>
|
||||||
|
#include <iostream>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <zbar.h>
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
#include "std_msgs/msg/int32.hpp"
|
||||||
|
#include "std_msgs/msg/string.hpp"
|
||||||
|
#include "hbm_img_msgs/msg/hbm_msg1080_p.hpp"
|
||||||
|
|
||||||
|
class MinimalHbmemSubscriber : public rclcpp::Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MinimalHbmemSubscriber()
|
||||||
|
: Node("qr_detection"), detect_qr_code_(true) // 默认不检测二维码
|
||||||
|
{
|
||||||
|
// 创建 subscription_hbmem,topic 为 "hbmem_img"
|
||||||
|
subscription_hbmem_ =
|
||||||
|
this->create_subscription_hbmem<hbm_img_msgs::msg::HbmMsg1080P>(
|
||||||
|
"hbmem_img",
|
||||||
|
10,
|
||||||
|
std::bind(&MinimalHbmemSubscriber::hbmem_callback, this, std::placeholders::_1));
|
||||||
|
|
||||||
|
// 创建订阅器,订阅 'sign4return' 话题
|
||||||
|
subscription_sign_ =
|
||||||
|
this->create_subscription<std_msgs::msg::Int32>(
|
||||||
|
"sign4return",
|
||||||
|
10,
|
||||||
|
std::bind(&MinimalHbmemSubscriber::sign_callback, this, std::placeholders::_1));
|
||||||
|
|
||||||
|
// 创建 publisher,topic 为 "qr_results"
|
||||||
|
publisher_ =
|
||||||
|
this->create_publisher<std_msgs::msg::String>("qr_results", 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 消息回调函数,处理 hbmem_img 话题
|
||||||
|
void hbmem_callback(const hbm_img_msgs::msg::HbmMsg1080P::SharedPtr msg)
|
||||||
|
{
|
||||||
|
if (!detect_qr_code_)
|
||||||
|
{
|
||||||
|
RCLCPP_INFO(this->get_logger(), "QR detection is disabled");
|
||||||
|
return; // 如果标志位为 false,则不进行二维码检测
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 Clock 对象并获取当前时间
|
||||||
|
auto clock = std::make_shared<rclcpp::Clock>(RCL_SYSTEM_TIME);
|
||||||
|
auto now = clock->now();
|
||||||
|
|
||||||
|
// 转换消息时间戳为 ROS 时间
|
||||||
|
auto msg_time = rclcpp::Time(msg->time_stamp.sec, msg->time_stamp.nanosec);
|
||||||
|
|
||||||
|
// 计算延时(单位:微秒)
|
||||||
|
auto duration = now - msg_time;
|
||||||
|
auto delay_us = duration.nanoseconds() / 1000; // 转换为微秒
|
||||||
|
|
||||||
|
// 打印延迟
|
||||||
|
RCLCPP_INFO(this->get_logger(), "msg index: %d, time cost %dus", msg->index, delay_us);
|
||||||
|
|
||||||
|
// 获取图像数据并将其转换为 OpenCV 格式
|
||||||
|
cv::Mat image(msg->height, msg->width, CV_8UC1, const_cast<uint8_t*>(msg->data.data()));
|
||||||
|
|
||||||
|
// 初始化 ZBar 扫描器
|
||||||
|
zbar::ImageScanner scanner;
|
||||||
|
scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
|
||||||
|
|
||||||
|
// 将 OpenCV 图像数据包装成 ZBar 图像
|
||||||
|
zbar::Image zbar_image(image.cols, image.rows, "Y800", image.data, image.cols * image.rows);
|
||||||
|
|
||||||
|
// 扫描图像中的条形码和二维码
|
||||||
|
std::string qr_results;
|
||||||
|
int n = scanner.scan(zbar_image);
|
||||||
|
if (n > 0) {
|
||||||
|
for (auto symbol = zbar_image.symbol_begin(); symbol != zbar_image.symbol_end(); ++symbol) {
|
||||||
|
qr_results += symbol->get_data();
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Decoded %s symbol \"%s\"", symbol->get_type_name().c_str(), symbol->get_data().c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qr_results = "QR Code not detected";
|
||||||
|
RCLCPP_INFO(this->get_logger(), "QR Code not detected");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发布 QR 结果
|
||||||
|
auto message = std_msgs::msg::String();
|
||||||
|
message.data = qr_results;
|
||||||
|
publisher_->publish(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 消息回调函数,处理 sign4return 话题
|
||||||
|
void sign_callback(const std_msgs::msg::Int32::SharedPtr msg)
|
||||||
|
{
|
||||||
|
if (msg->data == 0)
|
||||||
|
{
|
||||||
|
detect_qr_code_ = true; // 启动二维码检测
|
||||||
|
RCLCPP_INFO(this->get_logger(), "QR detection started");
|
||||||
|
}
|
||||||
|
else if (msg->data == 5)
|
||||||
|
{
|
||||||
|
detect_qr_code_ = false; // 停止二维码检测
|
||||||
|
RCLCPP_INFO(this->get_logger(), "QR detection stopped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hbmem_img 订阅器
|
||||||
|
rclcpp::SubscriptionHbmem<hbm_img_msgs::msg::HbmMsg1080P>::SharedPtr subscription_hbmem_;
|
||||||
|
// sign4return 订阅器
|
||||||
|
rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr subscription_sign_;
|
||||||
|
// QR code results 发布器
|
||||||
|
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
|
||||||
|
|
||||||
|
// 二维码检测标志位
|
||||||
|
bool detect_qr_code_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
rclcpp::spin(std::make_shared<MinimalHbmemSubscriber>());
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
实现接收和发布
|
||||||
|
*/
|
||||||
|
//#include <memory>
|
||||||
|
//#include <iostream>
|
||||||
|
//#include <opencv2/opencv.hpp>
|
||||||
|
//#include <zbar.h>
|
||||||
|
//#include "rclcpp/rclcpp.hpp"
|
||||||
|
//#include "std_msgs/msg/string.hpp"
|
||||||
|
//#include "hbm_img_msgs/msg/hbm_msg1080_p.hpp"
|
||||||
|
//
|
||||||
|
//class MinimalHbmemSubscriber : public rclcpp::Node
|
||||||
|
//{
|
||||||
|
//public:
|
||||||
|
// MinimalHbmemSubscriber()
|
||||||
|
// : Node("qr_detection")
|
||||||
|
// {
|
||||||
|
// // 创建 subscription_hbmem,topic 为 "hbmem_img"
|
||||||
|
// // 消息回调函数为 topic_callback
|
||||||
|
// subscription_ =
|
||||||
|
// this->create_subscription_hbmem<hbm_img_msgs::msg::HbmMsg1080P>(
|
||||||
|
// "hbmem_img",
|
||||||
|
// 10,
|
||||||
|
// std::bind(&MinimalHbmemSubscriber::topic_callback, this, std::placeholders::_1));
|
||||||
|
//
|
||||||
|
// // 创建 publisher,topic 为 "qr_results"
|
||||||
|
// publisher_ =
|
||||||
|
// this->create_publisher<std_msgs::msg::String>("qr_results", 10);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//private:
|
||||||
|
// // 消息回调函数
|
||||||
|
// void topic_callback(const hbm_img_msgs::msg::HbmMsg1080P::SharedPtr msg) const
|
||||||
|
// {
|
||||||
|
// // 创建 Clock 对象并获取当前时间
|
||||||
|
// auto clock = std::make_shared<rclcpp::Clock>(RCL_SYSTEM_TIME);
|
||||||
|
// auto now = clock->now();
|
||||||
|
//
|
||||||
|
// // 转换消息时间戳为 ROS 时间
|
||||||
|
// auto msg_time = rclcpp::Time(msg->time_stamp.sec, msg->time_stamp.nanosec);
|
||||||
|
//
|
||||||
|
// // 计算延时(单位:微秒)
|
||||||
|
// auto duration = now - msg_time;
|
||||||
|
// auto delay_us = duration.nanoseconds() / 1000; // 转换为微秒
|
||||||
|
//
|
||||||
|
// // 打印延迟
|
||||||
|
// RCLCPP_INFO(this->get_logger(), "msg index: %d, time cost %dus", msg->index, delay_us);
|
||||||
|
//
|
||||||
|
// // 获取图像数据并将其转换为 OpenCV 格式
|
||||||
|
// cv::Mat image(msg->height, msg->width, CV_8UC1, const_cast<uint8_t*>(msg->data.data()));
|
||||||
|
//
|
||||||
|
// // 初始化 ZBar 扫描器
|
||||||
|
// zbar::ImageScanner scanner;
|
||||||
|
// scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
|
||||||
|
//
|
||||||
|
// // 将 OpenCV 图像数据包装成 ZBar 图像
|
||||||
|
// zbar::Image zbar_image(image.cols, image.rows, "Y800", image.data, image.cols * image.rows);
|
||||||
|
//
|
||||||
|
// // 扫描图像中的条形码和二维码
|
||||||
|
// std::string qr_results;
|
||||||
|
// int n = scanner.scan(zbar_image);
|
||||||
|
// if (n > 0) {
|
||||||
|
// for (auto symbol = zbar_image.symbol_begin(); symbol != zbar_image.symbol_end(); ++symbol) {
|
||||||
|
// qr_results += symbol->get_data() ;
|
||||||
|
// RCLCPP_INFO(this->get_logger(), "Decoded %s symbol \"%s\"", symbol->get_type_name().c_str(), symbol->get_data().c_str());
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// qr_results = "QR Code not detected";
|
||||||
|
// RCLCPP_INFO(this->get_logger(), "QR Code not detected");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 发布 QR 结果
|
||||||
|
// auto message = std_msgs::msg::String();
|
||||||
|
// message.data = qr_results;
|
||||||
|
// publisher_->publish(message);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // hbmem subscription
|
||||||
|
// rclcpp::SubscriptionHbmem<hbm_img_msgs::msg::HbmMsg1080P>::SharedPtr subscription_;
|
||||||
|
// // QR code results publisher
|
||||||
|
// rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//int main(int argc, char * argv[])
|
||||||
|
//{
|
||||||
|
// rclcpp::init(argc, argv);
|
||||||
|
// rclcpp::spin(std::make_shared<MinimalHbmemSubscriber>());
|
||||||
|
// rclcpp::shutdown();
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
只实现接收消息,不进行发布
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//#include <memory>
|
||||||
|
//#include <iostream>
|
||||||
|
//#include <opencv2/opencv.hpp>
|
||||||
|
//#include <zbar.h>
|
||||||
|
//#include "rclcpp/rclcpp.hpp"
|
||||||
|
//#include "hbm_img_msgs/msg/hbm_msg1080_p.hpp"
|
||||||
|
//
|
||||||
|
//class MinimalHbmemSubscriber : public rclcpp::Node
|
||||||
|
//{
|
||||||
|
//public:
|
||||||
|
// MinimalHbmemSubscriber()
|
||||||
|
// : Node("qr_detection")
|
||||||
|
// {
|
||||||
|
// // 创建 subscription_hbmem,topic 为 "hbmem_img"
|
||||||
|
// // 消息回调函数为 topic_callback
|
||||||
|
// subscription_ =
|
||||||
|
// this->create_subscription_hbmem<hbm_img_msgs::msg::HbmMsg1080P>(
|
||||||
|
// "hbmem_img",
|
||||||
|
// 10,
|
||||||
|
// std::bind(&MinimalHbmemSubscriber::topic_callback, this, std::placeholders::_1));
|
||||||
|
// }
|
||||||
|
//private:
|
||||||
|
// // 消息回调函数
|
||||||
|
// void topic_callback(
|
||||||
|
// const hbm_img_msgs::msg::HbmMsg1080P::SharedPtr msg) const
|
||||||
|
// {
|
||||||
|
// // 创建 Clock 对象并获取当前时间
|
||||||
|
// auto clock = std::make_shared<rclcpp::Clock>(RCL_SYSTEM_TIME);
|
||||||
|
// auto now = clock->now();
|
||||||
|
//
|
||||||
|
// // 转换消息时间戳为 ROS 时间
|
||||||
|
// auto msg_time = rclcpp::Time(msg->time_stamp.sec, msg->time_stamp.nanosec);
|
||||||
|
//
|
||||||
|
// // 计算延时(单位:微秒)
|
||||||
|
// auto duration = now - msg_time;
|
||||||
|
// auto delay_us = duration.nanoseconds() / 1000; // 转换为微秒
|
||||||
|
//
|
||||||
|
// // 打印延迟
|
||||||
|
// RCLCPP_INFO(this->get_logger(), "msg index: %d, time cost %dus", msg->index, delay_us);
|
||||||
|
//
|
||||||
|
// // 获取图像数据并将其转换为 OpenCV 格式
|
||||||
|
// cv::Mat image(msg->height, msg->width, CV_8UC1, const_cast<uint8_t*>(msg->data.data()));
|
||||||
|
//
|
||||||
|
// // 初始化 ZBar 扫描器
|
||||||
|
// zbar::ImageScanner scanner;
|
||||||
|
// scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
|
||||||
|
//
|
||||||
|
// // 将 OpenCV 图像数据包装成 ZBar 图像
|
||||||
|
// zbar::Image zbar_image(image.cols, image.rows, "Y800", image.data, image.cols * image.rows);
|
||||||
|
//
|
||||||
|
// // 扫描图像中的条形码和二维码
|
||||||
|
// int n = scanner.scan(zbar_image);
|
||||||
|
// if (n > 0) {
|
||||||
|
// for (auto symbol = zbar_image.symbol_begin(); symbol != zbar_image.symbol_end(); ++symbol) {
|
||||||
|
// RCLCPP_INFO(this->get_logger(), "Decoded %s symbol \"%s\"", symbol->get_type_name().c_str(), symbol->get_data().c_str());
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// RCLCPP_INFO(this->get_logger(), "QR Code not detected");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // hbmem subscription
|
||||||
|
// rclcpp::SubscriptionHbmem<hbm_img_msgs::msg::HbmMsg1080P>::SharedPtr subscription_;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//int main(int argc, char * argv[])
|
||||||
|
//{
|
||||||
|
// rclcpp::init(argc, argv);
|
||||||
|
// rclcpp::spin(std::make_shared<MinimalHbmemSubscriber>());
|
||||||
|
// rclcpp::shutdown();
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
131
src/qr_detection/src/qr_dete_depth.cpp
Normal file
131
src/qr_detection/src/qr_dete_depth.cpp
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#include <memory>
|
||||||
|
#include <iostream>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <zbar.h>
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
#include "std_msgs/msg/int32.hpp"
|
||||||
|
#include "std_msgs/msg/string.hpp"
|
||||||
|
#include "sensor_msgs/msg/image.hpp"
|
||||||
|
|
||||||
|
class MinimalHbmemSubscriber : public rclcpp::Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MinimalHbmemSubscriber()
|
||||||
|
: Node("qr_detection"), detect_qr_code_(true) // 默认检测二维码
|
||||||
|
{
|
||||||
|
// 订阅 /aurora/rgb/image_raw(sensor_msgs::msg::Image 格式)
|
||||||
|
subscription_image_ =
|
||||||
|
this->create_subscription<sensor_msgs::msg::Image>(
|
||||||
|
"/aurora/rgb/image_raw",
|
||||||
|
10,
|
||||||
|
std::bind(&MinimalHbmemSubscriber::image_callback, this, std::placeholders::_1));
|
||||||
|
|
||||||
|
// 创建订阅器,订阅 'sign4return' 话题
|
||||||
|
subscription_sign_ =
|
||||||
|
this->create_subscription<std_msgs::msg::Int32>(
|
||||||
|
"sign4return",
|
||||||
|
10,
|
||||||
|
std::bind(&MinimalHbmemSubscriber::sign_callback, this, std::placeholders::_1));
|
||||||
|
|
||||||
|
// 创建 publisher,topic 为 "qr_results"
|
||||||
|
publisher_ =
|
||||||
|
this->create_publisher<std_msgs::msg::String>("qr_results", 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 图像回调函数,处理 /aurora/rgb/image_raw 话题
|
||||||
|
void image_callback(const sensor_msgs::msg::Image::SharedPtr msg)
|
||||||
|
{
|
||||||
|
if (!detect_qr_code_)
|
||||||
|
{
|
||||||
|
RCLCPP_INFO(this->get_logger(), "QR detection is disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 Clock 对象并获取当前时间
|
||||||
|
auto clock = std::make_shared<rclcpp::Clock>(RCL_SYSTEM_TIME);
|
||||||
|
auto now = clock->now();
|
||||||
|
|
||||||
|
// 转换消息时间戳为 ROS 时间
|
||||||
|
auto msg_time = rclcpp::Time(msg->header.stamp.sec, msg->header.stamp.nanosec);
|
||||||
|
|
||||||
|
// 计算延时(单位:微秒)
|
||||||
|
auto duration = now - msg_time;
|
||||||
|
auto delay_us = duration.nanoseconds() / 1000; // 转换为微秒
|
||||||
|
|
||||||
|
// 打印延迟
|
||||||
|
RCLCPP_INFO(this->get_logger(), "frame_id: %s, time cost %ldus",
|
||||||
|
msg->header.frame_id.c_str(), delay_us);
|
||||||
|
|
||||||
|
// 将 sensor_msgs::Image 转换为 OpenCV 格式(Aurora RGB 为 bgr8 编码,需转为灰度给 ZBar)
|
||||||
|
if (msg->encoding != "bgr8") {
|
||||||
|
RCLCPP_ERROR(this->get_logger(), "Expected bgr8 encoding, got %s", msg->encoding.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cv::Mat rgb_image(msg->height, msg->width, CV_8UC3,
|
||||||
|
const_cast<uint8_t*>(msg->data.data()));
|
||||||
|
cv::Mat gray_image;
|
||||||
|
cv::cvtColor(rgb_image, gray_image, cv::COLOR_BGR2GRAY);
|
||||||
|
|
||||||
|
// 初始化 ZBar 扫描器
|
||||||
|
zbar::ImageScanner scanner;
|
||||||
|
scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
|
||||||
|
|
||||||
|
// 将 OpenCV 图像数据包装成 ZBar 图像
|
||||||
|
zbar::Image zbar_image(gray_image.cols, gray_image.rows, "Y800",
|
||||||
|
gray_image.data, gray_image.cols * gray_image.rows);
|
||||||
|
|
||||||
|
// 扫描图像中的条形码和二维码
|
||||||
|
std::string qr_results;
|
||||||
|
int n = scanner.scan(zbar_image);
|
||||||
|
if (n > 0) {
|
||||||
|
for (auto symbol = zbar_image.symbol_begin();
|
||||||
|
symbol != zbar_image.symbol_end(); ++symbol) {
|
||||||
|
qr_results += symbol->get_data();
|
||||||
|
RCLCPP_INFO(this->get_logger(), "Decoded %s symbol \"%s\"",
|
||||||
|
symbol->get_type_name().c_str(), symbol->get_data().c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qr_results = "QR Code not detected";
|
||||||
|
RCLCPP_INFO(this->get_logger(), "QR Code not detected");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发布 QR 结果
|
||||||
|
auto message = std_msgs::msg::String();
|
||||||
|
message.data = qr_results;
|
||||||
|
publisher_->publish(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 消息回调函数,处理 sign4return 话题
|
||||||
|
void sign_callback(const std_msgs::msg::Int32::SharedPtr msg)
|
||||||
|
{
|
||||||
|
if (msg->data == 0)
|
||||||
|
{
|
||||||
|
detect_qr_code_ = true; // 启动二维码检测
|
||||||
|
RCLCPP_INFO(this->get_logger(), "QR detection started");
|
||||||
|
}
|
||||||
|
else if (msg->data == 5)
|
||||||
|
{
|
||||||
|
detect_qr_code_ = false; // 停止二维码检测
|
||||||
|
RCLCPP_INFO(this->get_logger(), "QR detection stopped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// /aurora/rgb/image_raw 订阅器
|
||||||
|
rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr subscription_image_;
|
||||||
|
// sign4return 订阅器
|
||||||
|
rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr subscription_sign_;
|
||||||
|
// QR code results 发布器
|
||||||
|
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
|
||||||
|
|
||||||
|
// 二维码检测标志位
|
||||||
|
bool detect_qr_code_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
rclcpp::spin(std::make_shared<MinimalHbmemSubscriber>());
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
50
src/qr_detection/src/qr_detection_node.cpp
Normal file
50
src/qr_detection/src/qr_detection_node.cpp
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#include <memory>
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
#include "hbm_img_msgs/msg/hbm_msg1080_p.hpp"
|
||||||
|
|
||||||
|
class MinimalHbmemSubscriber : public rclcpp::Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MinimalHbmemSubscriber()
|
||||||
|
: Node("qr_detection")
|
||||||
|
{
|
||||||
|
// 创建 subscription_hbmem,topic 为 "hbmem_img"
|
||||||
|
// 消息回调函数为 topic_callback
|
||||||
|
subscription_ =
|
||||||
|
this->create_subscription_hbmem<hbm_img_msgs::msg::HbmMsg1080P>(
|
||||||
|
"hbmem_img",
|
||||||
|
10,
|
||||||
|
std::bind(&MinimalHbmemSubscriber::topic_callback, this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 消息回调函数
|
||||||
|
void topic_callback(
|
||||||
|
const hbm_img_msgs::msg::HbmMsg1080P::SharedPtr msg) const
|
||||||
|
{
|
||||||
|
// 创建 Clock 对象并获取当前时间
|
||||||
|
auto clock = std::make_shared<rclcpp::Clock>(RCL_SYSTEM_TIME);
|
||||||
|
auto now = clock->now();
|
||||||
|
|
||||||
|
// 转换消息时间戳为 ROS 时间
|
||||||
|
auto msg_time = rclcpp::Time(msg->time_stamp.sec, msg->time_stamp.nanosec);
|
||||||
|
|
||||||
|
// 计算延时(单位:微秒)
|
||||||
|
auto duration = now - msg_time;
|
||||||
|
auto delay_us = duration.nanoseconds() / 1000; // 转换为微秒
|
||||||
|
|
||||||
|
// 打印延迟
|
||||||
|
RCLCPP_INFO(this->get_logger(), "msg index: %d, time cost %dus", msg->index, delay_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hbmem subscription
|
||||||
|
rclcpp::SubscriptionHbmem<hbm_img_msgs::msg::HbmMsg1080P>::SharedPtr subscription_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
rclcpp::spin(std::make_shared<MinimalHbmemSubscriber>());
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
36
src/qr_detection/src/sameple_zbar.cpp
Normal file
36
src/qr_detection/src/sameple_zbar.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <zbar.h>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cerr << "Usage: " << argv[0] << " <image_path>" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string image_path = argv[1];
|
||||||
|
cv::Mat image = cv::imread(image_path, cv::IMREAD_GRAYSCALE);
|
||||||
|
if (image.empty()) {
|
||||||
|
std::cerr << "Could not open or find the image: " << image_path << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize ZBar scanner
|
||||||
|
zbar::ImageScanner scanner;
|
||||||
|
scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
|
||||||
|
|
||||||
|
// Wrap OpenCV image data in a ZBar image
|
||||||
|
zbar::Image zbar_image(image.cols, image.rows, "Y800", image.data, image.cols * image.rows);
|
||||||
|
|
||||||
|
// Scan the image for barcodes and QR codes
|
||||||
|
int n = scanner.scan(zbar_image);
|
||||||
|
if (n > 0) {
|
||||||
|
for (auto symbol = zbar_image.symbol_begin(); symbol != zbar_image.symbol_end(); ++symbol) {
|
||||||
|
std::cout << "Decoded " << symbol->get_type_name() << " symbol \"" << symbol->get_data() << '"' << std::endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cout << "QR Code not detected" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
45
src/qr_detection/src/subscriber_hbmem.cpp
Normal file
45
src/qr_detection/src/subscriber_hbmem.cpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "rclcpp/rclcpp.hpp"
|
||||||
|
#include "qr_detection/msg/sample_message.hpp"
|
||||||
|
|
||||||
|
class MinimalHbmemSubscriber : public rclcpp::Node {
|
||||||
|
public:
|
||||||
|
MinimalHbmemSubscriber () : Node("minimal_hbmem_subscriber") {
|
||||||
|
// 创建subscription_hbmem,topic为"sample"
|
||||||
|
// 消息回调函数为topic_callback
|
||||||
|
subscription_ =
|
||||||
|
this->create_subscription_hbmem<qr_detection::msg::SampleMessage>(
|
||||||
|
"topic", rclcpp::SensorDataQoS(),
|
||||||
|
std::bind(&MinimalHbmemSubscriber ::topic_callback, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 消息回调函数
|
||||||
|
void topic_callback(
|
||||||
|
const qr_detection::msg::SampleMessage::SharedPtr msg) const {
|
||||||
|
// 注意,msg只能在回调函数中使用,回调函数返回后,该消息就会被释放
|
||||||
|
// 获取当前时间
|
||||||
|
auto time_now =
|
||||||
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
|
std::chrono::steady_clock::now().time_since_epoch())
|
||||||
|
.count();
|
||||||
|
// 计算延时并打印出来
|
||||||
|
RCLCPP_INFO(this->get_logger(), "msg %d, time cost %dus", msg->index,
|
||||||
|
time_now - msg->time_stamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hbmem subscription
|
||||||
|
rclcpp::SubscriptionHbmem<qr_detection::msg::SampleMessage>::SharedPtr
|
||||||
|
subscription_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
rclcpp::init(argc, argv);
|
||||||
|
rclcpp::spin(std::make_shared<MinimalHbmemSubscriber>());
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
18
src/vlm_detect/package.xml
Normal file
18
src/vlm_detect/package.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?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>vlm_detect</name>
|
||||||
|
<version>0.0.0</version>
|
||||||
|
<description>TODO: Package description</description>
|
||||||
|
<maintainer email="root@todo.todo">root</maintainer>
|
||||||
|
<license>TODO: License declaration</license>
|
||||||
|
|
||||||
|
<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>
|
||||||
0
src/vlm_detect/resource/vlm_detect
Normal file
0
src/vlm_detect/resource/vlm_detect
Normal file
4
src/vlm_detect/setup.cfg
Normal file
4
src/vlm_detect/setup.cfg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[develop]
|
||||||
|
script_dir=$base/lib/vlm_detect
|
||||||
|
[install]
|
||||||
|
install_scripts=$base/lib/vlm_detect
|
||||||
26
src/vlm_detect/setup.py
Normal file
26
src/vlm_detect/setup.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
from setuptools import find_packages, setup
|
||||||
|
|
||||||
|
package_name = 'vlm_detect'
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name=package_name,
|
||||||
|
version='0.0.0',
|
||||||
|
packages=find_packages(exclude=['test']),
|
||||||
|
data_files=[
|
||||||
|
('share/ament_index/resource_index/packages',
|
||||||
|
['resource/' + package_name]),
|
||||||
|
('share/' + package_name, ['package.xml']),
|
||||||
|
],
|
||||||
|
install_requires=['setuptools'],
|
||||||
|
zip_safe=True,
|
||||||
|
maintainer='root',
|
||||||
|
maintainer_email='root@todo.todo',
|
||||||
|
description='TODO: Package description',
|
||||||
|
license='TODO: License declaration',
|
||||||
|
tests_require=['pytest'],
|
||||||
|
entry_points={
|
||||||
|
'console_scripts': [
|
||||||
|
'vlm_node = vlm_detect.vlm_node:main',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
25
src/vlm_detect/test/test_copyright.py
Normal file
25
src/vlm_detect/test/test_copyright.py
Normal file
@@ -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'
|
||||||
25
src/vlm_detect/test/test_flake8.py
Normal file
25
src/vlm_detect/test/test_flake8.py
Normal file
@@ -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)
|
||||||
23
src/vlm_detect/test/test_pep257.py
Normal file
23
src/vlm_detect/test/test_pep257.py
Normal file
@@ -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'
|
||||||
0
src/vlm_detect/vlm_detect/__init__.py
Normal file
0
src/vlm_detect/vlm_detect/__init__.py
Normal file
BIN
src/vlm_detect/vlm_detect/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
src/vlm_detect/vlm_detect/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
src/vlm_detect/vlm_detect/__pycache__/vlm_node.cpython-38.pyc
Normal file
BIN
src/vlm_detect/vlm_detect/__pycache__/vlm_node.cpython-38.pyc
Normal file
Binary file not shown.
144
src/vlm_detect/vlm_detect/vlm_node.py
Normal file
144
src/vlm_detect/vlm_detect/vlm_node.py
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import rclpy
|
||||||
|
from rclpy.node import Node
|
||||||
|
from std_msgs.msg import Int32, String
|
||||||
|
from sensor_msgs.msg import CompressedImage
|
||||||
|
from cv_bridge import CvBridge
|
||||||
|
import cv2
|
||||||
|
import base64
|
||||||
|
import threading
|
||||||
|
from openai import OpenAI
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class VLMProcessor(Node):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__('vlm_dtetct')
|
||||||
|
|
||||||
|
# 初始化 OpenAI 客户端
|
||||||
|
self.client = OpenAI(
|
||||||
|
base_url="http://192.168.1.103:8000/v1",
|
||||||
|
api_key="EMPTY"
|
||||||
|
)
|
||||||
|
|
||||||
|
# ROS2 组件
|
||||||
|
self.bridge = CvBridge()
|
||||||
|
self.latest_image = None
|
||||||
|
self.image_lock = threading.Lock()
|
||||||
|
|
||||||
|
# 订阅图像话题
|
||||||
|
self.image_sub = self.create_subscription(
|
||||||
|
CompressedImage,
|
||||||
|
'/image',
|
||||||
|
self.image_callback,
|
||||||
|
10
|
||||||
|
)
|
||||||
|
|
||||||
|
# 订阅触发信号
|
||||||
|
self.sign_sub = self.create_subscription(
|
||||||
|
Int32,
|
||||||
|
'/sign4return',
|
||||||
|
self.sign_callback,
|
||||||
|
10
|
||||||
|
)
|
||||||
|
|
||||||
|
# 发布结果
|
||||||
|
self.result_pub = self.create_publisher(
|
||||||
|
String,
|
||||||
|
'/vlm_result',
|
||||||
|
10
|
||||||
|
)
|
||||||
|
|
||||||
|
self.get_logger().info("VLM Processor...")
|
||||||
|
|
||||||
|
def image_callback(self, msg):
|
||||||
|
"""保存最新的图像"""
|
||||||
|
with self.image_lock:
|
||||||
|
try:
|
||||||
|
np_arr = np.frombuffer(msg.data, np.uint8)
|
||||||
|
# 使用 OpenCV 解码图像
|
||||||
|
cv_image = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
|
||||||
|
self.latest_image = cv_image
|
||||||
|
self.get_logger().debug("recive picture")
|
||||||
|
except Exception as e:
|
||||||
|
self.get_logger().error("err picture")
|
||||||
|
|
||||||
|
def sign_callback(self, msg):
|
||||||
|
"""处理触发信号"""
|
||||||
|
if msg.data == 9:
|
||||||
|
self.get_logger().info("收到触发信号 (6),开始处理图像...")
|
||||||
|
|
||||||
|
# 检查是否有可用图像
|
||||||
|
with self.image_lock:
|
||||||
|
if self.latest_image is None:
|
||||||
|
self.get_logger().warning("没有可用图像")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 保存临时图像文件
|
||||||
|
temp_path = "/tmp/vlm_temp_image.jpg"
|
||||||
|
cv2.imwrite(temp_path, self.latest_image)
|
||||||
|
self.get_logger().info("已保存临时图像}")
|
||||||
|
|
||||||
|
# 处理图像
|
||||||
|
try:
|
||||||
|
description = self.process_image(temp_path)
|
||||||
|
self.get_logger().info(f"图像描述结果:")
|
||||||
|
|
||||||
|
# 发布结果
|
||||||
|
result_msg = String()
|
||||||
|
result_msg.data = description
|
||||||
|
self.result_pub.publish(result_msg)
|
||||||
|
|
||||||
|
# 清理临时文件
|
||||||
|
os.remove(temp_path)
|
||||||
|
except Exception as e:
|
||||||
|
self.get_logger().error(f"处理图像时出错:{e}")
|
||||||
|
|
||||||
|
def process_image(self, image_path):
|
||||||
|
"""使用 VLM 模型处理图像"""
|
||||||
|
# 读取并编码图像
|
||||||
|
with open(image_path, "rb") as image_file:
|
||||||
|
base64_image = base64.b64encode(image_file.read()).decode('utf-8')
|
||||||
|
|
||||||
|
# 发送请求到 VLM 模型
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
response = self.client.chat.completions.create(
|
||||||
|
model="/home/yyh/vllm_test/model/InternVL3-1B",
|
||||||
|
messages=[
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": [
|
||||||
|
{"type": "text", "text": "描述图片中的动漫病人"},
|
||||||
|
{
|
||||||
|
"type": "image_url",
|
||||||
|
"image_url": {
|
||||||
|
"url": f"data:image/jpeg;base64,{base64_image}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
max_tokens=100
|
||||||
|
)
|
||||||
|
|
||||||
|
processing_time = time.time() - start_time
|
||||||
|
self.get_logger().info("VLM 处理耗时秒")
|
||||||
|
|
||||||
|
return response.choices[0].message.content
|
||||||
|
|
||||||
|
def main(args=None):
|
||||||
|
rclpy.init(args=args)
|
||||||
|
node = VLMProcessor()
|
||||||
|
try:
|
||||||
|
rclpy.spin(node)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
node.destroy_node()
|
||||||
|
rclpy.shutdown()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
1
src/yolov8_launch/class_list/cone.list
Normal file
1
src/yolov8_launch/class_list/cone.list
Normal file
@@ -0,0 +1 @@
|
|||||||
|
cone
|
||||||
239
src/yolov8_launch/launch/dnn_node_example.launch.py
Normal file
239
src/yolov8_launch/launch/dnn_node_example.launch.py
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
# Copyright (c) 2024,D-Robotics.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from launch import LaunchDescription
|
||||||
|
from launch.actions import DeclareLaunchArgument
|
||||||
|
from launch.actions import IncludeLaunchDescription
|
||||||
|
from launch_ros.actions import Node
|
||||||
|
from launch.substitutions import TextSubstitution
|
||||||
|
from launch.substitutions import LaunchConfiguration
|
||||||
|
from launch.launch_description_sources import PythonLaunchDescriptionSource
|
||||||
|
from ament_index_python import get_package_share_directory
|
||||||
|
from ament_index_python.packages import get_package_prefix
|
||||||
|
|
||||||
|
|
||||||
|
def generate_launch_description():
|
||||||
|
|
||||||
|
# args that can be set from the command line or a default will be used
|
||||||
|
config_file_launch_arg = DeclareLaunchArgument(
|
||||||
|
"dnn_example_config_file", default_value=TextSubstitution(text="/root/yolov8workconfig.json")
|
||||||
|
)
|
||||||
|
dump_render_launch_arg = DeclareLaunchArgument(
|
||||||
|
"dnn_example_dump_render_img", default_value=TextSubstitution(text="0")
|
||||||
|
)
|
||||||
|
image_width_launch_arg = DeclareLaunchArgument(
|
||||||
|
"dnn_example_image_width", default_value=TextSubstitution(text="640")
|
||||||
|
)
|
||||||
|
image_height_launch_arg = DeclareLaunchArgument(
|
||||||
|
"dnn_example_image_height", default_value=TextSubstitution(text="480")
|
||||||
|
)
|
||||||
|
msg_pub_topic_name_launch_arg = DeclareLaunchArgument(
|
||||||
|
"dnn_example_msg_pub_topic_name", default_value=TextSubstitution(text="hobot_dnn_detection")
|
||||||
|
)
|
||||||
|
|
||||||
|
camera_type = os.getenv('CAM_TYPE')
|
||||||
|
camera_type = 'usb'
|
||||||
|
print("camera_type is ", camera_type)
|
||||||
|
|
||||||
|
cam_node = None
|
||||||
|
camera_type_mipi = None
|
||||||
|
camera_device_arg = None
|
||||||
|
|
||||||
|
if camera_type == "usb":
|
||||||
|
# usb cam图片发布pkg
|
||||||
|
usb_cam_device_arg = DeclareLaunchArgument(
|
||||||
|
'device',
|
||||||
|
default_value='/dev/video8',
|
||||||
|
description='usb camera device')
|
||||||
|
|
||||||
|
usb_node = IncludeLaunchDescription(
|
||||||
|
PythonLaunchDescriptionSource(
|
||||||
|
os.path.join(
|
||||||
|
get_package_share_directory('hobot_usb_cam'),
|
||||||
|
'launch/hobot_usb_cam.launch.py')),
|
||||||
|
launch_arguments={
|
||||||
|
'usb_image_width': LaunchConfiguration('dnn_example_image_width'),
|
||||||
|
'usb_image_height': LaunchConfiguration('dnn_example_image_height'),
|
||||||
|
'usb_video_device': LaunchConfiguration('device')
|
||||||
|
}.items()
|
||||||
|
)
|
||||||
|
print("using usb cam")
|
||||||
|
cam_node = usb_node
|
||||||
|
camera_type_mipi = False
|
||||||
|
camera_device_arg = usb_cam_device_arg
|
||||||
|
|
||||||
|
elif camera_type == "fb":
|
||||||
|
# 本地图片发布
|
||||||
|
feedback_picture_arg = DeclareLaunchArgument(
|
||||||
|
'publish_image_source',
|
||||||
|
default_value='./config/target.jpg',
|
||||||
|
description='feedback picture')
|
||||||
|
|
||||||
|
publish_image_fps = DeclareLaunchArgument(
|
||||||
|
'publish_image_fps',
|
||||||
|
default_value='5',
|
||||||
|
description='publish_image_fps picture')
|
||||||
|
|
||||||
|
fb_node = IncludeLaunchDescription(
|
||||||
|
PythonLaunchDescriptionSource(
|
||||||
|
os.path.join(
|
||||||
|
get_package_share_directory('hobot_image_publisher'),
|
||||||
|
'launch/hobot_image_publisher.launch.py')),
|
||||||
|
launch_arguments={
|
||||||
|
'publish_image_source': LaunchConfiguration('publish_image_source'),
|
||||||
|
'publish_image_format': LaunchConfiguration('publish_image_format'),
|
||||||
|
'publish_message_topic_name': '/hbmem_img',
|
||||||
|
'publish_fps': LaunchConfiguration('publish_image_fps')
|
||||||
|
}.items()
|
||||||
|
)
|
||||||
|
|
||||||
|
print("using feedback")
|
||||||
|
cam_node = fb_node
|
||||||
|
camera_type_mipi = True
|
||||||
|
camera_device_arg = feedback_picture_arg
|
||||||
|
|
||||||
|
else:
|
||||||
|
if camera_type == "mipi":
|
||||||
|
print("using mipi cam")
|
||||||
|
else:
|
||||||
|
print("invalid camera_type ", camera_type,
|
||||||
|
", which is set with export CAM_TYPE=usb/mipi/fb, using default mipi cam")
|
||||||
|
# mipi cam图片发布pkg
|
||||||
|
mipi_cam_device_arg = DeclareLaunchArgument(
|
||||||
|
'device',
|
||||||
|
default_value='F37',
|
||||||
|
description='mipi camera device')
|
||||||
|
mipi_node = IncludeLaunchDescription(
|
||||||
|
PythonLaunchDescriptionSource(
|
||||||
|
os.path.join(
|
||||||
|
get_package_share_directory('mipi_cam'),
|
||||||
|
'launch/mipi_cam.launch.py')),
|
||||||
|
launch_arguments={
|
||||||
|
'mipi_image_width': LaunchConfiguration('dnn_example_image_width'),
|
||||||
|
'mipi_image_height': LaunchConfiguration('dnn_example_image_height'),
|
||||||
|
'mipi_io_method': 'shared_mem',
|
||||||
|
'mipi_frame_ts_type': 'realtime',
|
||||||
|
'mipi_video_device': LaunchConfiguration('device')
|
||||||
|
}.items()
|
||||||
|
)
|
||||||
|
|
||||||
|
cam_node = mipi_node
|
||||||
|
camera_type_mipi = True
|
||||||
|
camera_device_arg = mipi_cam_device_arg
|
||||||
|
|
||||||
|
# jpeg图片编码&发布pkg
|
||||||
|
jpeg_codec_node = IncludeLaunchDescription(
|
||||||
|
PythonLaunchDescriptionSource(
|
||||||
|
os.path.join(
|
||||||
|
get_package_share_directory('hobot_codec'),
|
||||||
|
'launch/hobot_codec_encode.launch.py')),
|
||||||
|
launch_arguments={
|
||||||
|
'codec_in_mode': 'shared_mem',
|
||||||
|
'codec_out_mode': 'ros',
|
||||||
|
'codec_sub_topic': '/hbmem_img',
|
||||||
|
'codec_pub_topic': '/image'
|
||||||
|
}.items()
|
||||||
|
)
|
||||||
|
|
||||||
|
# nv12图片解码&发布pkg
|
||||||
|
nv12_codec_node = IncludeLaunchDescription(
|
||||||
|
PythonLaunchDescriptionSource(
|
||||||
|
os.path.join(
|
||||||
|
get_package_share_directory('hobot_codec'),
|
||||||
|
'launch/hobot_codec_decode.launch.py')),
|
||||||
|
launch_arguments={
|
||||||
|
'codec_in_mode': 'ros',
|
||||||
|
'codec_out_mode': 'shared_mem',
|
||||||
|
'codec_sub_topic': '/image',
|
||||||
|
'codec_pub_topic': '/hbmem_img'
|
||||||
|
}.items()
|
||||||
|
)
|
||||||
|
|
||||||
|
# web展示pkg
|
||||||
|
web_node = IncludeLaunchDescription(
|
||||||
|
PythonLaunchDescriptionSource(
|
||||||
|
os.path.join(
|
||||||
|
get_package_share_directory('websocket'),
|
||||||
|
'launch/websocket.launch.py')),
|
||||||
|
launch_arguments={
|
||||||
|
'websocket_image_topic': '/image',
|
||||||
|
'websocket_image_type': 'mjpeg',
|
||||||
|
'websocket_smart_topic': LaunchConfiguration("dnn_example_msg_pub_topic_name")
|
||||||
|
}.items()
|
||||||
|
)
|
||||||
|
|
||||||
|
# 算法pkg
|
||||||
|
dnn_node_example_node = Node(
|
||||||
|
package='dnn_node_example',
|
||||||
|
executable='example',
|
||||||
|
output='screen',
|
||||||
|
parameters=[
|
||||||
|
{"config_file": LaunchConfiguration('dnn_example_config_file')},
|
||||||
|
{"dump_render_img": LaunchConfiguration(
|
||||||
|
'dnn_example_dump_render_img')},
|
||||||
|
{"feed_type": 1},
|
||||||
|
{"is_shared_mem_sub": 1},
|
||||||
|
{"msg_pub_topic_name": LaunchConfiguration(
|
||||||
|
"dnn_example_msg_pub_topic_name")}
|
||||||
|
],
|
||||||
|
arguments=['--ros-args', '--log-level', 'warn']
|
||||||
|
)
|
||||||
|
|
||||||
|
shared_mem_node = IncludeLaunchDescription(
|
||||||
|
PythonLaunchDescriptionSource(
|
||||||
|
os.path.join(
|
||||||
|
get_package_share_directory('hobot_shm'),
|
||||||
|
'launch/hobot_shm.launch.py'))
|
||||||
|
)
|
||||||
|
|
||||||
|
if camera_type_mipi:
|
||||||
|
return LaunchDescription([
|
||||||
|
camera_device_arg,
|
||||||
|
config_file_launch_arg,
|
||||||
|
dump_render_launch_arg,
|
||||||
|
image_width_launch_arg,
|
||||||
|
image_height_launch_arg,
|
||||||
|
msg_pub_topic_name_launch_arg,
|
||||||
|
# 启动零拷贝环境配置node
|
||||||
|
# shared_mem_node,
|
||||||
|
# 图片发布pkg
|
||||||
|
cam_node,
|
||||||
|
# 图片编解码&发布pkg
|
||||||
|
nv12_codec_node,
|
||||||
|
# 启动example pkg
|
||||||
|
dnn_node_example_node,
|
||||||
|
# 启动web展示pkg
|
||||||
|
web_node
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
return LaunchDescription([
|
||||||
|
camera_device_arg,
|
||||||
|
config_file_launch_arg,
|
||||||
|
dump_render_launch_arg,
|
||||||
|
image_width_launch_arg,
|
||||||
|
image_height_launch_arg,
|
||||||
|
msg_pub_topic_name_launch_arg,
|
||||||
|
# 启动零拷贝环境配置node
|
||||||
|
# shared_mem_node,
|
||||||
|
# 图片发布pkg
|
||||||
|
cam_node,
|
||||||
|
# 图片编解码&发布pkg
|
||||||
|
nv12_codec_node,
|
||||||
|
# 启动example pkg
|
||||||
|
dnn_node_example_node,
|
||||||
|
# 启动web展示pkg
|
||||||
|
web_node
|
||||||
|
])
|
||||||
18
src/yolov8_launch/package.xml
Normal file
18
src/yolov8_launch/package.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?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_launch</name>
|
||||||
|
<version>0.0.0</version>
|
||||||
|
<description>TODO: Package description</description>
|
||||||
|
<maintainer email="root@todo.todo">root</maintainer>
|
||||||
|
<license>TODO: License declaration</license>
|
||||||
|
|
||||||
|
<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>
|
||||||
0
src/yolov8_launch/resource/yolov8_launch
Normal file
0
src/yolov8_launch/resource/yolov8_launch
Normal file
4
src/yolov8_launch/setup.cfg
Normal file
4
src/yolov8_launch/setup.cfg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[develop]
|
||||||
|
script_dir=$base/lib/yolov8_launch
|
||||||
|
[install]
|
||||||
|
install_scripts=$base/lib/yolov8_launch
|
||||||
27
src/yolov8_launch/setup.py
Normal file
27
src/yolov8_launch/setup.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from setuptools import find_packages, setup
|
||||||
|
import os
|
||||||
|
from glob import glob
|
||||||
|
package_name = 'yolov8_launch'
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name=package_name,
|
||||||
|
version='0.0.0',
|
||||||
|
packages=find_packages(exclude=['test']),
|
||||||
|
data_files=[
|
||||||
|
('share/ament_index/resource_index/packages',
|
||||||
|
['resource/' + package_name]),
|
||||||
|
('share/' + package_name, ['package.xml']),
|
||||||
|
('share/' + package_name + '/launch', glob('launch/*.launch.py')),
|
||||||
|
],
|
||||||
|
install_requires=['setuptools'],
|
||||||
|
zip_safe=True,
|
||||||
|
maintainer='root',
|
||||||
|
maintainer_email='root@todo.todo',
|
||||||
|
description='TODO: Package description',
|
||||||
|
license='TODO: License declaration',
|
||||||
|
tests_require=['pytest'],
|
||||||
|
entry_points={
|
||||||
|
'console_scripts': [
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
25
src/yolov8_launch/test/test_copyright.py
Normal file
25
src/yolov8_launch/test/test_copyright.py
Normal file
@@ -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'
|
||||||
25
src/yolov8_launch/test/test_flake8.py
Normal file
25
src/yolov8_launch/test/test_flake8.py
Normal file
@@ -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)
|
||||||
23
src/yolov8_launch/test/test_pep257.py
Normal file
23
src/yolov8_launch/test/test_pep257.py
Normal file
@@ -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'
|
||||||
0
src/yolov8_launch/yolov8_launch/__init__.py
Normal file
0
src/yolov8_launch/yolov8_launch/__init__.py
Normal file
47
wget-log
Normal file
47
wget-log
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
--2026-06-15 22:41:04-- https://github.com/xiongqi123123/dtop/releases/download/v1.1.0/dtop-arm64-ubuntu22.04.tar.gz
|
||||||
|
Resolving github.com (github.com)... 20.205.243.166
|
||||||
|
Connecting to github.com (github.com)|20.205.243.166|:443... connected.
|
||||||
|
HTTP request sent, awaiting response... No data received.
|
||||||
|
Retrying.
|
||||||
|
|
||||||
|
--2026-06-15 22:42:35-- (try: 2) https://github.com/xiongqi123123/dtop/releases/download/v1.1.0/dtop-arm64-ubuntu22.04.tar.gz
|
||||||
|
Connecting to github.com (github.com)|20.205.243.166|:443... connected.
|
||||||
|
HTTP request sent, awaiting response... No data received.
|
||||||
|
Retrying.
|
||||||
|
|
||||||
|
--2026-06-15 22:44:23-- (try: 3) https://github.com/xiongqi123123/dtop/releases/download/v1.1.0/dtop-arm64-ubuntu22.04.tar.gz
|
||||||
|
Connecting to github.com (github.com)|20.205.243.166|:443... connected.
|
||||||
|
HTTP request sent, awaiting response... No data received.
|
||||||
|
Retrying.
|
||||||
|
|
||||||
|
--2026-06-15 22:45:57-- (try: 4) https://github.com/xiongqi123123/dtop/releases/download/v1.1.0/dtop-arm64-ubuntu22.04.tar.gz
|
||||||
|
Connecting to github.com (github.com)|20.205.243.166|:443... failed: Connection timed out.
|
||||||
|
Resolving github.com (github.com)... 20.205.243.166
|
||||||
|
Connecting to github.com (github.com)|20.205.243.166|:443... failed: Connection timed out.
|
||||||
|
Retrying.
|
||||||
|
|
||||||
|
--2026-06-15 22:50:24-- (try: 5) https://github.com/xiongqi123123/dtop/releases/download/v1.1.0/dtop-arm64-ubuntu22.04.tar.gz
|
||||||
|
Connecting to github.com (github.com)|20.205.243.166|:443... connected.
|
||||||
|
HTTP request sent, awaiting response... 302 Found
|
||||||
|
Location: https://release-assets.githubusercontent.com/github-production-release-asset/1029081525/f827fe4e-a10d-4add-b5e0-0826bb0ab476?sp=r&sv=2018-11-09&sr=b&spr=https&se=2026-06-15T15%3A45%3A59Z&rscd=attachment%3B+filename%3Ddtop-arm64-ubuntu22.04.tar.gz&rsct=application%2Foctet-stream&skoid=96c2d410-5711-43a1-aedd-ab1947aa7ab0&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skt=2026-06-15T14%3A45%3A25Z&ske=2026-06-15T15%3A45%3A59Z&sks=b&skv=2018-11-09&sig=kk4nXxUt6miqrbhECM%2FuKWbFpwRp9VUofTHRECaQVq0%3D&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmVsZWFzZS1hc3NldHMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwia2V5Ijoia2V5MSIsImV4cCI6MTc4MTUzNTMyNSwibmJmIjoxNzgxNTM1MDI1LCJwYXRoIjoicmVsZWFzZWFzc2V0cHJvZHVjdGlvbi5ibG9iLmNvcmUud2luZG93cy5uZXQifQ.utpBoEPybhRRSyqA_PRGkEHpxOA5k0qAXygmA87AjhQ&response-content-disposition=attachment%3B%20filename%3Ddtop-arm64-ubuntu22.04.tar.gz&response-content-type=application%2Foctet-stream [following]
|
||||||
|
--2026-06-15 22:50:25-- https://release-assets.githubusercontent.com/github-production-release-asset/1029081525/f827fe4e-a10d-4add-b5e0-0826bb0ab476?sp=r&sv=2018-11-09&sr=b&spr=https&se=2026-06-15T15%3A45%3A59Z&rscd=attachment%3B+filename%3Ddtop-arm64-ubuntu22.04.tar.gz&rsct=application%2Foctet-stream&skoid=96c2d410-5711-43a1-aedd-ab1947aa7ab0&sktid=398a6654-997b-47e9-b12b-9515b896b4de&skt=2026-06-15T14%3A45%3A25Z&ske=2026-06-15T15%3A45%3A59Z&sks=b&skv=2018-11-09&sig=kk4nXxUt6miqrbhECM%2FuKWbFpwRp9VUofTHRECaQVq0%3D&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmVsZWFzZS1hc3NldHMuZ2l0aHVidXNlcmNvbnRlbnQuY29tIiwia2V5Ijoia2V5MSIsImV4cCI6MTc4MTUzNTMyNSwibmJmIjoxNzgxNTM1MDI1LCJwYXRoIjoicmVsZWFzZWFzc2V0cHJvZHVjdGlvbi5ibG9iLmNvcmUud2luZG93cy5uZXQifQ.utpBoEPybhRRSyqA_PRGkEHpxOA5k0qAXygmA87AjhQ&response-content-disposition=attachment%3B%20filename%3Ddtop-arm64-ubuntu22.04.tar.gz&response-content-type=application%2Foctet-stream
|
||||||
|
Resolving release-assets.githubusercontent.com (release-assets.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.108.133, ...
|
||||||
|
Connecting to release-assets.githubusercontent.com (release-assets.githubusercontent.com)|185.199.109.133|:443... connected.
|
||||||
|
HTTP request sent, awaiting response... 200 OK
|
||||||
|
Length: 529991 (518K) [application/octet-stream]
|
||||||
|
Saving to: ‘dtop-arm64-ubuntu22.04.tar.gz’
|
||||||
|
|
||||||
|
0K .......... .......... .......... .......... .......... 9% 206K 2s
|
||||||
|
50K .......... .......... .......... .......... .......... 19% 258K 2s
|
||||||
|
100K .......... .......... .......... .......... .......... 28% 915K 1s
|
||||||
|
150K .......... .......... .......... .......... .......... 38% 1.11M 1s
|
||||||
|
200K .......... .......... .......... .......... .......... 48% 460K 1s
|
||||||
|
250K .......... .......... .......... .......... .......... 57% 1.48M 0s
|
||||||
|
300K .......... .......... .......... .......... .......... 67% 1.36M 0s
|
||||||
|
350K .......... .......... .......... .......... .......... 77% 1.30M 0s
|
||||||
|
400K .......... .......... .......... .......... .......... 86% 2.84M 0s
|
||||||
|
450K .......... .......... .......... .......... .......... 96% 2.01M 0s
|
||||||
|
500K .......... ....... 100% 390K=0.8s
|
||||||
|
|
||||||
|
2026-06-15 22:50:27 (619 KB/s) - ‘dtop-arm64-ubuntu22.04.tar.gz’ saved [529991/529991]
|
||||||
|
|
||||||
Reference in New Issue
Block a user