update
This commit is contained in:
parent
c8dddfb394
commit
8f0f859f48
|
|
@ -8,9 +8,10 @@ find_package(ament_cmake REQUIRED)
|
||||||
find_package(rclcpp REQUIRED)
|
find_package(rclcpp REQUIRED)
|
||||||
find_package(sensor_msgs REQUIRED)
|
find_package(sensor_msgs REQUIRED)
|
||||||
find_package(image_transport REQUIRED)
|
find_package(image_transport REQUIRED)
|
||||||
|
find_package(pluginlib REQUIRED)
|
||||||
|
|
||||||
add_executable(adapter src/adapter.cpp)
|
add_executable(adapter src/adapter.cpp)
|
||||||
ament_target_dependencies(adapter rclcpp sensor_msgs image_transport)
|
ament_target_dependencies(adapter rclcpp sensor_msgs image_transport pluginlib)
|
||||||
install(TARGETS adapter DESTINATION lib/${PROJECT_NAME})
|
install(TARGETS adapter DESTINATION lib/${PROJECT_NAME})
|
||||||
install(DIRECTORY launch DESTINATION share/${PROJECT_NAME})
|
install(DIRECTORY launch DESTINATION share/${PROJECT_NAME})
|
||||||
install(FILES README.md DESTINATION share/${PROJECT_NAME})
|
install(FILES README.md DESTINATION share/${PROJECT_NAME})
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ YAML 配置文件。节点自动发现 `sensor_msgs/msg/Image` 和
|
||||||
|
|
||||||
## 输出
|
## 输出
|
||||||
|
|
||||||
- RGB:通过 `image_transport` 发布 base topic `/viz/<source>/rgb`。
|
- RGB:直接加载 `image_transport/compressed_pub`,只发布其
|
||||||
安装 `compressed_image_transport` 后,平台订阅其 `/compressed` 传输。
|
`/viz/<source>/rgb/compressed` 传输 topic,不创建 raw base topic。
|
||||||
- 深度:通过 `image_transport` 发布 base topic `/viz/<source>/depth`。
|
- 深度:直接加载 `image_transport/compressedDepth_pub`,只发布其
|
||||||
安装 `compressed_depth_image_transport` 后,平台订阅其 `/compressedDepth`。
|
`/viz/<source>/depth/compressedDepth` 传输 topic,不创建 raw base topic。
|
||||||
- 点云:`/viz/<source>/points`,消息仍为 `sensor_msgs/msg/PointCloud2`,但只保留
|
- 点云:`/viz/<source>/points`,消息仍为 `sensor_msgs/msg/PointCloud2`,但只保留
|
||||||
`x/y/z`,去除 NaN,执行体素降采样、最大点数限制和限频。
|
`x/y/z`,去除 NaN,执行体素降采样、最大点数限制和限频。
|
||||||
|
|
||||||
|
|
@ -20,6 +20,7 @@ YAML 配置文件。节点自动发现 `sensor_msgs/msg/Image` 和
|
||||||
## 运行
|
## 运行
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
colcon build --packages-select ros_viz_adapter --symlink-install
|
||||||
ros2 launch ros_viz_adapter adapter.launch.py
|
ros2 launch ros_viz_adapter adapter.launch.py
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -29,6 +30,7 @@ ros2 launch ros_viz_adapter adapter.launch.py
|
||||||
output_namespace 默认 /viz
|
output_namespace 默认 /viz
|
||||||
input_fps_limit 默认 30,回调入口丢弃超频帧
|
input_fps_limit 默认 30,回调入口丢弃超频帧
|
||||||
output_fps 默认 10,处理线程输出上限
|
output_fps 默认 10,处理线程输出上限
|
||||||
|
jpeg_quality 默认 80,范围 1-100
|
||||||
voxel_size_m 默认 0.05
|
voxel_size_m 默认 0.05
|
||||||
max_points 默认 100000
|
max_points 默认 100000
|
||||||
```
|
```
|
||||||
|
|
@ -77,7 +79,9 @@ ros2 run ros_viz_adapter adapter
|
||||||
### 独立 ROS 容器或 sidecar
|
### 独立 ROS 容器或 sidecar
|
||||||
|
|
||||||
适配器容器与用户容器必须使用相同的 `ROS_DOMAIN_ID`、`RMW_IMPLEMENTATION` 和可互相发现的
|
适配器容器与用户容器必须使用相同的 `ROS_DOMAIN_ID`、`RMW_IMPLEMENTATION` 和可互相发现的
|
||||||
ROS 2 网络。适配器容器只需安装本包及 image_transport 压缩插件,不需要复制用户项目代码。
|
ROS 2 网络。适配器容器只需安装本包、`compressed_image_transport` 和
|
||||||
|
`compressed_depth_image_transport`,不需要复制用户项目代码。代码只加载上述两个
|
||||||
|
指定插件,不遍历或加载 Theora 插件。
|
||||||
|
|
||||||
### 多容器隔离
|
### 多容器隔离
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
<depend>rclcpp</depend>
|
<depend>rclcpp</depend>
|
||||||
<depend>sensor_msgs</depend>
|
<depend>sensor_msgs</depend>
|
||||||
<depend>image_transport</depend>
|
<depend>image_transport</depend>
|
||||||
|
<depend>pluginlib</depend>
|
||||||
<exec_depend>compressed_image_transport</exec_depend>
|
<exec_depend>compressed_image_transport</exec_depend>
|
||||||
<exec_depend>compressed_depth_image_transport</exec_depend>
|
<exec_depend>compressed_depth_image_transport</exec_depend>
|
||||||
<export><build_type>ament_cmake</build_type></export>
|
<export><build_type>ament_cmake</build_type></export>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "image_transport/image_transport.hpp"
|
#include "image_transport/publisher_plugin.hpp"
|
||||||
|
#include "pluginlib/class_loader.hpp"
|
||||||
#include "rclcpp/rclcpp.hpp"
|
#include "rclcpp/rclcpp.hpp"
|
||||||
#include "sensor_msgs/msg/image.hpp"
|
#include "sensor_msgs/msg/image.hpp"
|
||||||
#include "sensor_msgs/msg/point_cloud2.hpp"
|
#include "sensor_msgs/msg/point_cloud2.hpp"
|
||||||
|
|
@ -103,8 +104,8 @@ private:
|
||||||
wake_.notify_all();
|
wake_.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string base(const std::string & topic, bool depth) const {
|
std::string image_topic(const std::string & topic, bool depth) const {
|
||||||
return (output_ns_.empty() ? "/viz" : output_ns_) + "/" + safe_name(topic) + (depth ? "/depth" : "/rgb");
|
return (output_ns_.empty() ? "/viz" : output_ns_) + "/" + safe_name(topic) + (depth ? "/depth/compressedDepth" : "/rgb/compressed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void image_loop(std::unordered_map<std::string, Image::ConstSharedPtr> & slots, bool depth) {
|
void image_loop(std::unordered_map<std::string, Image::ConstSharedPtr> & slots, bool depth) {
|
||||||
|
|
@ -121,10 +122,17 @@ private:
|
||||||
std::lock_guard<std::mutex> lock(pub_mutex_);
|
std::lock_guard<std::mutex> lock(pub_mutex_);
|
||||||
auto it = image_publishers_.find(key);
|
auto it = image_publishers_.find(key);
|
||||||
if (it == image_publishers_.end()) {
|
if (it == image_publishers_.end()) {
|
||||||
auto pub = image_transport::create_publisher(this, base(item.first, depth), qos_.get_rmw_qos_profile());
|
const auto lookup = depth ? "image_transport/compressedDepth_pub" : "image_transport/compressed_pub";
|
||||||
it = image_publishers_.emplace(key, std::move(pub)).first;
|
try {
|
||||||
|
auto plugin = image_loader_->createSharedInstance(lookup);
|
||||||
|
plugin->advertise(this, image_topic(item.first, depth), qos_.get_rmw_qos_profile());
|
||||||
|
it = image_publishers_.emplace(key, std::move(plugin)).first;
|
||||||
|
} catch (const pluginlib::PluginlibException & ex) {
|
||||||
|
RCLCPP_ERROR(get_logger(), "Cannot load image_transport plugin %s: %s", lookup, ex.what());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
it->second.publish(item.second);
|
it->second->publishPtr(item.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -175,13 +183,15 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string output_ns_; double input_fps_{30.0}, output_fps_{10.0}, voxel_{0.05}; int max_points_{100000};
|
std::string output_ns_; double input_fps_{30.0}, output_fps_{10.0}, voxel_{0.05}; int max_points_{100000};
|
||||||
|
std::shared_ptr<pluginlib::ClassLoader<image_transport::PublisherPlugin>> image_loader_{
|
||||||
|
std::make_shared<pluginlib::ClassLoader<image_transport::PublisherPlugin>>("image_transport", "image_transport::PublisherPlugin")};
|
||||||
rclcpp::QoS qos_{rclcpp::SensorDataQoS()}; rclcpp::TimerBase::SharedPtr timer_;
|
rclcpp::QoS qos_{rclcpp::SensorDataQoS()}; rclcpp::TimerBase::SharedPtr timer_;
|
||||||
std::atomic_bool stop_{false}; std::mutex data_mutex_, rate_mutex_, pub_mutex_; std::condition_variable wake_;
|
std::atomic_bool stop_{false}; std::mutex data_mutex_, rate_mutex_, pub_mutex_; std::condition_variable wake_;
|
||||||
std::thread rgb_thread_, depth_thread_, cloud_thread_;
|
std::thread rgb_thread_, depth_thread_, cloud_thread_;
|
||||||
std::unordered_map<std::string, rclcpp::Subscription<Image>::SharedPtr> subscriptions_; std::unordered_map<std::string, rclcpp::Subscription<PointCloud2>::SharedPtr> cloud_subscriptions_;
|
std::unordered_map<std::string, rclcpp::Subscription<Image>::SharedPtr> subscriptions_; std::unordered_map<std::string, rclcpp::Subscription<PointCloud2>::SharedPtr> cloud_subscriptions_;
|
||||||
std::unordered_map<std::string, Image::ConstSharedPtr> rgb_latest_, depth_latest_; std::unordered_map<std::string, PointCloud2::ConstSharedPtr> cloud_latest_;
|
std::unordered_map<std::string, Image::ConstSharedPtr> rgb_latest_, depth_latest_; std::unordered_map<std::string, PointCloud2::ConstSharedPtr> cloud_latest_;
|
||||||
std::unordered_map<std::string, std::chrono::steady_clock::time_point> input_times_, output_times_;
|
std::unordered_map<std::string, std::chrono::steady_clock::time_point> input_times_, output_times_;
|
||||||
std::unordered_map<std::string, image_transport::Publisher> image_publishers_; std::unordered_map<std::string, rclcpp::Publisher<PointCloud2>::SharedPtr> cloud_publishers_;
|
std::unordered_map<std::string, std::shared_ptr<image_transport::PublisherPlugin>> image_publishers_; std::unordered_map<std::string, rclcpp::Publisher<PointCloud2>::SharedPtr> cloud_publishers_;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char ** argv) { rclcpp::init(argc, argv); auto node = std::make_shared<Adapter>(); rclcpp::spin(node); rclcpp::shutdown(); return 0; }
|
int main(int argc, char ** argv) { rclcpp::init(argc, argv); auto node = std::make_shared<Adapter>(); rclcpp::spin(node); rclcpp::shutdown(); return 0; }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue