From 6191a298353559ec844b986f591911e01150d12f Mon Sep 17 00:00:00 2001 From: "tom.lemmel" Date: Thu, 25 Jun 2026 08:28:55 +0000 Subject: [PATCH] DaBai DCW: software 180-deg rotation fallback for color/depth Devices whose firmware does not support the hardware rotate property (e.g. DaBai DCW) silently ignored color_rotation/depth_rotation. Add a software fallback: in setupDevices(), when OB_PROP_*_ROTATE_INT is not supported, record the requested angle in dedicated *_sw_ members and apply cv::rotate(ROTATE_180) in the image path. Only 180 deg is handled in software since it preserves image dimensions (step / camera_info stay valid). Hardware rotation behaviour is unchanged. Also expose color_rotation / depth_rotation launch args in dabai_dcw.launch.py. --- .../include/orbbec_camera/ob_camera_node.h | 4 ++ orbbec_camera/launch/dabai_dcw.launch.py | 2 + orbbec_camera/src/ob_camera_node.cpp | 38 ++++++++++++++----- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/orbbec_camera/include/orbbec_camera/ob_camera_node.h b/orbbec_camera/include/orbbec_camera/ob_camera_node.h index e053d599..de238f88 100644 --- a/orbbec_camera/include/orbbec_camera/ob_camera_node.h +++ b/orbbec_camera/include/orbbec_camera/ob_camera_node.h @@ -475,6 +475,10 @@ class OBCameraNode { int depth_rotation_ = -1; int left_ir_rotation_ = -1; int right_ir_rotation_ = -1; + // Software-rotation fallback values (degrees), set in setupDevices() only when the + // device firmware does not support hardware rotate (e.g. DaBai DCW). -1 = disabled. + int color_rotation_sw_ = -1; + int depth_rotation_sw_ = -1; int color_exposure_ = -1; int color_gain_ = -1; int color_white_balance_ = -1; diff --git a/orbbec_camera/launch/dabai_dcw.launch.py b/orbbec_camera/launch/dabai_dcw.launch.py index 96e1618f..cabc58da 100644 --- a/orbbec_camera/launch/dabai_dcw.launch.py +++ b/orbbec_camera/launch/dabai_dcw.launch.py @@ -30,6 +30,7 @@ def generate_launch_description(): DeclareLaunchArgument('color_format', default_value='MJPG'), DeclareLaunchArgument('enable_color', default_value='true'), DeclareLaunchArgument('flip_color', default_value='false'), + DeclareLaunchArgument('color_rotation', default_value='-1'), DeclareLaunchArgument('color_qos', default_value='default'), DeclareLaunchArgument('color_camera_info_qos', default_value='default'), DeclareLaunchArgument('enable_color_auto_exposure', default_value='true'), @@ -44,6 +45,7 @@ def generate_launch_description(): DeclareLaunchArgument('depth_format', default_value='Y11'), DeclareLaunchArgument('enable_depth', default_value='true'), DeclareLaunchArgument('flip_depth', default_value='false'), + DeclareLaunchArgument('depth_rotation', default_value='-1'), DeclareLaunchArgument('min_depth_limit', default_value='0'), DeclareLaunchArgument('max_depth_limit', default_value='0'), DeclareLaunchArgument('depth_qos', default_value='default'), diff --git a/orbbec_camera/src/ob_camera_node.cpp b/orbbec_camera/src/ob_camera_node.cpp index 39414d5c..aedbe64e 100644 --- a/orbbec_camera/src/ob_camera_node.cpp +++ b/orbbec_camera/src/ob_camera_node.cpp @@ -347,17 +347,25 @@ void OBCameraNode::setupDevices() { roi.y1_bottom = depth_ae_roi_bottom_; device_->setStructuredData(OB_STRUCT_DEPTH_AE_ROI, &roi, sizeof(AE_ROI)); } - if (color_rotation_ != -1 && - device_->isPropertySupported(OB_PROP_COLOR_ROTATE_INT, OB_PERMISSION_READ_WRITE)) { - device_->setIntProperty(OB_PROP_COLOR_ROTATE_INT, color_rotation_); - RCLCPP_INFO_STREAM( - logger_, "set color rotation to " << device_->getIntProperty(OB_PROP_COLOR_ROTATE_INT)); + if (color_rotation_ != -1) { + if (device_->isPropertySupported(OB_PROP_COLOR_ROTATE_INT, OB_PERMISSION_READ_WRITE)) { + device_->setIntProperty(OB_PROP_COLOR_ROTATE_INT, color_rotation_); + RCLCPP_INFO_STREAM( + logger_, "set color rotation to " << device_->getIntProperty(OB_PROP_COLOR_ROTATE_INT)); + } else { + // Firmware has no hardware color rotate (e.g. DaBai DCW); fall back to software. + color_rotation_sw_ = color_rotation_; + } } - if (depth_rotation_ != -1 && - device_->isPropertySupported(OB_PROP_DEPTH_ROTATE_INT, OB_PERMISSION_READ_WRITE)) { - device_->setIntProperty(OB_PROP_DEPTH_ROTATE_INT, depth_rotation_); - RCLCPP_INFO_STREAM( - logger_, "set depth rotation to " << device_->getIntProperty(OB_PROP_DEPTH_ROTATE_INT)); + if (depth_rotation_ != -1) { + if (device_->isPropertySupported(OB_PROP_DEPTH_ROTATE_INT, OB_PERMISSION_READ_WRITE)) { + device_->setIntProperty(OB_PROP_DEPTH_ROTATE_INT, depth_rotation_); + RCLCPP_INFO_STREAM( + logger_, "set depth rotation to " << device_->getIntProperty(OB_PROP_DEPTH_ROTATE_INT)); + } else { + // Firmware has no hardware depth rotate (e.g. DaBai DCW); fall back to software. + depth_rotation_sw_ = depth_rotation_; + } } if (left_ir_rotation_ != -1 && device_->isPropertySupported(OB_PROP_IR_ROTATE_INT, OB_PERMISSION_READ_WRITE)) { @@ -2190,6 +2198,16 @@ void OBCameraNode::onNewFrameCallback(const std::shared_ptr &frame, // flip image cv::flip(image, image, 1); } + // Software rotation fallback for devices whose firmware does not support hardware + // rotate (e.g. DaBai DCW). color_rotation_sw_/depth_rotation_sw_ are only set in + // setupDevices() when the hardware rotate property was unavailable. Only 180 is done + // in software since it preserves image dimensions (step / camera_info stay valid). + int rotation_deg = (stream_index == COLOR) ? color_rotation_sw_ + : (stream_index == DEPTH) ? depth_rotation_sw_ + : -1; + if (rotation_deg == 180) { + cv::rotate(image, image, cv::ROTATE_180); + } sensor_msgs::msg::Image::UniquePtr image_msg(new sensor_msgs::msg::Image()); cv_bridge::CvImage(std_msgs::msg::Header(), encoding_[stream_index], image)