feat: add SDK logging capabilities to tools and utilities

This commit is contained in:
ob-yalian
2026-05-07 17:57:28 +08:00
parent 043ec39788
commit 9791aee1aa
6 changed files with 263 additions and 7 deletions
@@ -31,6 +31,7 @@
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <string_view>
namespace orbbec_camera { namespace orbbec_camera {
inline void LogFatal(const char* file, int line, const std::string& message) { inline void LogFatal(const char* file, int line, const std::string& message) {
@@ -163,6 +164,13 @@ rclcpp::Time fromUsToROSTime(uint64_t us);
std::string getObSDKVersion(); std::string getObSDKVersion();
OBLogSeverity obLogSeverityFromString(const std::string_view& log_level);
std::string getRosLogDirectory();
std::string configureObSdkLoggerForTool(const std::string& tool_name,
const std::string& log_level);
OBFormat OBFormatFromString(const std::string& format); OBFormat OBFormatFromString(const std::string& format);
OBLiDARScanRate OBScanRateFromInt(const int rate); OBLiDARScanRate OBScanRateFromInt(const int rate);
+61
View File
@@ -15,13 +15,74 @@
*******************************************************************************/ *******************************************************************************/
#include <algorithm> #include <algorithm>
#include <chrono>
#include <cstdlib>
#include <filesystem>
#include <iomanip>
#include <mutex> #include <mutex>
#include <regex> #include <regex>
#include <sstream>
#include <vector> #include <vector>
#include "orbbec_camera/utils.h" #include "orbbec_camera/utils.h"
#include <sensor_msgs/point_cloud2_iterator.hpp> #include <sensor_msgs/point_cloud2_iterator.hpp>
#include "orbbec_camera/constants.h" #include "orbbec_camera/constants.h"
namespace orbbec_camera { namespace orbbec_camera {
OBLogSeverity obLogSeverityFromString(const std::string_view &log_level) {
if (log_level == "debug") {
return OBLogSeverity::OB_LOG_SEVERITY_DEBUG;
}
if (log_level == "info") {
return OBLogSeverity::OB_LOG_SEVERITY_INFO;
}
if (log_level == "warn" || log_level == "warning") {
return OBLogSeverity::OB_LOG_SEVERITY_WARN;
}
if (log_level == "error") {
return OBLogSeverity::OB_LOG_SEVERITY_ERROR;
}
if (log_level == "fatal") {
return OBLogSeverity::OB_LOG_SEVERITY_FATAL;
}
return OBLogSeverity::OB_LOG_SEVERITY_OFF;
}
std::string getRosLogDirectory() {
const char *home = std::getenv("HOME");
const std::filesystem::path home_dir = home != nullptr ? home : "";
return (home_dir / ".ros" / "Log").string();
}
std::string configureObSdkLoggerForTool(const std::string &tool_name,
const std::string &log_level) {
const auto severity = obLogSeverityFromString(log_level);
ob::Context::setLoggerSeverity(severity);
ob::Context::setLoggerToConsole(OBLogSeverity::OB_LOG_SEVERITY_OFF);
if (severity == OBLogSeverity::OB_LOG_SEVERITY_OFF) {
ob::Context::setLoggerToFile(OBLogSeverity::OB_LOG_SEVERITY_OFF, "");
return "";
}
const std::filesystem::path log_dir(getRosLogDirectory());
std::filesystem::create_directories(log_dir);
const auto now = std::chrono::system_clock::now();
const std::time_t now_time = std::chrono::system_clock::to_time_t(now);
std::tm tm{};
#if defined(_WIN32)
localtime_s(&tm, &now_time);
#else
localtime_r(&now_time, &tm);
#endif
std::ostringstream file_name;
file_name << tool_name << "_sdk_" << std::put_time(&tm, "%Y%m%d_%H%M%S") << ".log";
ob::Context::setLoggerFileName(file_name.str());
ob::Context::setLoggerToFile(severity, log_dir.string().c_str());
return (log_dir / file_name.str()).string();
}
sensor_msgs::msg::CameraInfo convertToCameraInfo(OBCameraIntrinsic intrinsic, sensor_msgs::msg::CameraInfo convertToCameraInfo(OBCameraIntrinsic intrinsic,
OBCameraDistortion distortion, int width) { OBCameraDistortion distortion, int width) {
(void)width; (void)width;
+40 -2
View File
@@ -45,6 +45,7 @@ struct CliArgs {
std::string preset_path; std::string preset_path;
int reconnect_timeout_sec = 120; int reconnect_timeout_sec = 120;
int reconnect_poll_ms = 1000; int reconnect_poll_ms = 1000;
std::string sdk_log_level = "off";
bool continue_on_error = false; bool continue_on_error = false;
bool used_deprecated_upgrade_firmware = false; bool used_deprecated_upgrade_firmware = false;
bool used_deprecated_preset_firmware_path = false; bool used_deprecated_preset_firmware_path = false;
@@ -100,13 +101,21 @@ void printUsage() {
<< " [--serial_number SN[,SN2...]]\\\n" << " [--serial_number SN[,SN2...]]\\\n"
<< " [--firmware_path /path/to/firmware.bin]\\\n" << " [--firmware_path /path/to/firmware.bin]\\\n"
<< " [--preset_path /path/a.bin,/path/b.bin]\\\n" << " [--preset_path /path/a.bin,/path/b.bin]\\\n"
<< " [--continue_on_error]\n\n" << " [--continue_on_error]\\\n"
<< " [--enable_sdk_log] [--sdk_log_level debug]\n\n"
<< "Parameters:\n" << "Parameters:\n"
<< " --serial_number SN[,SN2...] Target serial number(s). Supports comma-separated " << " --serial_number SN[,SN2...] Target serial number(s). Supports comma-separated "
"values.\n" "values.\n"
<< " --firmware_path PATH Firmware image file path for firmware update.\n" << " --firmware_path PATH Firmware image file path for firmware update.\n"
<< " --preset_path PATH[,PATH2...] Preset file path(s), comma-separated.\n" << " --preset_path PATH[,PATH2...] Preset file path(s), comma-separated.\n"
<< " --continue_on_error Continue with next target if one device update fails.\n" << " --continue_on_error Continue with next target if one device update fails.\n"
<< " --enable_sdk_log Enable SDK file log at debug level under ~/.ros/Log.\n"
<< " --sdk_log_level LEVEL SDK file log level: debug/info/warn/error/fatal/off "
"(default: off).\n"
<< "Examples:\n"
<< " ros2 run orbbec_camera firmware_update_tool -- \\\n"
<< " --preset_path /path/to/preset.bin \\\n"
<< " --enable_sdk_log --sdk_log_level debug\n"
<< "Notes:\n" << "Notes:\n"
<< " 1) At least one of --firmware_path / --preset_path must be provided.\n" << " 1) At least one of --firmware_path / --preset_path must be provided.\n"
<< " 2) If multiple devices are connected, specify target by serial/usb/ip to avoid wrong " << " 2) If multiple devices are connected, specify target by serial/usb/ip to avoid wrong "
@@ -288,6 +297,24 @@ bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
continue; continue;
} }
if (current == "--enable_sdk_log") {
args.sdk_log_level = "debug";
continue;
}
if (current.rfind("--sdk_log_level=", 0) == 0) {
args.sdk_log_level = current.substr(std::strlen("--sdk_log_level="));
continue;
}
if (current == "--sdk_log_level") {
if (++i >= argc) {
error = "--sdk_log_level requires a value";
return false;
}
args.sdk_log_level = argv[i];
continue;
}
error = "Unknown argument: " + current; error = "Unknown argument: " + current;
return false; return false;
} }
@@ -319,6 +346,13 @@ bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
return false; return false;
} }
const auto log_severity = orbbec_camera::obLogSeverityFromString(args.sdk_log_level);
if (log_severity == OBLogSeverity::OB_LOG_SEVERITY_OFF && args.sdk_log_level != "off" &&
args.sdk_log_level != "none") {
error = "--sdk_log_level expects one of: debug, info, warn, error, fatal, off";
return false;
}
return true; return true;
} }
@@ -640,7 +674,11 @@ int main(int argc, char **argv) {
auto logger = rclcpp::get_logger("firmware_update_tool"); auto logger = rclcpp::get_logger("firmware_update_tool");
try { try {
ob::Context::setLoggerSeverity(OBLogSeverity::OB_LOG_SEVERITY_OFF); const auto sdk_log_path =
orbbec_camera::configureObSdkLoggerForTool("firmware_update_tool", args.sdk_log_level);
if (!sdk_log_path.empty()) {
RCLCPP_INFO(logger, "SDK file log enabled: %s", sdk_log_path.c_str());
}
auto ctx = std::make_shared<ob::Context>(); auto ctx = std::make_shared<ob::Context>();
std::vector<std::string> batch_targets = splitCsv(args.serial_number); std::vector<std::string> batch_targets = splitCsv(args.serial_number);
if (batch_targets.empty()) { if (batch_targets.empty()) {
+39 -2
View File
@@ -31,6 +31,7 @@ struct CliArgs {
std::string new_ip = "192.168.1.200"; std::string new_ip = "192.168.1.200";
std::string mask = "255.255.255.0"; std::string mask = "255.255.255.0";
std::string gateway = "192.168.1.1"; std::string gateway = "192.168.1.1";
std::string sdk_log_level = "off";
}; };
bool parseIpString(const std::string &ip_str, uint8_t ip[4]) { bool parseIpString(const std::string &ip_str, uint8_t ip[4]) {
@@ -90,6 +91,7 @@ void printHelp() {
<< " [--enable_dhcp <true|false>] [--new_ip <ip>] [--mask <ip>] [--gateway <ip>]\n" << " [--enable_dhcp <true|false>] [--new_ip <ip>] [--mask <ip>] [--gateway <ip>]\n"
<< " ros2 run orbbec_camera ip_config_tool -- set_dhcp_timeout\\\n" << " ros2 run orbbec_camera ip_config_tool -- set_dhcp_timeout\\\n"
<< " [--current_ip <ip>] [--port <port>] --timeout <seconds>\n" << " [--current_ip <ip>] [--port <port>] --timeout <seconds>\n"
<< " [--enable_sdk_log] [--sdk_log_level debug]\n"
<< " (legacy alias: set_device_ip)\n\n" << " (legacy alias: set_device_ip)\n\n"
<< "Subcommands:\n" << "Subcommands:\n"
<< " dhcp Configure DHCP on device by current device address.\n" << " dhcp Configure DHCP on device by current device address.\n"
@@ -110,6 +112,9 @@ void printHelp() {
<< " --timeout <sec> DHCP timeout in seconds for set_dhcp_timeout.\n" << " --timeout <sec> DHCP timeout in seconds for set_dhcp_timeout.\n"
<< " --dhcp_assign_ip_timeout <sec>\n" << " --dhcp_assign_ip_timeout <sec>\n"
<< " Alias of --timeout.\n\n" << " Alias of --timeout.\n\n"
<< " --enable_sdk_log Enable SDK file log at debug level under ~/.ros/Log.\n"
<< " --sdk_log_level LEVEL SDK file log level: debug/info/warn/error/fatal/off "
"(default: off).\n\n"
<< "Examples:\n" << "Examples:\n"
<< "\n" << "\n"
<< " [DHCP]\n" << " [DHCP]\n"
@@ -137,7 +142,11 @@ void printHelp() {
<< " Timeout: ros2 run orbbec_camera ip_config_tool -- \\\n" << " Timeout: ros2 run orbbec_camera ip_config_tool -- \\\n"
<< " set_dhcp_timeout \\\n" << " set_dhcp_timeout \\\n"
<< " --current_ip 192.168.1.10 \\\n" << " --current_ip 192.168.1.10 \\\n"
<< " --timeout 10\n"; << " --timeout 10\n"
<< " [SDK Log]\n"
<< " Debug: ros2 run orbbec_camera ip_config_tool -- \\\n"
<< " dhcp --current_ip 192.168.1.10 --enable_dhcp true \\\n"
<< " --enable_sdk_log --sdk_log_level debug\n";
} }
bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) { bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
@@ -313,6 +322,24 @@ bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
continue; continue;
} }
if (current == "--enable_sdk_log") {
args.sdk_log_level = "debug";
continue;
}
if (current.rfind("--sdk_log_level=", 0) == 0) {
args.sdk_log_level = current.substr(std::strlen("--sdk_log_level="));
continue;
}
if (current == "--sdk_log_level") {
if (++i >= argc) {
error = "--sdk_log_level requires a value";
return false;
}
args.sdk_log_level = argv[i];
continue;
}
error = "Unknown argument: " + current; error = "Unknown argument: " + current;
return false; return false;
} }
@@ -337,6 +364,12 @@ bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
error = "set_dhcp_timeout requires --timeout <seconds>"; error = "set_dhcp_timeout requires --timeout <seconds>";
return false; return false;
} }
const auto log_severity = orbbec_camera::obLogSeverityFromString(args.sdk_log_level);
if (log_severity == OBLogSeverity::OB_LOG_SEVERITY_OFF && args.sdk_log_level != "off" &&
args.sdk_log_level != "none") {
error = "--sdk_log_level expects one of: debug, info, warn, error, fatal, off";
return false;
}
return true; return true;
} }
@@ -358,7 +391,11 @@ int main(int argc, char **argv) {
auto logger = rclcpp::get_logger("ip_config_tool"); auto logger = rclcpp::get_logger("ip_config_tool");
try { try {
ob::Context::setLoggerSeverity(OBLogSeverity::OB_LOG_SEVERITY_OFF); const auto sdk_log_path =
orbbec_camera::configureObSdkLoggerForTool("ip_config_tool", args.sdk_log_level);
if (!sdk_log_path.empty()) {
RCLCPP_INFO(logger, "SDK file log enabled: %s", sdk_log_path.c_str());
}
auto context = std::make_shared<ob::Context>(); auto context = std::make_shared<ob::Context>();
if (args.operation == CliArgs::Operation::DHCP) { if (args.operation == CliArgs::Operation::DHCP) {
+40 -1
View File
@@ -14,6 +14,7 @@ namespace {
struct CliArgs { struct CliArgs {
bool help = false; bool help = false;
std::string serial_number; std::string serial_number;
std::string sdk_log_level = "off";
}; };
void printUsage() { void printUsage() {
@@ -23,7 +24,14 @@ void printUsage() {
<< " [--serial_number SN]\n\n" << " [--serial_number SN]\n\n"
<< "Parameters:\n" << "Parameters:\n"
<< " --serial_number SN Select a specific camera by serial number.\n" << " --serial_number SN Select a specific camera by serial number.\n"
<< " -h, --help Show this help message.\n"; << " --enable_sdk_log Enable SDK file log at debug level under ~/.ros/Log.\n"
<< " --sdk_log_level LEVEL\n"
<< " SDK file log level: debug/info/warn/error/fatal/off "
"(default: off).\n"
<< " -h, --help Show this help message.\n"
<< "Examples:\n"
<< " ros2 run orbbec_camera list_camera_profile_mode_node -- --enable_sdk_log "
"--sdk_log_level debug\n";
} }
bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) { bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
@@ -52,10 +60,35 @@ bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
continue; continue;
} }
if (current == "--enable_sdk_log") {
args.sdk_log_level = "debug";
continue;
}
if (current.rfind("--sdk_log_level=", 0) == 0) {
args.sdk_log_level = current.substr(std::strlen("--sdk_log_level="));
continue;
}
if (current == "--sdk_log_level") {
if (++i >= argc) {
error = "--sdk_log_level requires a value";
return false;
}
args.sdk_log_level = argv[i];
continue;
}
error = "Unknown argument: " + current; error = "Unknown argument: " + current;
return false; return false;
} }
const auto log_severity = obLogSeverityFromString(args.sdk_log_level);
if (log_severity == OBLogSeverity::OB_LOG_SEVERITY_OFF && args.sdk_log_level != "off" &&
args.sdk_log_level != "none") {
error = "--sdk_log_level expects one of: debug, info, warn, error, fatal, off";
return false;
}
return true; return true;
} }
@@ -163,6 +196,12 @@ int main(int argc, char **argv) {
return 0; return 0;
} }
const auto sdk_log_path =
configureObSdkLoggerForTool("list_camera_profile_mode_node", args.sdk_log_level);
if (!sdk_log_path.empty()) {
std::cout << "SDK file log enabled: " << sdk_log_path << std::endl;
}
auto device = initializeDevice(args.serial_number); auto device = initializeDevice(args.serial_number);
if (!device) { if (!device) {
return -1; return -1;
+75 -2
View File
@@ -16,6 +16,8 @@
#include <rclcpp/rclcpp.hpp> #include <rclcpp/rclcpp.hpp>
#include <iomanip> #include <iomanip>
#include <cstring>
#include <iostream>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <string> #include <string>
@@ -24,6 +26,60 @@
#include <orbbec_camera/utils.h> #include <orbbec_camera/utils.h>
namespace { namespace {
struct CliArgs {
bool help = false;
std::string sdk_log_level = "off";
};
void printUsage() {
std::cout << "Usage:\n"
<< " ros2 run orbbec_camera list_devices_node -- [options]\n\n"
<< "Options:\n"
<< " --enable_sdk_log Enable SDK file log at debug level under ~/.ros/Log.\n"
<< " --sdk_log_level LEVEL SDK file log level: debug/info/warn/error/fatal/off "
"(default: off).\n\n"
<< "Examples:\n"
<< " ros2 run orbbec_camera list_devices_node -- --enable_sdk_log --sdk_log_level "
"debug\n";
}
bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
for (int i = 1; i < argc; ++i) {
const std::string current = argv[i];
if (current == "-h" || current == "--help") {
args.help = true;
return true;
}
if (current == "--enable_sdk_log") {
args.sdk_log_level = "debug";
continue;
}
if (current.rfind("--sdk_log_level=", 0) == 0) {
args.sdk_log_level = current.substr(std::strlen("--sdk_log_level="));
continue;
}
if (current == "--sdk_log_level") {
if (++i >= argc) {
error = "--sdk_log_level requires a value";
return false;
}
args.sdk_log_level = argv[i];
continue;
}
error = "Unknown argument: " + current;
return false;
}
const auto log_severity = orbbec_camera::obLogSeverityFromString(args.sdk_log_level);
if (log_severity == OBLogSeverity::OB_LOG_SEVERITY_OFF && args.sdk_log_level != "off" &&
args.sdk_log_level != "none") {
error = "--sdk_log_level expects one of: debug, info, warn, error, fatal, off";
return false;
}
return true;
}
std::string ipSourceTypeToString(int ip_source_type) { std::string ipSourceTypeToString(int ip_source_type) {
switch (ip_source_type) { switch (ip_source_type) {
case 0: case 0:
@@ -66,9 +122,26 @@ void printPresetInfo(const std::shared_ptr<ob::Device>& device) {
} }
} // namespace } // namespace
int main() { int main(int argc, char **argv) {
CliArgs args;
std::string parse_error;
if (!parseArgs(argc, argv, args, parse_error)) {
std::cerr << "Argument error: " << parse_error << std::endl;
printUsage();
return 1;
}
if (args.help) {
printUsage();
return 0;
}
try { try {
ob::Context::setLoggerSeverity(OBLogSeverity::OB_LOG_SEVERITY_OFF); const auto sdk_log_path =
orbbec_camera::configureObSdkLoggerForTool("list_devices_node", args.sdk_log_level);
if (!sdk_log_path.empty()) {
RCLCPP_INFO(rclcpp::get_logger("list_device_node"), "SDK file log enabled: %s",
sdk_log_path.c_str());
}
auto context = std::make_unique<ob::Context>(); auto context = std::make_unique<ob::Context>();
auto list = context->queryDeviceList(); auto list = context->queryDeviceList();
for (size_t i = 0; i < list->deviceCount(); i++) { for (size_t i = 0; i < list->deviceCount(); i++) {