2121#include < ament_index_cpp/get_package_share_directory.hpp>
2222#include < rclcpp_components/register_node_macro.hpp>
2323#include < csignal>
24+ #include < sys/mman.h>
2425
2526namespace orbbec_camera {
2627OBCameraNodeDriver::OBCameraNodeDriver (const rclcpp::NodeOptions &node_options)
@@ -42,10 +43,6 @@ OBCameraNodeDriver::OBCameraNodeDriver(const std::string &node_name, const std::
4243
4344OBCameraNodeDriver::~OBCameraNodeDriver () {
4445 is_alive_.store (false );
45- sem_unlink (DEFAULT_SEM_NAME.c_str ());
46- if (int shm_id = shmget (DEFAULT_SEM_KEY, 1 , 0666 | IPC_CREAT); shm_id != -1 ) {
47- shmctl (shm_id, IPC_RMID, nullptr );
48- }
4946 if (device_count_update_thread_ && device_count_update_thread_->joinable ()) {
5047 device_count_update_thread_->join ();
5148 }
@@ -65,6 +62,27 @@ void OBCameraNodeDriver::init() {
6562 auto log_level_str = declare_parameter<std::string>(" log_level" , " none" );
6663 auto log_level = obLogSeverityFromString (log_level_str);
6764 ob::Context::setLoggerSeverity (log_level);
65+ orb_device_lock_shm_fd_ = shm_open (ORB_DEFAULT_LOCK_NAME.c_str (), O_CREAT | O_RDWR, 0666 );
66+ if (orb_device_lock_shm_fd_ < 0 ) {
67+ RCLCPP_ERROR_STREAM (logger_, " Failed to open shared memory " << ORB_DEFAULT_LOCK_NAME);
68+ return ;
69+ }
70+ int ret = ftruncate (orb_device_lock_shm_fd_, sizeof (pthread_mutex_t ));
71+ if (ret < 0 ) {
72+ RCLCPP_ERROR_STREAM (logger_, " Failed to truncate shared memory " << ORB_DEFAULT_LOCK_NAME);
73+ return ;
74+ }
75+ orb_device_lock_shm_addr_ =
76+ static_cast <uint8_t *>(mmap (NULL , sizeof (pthread_mutex_t ), PROT_READ | PROT_WRITE, MAP_SHARED,
77+ orb_device_lock_shm_fd_, 0 ));
78+ if (orb_device_lock_shm_addr_ == MAP_FAILED) {
79+ RCLCPP_ERROR_STREAM (logger_, " Failed to map shared memory " << ORB_DEFAULT_LOCK_NAME);
80+ return ;
81+ }
82+ pthread_mutexattr_init (&orb_device_lock_attr_);
83+ pthread_mutexattr_setpshared (&orb_device_lock_attr_, PTHREAD_PROCESS_SHARED);
84+ orb_device_lock_ = (pthread_mutex_t *)orb_device_lock_shm_addr_;
85+ pthread_mutex_init (orb_device_lock_, &orb_device_lock_attr_);
6886 is_alive_.store (true );
6987 parameters_ = std::make_shared<Parameters>(this );
7088 serial_number_ = declare_parameter<std::string>(" serial_number" , " " );
@@ -79,7 +97,6 @@ void OBCameraNodeDriver::init() {
7997 this ->create_wall_timer (std::chrono::milliseconds (1000 ), [this ]() { checkConnectTimer (); });
8098 CHECK_NOTNULL (check_connect_timer_);
8199 query_thread_ = std::make_shared<std::thread>([this ]() { queryDevice (); });
82- device_count_update_thread_ = std::make_shared<std::thread>([this ]() { deviceCountUpdate (); });
83100 sync_time_thread_ = std::make_shared<std::thread>([this ]() { syncTime (); });
84101 reset_device_thread_ = std::make_shared<std::thread>([this ]() { resetDevice (); });
85102}
@@ -89,7 +106,10 @@ void OBCameraNodeDriver::onDeviceConnected(const std::shared_ptr<ob::DeviceList>
89106 if (device_list->deviceCount () == 0 ) {
90107 return ;
91108 }
92- RCLCPP_INFO_STREAM_THROTTLE (logger_, *get_clock (), 1000 , " onDeviceConnected" );
109+ pthread_mutex_lock (orb_device_lock_);
110+ std::shared_ptr<int > lock_holder (nullptr ,
111+ [this ](int *) { pthread_mutex_unlock (orb_device_lock_); });
112+ RCLCPP_INFO_STREAM_THROTTLE (logger_, *get_clock (), 1000 , " device list count " << device_list->deviceCount ());
93113 if (!device_) {
94114 try {
95115 startDevice (device_list);
@@ -109,7 +129,6 @@ void OBCameraNodeDriver::onDeviceDisconnected(const std::shared_ptr<ob::DeviceLi
109129 return ;
110130 }
111131 RCLCPP_INFO_STREAM (logger_, " onDeviceDisconnected" );
112- bool current_device_disconnected = false ;
113132 for (size_t i = 0 ; i < device_list->deviceCount (); i++) {
114133 std::string uid = device_list->uid (i);
115134 std::scoped_lock<decltype (device_lock_)> lock (device_lock_);
@@ -118,14 +137,9 @@ void OBCameraNodeDriver::onDeviceDisconnected(const std::shared_ptr<ob::DeviceLi
118137 std::unique_lock<decltype (reset_device_mutex_)> reset_device_lock (reset_device_mutex_);
119138 reset_device_flag_ = true ;
120139 reset_device_cond_.notify_all ();
121- current_device_disconnected = true ;
122140 break ;
123141 }
124142 }
125- auto connect_event = current_device_disconnected
126- ? DeviceConnectionEvent::kDeviceDisconnected
127- : DeviceConnectionEvent::kOtherDeviceDisconnected ;
128- updateConnectedDeviceCount (num_devices_connected_, connect_event);
129143}
130144
131145OBLogSeverity OBCameraNodeDriver::obLogSeverityFromString (const std::string_view &log_level) {
@@ -157,7 +171,7 @@ void OBCameraNodeDriver::checkConnectTimer() {
157171void OBCameraNodeDriver::queryDevice () {
158172 while (is_alive_ && rclcpp::ok ()) {
159173 if (!device_connected_.load ()) {
160- RCLCPP_INFO_STREAM_THROTTLE (logger_, *get_clock (), 1000 , " Waiting for device connection..." );
174+ RCLCPP_DEBUG_STREAM_THROTTLE (logger_, *get_clock (), 1000 , " Waiting for device connection..." );
161175 auto device_list = ctx_->queryDeviceList ();
162176 if (device_list->deviceCount () == 0 ) {
163177 std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
@@ -170,13 +184,6 @@ void OBCameraNodeDriver::queryDevice() {
170184 }
171185}
172186
173- void OBCameraNodeDriver::deviceCountUpdate () {
174- while (is_alive_ && rclcpp::ok ()) {
175- updateConnectedDeviceCount (num_devices_connected_, DeviceConnectionEvent::kDeviceCountUpdate );
176- std::this_thread::sleep_for (std::chrono::milliseconds (500 ));
177- }
178- }
179-
180187void OBCameraNodeDriver::syncTime () {
181188 while (is_alive_ && rclcpp::ok ()) {
182189 if (device_ && device_info_ && !isOpenNIDevice (device_info_->pid ())) {
@@ -202,77 +209,14 @@ void OBCameraNodeDriver::resetDevice() {
202209 reset_device_flag_ = false ;
203210 }
204211}
205- void OBCameraNodeDriver::releaseDeviceSemaphore (sem_t *device_sem, int &num_devices_connected) {
206- RCLCPP_INFO_THROTTLE (logger_, *get_clock (), 1000 , " Release device semaphore" );
207- sem_post (device_sem);
208- int sem_value = 0 ;
209- sem_getvalue (device_sem, &sem_value);
210- RCLCPP_INFO_STREAM_THROTTLE (logger_, *get_clock (), 1000 , " semaphore value: " << sem_value);
211- RCLCPP_INFO_THROTTLE (logger_, *get_clock (), 1000 , " Release device semaphore done" );
212- if (num_devices_connected >= device_num_) {
213- sem_destroy (device_sem);
214- sem_unlink (DEFAULT_SEM_NAME.c_str ());
215- }
216- }
217-
218- void OBCameraNodeDriver::updateConnectedDeviceCount (int &num_devices_connected,
219- DeviceConnectionEvent connection_event) {
220- // write connected device count to file
221- int shm_id = shmget (DEFAULT_SEM_KEY, 1 , 0666 | IPC_CREAT);
222- if (shm_id == -1 ) {
223- RCLCPP_INFO_STREAM (logger_, " Failed to create shared memory " << strerror (errno));
224- return ;
225- }
226- auto shm_ptr = (int *)shmat (shm_id, nullptr , 0 );
227- if (shm_ptr == (void *)-1 ) {
228- RCLCPP_INFO_STREAM (logger_, " Failed to attach shared memory " << strerror (errno));
229- return ;
230- }
231- if (connection_event == DeviceConnectionEvent::kDeviceConnected ) {
232- num_devices_connected = *shm_ptr + 1 ;
233- } else if (connection_event == DeviceConnectionEvent::kDeviceDisconnected && *shm_ptr > 0 ) {
234- num_devices_connected = *shm_ptr - 1 ;
235- } else {
236- num_devices_connected = *shm_ptr;
237- }
238- RCLCPP_DEBUG_STREAM_THROTTLE (logger_, *get_clock (), 5000 ,
239- " Current connected device " << num_devices_connected);
240- *shm_ptr = static_cast <int >(num_devices_connected);
241- shmdt (shm_ptr);
242- if (connection_event == DeviceConnectionEvent::kDeviceDisconnected &&
243- num_devices_connected == 0 ) {
244- shmctl (shm_id, IPC_RMID, nullptr );
245- sem_unlink (DEFAULT_SEM_NAME.c_str ());
246- }
247- }
248212
249213std::shared_ptr<ob::Device> OBCameraNodeDriver::selectDevice (
250214 const std::shared_ptr<ob::DeviceList> &list) {
251215 if (device_num_ == 1 ) {
252216 RCLCPP_INFO_STREAM (logger_, " Connecting to the default device" );
253217 return list->getDevice (0 );
254218 }
255- sem_t *device_sem = sem_open (DEFAULT_SEM_NAME.c_str (), O_CREAT, 0644 , 1 );
256- std::shared_ptr<int > device_sem_guard (nullptr , [&, device_sem](int const *) {
257- if (device_sem != SEM_FAILED) {
258- sem_close (device_sem);
259- }
260- });
261- if (device_sem == SEM_FAILED) {
262- RCLCPP_INFO_STREAM (logger_, " Failed to open semaphore" );
263- return nullptr ;
264- }
265- RCLCPP_INFO_STREAM_THROTTLE (logger_, *get_clock (), 1000 ,
266- " Connecting to device with serial number: " << serial_number_);
267- int sem_value = 0 ;
268- sem_getvalue (device_sem, &sem_value);
269- RCLCPP_INFO_STREAM_THROTTLE (logger_, *get_clock (), 1000 , " semaphore value: " << sem_value);
270- int ret = sem_wait (device_sem);
271- if (ret != 0 ) {
272- RCLCPP_ERROR_STREAM (logger_, " Failed to wait semaphore " << strerror (errno));
273- releaseDeviceSemaphore (device_sem, num_devices_connected_);
274- return nullptr ;
275- }
219+
276220 std::shared_ptr<ob::Device> device = nullptr ;
277221 if (!serial_number_.empty ()) {
278222 RCLCPP_INFO_STREAM_THROTTLE (logger_, *get_clock (), 1000 ,
@@ -283,13 +227,6 @@ std::shared_ptr<ob::Device> OBCameraNodeDriver::selectDevice(
283227 " Connecting to device with usb port: " << usb_port_);
284228 device = selectDeviceByUSBPort (list, usb_port_);
285229 }
286- std::shared_ptr<int > sem_guard (nullptr , [&, device](int const *) {
287- auto connect_event = device != nullptr ? DeviceConnectionEvent::kDeviceConnected
288- : DeviceConnectionEvent::kOtherDeviceConnected ;
289- updateConnectedDeviceCount (num_devices_connected_, connect_event);
290-
291- releaseDeviceSemaphore (device_sem, num_devices_connected_);
292- });
293230 if (device == nullptr ) {
294231 RCLCPP_WARN_THROTTLE (logger_, *get_clock (), 1000 , " Device with serial number %s not found" ,
295232 serial_number_.c_str ());
0 commit comments