Skip to content

Commit c329964

Browse files
author
xiexun
committed
Fix device disconnection after reboot service call 2
1 parent d91db6b commit c329964

File tree

2 files changed

+119
-28
lines changed

2 files changed

+119
-28
lines changed

orbbec_camera/src/ob_camera_node.cpp

Lines changed: 116 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -128,27 +128,54 @@ void OBCameraNode::clean() noexcept {
128128
std::lock_guard<decltype(device_lock_)> lock(device_lock_);
129129
RCLCPP_WARN_STREAM(logger_, "Do destroy ~OBCameraNode");
130130
is_running_.store(false);
131+
132+
// Stop diagnostic timer and updater first to prevent access to disconnected device
133+
try {
134+
if (diagnostic_timer_) {
135+
diagnostic_timer_->cancel();
136+
diagnostic_timer_.reset();
137+
}
138+
if (diagnostic_updater_) {
139+
diagnostic_updater_.reset();
140+
}
141+
} catch (...) {
142+
// Ignore exceptions during diagnostic cleanup
143+
}
144+
131145
RCLCPP_WARN_STREAM(logger_, "Stop tf thread");
132-
if (tf_thread_ && tf_thread_->joinable()) {
133-
tf_thread_->join();
146+
try {
147+
if (tf_thread_ && tf_thread_->joinable()) {
148+
tf_cv_.notify_all(); // Wake up tf thread if it's waiting
149+
tf_thread_->join();
150+
}
151+
} catch (...) {
152+
RCLCPP_WARN_STREAM(logger_, "Exception while stopping tf thread");
134153
}
154+
135155
RCLCPP_WARN_STREAM(logger_, "Stop color frame thread");
136-
if (colorFrameThread_ && colorFrameThread_->joinable()) {
137-
color_frame_queue_cv_.notify_all();
138-
colorFrameThread_->join();
156+
try {
157+
if (colorFrameThread_ && colorFrameThread_->joinable()) {
158+
color_frame_queue_cv_.notify_all();
159+
colorFrameThread_->join();
160+
}
161+
} catch (...) {
162+
RCLCPP_WARN_STREAM(logger_, "Exception while stopping color frame thread");
139163
}
140164

141165
RCLCPP_WARN_STREAM(logger_, "stop streams");
142-
stopStreams();
143-
stopIMU();
144-
delete[] rgb_buffer_;
145-
rgb_buffer_ = nullptr;
146-
147-
delete[] depth_xy_table_data_;
148-
depth_xy_table_data_ = nullptr;
166+
try {
167+
stopStreams();
168+
stopIMU();
169+
} catch (...) {
170+
RCLCPP_WARN_STREAM(logger_, "Exception while stopping streams");
171+
}
149172

150-
delete[] depth_point_cloud_buffer_;
151-
depth_point_cloud_buffer_ = nullptr;
173+
try {
174+
delete[] rgb_buffer_;
175+
rgb_buffer_ = nullptr;
176+
} catch (...) {
177+
RCLCPP_WARN_STREAM(logger_, "Exception while cleaning up buffers");
178+
}
152179

153180
RCLCPP_WARN_STREAM(logger_, "Destroy ~OBCameraNode DONE");
154181
}
@@ -1410,22 +1437,53 @@ void OBCameraNode::startIMU() {
14101437
}
14111438

14121439
void OBCameraNode::stopStreams() {
1440+
std::lock_guard<decltype(device_lock_)> lock(device_lock_);
1441+
14131442
if (!pipeline_started_ || !pipeline_) {
14141443
RCLCPP_INFO_STREAM(logger_, "pipeline not started or not exist, skip stop pipeline");
14151444
return;
14161445
}
1446+
1447+
// Stop diagnostic timer first to prevent crashes during shutdown
1448+
try {
1449+
if (diagnostic_timer_) {
1450+
diagnostic_timer_->cancel();
1451+
diagnostic_timer_.reset();
1452+
}
1453+
if (diagnostic_updater_) {
1454+
diagnostic_updater_.reset();
1455+
}
1456+
} catch (...) {
1457+
// Ignore exceptions during diagnostic cleanup
1458+
}
1459+
1460+
// Mark pipeline as stopping to prevent new operations
1461+
pipeline_started_.store(false);
1462+
14171463
try {
1418-
pipeline_->stop();
1419-
// disable interleave frame
1420-
if ((interleave_ae_mode_ == "hdr") || (interleave_ae_mode_ == "laser")) {
1421-
RCLCPP_INFO_STREAM(logger_, "current interleave_ae_mode_: " << interleave_ae_mode_);
1422-
if (device_->isPropertySupported(OB_PROP_FRAME_INTERLEAVE_ENABLE_BOOL, OB_PERMISSION_WRITE)) {
1423-
interleave_frame_enable_ = false;
1424-
RCLCPP_INFO_STREAM(logger_, "Enable enable_interleave_depth_frame to "
1425-
<< (interleave_frame_enable_ ? "true" : "false"));
1426-
TRY_TO_SET_PROPERTY(setBoolProperty, OB_PROP_FRAME_INTERLEAVE_ENABLE_BOOL,
1427-
interleave_frame_enable_);
1464+
// Check if device is still valid before stopping pipeline
1465+
if (device_ && pipeline_) {
1466+
pipeline_->stop();
1467+
1468+
// disable interleave frame only if device is still connected
1469+
if ((interleave_ae_mode_ == "hdr") || (interleave_ae_mode_ == "laser")) {
1470+
try {
1471+
RCLCPP_INFO_STREAM(logger_, "current interleave_ae_mode_: " << interleave_ae_mode_);
1472+
if (device_->isPropertySupported(OB_PROP_FRAME_INTERLEAVE_ENABLE_BOOL, OB_PERMISSION_WRITE)) {
1473+
interleave_frame_enable_ = false;
1474+
RCLCPP_INFO_STREAM(logger_, "Enable enable_interleave_depth_frame to "
1475+
<< (interleave_frame_enable_ ? "true" : "false"));
1476+
TRY_TO_SET_PROPERTY(setBoolProperty, OB_PROP_FRAME_INTERLEAVE_ENABLE_BOOL,
1477+
interleave_frame_enable_);
1478+
}
1479+
} catch (const ob::Error &e) {
1480+
RCLCPP_WARN_STREAM(logger_, "Failed to disable interleave frame during shutdown: " << e.getMessage());
1481+
} catch (...) {
1482+
RCLCPP_WARN_STREAM(logger_, "Failed to disable interleave frame during shutdown");
1483+
}
14281484
}
1485+
} else {
1486+
RCLCPP_WARN_STREAM(logger_, "Device or pipeline not available during stop - likely disconnected");
14291487
}
14301488
} catch (const ob::Error &e) {
14311489
RCLCPP_ERROR_STREAM(logger_, "Failed to stop pipeline: " << e.getMessage());
@@ -1435,6 +1493,8 @@ void OBCameraNode::stopStreams() {
14351493
}
14361494

14371495
void OBCameraNode::stopIMU() {
1496+
std::lock_guard<decltype(device_lock_)> lock(device_lock_);
1497+
14381498
if (enable_sync_output_accel_gyro_) {
14391499
if (!imu_sync_output_start_ || !imuPipeline_) {
14401500
RCLCPP_INFO_STREAM(logger_, "imu pipeline not started or not exist, skip stop imu pipeline");
@@ -1880,6 +1940,14 @@ void OBCameraNode::setupTopics() {
18801940

18811941
void OBCameraNode::onTemperatureUpdate(diagnostic_updater::DiagnosticStatusWrapper &status) {
18821942
try {
1943+
1944+
//check to ensure we're not shutting down
1945+
std::lock_guard<decltype(device_lock_)> lock(device_lock_);
1946+
if (!device_ || !is_running_.load()) {
1947+
status.summary(diagnostic_msgs::msg::DiagnosticStatus::STALE, "Device disconnected");
1948+
return;
1949+
}
1950+
18831951
OBDeviceTemperature temperature;
18841952
uint32_t data_size = sizeof(OBDeviceTemperature);
18851953
device_->getStructuredData(OB_STRUCT_DEVICE_TEMPERATURE,
@@ -1897,17 +1965,38 @@ void OBCameraNode::onTemperatureUpdate(diagnostic_updater::DiagnosticStatusWrapp
18971965
status.add("Chip Bottom Temperature", temperature.chipBottomTemp);
18981966
status.summary(diagnostic_msgs::msg::DiagnosticStatus::OK, "Temperature is normal");
18991967
} catch (const ob::Error &e) {
1900-
if (is_running_.load()) {
1901-
diagnostic_timer_->cancel();
1902-
diagnostic_timer_.reset();
1968+
try {
1969+
if (is_running_.load() && diagnostic_timer_) {
1970+
diagnostic_timer_->cancel();
1971+
diagnostic_timer_.reset();
1972+
}
1973+
} catch (...) {
1974+
// Ignore exceptions during cleanup
19031975
}
19041976
RCLCPP_ERROR_STREAM(logger_, "Failed to TemperatureUpdate: " << e.getMessage());
19051977
status.summary(diagnostic_msgs::msg::DiagnosticStatus::ERROR, e.getMessage());
19061978
} catch (const std::exception &e) {
1979+
try {
1980+
if (is_running_.load() && diagnostic_timer_) {
1981+
diagnostic_timer_->cancel();
1982+
diagnostic_timer_.reset();
1983+
}
1984+
} catch (...) {
1985+
// Ignore exceptions during cleanup
1986+
}
19071987
RCLCPP_ERROR_STREAM(logger_, "Failed to TemperatureUpdate: " << e.what());
19081988
status.summary(diagnostic_msgs::msg::DiagnosticStatus::ERROR, e.what());
19091989
} catch (...) {
1990+
try {
1991+
if (is_running_.load() && diagnostic_timer_) {
1992+
diagnostic_timer_->cancel();
1993+
diagnostic_timer_.reset();
1994+
}
1995+
} catch (...) {
1996+
// Ignore exceptions during cleanup
1997+
}
19101998
RCLCPP_ERROR(logger_, "Failed to TemperatureUpdate");
1999+
status.summary(diagnostic_msgs::msg::DiagnosticStatus::ERROR, "Unknown error");
19112000
}
19122001
}
19132002

orbbec_camera/src/ob_camera_node_driver.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ OBCameraNodeDriver::~OBCameraNodeDriver() {
111111
reset_device_cond_.notify_all();
112112
reset_device_thread_->join();
113113
}
114-
ob_camera_node_->stopGmslTrigger();
114+
if (ob_camera_node_) {
115+
ob_camera_node_->stopGmslTrigger();
116+
}
115117
if (orb_device_lock_shm_fd_ != -1) {
116118
close(orb_device_lock_shm_fd_);
117119
orb_device_lock_shm_fd_ = -1;

0 commit comments

Comments
 (0)