Skip to content

Commit 7e775dc

Browse files
author
xiexun
committed
Fix firmware update and avoid colcon symlink issues
1 parent c329964 commit 7e775dc

File tree

3 files changed

+94
-33
lines changed

3 files changed

+94
-33
lines changed

orbbec_camera/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,11 @@ install(DIRECTORY config DESTINATION share/${PROJECT_NAME}/)
228228
install(DIRECTORY examples DESTINATION share/${PROJECT_NAME}/)
229229
install(DIRECTORY ${ORBBEC_INCLUDE_DIR} DESTINATION include)
230230
install(DIRECTORY ${ORBBEC_LIBS_DIR}/ DESTINATION lib/ FILES_MATCHING PATTERN "*.so*")
231-
install(DIRECTORY ${ORBBEC_LIBS_DIR}/extensions DESTINATION lib/)
231+
# Install extensions directory with explicit file copying to avoid symlink issues
232+
file(GLOB_RECURSE EXTENSION_FILES "${ORBBEC_LIBS_DIR}/extensions/*")
233+
if(EXTENSION_FILES)
234+
install(FILES ${EXTENSION_FILES} DESTINATION lib/extensions/)
235+
endif()
232236
if(DEFINED ENV{BUILDING_PACKAGE})
233237
# Install udev rules
234238
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/99-obsensor-libusb.rules DESTINATION /etc/udev/rules.d)

