Skip to content

Commit 23068e4

Browse files
committed
change sem to pthread lock
1 parent 4f78ec5 commit 23068e4

File tree

7 files changed

+57
-186
lines changed

7 files changed

+57
-186
lines changed

orbbec_camera/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ rclcpp_components_register_node(${PROJECT_NAME}
204204
)
205205
# Add nodes using the macro
206206
add_orbbec_executable(list_devices_node src/list_devices_node.cpp)
207-
add_orbbec_executable(ob_cleanup_shm_node src/ob_cleanup_shm.cpp)
208207
add_orbbec_executable(list_depth_work_mode_node src/list_depth_work_mode.cpp)
209208
add_orbbec_executable(list_camera_profile_mode_node src/list_camera_profile.cpp)
210209

@@ -221,7 +220,6 @@ install(DIRECTORY config DESTINATION share/${PROJECT_NAME}/)
221220
install(DIRECTORY ${ORBBEC_INCLUDE_DIR} DESTINATION include)
222221
install(DIRECTORY ${ORBBEC_LIBS_DIR}/ DESTINATION lib/ FILES_MATCHING PATTERN "*.so*")
223222
install(TARGETS list_devices_node
224-
ob_cleanup_shm_node
225223
list_depth_work_mode_node
226224
list_camera_profile_mode_node
227225
DESTINATION lib/${PROJECT_NAME}/)

orbbec_camera/include/orbbec_camera/constants.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ const int32_t OPENNI_END_PID = 0x06FF;
110110
const int32_t ASTRA_MINI_PID = 0x0404;
111111
const int32_t ASTRA_MINI_S_PID = 0x0407;
112112
const int GEMINI2_PID = 0x0670;
113-
const std::string DEFAULT_SEM_NAME = "orbbec_device_sem";
114-
const key_t DEFAULT_SEM_KEY = 0x0401;
113+
const std::string ORB_DEFAULT_LOCK_NAME = "orbbec_device_lock";
115114

116115
} // namespace orbbec_camera

orbbec_camera/include/orbbec_camera/ob_camera_node_driver.h

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023 Orbbec 3D Technology, Inc
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*******************************************************************************/
2+
* Copyright (c) 2023 Orbbec 3D Technology, Inc
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*******************************************************************************/
1616
#pragma once
1717
#include <atomic>
1818
#include <thread>
@@ -24,17 +24,10 @@
2424
#include "dynamic_params.h"
2525

2626
#include "libobsensor/ObSensor.hpp"
27+
#include <pthread.h>
2728

2829
namespace orbbec_camera {
2930

30-
enum DeviceConnectionEvent {
31-
kDeviceConnected = 0,
32-
kDeviceDisconnected,
33-
kOtherDeviceConnected,
34-
kOtherDeviceDisconnected,
35-
kDeviceCountUpdate,
36-
};
37-
3831
class OBCameraNodeDriver : public rclcpp::Node {
3932
public:
4033
explicit OBCameraNodeDriver(const rclcpp::NodeOptions& node_options = rclcpp::NodeOptions());
@@ -45,11 +38,6 @@ class OBCameraNodeDriver : public rclcpp::Node {
4538
private:
4639
void init();
4740

48-
void releaseDeviceSemaphore(sem_t* device_sem, int& num_devices_connected);
49-
50-
void updateConnectedDeviceCount(int& num_devices_connected,
51-
DeviceConnectionEvent connection_event);
52-
5341
std::shared_ptr<ob::Device> selectDevice(const std::shared_ptr<ob::DeviceList>& list);
5442

5543
std::shared_ptr<ob::Device> selectDeviceBySerialNumber(
@@ -72,8 +60,6 @@ class OBCameraNodeDriver : public rclcpp::Node {
7260

7361
void queryDevice();
7462

75-
void deviceCountUpdate();
76-
7763
void syncTime();
7864

7965
void resetDevice();
@@ -95,12 +81,16 @@ class OBCameraNodeDriver : public rclcpp::Node {
9581
std::shared_ptr<std::thread> device_count_update_thread_ = nullptr;
9682
std::recursive_mutex device_lock_;
9783
int device_num_ = 1;
98-
int num_devices_connected_ = 0;
9984
rclcpp::TimerBase::SharedPtr check_connect_timer_ = nullptr;
10085
std::shared_ptr<std::thread> sync_time_thread_ = nullptr;
10186
std::shared_ptr<std::thread> reset_device_thread_ = nullptr;
10287
std::mutex reset_device_mutex_;
10388
std::condition_variable reset_device_cond_;
10489
std::atomic_bool reset_device_flag_{false};
90+
pthread_mutex_t* orb_device_lock_ = nullptr;
91+
sem_t* orb_device_sem_ = nullptr;
92+
pthread_mutexattr_t orb_device_lock_attr_;
93+
uint8_t* orb_device_lock_shm_addr_ = nullptr;
94+
int orb_device_lock_shm_fd_ = -1;
10595
};
10696
} // namespace orbbec_camera

orbbec_camera/launch/dabai_dcw.launch.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def generate_launch_description():
2323
DeclareLaunchArgument('connection_delay', default_value='100'),
2424
DeclareLaunchArgument('color_width', default_value='640'),
2525
DeclareLaunchArgument('color_height', default_value='360'),
26-
DeclareLaunchArgument('color_fps', default_value='30'),
26+
DeclareLaunchArgument('color_fps', default_value='10'),
2727
DeclareLaunchArgument('color_format', default_value='MJPG'),
2828
DeclareLaunchArgument('enable_color', default_value='true'),
2929
DeclareLaunchArgument('flip_color', default_value='false'),
@@ -32,17 +32,17 @@ def generate_launch_description():
3232
DeclareLaunchArgument('enable_color_auto_exposure', default_value='true'),
3333
DeclareLaunchArgument('depth_width', default_value='640'),
3434
DeclareLaunchArgument('depth_height', default_value='360'),
35-
DeclareLaunchArgument('depth_fps', default_value='30'),
35+
DeclareLaunchArgument('depth_fps', default_value='10'),
3636
DeclareLaunchArgument('depth_format', default_value='Y11'),
3737
DeclareLaunchArgument('enable_depth', default_value='true'),
3838
DeclareLaunchArgument('flip_depth', default_value='false'),
3939
DeclareLaunchArgument('depth_qos', default_value='default'),
4040
DeclareLaunchArgument('depth_camera_info_qos', default_value='default'),
4141
DeclareLaunchArgument('ir_width', default_value='640'),
4242
DeclareLaunchArgument('ir_height', default_value='480'),
43-
DeclareLaunchArgument('ir_fps', default_value='30'),
43+
DeclareLaunchArgument('ir_fps', default_value='10'),
4444
DeclareLaunchArgument('ir_format', default_value='Y10'),
45-
DeclareLaunchArgument('enable_ir', default_value='true'),
45+
DeclareLaunchArgument('enable_ir', default_value='false'),
4646
DeclareLaunchArgument('flip_ir', default_value='false'),
4747
DeclareLaunchArgument('ir_qos', default_value='default'),
4848
DeclareLaunchArgument('ir_camera_info_qos', default_value='default'),

orbbec_camera/launch/multi_camera.launch.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,27 @@
77

88

99
def generate_launch_description():
10-
# Node configuration
11-
cleanup_node = Node(
12-
package='orbbec_camera',
13-
executable='ob_cleanup_shm_node',
14-
name='camera',
15-
output='screen'
16-
)
17-
1810
# Include launch files
1911
package_dir = get_package_share_directory('orbbec_camera')
2012
launch_file_dir = os.path.join(package_dir, 'launch')
2113
launch1_include = IncludeLaunchDescription(
2214
PythonLaunchDescriptionSource(
23-
os.path.join(launch_file_dir, 'dabai_dcw2.launch.py')
15+
os.path.join(launch_file_dir, 'dabai_dcw.launch.py')
2416
),
2517
launch_arguments={
2618
'camera_name': 'camera_01',
27-
'usb_port': '5-3.4.4.1.1',
19+
'usb_port': '5-3.4.4.3.1',
2820
'device_num': '2'
2921
}.items()
3022
)
3123

3224
launch2_include = IncludeLaunchDescription(
3325
PythonLaunchDescriptionSource(
34-
os.path.join(launch_file_dir, 'dabai_dcw2.launch.py')
26+
os.path.join(launch_file_dir, 'dabai_dcw.launch.py')
3527
),
3628
launch_arguments={
3729
'camera_name': 'camera_02',
38-
'usb_port': '5-3.4.4.3.1',
30+
'usb_port': '5-3.4.4.1.1',
3931
'device_num': '2'
4032
}.items()
4133
)
@@ -44,7 +36,6 @@ def generate_launch_description():
4436

4537
# Launch description
4638
ld = LaunchDescription([
47-
cleanup_node,
4839
GroupAction([launch1_include]),
4940
GroupAction([launch2_include]),
5041
])

orbbec_camera/src/ob_camera_node_driver.cpp

Lines changed: 28 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
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

2526
namespace orbbec_camera {
2627
OBCameraNodeDriver::OBCameraNodeDriver(const rclcpp::NodeOptions &node_options)
@@ -42,10 +43,6 @@ OBCameraNodeDriver::OBCameraNodeDriver(const std::string &node_name, const std::
4243

4344
OBCameraNodeDriver::~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

131145
OBLogSeverity OBCameraNodeDriver::obLogSeverityFromString(const std::string_view &log_level) {
@@ -157,7 +171,7 @@ void OBCameraNodeDriver::checkConnectTimer() {
157171
void 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-
180187
void 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

249213
std::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

Comments
 (0)