2023-09-08 08:55:16 +08:00
|
|
|
/*******************************************************************************
|
2023-09-12 11:12:40 +08:00
|
|
|
* Copyright (c) 2023 Orbbec 3D Technology, 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.
|
|
|
|
|
*******************************************************************************/
|
2022-06-08 14:51:00 +08:00
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
#include "orbbec_camera/ob_camera_node_driver.h"
|
2022-12-28 13:55:26 +08:00
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <semaphore.h>
|
|
|
|
|
#include <sys/shm.h>
|
2023-03-22 16:10:22 +08:00
|
|
|
#include <ament_index_cpp/get_package_share_directory.hpp>
|
2023-08-22 21:11:59 +08:00
|
|
|
#include <rclcpp_components/register_node_macro.hpp>
|
2023-09-05 17:59:19 +08:00
|
|
|
#include <csignal>
|
2023-09-15 10:30:23 +08:00
|
|
|
#include <sys/mman.h>
|
2022-12-28 13:55:26 +08:00
|
|
|
|
2022-06-06 19:00:12 +08:00
|
|
|
namespace orbbec_camera {
|
2023-02-20 09:39:44 +08:00
|
|
|
OBCameraNodeDriver::OBCameraNodeDriver(const rclcpp::NodeOptions &node_options)
|
2022-06-06 19:00:12 +08:00
|
|
|
: Node("orbbec_camera_node", "/", node_options),
|
2023-03-22 16:10:22 +08:00
|
|
|
config_path_(ament_index_cpp::get_package_share_directory("orbbec_camera") +
|
|
|
|
|
"/config/OrbbecSDKConfig_v1.0.xml"),
|
|
|
|
|
ctx_(std::make_unique<ob::Context>(config_path_.c_str())),
|
2022-06-06 19:00:12 +08:00
|
|
|
logger_(this->get_logger()) {
|
|
|
|
|
init();
|
|
|
|
|
}
|
2023-02-06 17:26:10 +08:00
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
OBCameraNodeDriver::OBCameraNodeDriver(const std::string &node_name, const std::string &ns,
|
|
|
|
|
const rclcpp::NodeOptions &node_options)
|
2022-06-06 19:00:12 +08:00
|
|
|
: Node(node_name, ns, node_options),
|
|
|
|
|
ctx_(std::make_unique<ob::Context>()),
|
|
|
|
|
logger_(this->get_logger()) {
|
|
|
|
|
init();
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
OBCameraNodeDriver::~OBCameraNodeDriver() {
|
2022-06-06 19:00:12 +08:00
|
|
|
is_alive_.store(false);
|
2023-02-20 09:39:44 +08:00
|
|
|
if (device_count_update_thread_ && device_count_update_thread_->joinable()) {
|
|
|
|
|
device_count_update_thread_->join();
|
|
|
|
|
}
|
2023-07-05 15:00:34 +08:00
|
|
|
if (sync_time_thread_ && sync_time_thread_->joinable()) {
|
|
|
|
|
sync_time_thread_->join();
|
|
|
|
|
}
|
2022-12-28 13:55:26 +08:00
|
|
|
if (query_thread_ && query_thread_->joinable()) {
|
|
|
|
|
query_thread_->join();
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
2023-07-13 17:15:48 +08:00
|
|
|
if (reset_device_thread_ && reset_device_thread_->joinable()) {
|
|
|
|
|
reset_device_cond_.notify_all();
|
|
|
|
|
reset_device_thread_->join();
|
|
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
2022-10-10 18:04:09 +08:00
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
void OBCameraNodeDriver::init() {
|
2023-02-06 17:26:10 +08:00
|
|
|
auto log_level_str = declare_parameter<std::string>("log_level", "none");
|
2024-04-02 20:56:56 +08:00
|
|
|
connection_delay_ = declare_parameter<int>("connection_delay", 100);
|
2023-02-06 17:26:10 +08:00
|
|
|
auto log_level = obLogSeverityFromString(log_level_str);
|
|
|
|
|
ob::Context::setLoggerSeverity(log_level);
|
2023-09-15 10:30:23 +08:00
|
|
|
orb_device_lock_shm_fd_ = shm_open(ORB_DEFAULT_LOCK_NAME.c_str(), O_CREAT | O_RDWR, 0666);
|
|
|
|
|
if (orb_device_lock_shm_fd_ < 0) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to open shared memory " << ORB_DEFAULT_LOCK_NAME);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int ret = ftruncate(orb_device_lock_shm_fd_, sizeof(pthread_mutex_t));
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to truncate shared memory " << ORB_DEFAULT_LOCK_NAME);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
orb_device_lock_shm_addr_ =
|
|
|
|
|
static_cast<uint8_t *>(mmap(NULL, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED,
|
|
|
|
|
orb_device_lock_shm_fd_, 0));
|
|
|
|
|
if (orb_device_lock_shm_addr_ == MAP_FAILED) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to map shared memory " << ORB_DEFAULT_LOCK_NAME);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutexattr_init(&orb_device_lock_attr_);
|
|
|
|
|
pthread_mutexattr_setpshared(&orb_device_lock_attr_, PTHREAD_PROCESS_SHARED);
|
|
|
|
|
orb_device_lock_ = (pthread_mutex_t *)orb_device_lock_shm_addr_;
|
|
|
|
|
pthread_mutex_init(orb_device_lock_, &orb_device_lock_attr_);
|
2022-06-06 19:00:12 +08:00
|
|
|
is_alive_.store(true);
|
2022-06-08 14:51:00 +08:00
|
|
|
parameters_ = std::make_shared<Parameters>(this);
|
2022-06-08 13:41:31 +08:00
|
|
|
serial_number_ = declare_parameter<std::string>("serial_number", "");
|
2023-02-17 22:25:24 +08:00
|
|
|
device_num_ = static_cast<int>(declare_parameter<int>("device_num", 1));
|
2023-07-05 17:50:44 +08:00
|
|
|
usb_port_ = declare_parameter<std::string>("usb_port", "");
|
2024-03-04 14:56:54 +08:00
|
|
|
net_device_ip_ = declare_parameter<std::string>("net_device_ip", "");
|
|
|
|
|
net_device_port_ = static_cast<int>(declare_parameter<int>("net_device_port", 0));
|
|
|
|
|
enumerate_net_device_ = declare_parameter<bool>("enumerate_net_device", false);
|
2023-10-11 17:12:24 +08:00
|
|
|
ctx_->enableNetDeviceEnumeration(enumerate_net_device_);
|
2023-07-05 15:00:34 +08:00
|
|
|
ctx_->setDeviceChangedCallback([this](const std::shared_ptr<ob::DeviceList> &removed_list,
|
|
|
|
|
const std::shared_ptr<ob::DeviceList> &added_list) {
|
2023-10-14 18:28:16 +08:00
|
|
|
onDeviceConnected(added_list);
|
2023-02-06 17:26:10 +08:00
|
|
|
onDeviceDisconnected(removed_list);
|
2022-06-06 19:00:12 +08:00
|
|
|
});
|
2022-12-28 17:11:30 +08:00
|
|
|
check_connect_timer_ =
|
|
|
|
|
this->create_wall_timer(std::chrono::milliseconds(1000), [this]() { checkConnectTimer(); });
|
2023-02-06 17:26:10 +08:00
|
|
|
CHECK_NOTNULL(check_connect_timer_);
|
2022-12-28 13:55:26 +08:00
|
|
|
query_thread_ = std::make_shared<std::thread>([this]() { queryDevice(); });
|
2023-07-05 15:00:34 +08:00
|
|
|
sync_time_thread_ = std::make_shared<std::thread>([this]() { syncTime(); });
|
2023-07-13 17:15:48 +08:00
|
|
|
reset_device_thread_ = std::make_shared<std::thread>([this]() { resetDevice(); });
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
void OBCameraNodeDriver::onDeviceConnected(const std::shared_ptr<ob::DeviceList> &device_list) {
|
2023-02-06 17:40:01 +08:00
|
|
|
CHECK_NOTNULL(device_list);
|
2022-06-08 13:41:31 +08:00
|
|
|
if (device_list->deviceCount() == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
if (!device_) {
|
2023-10-12 20:52:10 +08:00
|
|
|
startDevice(device_list);
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
void OBCameraNodeDriver::onDeviceDisconnected(const std::shared_ptr<ob::DeviceList> &device_list) {
|
2023-02-06 17:40:01 +08:00
|
|
|
CHECK_NOTNULL(device_list);
|
2022-06-08 13:41:31 +08:00
|
|
|
if (device_list->deviceCount() == 0) {
|
|
|
|
|
return;
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
2023-02-06 17:26:10 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "onDeviceDisconnected");
|
2022-12-28 13:55:26 +08:00
|
|
|
for (size_t i = 0; i < device_list->deviceCount(); i++) {
|
2023-02-15 19:50:30 +08:00
|
|
|
std::string uid = device_list->uid(i);
|
2023-10-14 18:28:16 +08:00
|
|
|
std::string serial_number = device_list->serialNumber(i);
|
|
|
|
|
std::lock_guard<decltype(device_lock_)> lock(device_lock_);
|
2023-02-15 21:20:02 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "device with " << uid << " disconnected");
|
2023-10-14 18:28:16 +08:00
|
|
|
if (uid == device_unique_id_ || serial_number_ == serial_number) {
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_,
|
|
|
|
|
"device with " << uid << " disconnected, notify reset device thread.");
|
2023-07-13 17:15:48 +08:00
|
|
|
std::unique_lock<decltype(reset_device_mutex_)> reset_device_lock(reset_device_mutex_);
|
|
|
|
|
reset_device_flag_ = true;
|
|
|
|
|
reset_device_cond_.notify_all();
|
2022-12-28 13:55:26 +08:00
|
|
|
break;
|
2022-06-08 15:33:16 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-08 13:41:31 +08:00
|
|
|
}
|
|
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
OBLogSeverity OBCameraNodeDriver::obLogSeverityFromString(const std::string_view &log_level) {
|
2022-10-10 18:04:09 +08:00
|
|
|
if (log_level == "debug") {
|
|
|
|
|
return OBLogSeverity::OB_LOG_SEVERITY_DEBUG;
|
|
|
|
|
} else if (log_level == "info") {
|
|
|
|
|
return OBLogSeverity::OB_LOG_SEVERITY_INFO;
|
|
|
|
|
} else if (log_level == "warn") {
|
|
|
|
|
return OBLogSeverity::OB_LOG_SEVERITY_WARN;
|
|
|
|
|
} else if (log_level == "error") {
|
|
|
|
|
return OBLogSeverity::OB_LOG_SEVERITY_ERROR;
|
|
|
|
|
} else if (log_level == "fatal") {
|
|
|
|
|
return OBLogSeverity::OB_LOG_SEVERITY_FATAL;
|
|
|
|
|
} else {
|
2022-12-28 17:11:30 +08:00
|
|
|
return OBLogSeverity::OB_LOG_SEVERITY_NONE;
|
2022-10-10 18:04:09 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-12-28 13:55:26 +08:00
|
|
|
|
2023-03-01 22:01:08 +08:00
|
|
|
void OBCameraNodeDriver::checkConnectTimer() {
|
2023-02-06 17:26:10 +08:00
|
|
|
if (!device_connected_.load()) {
|
2023-09-11 17:57:02 +08:00
|
|
|
RCLCPP_DEBUG_STREAM(logger_,
|
2023-02-15 21:20:02 +08:00
|
|
|
"checkConnectTimer: device " << serial_number_ << " not connected");
|
2022-12-28 17:11:30 +08:00
|
|
|
return;
|
2023-03-01 22:01:08 +08:00
|
|
|
} else if (!ob_camera_node_) {
|
|
|
|
|
device_connected_.store(false);
|
2022-12-28 17:11:30 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-02-06 17:26:10 +08:00
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
void OBCameraNodeDriver::queryDevice() {
|
2024-04-02 20:58:29 +08:00
|
|
|
while (rclcpp::ok() && is_alive_ && !device_connected_.load()) {
|
2024-03-04 14:56:54 +08:00
|
|
|
if (!net_device_ip_.empty() && net_device_port_ != 0) {
|
|
|
|
|
connectNetDevice(net_device_ip_, net_device_port_);
|
|
|
|
|
} else {
|
|
|
|
|
auto device_list = ctx_->queryDeviceList();
|
|
|
|
|
if (device_list->deviceCount() == 0) {
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "queryDevice : No device found");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
startDevice(device_list);
|
2022-12-28 13:55:26 +08:00
|
|
|
}
|
2024-04-02 20:56:56 +08:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
2022-12-28 13:55:26 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-05 15:00:34 +08:00
|
|
|
void OBCameraNodeDriver::syncTime() {
|
|
|
|
|
while (is_alive_ && rclcpp::ok()) {
|
2023-07-20 10:50:40 +08:00
|
|
|
if (device_ && device_info_ && !isOpenNIDevice(device_info_->pid())) {
|
2023-09-05 17:59:19 +08:00
|
|
|
ctx_->enableDeviceClockSync(0);
|
2023-07-20 10:50:40 +08:00
|
|
|
}
|
2023-07-05 15:00:34 +08:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-13 17:15:48 +08:00
|
|
|
void OBCameraNodeDriver::resetDevice() {
|
|
|
|
|
while (is_alive_ && rclcpp::ok()) {
|
|
|
|
|
std::unique_lock<decltype(reset_device_mutex_)> lock(reset_device_mutex_);
|
|
|
|
|
reset_device_cond_.wait(lock,
|
2023-10-12 20:52:10 +08:00
|
|
|
[this]() { return !is_alive_ || !rclcpp::ok() || reset_device_flag_; });
|
2023-07-13 17:15:48 +08:00
|
|
|
if (!is_alive_ || !rclcpp::ok()) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-10-14 18:28:16 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "resetDevice : Reset device uid: " << device_unique_id_);
|
|
|
|
|
std::lock_guard<decltype(device_lock_)> device_lock(device_lock_);
|
|
|
|
|
{
|
|
|
|
|
ob_camera_node_.reset();
|
|
|
|
|
device_.reset();
|
|
|
|
|
device_info_.reset();
|
|
|
|
|
device_connected_ = false;
|
|
|
|
|
device_unique_id_.clear();
|
|
|
|
|
serial_number_.clear();
|
|
|
|
|
reset_device_flag_ = false;
|
|
|
|
|
}
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "Reset device uid: " << device_unique_id_ << " done");
|
2023-07-13 17:15:48 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-02-17 20:18:55 +08:00
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
std::shared_ptr<ob::Device> OBCameraNodeDriver::selectDevice(
|
2023-02-17 20:18:55 +08:00
|
|
|
const std::shared_ptr<ob::DeviceList> &list) {
|
2023-02-06 17:26:10 +08:00
|
|
|
if (device_num_ == 1) {
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "Connecting to the default device");
|
2023-02-17 20:18:55 +08:00
|
|
|
return list->getDevice(0);
|
|
|
|
|
}
|
2023-09-15 10:30:23 +08:00
|
|
|
|
2023-07-05 15:00:34 +08:00
|
|
|
std::shared_ptr<ob::Device> device = nullptr;
|
|
|
|
|
if (!serial_number_.empty()) {
|
2023-10-14 18:28:16 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "Connecting to device with serial number: " << serial_number_);
|
2023-07-05 15:00:34 +08:00
|
|
|
device = selectDeviceBySerialNumber(list, serial_number_);
|
|
|
|
|
} else if (!usb_port_.empty()) {
|
2023-10-14 18:28:16 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "Connecting to device with usb port: " << usb_port_);
|
2023-07-05 15:00:34 +08:00
|
|
|
device = selectDeviceByUSBPort(list, usb_port_);
|
|
|
|
|
}
|
2023-02-17 20:18:55 +08:00
|
|
|
if (device == nullptr) {
|
2023-02-17 22:25:24 +08:00
|
|
|
RCLCPP_WARN_THROTTLE(logger_, *get_clock(), 1000, "Device with serial number %s not found",
|
|
|
|
|
serial_number_.c_str());
|
2023-02-17 20:18:55 +08:00
|
|
|
device_connected_ = false;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return device;
|
|
|
|
|
}
|
2023-02-16 16:14:38 +08:00
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
std::shared_ptr<ob::Device> OBCameraNodeDriver::selectDeviceBySerialNumber(
|
2023-02-17 20:18:55 +08:00
|
|
|
const std::shared_ptr<ob::DeviceList> &list, const std::string &serial_number) {
|
|
|
|
|
std::string lower_sn;
|
|
|
|
|
std::transform(serial_number.begin(), serial_number.end(), std::back_inserter(lower_sn),
|
|
|
|
|
[](auto ch) { return isalpha(ch) ? tolower(ch) : static_cast<int>(ch); });
|
|
|
|
|
for (size_t i = 0; i < list->deviceCount(); i++) {
|
2023-10-14 18:34:54 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "Before lock: Select device serial number: " << serial_number);
|
|
|
|
|
std::lock_guard<decltype(device_lock_)> lock(device_lock_);
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "After lock: Select device serial number: " << serial_number);
|
2023-02-17 20:18:55 +08:00
|
|
|
try {
|
|
|
|
|
auto pid = list->pid(i);
|
2023-03-02 20:15:01 +08:00
|
|
|
if (isOpenNIDevice(pid)) {
|
2023-02-17 20:18:55 +08:00
|
|
|
// openNI device
|
|
|
|
|
auto device = list->getDevice(i);
|
|
|
|
|
auto device_info = device->getDeviceInfo();
|
|
|
|
|
if (device_info->serialNumber() == serial_number) {
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_,
|
|
|
|
|
"Device serial number " << device_info->serialNumber() << " matched");
|
|
|
|
|
return device;
|
2023-02-15 15:05:47 +08:00
|
|
|
}
|
2022-12-28 13:55:26 +08:00
|
|
|
} else {
|
2023-02-17 20:18:55 +08:00
|
|
|
std::string sn = list->serialNumber(i);
|
2023-02-17 22:25:24 +08:00
|
|
|
RCLCPP_INFO_STREAM_THROTTLE(logger_, *get_clock(), 1000, "Device serial number: " << sn);
|
2023-02-17 20:18:55 +08:00
|
|
|
if (sn == serial_number) {
|
2023-03-02 20:15:01 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "Device serial number " << sn << " matched");
|
2023-02-17 20:18:55 +08:00
|
|
|
return list->getDevice(i);
|
2022-12-28 13:55:26 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-02-17 20:18:55 +08:00
|
|
|
} catch (ob::Error &e) {
|
2023-02-17 22:25:24 +08:00
|
|
|
RCLCPP_ERROR_STREAM_THROTTLE(logger_, *get_clock(), 1000,
|
|
|
|
|
"Failed to get device info " << e.getMessage());
|
2023-02-17 20:18:55 +08:00
|
|
|
} catch (std::exception &e) {
|
2023-02-17 22:25:24 +08:00
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to get device info " << e.what());
|
2023-02-17 20:18:55 +08:00
|
|
|
} catch (...) {
|
2023-02-17 22:25:24 +08:00
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to get device info");
|
2022-12-28 13:55:26 +08:00
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
2023-02-17 20:18:55 +08:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-05 15:00:34 +08:00
|
|
|
std::shared_ptr<ob::Device> OBCameraNodeDriver::selectDeviceByUSBPort(
|
|
|
|
|
const std::shared_ptr<ob::DeviceList> &list, const std::string &usb_port) {
|
2023-09-15 10:35:38 +08:00
|
|
|
try {
|
2023-10-14 18:28:16 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "Before lock: Select device usb port: " << usb_port);
|
|
|
|
|
std::lock_guard<decltype(device_lock_)> lock(device_lock_);
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "After lock: Select device usb port: " << usb_port);
|
2023-09-15 10:35:38 +08:00
|
|
|
auto device = list->getDeviceByUid(usb_port.c_str());
|
2023-10-14 18:28:16 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "Device usb port " << usb_port << " done");
|
2023-09-15 10:35:38 +08:00
|
|
|
return device;
|
|
|
|
|
} catch (ob::Error &e) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to get device info " << e.getMessage());
|
|
|
|
|
} catch (std::exception &e) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to get device info " << e.what());
|
|
|
|
|
} catch (...) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to get device info");
|
2023-07-05 15:00:34 +08:00
|
|
|
}
|
2023-09-15 10:35:38 +08:00
|
|
|
|
2023-07-05 15:00:34 +08:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
void OBCameraNodeDriver::initializeDevice(const std::shared_ptr<ob::Device> &device) {
|
2023-02-17 20:18:55 +08:00
|
|
|
device_ = device;
|
2023-02-06 17:26:10 +08:00
|
|
|
CHECK_NOTNULL(device_);
|
|
|
|
|
CHECK_NOTNULL(device_.get());
|
|
|
|
|
if (ob_camera_node_) {
|
|
|
|
|
ob_camera_node_.reset();
|
|
|
|
|
}
|
|
|
|
|
ob_camera_node_ = std::make_unique<OBCameraNode>(this, device_, parameters_);
|
2023-10-12 20:52:10 +08:00
|
|
|
ob_camera_node_->startStreams();
|
2023-10-13 21:40:32 +08:00
|
|
|
ob_camera_node_->startIMU();
|
2023-02-06 17:26:10 +08:00
|
|
|
device_connected_ = true;
|
|
|
|
|
device_info_ = device_->getDeviceInfo();
|
2023-10-14 18:28:16 +08:00
|
|
|
serial_number_ = device_info_->serialNumber();
|
2023-02-06 17:26:10 +08:00
|
|
|
CHECK_NOTNULL(device_info_.get());
|
2023-02-15 19:50:30 +08:00
|
|
|
device_unique_id_ = device_info_->uid();
|
2023-07-20 10:50:40 +08:00
|
|
|
if (!isOpenNIDevice(device_info_->pid())) {
|
2023-09-05 17:59:19 +08:00
|
|
|
ctx_->enableDeviceClockSync(0); // sync time stamp
|
2023-07-20 10:50:40 +08:00
|
|
|
}
|
2023-02-06 17:26:10 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "Device " << device_info_->name() << " connected");
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "Serial number: " << device_info_->serialNumber());
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "Firmware version: " << device_info_->firmwareVersion());
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "Hardware version: " << device_info_->hardwareVersion());
|
2023-02-15 21:20:02 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "device unique id: " << device_unique_id_);
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
2023-02-17 20:18:55 +08:00
|
|
|
|
2024-03-04 14:56:54 +08:00
|
|
|
void OBCameraNodeDriver::connectNetDevice(const std::string &net_device_ip, int net_device_port) {
|
|
|
|
|
if (net_device_ip.empty() || net_device_port == 0) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Invalid net device ip or port");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
auto device = ctx_->createNetDevice(net_device_ip.c_str(), net_device_port);
|
|
|
|
|
if (device == nullptr) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to connect to net device " << net_device_ip);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
initializeDevice(device);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-20 09:39:44 +08:00
|
|
|
void OBCameraNodeDriver::startDevice(const std::shared_ptr<ob::DeviceList> &list) {
|
2023-02-17 20:18:55 +08:00
|
|
|
if (device_connected_) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (list->deviceCount() == 0) {
|
|
|
|
|
RCLCPP_WARN(logger_, "No device found");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (device_) {
|
|
|
|
|
device_.reset();
|
|
|
|
|
}
|
2024-04-02 20:56:56 +08:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(connection_delay_));
|
2023-10-14 18:28:16 +08:00
|
|
|
pthread_mutex_lock(orb_device_lock_);
|
|
|
|
|
std::shared_ptr<int> lock_holder(nullptr,
|
|
|
|
|
[this](int *) { pthread_mutex_unlock(orb_device_lock_); });
|
|
|
|
|
bool start_device_failed = false;
|
|
|
|
|
try {
|
|
|
|
|
auto device = selectDevice(list);
|
|
|
|
|
if (device == nullptr) {
|
|
|
|
|
RCLCPP_WARN_THROTTLE(logger_, *get_clock(), 1000, "Device with serial number %s not found",
|
|
|
|
|
serial_number_.c_str());
|
|
|
|
|
device_connected_ = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
initializeDevice(device);
|
|
|
|
|
} catch (ob::Error &e) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to initialize device " << e.getMessage());
|
|
|
|
|
start_device_failed = true;
|
|
|
|
|
} catch (std::exception &e) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to initialize device " << e.what());
|
|
|
|
|
start_device_failed = true;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, "Failed to initialize device");
|
|
|
|
|
start_device_failed = true;
|
|
|
|
|
}
|
|
|
|
|
if (start_device_failed) {
|
2023-02-17 20:18:55 +08:00
|
|
|
device_connected_ = false;
|
2023-10-14 18:28:16 +08:00
|
|
|
std::unique_lock<decltype(reset_device_mutex_)> reset_device_lock(reset_device_mutex_);
|
|
|
|
|
reset_device_flag_ = true;
|
|
|
|
|
reset_device_cond_.notify_all();
|
2023-02-17 20:18:55 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
} // namespace orbbec_camera
|
2023-08-22 21:11:59 +08:00
|
|
|
|
2023-10-12 20:52:10 +08:00
|
|
|
RCLCPP_COMPONENTS_REGISTER_NODE(orbbec_camera::OBCameraNodeDriver)
|