2025-07-11 19:42:45 +08:00
|
|
|
#include "host_sdk_sample.h"
|
|
|
|
|
#include "yaml_parser.h"
|
2025-07-23 19:15:59 +08:00
|
|
|
#include "rawCloudRender.h"
|
2025-07-11 19:42:45 +08:00
|
|
|
#include <filesystem>
|
|
|
|
|
#include <thread>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <atomic>
|
2025-07-23 19:15:59 +08:00
|
|
|
#include <mutex>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
|
#include <deque>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/wait.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <chrono>
|
2025-07-11 19:42:45 +08:00
|
|
|
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
#include <ament_index_cpp/get_package_share_directory.hpp>
|
2025-07-23 19:15:59 +08:00
|
|
|
#include <rclcpp/rclcpp.hpp>
|
2025-07-11 19:42:45 +08:00
|
|
|
#else
|
|
|
|
|
#include <ros/package.h>
|
2025-07-23 19:15:59 +08:00
|
|
|
#include <ros/ros.h>
|
2025-07-11 19:42:45 +08:00
|
|
|
#endif
|
|
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
// Global variable declarations
|
2025-07-11 19:42:45 +08:00
|
|
|
static device_handle odinDevice = nullptr;
|
|
|
|
|
static std::atomic<bool> deviceConnected(false);
|
2025-07-23 19:15:59 +08:00
|
|
|
static std::atomic<bool> deviceDisconnected(false); // Device disconnection flag
|
|
|
|
|
static std::mutex device_mutex; // Device operation mutex lock
|
2025-07-11 19:42:45 +08:00
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
#ifdef ROS2
|
|
|
|
|
std::shared_ptr<MultiSensorPublisher> g_ros_object = nullptr;
|
|
|
|
|
#else
|
|
|
|
|
MultiSensorPublisher* g_ros_object = nullptr;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
int g_log_level = LOG_LEVEL_INFO;
|
|
|
|
|
int g_show_fps = 0; // FPS display toggle control
|
|
|
|
|
|
|
|
|
|
static std::mutex g_rgb_mutex;
|
|
|
|
|
static std::shared_ptr<cv::Mat> g_latest_bgr;
|
|
|
|
|
static uint64_t g_latest_rgb_timestamp = 0;
|
|
|
|
|
static bool g_has_rgb = false;
|
|
|
|
|
static capture_Image_List_t g_latest_rgb;
|
|
|
|
|
static bool g_renderer_initialized = false;
|
|
|
|
|
static std::shared_ptr<rawCloudRender> g_renderer = nullptr;
|
|
|
|
|
|
|
|
|
|
// Global configuration variables
|
|
|
|
|
int g_sendrgb = 1;
|
|
|
|
|
int g_sendimu = 1;
|
|
|
|
|
int g_senddtof = 1;
|
|
|
|
|
int g_sendodom = 1;
|
|
|
|
|
int g_sendcloudslam = 0;
|
|
|
|
|
int g_sendcloudrender = 0;
|
|
|
|
|
int g_sendrgb_compressed = 0;
|
|
|
|
|
|
|
|
|
|
// Function declarations
|
|
|
|
|
void clear_all_queues();
|
|
|
|
|
|
|
|
|
|
// Get package share path
|
2025-07-11 19:42:45 +08:00
|
|
|
std::string get_package_share_path(const std::string& package_name) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
try {
|
|
|
|
|
return ament_index_cpp::get_package_share_directory(package_name);
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
throw std::runtime_error("Package not found: " + std::string(e.what()));
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
try {
|
|
|
|
|
return ros::package::getPath(package_name);
|
|
|
|
|
} catch (const ros::InvalidNameException& e) {
|
|
|
|
|
throw std::runtime_error("Package not found: " + std::string(e.what()));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
// Get package path
|
|
|
|
|
std::string get_package_path(const std::string& package_name) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
return ament_index_cpp::get_package_share_directory(package_name);
|
|
|
|
|
#else
|
|
|
|
|
return ros::package::getPath(package_name);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2025-07-11 19:42:45 +08:00
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
// Clear all queues
|
|
|
|
|
void clear_all_queues() {
|
|
|
|
|
// Reset state variables
|
|
|
|
|
g_latest_bgr.reset();
|
|
|
|
|
g_latest_rgb_timestamp = 0;
|
|
|
|
|
g_has_rgb = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Lidar data callback
|
2025-07-11 19:42:45 +08:00
|
|
|
static void lidar_data_callback(const lidar_data_t *data, void *user_data)
|
|
|
|
|
{
|
2025-07-23 19:15:59 +08:00
|
|
|
// If device is not connected, ignore all data
|
|
|
|
|
if (!deviceConnected) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-11 19:42:45 +08:00
|
|
|
device_handle *dev_handle = static_cast<device_handle *>(user_data);
|
|
|
|
|
if(!dev_handle || !data) {
|
|
|
|
|
printf("Invalid device handle or data.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(data->type) {
|
|
|
|
|
case LIDAR_DT_NONE:
|
|
|
|
|
printf("empty lidar data type: %x\n", data->type);
|
|
|
|
|
break;
|
|
|
|
|
case LIDAR_DT_RAW_RGB:
|
|
|
|
|
if (g_sendrgb) {
|
|
|
|
|
g_ros_object->publishRgb((capture_Image_List_t *)&data->stream);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LIDAR_DT_RAW_IMU:
|
|
|
|
|
if (g_sendimu) {
|
|
|
|
|
g_ros_object->publishImu((icm_6aixs_data_t *)data->stream.imageList[0].pAddr);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LIDAR_DT_RAW_DTOF:
|
2025-07-23 19:15:59 +08:00
|
|
|
if (g_senddtof ) {
|
|
|
|
|
g_ros_object->publishIntensityCloud((capture_Image_List_t *)&data->stream, 1);
|
2025-07-11 19:42:45 +08:00
|
|
|
}
|
2025-07-23 19:15:59 +08:00
|
|
|
break;
|
2025-07-11 19:42:45 +08:00
|
|
|
case LIDAR_DT_SLAM_CLOUD:
|
|
|
|
|
if (g_sendcloudslam) {
|
|
|
|
|
g_ros_object->publishPC2XYZRGBA((capture_Image_List_t *)&data->stream, 0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LIDAR_DT_SLAM_ODOMETRY:
|
|
|
|
|
if (g_sendodom) {
|
|
|
|
|
g_ros_object->publishOdometry((capture_Image_List_t *)&data->stream);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
printf("Unknown lidar data type: %x", data->type);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
// Lidar device callback
|
2025-07-11 19:42:45 +08:00
|
|
|
static void lidar_device_callback(const lidar_device_info_t* device, bool attach)
|
|
|
|
|
{
|
|
|
|
|
int type = LIDAR_MODE_SLAM;
|
|
|
|
|
if(attach == true) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_INFO(rclcpp::get_logger("device_cb"), "Device attaching...");
|
|
|
|
|
#else
|
|
|
|
|
ROS_INFO("Device attaching...");
|
|
|
|
|
#endif
|
|
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
// Clean up existing device resources
|
2025-07-11 19:42:45 +08:00
|
|
|
if (odinDevice) {
|
2025-07-23 19:15:59 +08:00
|
|
|
// Skip stopping data stream, unregistering callbacks, closing device, destroying device
|
2025-07-11 19:42:45 +08:00
|
|
|
odinDevice = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
// Create new device
|
2025-07-11 19:42:45 +08:00
|
|
|
if (lidar_create_device(const_cast<lidar_device_info_t*>(device), &odinDevice)) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Create device failed");
|
|
|
|
|
#else
|
|
|
|
|
ROS_ERROR("Create device failed");
|
|
|
|
|
#endif
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-12 21:01:38 +08:00
|
|
|
// Open device
|
2025-07-11 19:42:45 +08:00
|
|
|
if (lidar_open_device(odinDevice)) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Open device failed");
|
|
|
|
|
#else
|
|
|
|
|
ROS_ERROR("Open device failed");
|
|
|
|
|
#endif
|
|
|
|
|
lidar_destory_device(odinDevice);
|
|
|
|
|
odinDevice = nullptr;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
// Get package path
|
|
|
|
|
const std::string package_name = "odin_ros_driver";
|
|
|
|
|
std::string config_dir = "";
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
// Get source code directory (not install directory)
|
|
|
|
|
char* ros_workspace = std::getenv("COLCON_PREFIX_PATH");
|
|
|
|
|
if (ros_workspace) {
|
|
|
|
|
// Infer source directory from COLCON_PREFIX_PATH
|
|
|
|
|
std::string workspace_path(ros_workspace);
|
|
|
|
|
// Remove "/install" part
|
|
|
|
|
size_t pos = workspace_path.find("/install");
|
|
|
|
|
if (pos != std::string::npos) {
|
|
|
|
|
config_dir = workspace_path.substr(0, pos) + "/src/odin_ros_driver/config";
|
|
|
|
|
} else {
|
|
|
|
|
// Fallback to install directory
|
|
|
|
|
config_dir = ament_index_cpp::get_package_share_directory(package_name) + "/config";
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Fallback to install directory
|
|
|
|
|
config_dir = ament_index_cpp::get_package_share_directory(package_name) + "/config";
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
config_dir = ros::package::getPath(package_name) + "/config";
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Print path information
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_INFO(rclcpp::get_logger("device_cb"), "Calibration files will be saved to: %s", config_dir.c_str());
|
|
|
|
|
#else
|
|
|
|
|
ROS_INFO("Calibration files will be saved to: %s", config_dir.c_str());
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Get calibration files - using modified function
|
|
|
|
|
if (lidar_get_calib_file(odinDevice, config_dir.c_str())) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Failed to get calibration file");
|
|
|
|
|
#else
|
|
|
|
|
ROS_ERROR("Failed to get calibration file");
|
|
|
|
|
#endif
|
|
|
|
|
lidar_close_device(odinDevice);
|
|
|
|
|
lidar_destory_device(odinDevice);
|
|
|
|
|
odinDevice = nullptr;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_INFO(rclcpp::get_logger("device_cb"), "Successfully retrieved calibration files");
|
|
|
|
|
#else
|
|
|
|
|
ROS_INFO("Successfully retrieved calibration files");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Move point cloud renderer initialization here
|
|
|
|
|
std::string calib_config = config_dir + "/calib.yaml";
|
|
|
|
|
if (std::filesystem::exists(calib_config)) {
|
|
|
|
|
g_renderer = std::make_shared<rawCloudRender>();
|
|
|
|
|
if (g_renderer->init(calib_config)) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_INFO(rclcpp::get_logger("device_cb"), "Point cloud renderer initialized");
|
|
|
|
|
#else
|
|
|
|
|
ROS_INFO("Point cloud renderer initialized");
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Failed to initialize point cloud renderer");
|
|
|
|
|
#else
|
|
|
|
|
ROS_ERROR("Failed to initialize point cloud renderer");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_WARN(rclcpp::get_logger("device_cb"), "Renderer config file not found: %s", calib_config.c_str());
|
|
|
|
|
#else
|
|
|
|
|
ROS_WARN("Renderer config file not found: %s", calib_config.c_str());
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-11 19:42:45 +08:00
|
|
|
if (lidar_set_mode(odinDevice, type)) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Set mode failed");
|
|
|
|
|
#else
|
|
|
|
|
ROS_ERROR("Set mode failed");
|
|
|
|
|
#endif
|
|
|
|
|
lidar_close_device(odinDevice);
|
|
|
|
|
lidar_destory_device(odinDevice);
|
|
|
|
|
odinDevice = nullptr;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-07-23 19:15:59 +08:00
|
|
|
|
2025-07-12 21:01:38 +08:00
|
|
|
// Register callback
|
2025-07-11 19:42:45 +08:00
|
|
|
lidar_data_callback_info_t data_callback_info;
|
|
|
|
|
data_callback_info.data_callback = lidar_data_callback;
|
|
|
|
|
data_callback_info.user_data = &odinDevice;
|
|
|
|
|
|
|
|
|
|
if (lidar_register_stream_callback(odinDevice, data_callback_info)) {
|
|
|
|
|
#ifdef ROS2
|
2025-07-23 19:15:59 +08:00
|
|
|
RCLCPP_ERROR(rclcpp::get_logger("device"), "Register callback failed");
|
2025-07-11 19:42:45 +08:00
|
|
|
#else
|
|
|
|
|
ROS_ERROR("Register callback failed");
|
|
|
|
|
#endif
|
|
|
|
|
lidar_close_device(odinDevice);
|
|
|
|
|
lidar_destory_device(odinDevice);
|
|
|
|
|
odinDevice = nullptr;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-12 21:01:38 +08:00
|
|
|
// Start data stream
|
2025-07-11 19:42:45 +08:00
|
|
|
if (lidar_start_stream(odinDevice, type)) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_ERROR(rclcpp::get_logger("device_cb"), "Start stream failed");
|
|
|
|
|
#else
|
|
|
|
|
ROS_ERROR("Start stream failed");
|
|
|
|
|
#endif
|
|
|
|
|
lidar_close_device(odinDevice);
|
|
|
|
|
lidar_destory_device(odinDevice);
|
|
|
|
|
odinDevice = nullptr;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-12 21:01:38 +08:00
|
|
|
// Activate stream types based on configuration
|
2025-07-11 19:42:45 +08:00
|
|
|
if (g_sendrgb) {
|
|
|
|
|
lidar_activate_stream_type(odinDevice, LIDAR_DT_RAW_RGB);
|
|
|
|
|
}
|
|
|
|
|
if (g_sendimu) {
|
|
|
|
|
lidar_activate_stream_type(odinDevice, LIDAR_DT_RAW_IMU);
|
|
|
|
|
}
|
|
|
|
|
if (g_sendodom) {
|
|
|
|
|
lidar_activate_stream_type(odinDevice, LIDAR_DT_SLAM_ODOMETRY);
|
|
|
|
|
}
|
|
|
|
|
if (g_senddtof) {
|
|
|
|
|
lidar_activate_stream_type(odinDevice, LIDAR_DT_RAW_DTOF);
|
|
|
|
|
}
|
|
|
|
|
if (g_sendcloudslam) {
|
|
|
|
|
lidar_activate_stream_type(odinDevice, LIDAR_DT_SLAM_CLOUD);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deviceConnected = true;
|
2025-07-23 19:15:59 +08:00
|
|
|
deviceDisconnected = false; // Reset disconnection flag
|
2025-07-11 19:42:45 +08:00
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_INFO(rclcpp::get_logger("device_cb"), "Device ready and streams activated");
|
|
|
|
|
#else
|
|
|
|
|
ROS_INFO("Device ready and streams activated");
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_INFO(rclcpp::get_logger("device_cb"), "Device detaching...");
|
|
|
|
|
#else
|
|
|
|
|
ROS_INFO("Device detaching...");
|
|
|
|
|
#endif
|
2025-07-23 19:15:59 +08:00
|
|
|
|
|
|
|
|
// Set device disconnection flag
|
2025-07-11 19:42:45 +08:00
|
|
|
deviceConnected = false;
|
2025-07-23 19:15:59 +08:00
|
|
|
deviceDisconnected = true;
|
|
|
|
|
|
|
|
|
|
// Clear all message queues
|
|
|
|
|
clear_all_queues();
|
|
|
|
|
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_INFO(rclcpp::get_logger("device_cb"), "Waiting for device reconnection...");
|
|
|
|
|
#else
|
|
|
|
|
ROS_INFO("Waiting for device reconnection...");
|
|
|
|
|
#endif
|
2025-07-11 19:42:45 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
|
{
|
2025-07-23 19:15:59 +08:00
|
|
|
#ifdef ROS2
|
|
|
|
|
rclcpp::init(argc, argv);
|
|
|
|
|
auto node = std::make_shared<rclcpp::Node>("lydros_node");
|
|
|
|
|
g_ros_object = std::make_shared<MultiSensorPublisher>(node);
|
|
|
|
|
#else
|
|
|
|
|
ros::init(argc, argv, "lydros_node");
|
|
|
|
|
ros::NodeHandle nh;
|
|
|
|
|
g_ros_object = new MultiSensorPublisher(nh);
|
|
|
|
|
#endif
|
2025-07-11 19:42:45 +08:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
std::string package_path = get_package_share_path("odin_ros_driver");
|
|
|
|
|
std::string config_file = package_path + "/config/control_command.yaml";
|
|
|
|
|
|
|
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
|
|
|
|
|
odin_ros_driver::YamlParser parser(config_file);
|
2025-07-11 19:42:45 +08:00
|
|
|
if (!parser.loadConfig()) {
|
2025-07-23 19:15:59 +08:00
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_ERROR(node->get_logger(), "Failed to load config file: %s", config_file.c_str());
|
|
|
|
|
#else
|
|
|
|
|
ROS_ERROR("Failed to load config file: %s", config_file.c_str());
|
|
|
|
|
#endif
|
2025-07-11 19:42:45 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2025-07-23 19:15:59 +08:00
|
|
|
|
2025-07-11 19:42:45 +08:00
|
|
|
auto keys = parser.getRegisterKeys();
|
|
|
|
|
parser.printConfig();
|
2025-07-23 19:15:59 +08:00
|
|
|
|
|
|
|
|
auto get_key_value = [&](const std::string& key, int default_value) -> int {
|
|
|
|
|
auto it = keys.find(key);
|
|
|
|
|
return it != keys.end() ? it->second : default_value;
|
2025-07-11 19:42:45 +08:00
|
|
|
};
|
2025-07-23 19:15:59 +08:00
|
|
|
|
|
|
|
|
g_sendrgb = get_key_value("sendrgb", 1);
|
|
|
|
|
g_sendimu = get_key_value("sendimu", 1);
|
|
|
|
|
g_senddtof = get_key_value("senddtof", 1);
|
|
|
|
|
g_sendodom = get_key_value("sendodom", 1);
|
2025-07-11 19:42:45 +08:00
|
|
|
g_sendcloudslam = get_key_value("sendcloudslam", 0);
|
2025-07-23 19:15:59 +08:00
|
|
|
g_sendcloudrender = get_key_value("sendcloudrender", 1);
|
|
|
|
|
g_sendrgb_compressed = get_key_value("sendrgbcompressed", 1);
|
|
|
|
|
g_log_level = get_key_value("log_devel", LOG_LEVEL_INFO);
|
2025-07-11 19:42:45 +08:00
|
|
|
lidar_log_set_level(LIDAR_LOG_INFO);
|
|
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
if (lidar_system_init(lidar_device_callback)) {
|
2025-07-11 19:42:45 +08:00
|
|
|
#ifdef ROS2
|
2025-07-23 19:15:59 +08:00
|
|
|
RCLCPP_ERROR(node->get_logger(), "Lidar system init failed");
|
2025-07-11 19:42:45 +08:00
|
|
|
#else
|
2025-07-23 19:15:59 +08:00
|
|
|
ROS_ERROR("Lidar system init failed");
|
2025-07-11 19:42:45 +08:00
|
|
|
#endif
|
2025-07-23 19:15:59 +08:00
|
|
|
return -1;
|
2025-07-11 19:42:45 +08:00
|
|
|
}
|
2025-07-23 19:15:59 +08:00
|
|
|
|
2025-07-11 19:42:45 +08:00
|
|
|
#ifdef ROS2
|
2025-07-23 19:15:59 +08:00
|
|
|
RCLCPP_INFO(node->get_logger(), "Waiting for device connection...");
|
2025-07-11 19:42:45 +08:00
|
|
|
#else
|
2025-07-23 19:15:59 +08:00
|
|
|
ROS_INFO("Waiting for device connection...");
|
2025-07-11 19:42:45 +08:00
|
|
|
#endif
|
2025-07-23 19:15:59 +08:00
|
|
|
|
|
|
|
|
// Wait indefinitely for device connection
|
2025-07-11 19:42:45 +08:00
|
|
|
while (!deviceConnected) {
|
|
|
|
|
#ifdef ROS2
|
2025-07-23 19:15:59 +08:00
|
|
|
RCLCPP_INFO(node->get_logger(), "Waiting for device connection...");
|
2025-07-11 19:42:45 +08:00
|
|
|
#else
|
2025-07-23 19:15:59 +08:00
|
|
|
ROS_INFO("Waiting for device connection...");
|
2025-07-11 19:42:45 +08:00
|
|
|
#endif
|
2025-07-23 19:15:59 +08:00
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1)); // Check every second
|
2025-07-11 19:42:45 +08:00
|
|
|
}
|
2025-07-23 19:15:59 +08:00
|
|
|
|
2025-07-11 19:42:45 +08:00
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
#ifdef ROS2
|
2025-07-23 19:15:59 +08:00
|
|
|
RCLCPP_ERROR(node->get_logger(), "Exception: %s", e.what());
|
2025-07-11 19:42:45 +08:00
|
|
|
#else
|
2025-07-23 19:15:59 +08:00
|
|
|
ROS_ERROR("Exception: %s", e.what());
|
2025-07-11 19:42:45 +08:00
|
|
|
#endif
|
2025-07-23 19:15:59 +08:00
|
|
|
lidar_system_deinit();
|
|
|
|
|
return -1;
|
2025-07-11 19:42:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef ROS2
|
2025-07-23 19:15:59 +08:00
|
|
|
// Create 10Hz Rate object
|
|
|
|
|
rclcpp::Rate rate(10);
|
|
|
|
|
while (rclcpp::ok()) {
|
|
|
|
|
rclcpp::spin_some(node);
|
|
|
|
|
|
|
|
|
|
// Check device disconnection status
|
|
|
|
|
if (deviceDisconnected.load()) {
|
|
|
|
|
#ifdef ROS2
|
|
|
|
|
RCLCPP_INFO(node->get_logger(), "Device disconnected, waiting for reconnection...");
|
|
|
|
|
#else
|
|
|
|
|
ROS_INFO("Device disconnected, waiting for reconnection...");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Wait 0.1 seconds
|
|
|
|
|
rate.sleep();
|
|
|
|
|
continue; // Skip rest of this loop iteration
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Data processing when device is connected
|
|
|
|
|
if (g_sendcloudrender) {
|
|
|
|
|
g_ros_object->try_process_pair();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wait 0.1 seconds
|
|
|
|
|
rate.sleep();
|
|
|
|
|
}
|
2025-07-11 19:42:45 +08:00
|
|
|
rclcpp::shutdown();
|
|
|
|
|
#else
|
2025-07-23 19:15:59 +08:00
|
|
|
// Create 10Hz Rate object
|
|
|
|
|
ros::Rate rate(10);
|
|
|
|
|
while (ros::ok()) {
|
|
|
|
|
ros::spinOnce();
|
|
|
|
|
|
|
|
|
|
// Check device disconnection status
|
|
|
|
|
if (deviceDisconnected.load()) {
|
|
|
|
|
ROS_INFO("Device disconnected, waiting for reconnection...");
|
|
|
|
|
|
|
|
|
|
// Wait 0.1 seconds
|
|
|
|
|
rate.sleep();
|
|
|
|
|
continue; // Skip rest of this loop iteration
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Data processing when device is connected
|
|
|
|
|
if (g_sendcloudrender) {
|
|
|
|
|
g_ros_object->try_process_pair();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wait 0.1 seconds
|
|
|
|
|
rate.sleep();
|
|
|
|
|
}
|
2025-07-11 19:42:45 +08:00
|
|
|
ros::shutdown();
|
|
|
|
|
#endif
|
|
|
|
|
|
2025-07-23 19:15:59 +08:00
|
|
|
// Cleanup on normal program exit
|
2025-07-11 19:42:45 +08:00
|
|
|
if (odinDevice) {
|
2025-07-23 19:15:59 +08:00
|
|
|
// Perform cleanup on normal exit
|
2025-07-11 19:42:45 +08:00
|
|
|
lidar_stop_stream(odinDevice, LIDAR_MODE_SLAM);
|
|
|
|
|
lidar_unregister_stream_callback(odinDevice);
|
|
|
|
|
lidar_close_device(odinDevice);
|
|
|
|
|
lidar_destory_device(odinDevice);
|
|
|
|
|
}
|
|
|
|
|
lidar_system_deinit();
|
2025-07-23 19:15:59 +08:00
|
|
|
|
2025-07-11 19:42:45 +08:00
|
|
|
return 0;
|
2025-07-23 19:15:59 +08:00
|
|
|
}
|