feat: add Force IP configuration support with MAC address specification

This commit is contained in:
obyalian
2025-09-18 14:09:49 +08:00
parent 88922c3488
commit 8a0b92e4f7
5 changed files with 36 additions and 30 deletions
@@ -135,6 +135,7 @@ class OBCameraNodeDriver : public rclcpp::Node {
std::string node_name_; std::string node_name_;
bool force_ip_enable_{false}; bool force_ip_enable_{false};
bool force_ip_dhcp_{false}; bool force_ip_dhcp_{false};
std::string force_ip_mac_; // e.g. "54:14:FD:06:07:DA"
std::string force_ip_address_; // e.g. "192.168.1.10" std::string force_ip_address_; // e.g. "192.168.1.10"
std::string force_ip_subnet_mask_; // e.g. "255.255.255.0" std::string force_ip_subnet_mask_; // e.g. "255.255.255.0"
std::string force_ip_gateway_; // e.g. "192.168.1.1" std::string force_ip_gateway_; // e.g. "192.168.1.1"
@@ -114,6 +114,15 @@ def generate_launch_description():
DeclareLaunchArgument("laser_energy_level", default_value="-1"), DeclareLaunchArgument("laser_energy_level", default_value="-1"),
DeclareLaunchArgument("enable_heartbeat", default_value="false"), DeclareLaunchArgument("enable_heartbeat", default_value="false"),
DeclareLaunchArgument("time_domain", default_value="global"), DeclareLaunchArgument("time_domain", default_value="global"),
# If only one camera (network device) is currently connected, you do not need to specify the MAC address.
# Otherwise, you need to specify it yourself. For example, "54:14:FD:06:07:DA"
DeclareLaunchArgument("force_ip_enable", default_value="false"),
DeclareLaunchArgument("force_ip_mac", default_value=""),
DeclareLaunchArgument("force_ip_dhcp", default_value="false"),
DeclareLaunchArgument("force_ip_address", default_value="192.168.1.10"),
DeclareLaunchArgument("force_ip_subnet_mask", default_value="255.255.255.0"),
DeclareLaunchArgument("force_ip_gateway", default_value="192.168.1.1"),
] ]
# Node configuration # Node configuration
@@ -285,6 +285,14 @@ def generate_launch_description():
DeclareLaunchArgument('laser_index0_ir_brightness', default_value='60'), DeclareLaunchArgument('laser_index0_ir_brightness', default_value='60'),
DeclareLaunchArgument('laser_index0_ir_ae_max_exposure', default_value='30000'), DeclareLaunchArgument('laser_index0_ir_ae_max_exposure', default_value='30000'),
DeclareLaunchArgument('show_fps_enable', default_value='false'), DeclareLaunchArgument('show_fps_enable', default_value='false'),
# If only one camera (network device) is currently connected, you do not need to specify the MAC address.
# Otherwise, you need to specify it yourself. For example, "54:14:FD:06:07:DA"
DeclareLaunchArgument("force_ip_enable", default_value="false"),
DeclareLaunchArgument("force_ip_mac", default_value=""),
DeclareLaunchArgument("force_ip_dhcp", default_value="false"),
DeclareLaunchArgument("force_ip_address", default_value="192.168.1.10"),
DeclareLaunchArgument("force_ip_subnet_mask", default_value="255.255.255.0"),
DeclareLaunchArgument("force_ip_gateway", default_value="192.168.1.1"),
#color image transport plugins #color image transport plugins
DeclareLaunchArgument('color.image_raw.enable_pub_plugins',default_value='["image_transport/compressed", "image_transport/raw", "image_transport/theora"]'), DeclareLaunchArgument('color.image_raw.enable_pub_plugins',default_value='["image_transport/compressed", "image_transport/raw", "image_transport/theora"]'),
@@ -297,6 +297,9 @@ def generate_launch_description():
DeclareLaunchArgument('right_ir.image_raw.enable_pub_plugins',default_value='["image_transport/compressed", "image_transport/raw", "image_transport/theora"]'), DeclareLaunchArgument('right_ir.image_raw.enable_pub_plugins',default_value='["image_transport/compressed", "image_transport/raw", "image_transport/theora"]'),
DeclareLaunchArgument("force_ip_enable", default_value="false"), DeclareLaunchArgument("force_ip_enable", default_value="false"),
# If only one camera (network device) is currently connected, you do not need to specify the MAC address.
# Otherwise, you need to specify it yourself. For example, "54:14:FD:06:07:DA"
DeclareLaunchArgument("force_ip_mac", default_value=""),
DeclareLaunchArgument("force_ip_dhcp", default_value="false"), DeclareLaunchArgument("force_ip_dhcp", default_value="false"),
DeclareLaunchArgument("force_ip_address", default_value="192.168.1.10"), DeclareLaunchArgument("force_ip_address", default_value="192.168.1.10"),
DeclareLaunchArgument("force_ip_subnet_mask", default_value="255.255.255.0"), DeclareLaunchArgument("force_ip_subnet_mask", default_value="255.255.255.0"),
+15 -30
View File
@@ -185,7 +185,14 @@ void OBCameraNodeDriver::init() {
} else { } else {
ctx_ = std::make_unique<ob::Context>(config_path_.c_str()); ctx_ = std::make_unique<ob::Context>(config_path_.c_str());
} }
// Force IP
force_ip_enable_ = declare_parameter<bool>("force_ip_enable", false);
force_ip_mac_ = declare_parameter<std::string>("force_ip_mac", "");
force_ip_dhcp_ = declare_parameter<bool>("force_ip_dhcp", false);
force_ip_address_ = declare_parameter<std::string>("force_ip_address", "192.168.1.10");
force_ip_subnet_mask_ = declare_parameter<std::string>("force_ip_subnet_mask", "255.255.255.0");
force_ip_gateway_ = declare_parameter<std::string>("force_ip_gateway", "192.168.1.1");
applyForceIpConfig();
auto log_level_str = declare_parameter<std::string>("log_level", "none"); auto log_level_str = declare_parameter<std::string>("log_level", "none");
auto log_level = obLogSeverityFromString(log_level_str); auto log_level = obLogSeverityFromString(log_level_str);
connection_delay_ = static_cast<int>(declare_parameter<int>("connection_delay", 100)); connection_delay_ = static_cast<int>(declare_parameter<int>("connection_delay", 100));
@@ -243,12 +250,6 @@ void OBCameraNodeDriver::init() {
ctx_->setUvcBackendType(OB_UVC_BACKEND_TYPE_LIBUVC); ctx_->setUvcBackendType(OB_UVC_BACKEND_TYPE_LIBUVC);
RCLCPP_INFO_STREAM(logger_, "setUvcBackendType:" << uvc_backend_); RCLCPP_INFO_STREAM(logger_, "setUvcBackendType:" << uvc_backend_);
} }
// Force IP
force_ip_enable_ = declare_parameter<bool>("force_ip_enable", false);
force_ip_dhcp_ = declare_parameter<bool>("force_ip_dhcp", false);
force_ip_address_ = declare_parameter<std::string>("force_ip_address", "192.168.1.10");
force_ip_subnet_mask_ = declare_parameter<std::string>("force_ip_subnet_mask", "255.255.255.0");
force_ip_gateway_ = declare_parameter<std::string>("force_ip_gateway", "192.168.1.1");
ctx_->enableNetDeviceEnumeration(enumerate_net_device_); ctx_->enableNetDeviceEnumeration(enumerate_net_device_);
ctx_->setDeviceChangedCallback([this](const std::shared_ptr<ob::DeviceList> &removed_list, ctx_->setDeviceChangedCallback([this](const std::shared_ptr<ob::DeviceList> &removed_list,
const std::shared_ptr<ob::DeviceList> &added_list) { const std::shared_ptr<ob::DeviceList> &added_list) {
@@ -1034,34 +1035,20 @@ bool OBCameraNodeDriver::applyForceIpConfig() {
auto device_list = ctx_->queryDeviceList(); auto device_list = ctx_->queryDeviceList();
uint32_t index = 0; uint32_t index = 0;
std::string mac; std::string mac;
if (!serial_number_.empty() && device_list->getCount() > 1) { if (!force_ip_mac_.empty()) {
RCLCPP_INFO(logger_, "Multiple devices detected, selecting by serial number: %s", mac = force_ip_mac_;
serial_number_.c_str()); } else if (device_list->getCount() == 1) {
auto device = selectDeviceBySerialNumber(device_list, serial_number_);
if (device == nullptr) {
RCLCPP_ERROR(logger_, "Device with serial number %s not found for Force IP",
serial_number_.c_str());
return false;
}
mac = device->getDeviceInfo()->getUid();
std::cout << "Selected device MAC for Force IP: " << mac << std::endl;
} else {
mac = device_list->getUid(index); mac = device_list->getUid(index);
std::cout << "Default selected device MAC: " << mac << std::endl; } else {
RCLCPP_ERROR(logger_, "MAC address is empty");
return false;
} }
if (ctx_->changeNetDeviceIpConfig(mac.c_str(), config)) { if (ctx_->changeNetDeviceIpConfig(mac.c_str(), config)) {
RCLCPP_INFO(logger_, RCLCPP_INFO(logger_,
"Force IP config applied. force_ip_dhcp=%d ip=%s mask=%s force_ip_gateway=%s", "Force IP config applied. force_ip_dhcp=%d ip=%s mask=%s force_ip_gateway=%s",
config.dhcp, force_ip_address_.c_str(), force_ip_subnet_mask_.c_str(), config.dhcp, force_ip_address_.c_str(), force_ip_subnet_mask_.c_str(),
force_ip_gateway_.c_str()); force_ip_gateway_.c_str());
RCLCPP_INFO(logger_, "Reboot device after Force IP");
device_connected_ = false;
force_ip_success_ = true; force_ip_success_ = true;
{
std::unique_lock<decltype(reset_device_mutex_)> reset_device_lock(reset_device_mutex_);
reset_device_flag_ = true;
}
reset_device_cond_.notify_all();
} else { } else {
RCLCPP_ERROR(logger_, "Failed to apply Force IP config (SDK returned false)"); RCLCPP_ERROR(logger_, "Failed to apply Force IP config (SDK returned false)");
} }
@@ -1116,9 +1103,7 @@ void OBCameraNodeDriver::startDevice(const std::shared_ptr<ob::DeviceList> &list
if (device_connected_.load()) { if (device_connected_.load()) {
return; return;
} }
if (applyForceIpConfig()) {
return;
}
// Try to set connecting flag atomically // Try to set connecting flag atomically
bool expected = false; bool expected = false;
if (!device_connecting_.compare_exchange_strong(expected, true)) { if (!device_connecting_.compare_exchange_strong(expected, true)) {