orbbec_camera/src/ob_camera_node.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,11 +1940,22 @@ void OBCameraNode::setupTopics() {
19401940

19411941
void OBCameraNode::onTemperatureUpdate(diagnostic_updater::DiagnosticStatusWrapper &status) {
19421942
try {
1943-
1944-
//check to ensure we're not shutting down
1943+
// Check to ensure we're not shutting down and device is valid
19451944
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");
1945+
if (!device_ || !is_running_.load() || !is_camera_node_initialized_.load()) {
1946+
status.summary(diagnostic_msgs::msg::DiagnosticStatus::STALE, "Device disconnected or shutting down");
1947+
return;
1948+
}
1949+
1950+
// Additional safety check - verify device is actually accessible
1951+
try {
1952+
auto device_info = device_->getDeviceInfo();
1953+
if (!device_info) {
1954+
status.summary(diagnostic_msgs::msg::DiagnosticStatus::STALE, "Device info not available");
1955+
return;
1956+
}
1957+
} catch (...) {
1958+
status.summary(diagnostic_msgs::msg::DiagnosticStatus::STALE, "Device not accessible");
19481959
return;
19491960
}
19501961

@@ -1995,7 +2006,7 @@ void OBCameraNode::onTemperatureUpdate(diagnostic_updater::DiagnosticStatusWrapp
19952006
} catch (...) {
19962007
// Ignore exceptions during cleanup
19972008
}
1998-
RCLCPP_ERROR(logger_, "Failed to TemperatureUpdate");
2009+
RCLCPP_ERROR(logger_, "Failed to TemperatureUpdate: Device is deactivated/disconnected!");
19992010
status.summary(diagnostic_msgs::msg::DiagnosticStatus::ERROR, "Unknown error");
20002011
}
20012012
}

orbbec_camera/src/ob_camera_node_driver.cpp

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,39 +36,43 @@ std::string g_time_domain = "global"; // Assuming this is declared elsew
3636

3737
void signalHandler(int sig) {
3838
std::cout << "Received signal: " << sig << std::endl;
39+
if (sig == SIGINT || sig == SIGTERM) {
40+
rclcpp::shutdown();
41+
} else {
3942

40-
std::string log_dir = "Log/";
43+
std::string log_dir = "Log/";
4144

42-
// get current time
43-
std::time_t now = std::time(nullptr);
44-
std::tm *local_time = std::localtime(&now);
45+
// get current time
46+
std::time_t now = std::time(nullptr);
47+
std::tm *local_time = std::localtime(&now);
4548

46-
// format date and time to string, format as "2024_05_20_12_34_56"
47-
std::ostringstream time_stream;
48-
time_stream << std::put_time(local_time, "%Y_%m_%d_%H_%M_%S");
49+
// format date and time to string, format as "2024_05_20_12_34_56"
50+
std::ostringstream time_stream;
51+
time_stream << std::put_time(local_time, "%Y_%m_%d_%H_%M_%S");
4952

50-
// generate log file name
51-
std::string log_file_name = g_camera_name + "_crash_stack_trace_" + time_stream.str() + ".log";
52-
std::string log_file_path = log_dir + log_file_name;
53+
// generate log file name
54+
std::string log_file_name = g_camera_name + "_crash_stack_trace_" + time_stream.str() + ".log";
55+
std::string log_file_path = log_dir + log_file_name;
5356

54-
if (!std::filesystem::exists(log_dir)) {
55-
std::filesystem::create_directories(log_dir);
56-
}
57+
if (!std::filesystem::exists(log_dir)) {
58+
std::filesystem::create_directories(log_dir);
59+
}
5760

58-
std::cout << "Log crash stack trace to " << log_file_path << std::endl;
59-
std::ofstream log_file(log_file_path, std::ios::app);
61+
std::cout << "Log crash stack trace to " << log_file_path << std::endl;
62+
std::ofstream log_file(log_file_path, std::ios::app);
6063

61-
if (log_file.is_open()) {
62-
log_file << "Received signal: " << sig << std::endl;
64+
if (log_file.is_open()) {
65+
log_file << "Received signal: " << sig << std::endl;
6366

64-
backward::StackTrace st;
65-
st.load_here(32); // Capture stack
66-
backward::Printer p;
67-
p.print(st, log_file); // Print stack to log file
68-
}
67+
backward::StackTrace st;
68+
st.load_here(32); // Capture stack
69+
backward::Printer p;
70+
p.print(st, log_file); // Print stack to log file
71+
}
6972

70-
log_file.close();
71-
exit(sig); // Exit program
73+
log_file.close();
74+
exit(sig); // Exit program
75+
}
7276
}
7377

7478
namespace orbbec_camera {
@@ -97,10 +101,28 @@ OBCameraNodeDriver::OBCameraNodeDriver(const std::string &node_name, const std::
97101
OBCameraNodeDriver::~OBCameraNodeDriver() {
98102
is_alive_.store(false);
99103

104+
// First stop the camera node cleanly before stopping threads
105+
if (ob_camera_node_) {
106+
try {
107+
ob_camera_node_->clean();
108+
} catch (...) {
109+
RCLCPP_WARN_STREAM(logger_, "Exception during camera node cleanup in destructor");
110+
}
111+
ob_camera_node_->stopGmslTrigger();
112+
}
113+
114+
// Stop timers that might access the device
115+
if (sync_host_time_timer_) {
116+
sync_host_time_timer_->cancel();
117+
sync_host_time_timer_.reset();
118+
}
119+
100120
if (check_connect_timer_) {
121+
check_connect_timer_->cancel();
101122
check_connect_timer_.reset();
102123
}
103124

125+
// Now stop threads
104126
if (device_count_update_thread_ && device_count_update_thread_->joinable()) {
105127
device_count_update_thread_->join();
106128
}
@@ -111,9 +133,8 @@ OBCameraNodeDriver::~OBCameraNodeDriver() {
111133
reset_device_cond_.notify_all();
112134
reset_device_thread_->join();
113135
}
114-
if (ob_camera_node_) {
115-
ob_camera_node_->stopGmslTrigger();
116-
}
136+
137+
// Clean up shared memory
117138
if (orb_device_lock_shm_fd_ != -1) {
118139
close(orb_device_lock_shm_fd_);
119140
orb_device_lock_shm_fd_ = -1;
@@ -131,6 +152,8 @@ void OBCameraNodeDriver::init() {
131152
signal(SIGABRT, signalHandler); // abort
132153
signal(SIGFPE, signalHandler); // float point exception
133154
signal(SIGILL, signalHandler); // illegal instruction
155+
signal(SIGINT, signalHandler);
156+
signal(SIGTERM, signalHandler);
134157
ob::Context::setExtensionsDirectory(extension_path_.c_str());
135158
if (config_path_.empty()) {
136159
ctx_ = std::make_unique<ob::Context>();
@@ -301,6 +324,17 @@ void OBCameraNodeDriver::resetDevice() {
301324
RCLCPP_INFO_STREAM(logger_, "resetDevice : Reset device uid: " << device_unique_id_);
302325
std::lock_guard<decltype(device_lock_)> device_lock(device_lock_);
303326
{
327+
// First stop the camera node cleanly to prevent timer/diagnostic access to device
328+
if (ob_camera_node_) {
329+
try {
330+
// This will stop all timers and clean up properly
331+
ob_camera_node_->clean();
332+
} catch (...) {
333+
RCLCPP_WARN_STREAM(logger_, "Exception during camera node cleanup during reset");
334+
}
335+
}
336+
337+
// Now reset the objects
304338
ob_camera_node_.reset();
305339
device_.reset();
306340
device_info_.reset();
@@ -817,6 +851,18 @@ void OBCameraNodeDriver::firmwareUpdateCallback(OBFwUpdateState state, const cha
817851
std::cout << "Message : " << message << std::endl << std::flush;
818852
if (state == STAT_DONE) {
819853
RCLCPP_INFO(logger_, "Reboot device");
854+
855+
// Don't call clean() here to avoid deadlock - just stop timers and reboot
856+
// The resetDevice thread will handle proper cleanup when device disconnects
857+
if (sync_host_time_timer_) {
858+
try {
859+
sync_host_time_timer_->cancel();
860+
sync_host_time_timer_.reset();
861+
} catch (...) {
862+
// Ignore exceptions during timer cleanup
863+
}
864+
}
865+
820866
device_->reboot();
821867
device_connected_ = false;
822868
upgrade_firmware_ = "";

0 commit comments

Comments
 (0)