2023-09-08 08:55:16 +08:00
|
|
|
/*******************************************************************************
|
2023-09-13 19:27:20 +08:00
|
|
|
* Copyright (c) 2023 Orbbec 3D Technology, Inc
|
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
|
*
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*******************************************************************************/
|
2022-06-08 14:51:00 +08:00
|
|
|
|
2022-06-06 19:00:12 +08:00
|
|
|
#include "orbbec_camera/ob_camera_node.h"
|
|
|
|
|
#include <rclcpp/rclcpp.hpp>
|
2022-06-09 15:47:02 +08:00
|
|
|
#include <nlohmann/json.hpp>
|
2022-06-06 19:00:12 +08:00
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
|
|
#include "orbbec_camera/utils.h"
|
|
|
|
|
namespace orbbec_camera {
|
2022-06-10 14:52:49 +08:00
|
|
|
|
2026-02-27 17:33:34 +08:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
bool isGemini330SeriesForDisparity(uint32_t pid) {
|
|
|
|
|
return pid == GEMINI_335_PID || pid == GEMINI_336_PID || pid == GEMINI_330_PID ||
|
|
|
|
|
pid == GEMINI_335L_PID || pid == GEMINI_336L_PID || pid == GEMINI_330L_PID ||
|
|
|
|
|
pid == GEMINI_335LG_PID || pid == GEMINI_335LE_PID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isSupportedDisparityResolutionForPid(uint32_t pid, int width, int height) {
|
|
|
|
|
if (pid == GEMINI_335LE_PID) {
|
|
|
|
|
return (width == 1280 && height == 800) || (width == 640 && height == 400) ||
|
|
|
|
|
(width == 424 && height == 266) || (width == 320 && height == 200);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (width == 1280 && height == 800) || (width == 1280 && height == 720) ||
|
|
|
|
|
(width == 640 && height == 400) || (width == 424 && height == 266);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string getDisparityResolutionHintByPid(uint32_t pid) {
|
|
|
|
|
if (pid == GEMINI_335LE_PID) {
|
|
|
|
|
return "Supported resolutions for Gemini 335Le: 1280x800/640x400/424x266/320x200";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "Supported resolutions for Gemini 335/336/330/335L/336L/335Lg/330L: "
|
|
|
|
|
"1280x800/1280x720/640x400/424x266";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
2022-06-06 19:00:12 +08:00
|
|
|
void OBCameraNode::setupCameraCtrlServices() {
|
|
|
|
|
using std_srvs::srv::SetBool;
|
|
|
|
|
for (auto stream_index : IMAGE_STREAMS) {
|
2023-02-17 14:43:55 +08:00
|
|
|
if (!enable_stream_[stream_index]) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2023-02-06 17:26:10 +08:00
|
|
|
auto stream_name = stream_name_[stream_index];
|
2022-06-13 16:02:49 +08:00
|
|
|
std::string service_name = "get_" + stream_name + "_exposure";
|
|
|
|
|
get_exposure_srv_[stream_index] = node_->create_service<GetInt32>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<GetInt32::Request> request,
|
|
|
|
|
std::shared_ptr<GetInt32::Response> response) {
|
|
|
|
|
getExposureCallback(request, response, stream_index);
|
|
|
|
|
});
|
2022-06-06 19:00:12 +08:00
|
|
|
|
2022-06-13 16:02:49 +08:00
|
|
|
service_name = "set_" + stream_name + "_exposure";
|
|
|
|
|
set_exposure_srv_[stream_index] = node_->create_service<SetInt32>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<SetInt32::Request> request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response> response) {
|
|
|
|
|
setExposureCallback(request, response, stream_index);
|
|
|
|
|
});
|
|
|
|
|
service_name = "get_" + stream_name + "_gain";
|
|
|
|
|
get_gain_srv_[stream_index] = node_->create_service<GetInt32>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<GetInt32::Request> request,
|
|
|
|
|
std::shared_ptr<GetInt32::Response> response) {
|
|
|
|
|
getGainCallback(request, response, stream_index);
|
|
|
|
|
});
|
2022-06-06 19:00:12 +08:00
|
|
|
|
2022-06-13 16:02:49 +08:00
|
|
|
service_name = "set_" + stream_name + "_gain";
|
|
|
|
|
set_gain_srv_[stream_index] = node_->create_service<SetInt32>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<SetInt32::Request> request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response> response) {
|
|
|
|
|
setGainCallback(request, response, stream_index);
|
|
|
|
|
});
|
2022-06-24 14:58:43 +08:00
|
|
|
service_name = "set_" + stream_name + "_auto_exposure";
|
|
|
|
|
set_auto_exposure_srv_[stream_index] = node_->create_service<SetBool>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
|
|
|
|
setAutoExposureCallback(request, response, stream_index);
|
|
|
|
|
});
|
|
|
|
|
|
2025-03-21 09:28:42 +08:00
|
|
|
service_name = "set_" + stream_name + "_ae_roi";
|
|
|
|
|
set_ae_roi_srv_[stream_index] = node_->create_service<SetArrays>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<SetArrays::Request> request,
|
|
|
|
|
std::shared_ptr<SetArrays::Response> response) {
|
|
|
|
|
setAeRoiCallback(request, response, stream_index);
|
|
|
|
|
});
|
|
|
|
|
|
2022-06-13 16:02:49 +08:00
|
|
|
service_name = "toggle_" + stream_name;
|
|
|
|
|
|
|
|
|
|
toggle_sensor_srv_[stream_index] = node_->create_service<SetBool>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
|
|
|
|
toggleSensorCallback(request, response, stream_index);
|
|
|
|
|
});
|
2023-02-17 15:42:53 +08:00
|
|
|
service_name = "set_" + stream_name + "_mirror";
|
|
|
|
|
set_mirror_srv_[stream_index] = node_->create_service<SetBool>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
|
|
|
|
setMirrorCallback(request, response, stream_index);
|
|
|
|
|
});
|
2025-05-12 11:52:56 +08:00
|
|
|
service_name = "set_" + stream_name + "_flip";
|
|
|
|
|
set_flip_srv_[stream_index] = node_->create_service<SetBool>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
|
|
|
|
setFlipCallback(request, response, stream_index);
|
|
|
|
|
});
|
|
|
|
|
service_name = "set_" + stream_name + "_rotation";
|
|
|
|
|
set_rotation_srv_[stream_index] = node_->create_service<SetInt32>(
|
|
|
|
|
service_name,
|
|
|
|
|
[this, stream_index = stream_index](const std::shared_ptr<SetInt32::Request> request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response> response) {
|
|
|
|
|
setRotationCallback(request, response, stream_index);
|
|
|
|
|
});
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
2023-02-17 15:42:53 +08:00
|
|
|
set_fan_work_mode_srv_ = node_->create_service<SetInt32>(
|
2023-02-17 15:18:52 +08:00
|
|
|
"set_fan_work_mode", [this](const std::shared_ptr<SetInt32::Request> request,
|
2023-02-17 15:42:53 +08:00
|
|
|
std::shared_ptr<SetInt32::Response> response) {
|
|
|
|
|
setFanWorkModeCallback(request, response);
|
2022-06-06 19:00:12 +08:00
|
|
|
});
|
|
|
|
|
set_floor_enable_srv_ = node_->create_service<SetBool>(
|
2022-06-07 15:18:19 +08:00
|
|
|
"set_floor_enable", [this](const std::shared_ptr<rmw_request_id_t> request_header,
|
2022-06-07 18:09:17 +08:00
|
|
|
const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
2022-06-06 19:00:12 +08:00
|
|
|
setFloorEnableCallback(request_header, request, response);
|
|
|
|
|
});
|
|
|
|
|
set_laser_enable_srv_ = node_->create_service<SetBool>(
|
2022-06-07 15:18:19 +08:00
|
|
|
"set_laser_enable", [this](const std::shared_ptr<rmw_request_id_t> request_header,
|
2022-06-07 18:09:17 +08:00
|
|
|
const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
2022-06-06 19:00:12 +08:00
|
|
|
setLaserEnableCallback(request_header, request, response);
|
|
|
|
|
});
|
2025-02-28 10:50:43 +08:00
|
|
|
set_ldp_enable_srv_ = node_->create_service<SetBool>(
|
|
|
|
|
"set_ldp_enable", [this](const std::shared_ptr<rmw_request_id_t> request_header,
|
2022-06-07 18:09:17 +08:00
|
|
|
const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
2025-02-28 10:50:43 +08:00
|
|
|
setLdpEnableCallback(request_header, request, response);
|
2022-06-06 19:00:12 +08:00
|
|
|
});
|
2025-02-28 10:50:43 +08:00
|
|
|
get_ldp_status_srv_ = node_->create_service<GetBool>(
|
|
|
|
|
"get_ldp_status", [this](const std::shared_ptr<rmw_request_id_t> request_header,
|
2023-02-17 15:42:53 +08:00
|
|
|
const std::shared_ptr<GetBool::Request> request,
|
|
|
|
|
std::shared_ptr<GetBool::Response> response) {
|
|
|
|
|
(void)request_header;
|
2025-02-28 10:50:43 +08:00
|
|
|
getLdpStatusCallback(request, response);
|
2023-02-17 15:42:53 +08:00
|
|
|
});
|
2025-11-03 14:24:53 +08:00
|
|
|
get_laser_status_srv_ = node_->create_service<GetBool>(
|
|
|
|
|
"get_laser_status", [this](const std::shared_ptr<rmw_request_id_t> request_header,
|
|
|
|
|
const std::shared_ptr<GetBool::Request> request,
|
|
|
|
|
std::shared_ptr<GetBool::Response> response) {
|
|
|
|
|
(void)request_header;
|
|
|
|
|
getLaserStatusCallback(request, response);
|
|
|
|
|
});
|
2025-08-05 17:43:10 +08:00
|
|
|
set_ptp_config_srv_ = node_->create_service<SetBool>(
|
|
|
|
|
"set_ptp_config", [this](const std::shared_ptr<rmw_request_id_t> request_header,
|
|
|
|
|
const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
|
|
|
|
setPtpConfigCallback(request_header, request, response);
|
|
|
|
|
});
|
|
|
|
|
get_ptp_config_srv_ = node_->create_service<GetBool>(
|
|
|
|
|
"get_ptp_config", [this](const std::shared_ptr<rmw_request_id_t> request_header,
|
|
|
|
|
const std::shared_ptr<GetBool::Request> request,
|
|
|
|
|
std::shared_ptr<GetBool::Response> response) {
|
|
|
|
|
(void)request_header;
|
|
|
|
|
getPtpConfigCallback(request, response);
|
|
|
|
|
});
|
2022-06-06 19:00:12 +08:00
|
|
|
|
|
|
|
|
get_white_balance_srv_ = node_->create_service<GetInt32>(
|
2022-06-13 14:58:47 +08:00
|
|
|
"get_white_balance", [this](const std::shared_ptr<GetInt32::Request> request,
|
2022-06-07 18:09:17 +08:00
|
|
|
std::shared_ptr<GetInt32::Response> response) {
|
2022-06-13 14:58:47 +08:00
|
|
|
getWhiteBalanceCallback(request, response);
|
2022-06-06 19:00:12 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
set_white_balance_srv_ = node_->create_service<SetInt32>(
|
2022-06-13 14:58:47 +08:00
|
|
|
"set_white_balance", [this](const std::shared_ptr<SetInt32::Request> request,
|
2022-06-07 18:09:17 +08:00
|
|
|
std::shared_ptr<SetInt32::Response> response) {
|
2022-06-13 14:58:47 +08:00
|
|
|
setWhiteBalanceCallback(request, response);
|
2022-06-06 19:00:12 +08:00
|
|
|
});
|
2022-06-24 14:58:43 +08:00
|
|
|
get_auto_white_balance_srv_ = node_->create_service<GetInt32>(
|
2022-06-24 17:00:18 +08:00
|
|
|
"get_auto_white_balance", [this](const std::shared_ptr<GetInt32::Request> request,
|
2023-02-13 15:43:08 +08:00
|
|
|
std::shared_ptr<GetInt32::Response> response) {
|
2022-06-24 14:58:43 +08:00
|
|
|
getAutoWhiteBalanceCallback(request, response);
|
|
|
|
|
});
|
|
|
|
|
set_auto_white_balance_srv_ = node_->create_service<SetBool>(
|
2022-06-24 17:00:18 +08:00
|
|
|
"set_auto_white_balance", [this](const std::shared_ptr<SetBool::Request> request,
|
2023-02-13 15:43:08 +08:00
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
2022-06-24 14:58:43 +08:00
|
|
|
setAutoWhiteBalanceCallback(request, response);
|
|
|
|
|
});
|
2022-06-07 21:21:43 +08:00
|
|
|
get_device_srv_ = node_->create_service<GetDeviceInfo>(
|
2022-06-13 14:58:47 +08:00
|
|
|
"get_device_info", [this](const std::shared_ptr<GetDeviceInfo::Request> request,
|
2022-06-07 21:21:43 +08:00
|
|
|
std::shared_ptr<GetDeviceInfo::Response> response) {
|
2022-06-13 14:58:47 +08:00
|
|
|
getDeviceInfoCallback(request, response);
|
2022-06-09 15:47:02 +08:00
|
|
|
});
|
2022-06-13 14:58:47 +08:00
|
|
|
get_sdk_version_srv_ = node_->create_service<GetString>(
|
|
|
|
|
"get_sdk_version",
|
|
|
|
|
[this](const std::shared_ptr<GetString::Request> request,
|
|
|
|
|
std::shared_ptr<GetString::Response> response) { getSDKVersion(request, response); });
|
2023-02-20 14:46:02 +08:00
|
|
|
save_images_srv_ = node_->create_service<std_srvs::srv::Empty>(
|
|
|
|
|
"save_images", [this](const std::shared_ptr<std_srvs::srv::Empty::Request> request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::Empty::Response> response) {
|
|
|
|
|
saveImageCallback(request, response);
|
|
|
|
|
});
|
|
|
|
|
save_point_cloud_srv_ = node_->create_service<std_srvs::srv::Empty>(
|
|
|
|
|
"save_point_cloud", [this](const std::shared_ptr<std_srvs::srv::Empty::Request> request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::Empty::Response> response) {
|
|
|
|
|
savePointCloudCallback(request, response);
|
|
|
|
|
});
|
2023-02-27 14:02:23 +08:00
|
|
|
switch_ir_camera_srv_ = node_->create_service<SetString>(
|
|
|
|
|
"switch_ir", [this](const std::shared_ptr<SetString::Request> request,
|
2023-09-13 19:27:20 +08:00
|
|
|
std::shared_ptr<SetString::Response> response) {
|
2023-02-27 14:02:23 +08:00
|
|
|
switchIRCameraCallback(request, response);
|
|
|
|
|
});
|
2024-03-12 16:15:21 +08:00
|
|
|
set_ir_long_exposure_srv_ = node_->create_service<SetBool>(
|
|
|
|
|
"set_ir_long_exposure", [this](const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
|
|
|
|
setIRLongExposureCallback(request, response);
|
|
|
|
|
});
|
2025-02-25 11:32:50 +08:00
|
|
|
get_lrm_measure_distance_srv_ = node_->create_service<GetInt32>(
|
|
|
|
|
"get_lrm_measure_distance", [this](const std::shared_ptr<GetInt32::Request> request,
|
2024-07-10 19:57:17 +08:00
|
|
|
std::shared_ptr<GetInt32::Response> response) {
|
2025-02-25 11:32:50 +08:00
|
|
|
getLrmMeasureDistanceCallback(request, response);
|
2024-07-10 19:57:17 +08:00
|
|
|
});
|
2024-10-31 20:48:56 +08:00
|
|
|
set_reset_timestamp_srv_ = node_->create_service<SetBool>(
|
|
|
|
|
"set_reset_timestamp", [this](const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
|
|
|
|
setRESETTimestampCallback(request, response);
|
|
|
|
|
});
|
2024-11-21 15:51:00 +08:00
|
|
|
set_interleaver_laser_sync_srv_ = node_->create_service<SetInt32>(
|
|
|
|
|
"set_sync_interleaverlaser", [this](const std::shared_ptr<SetInt32::Request> request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response> response) {
|
|
|
|
|
setSYNCInterleaveLaserCallback(request, response);
|
|
|
|
|
});
|
2024-11-26 18:31:00 +08:00
|
|
|
set_sync_host_time_srv_ = node_->create_service<SetBool>(
|
2024-11-21 15:51:00 +08:00
|
|
|
"set_sync_hosttime", [this](const std::shared_ptr<SetBool::Request> request,
|
2024-11-26 18:31:00 +08:00
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
2024-11-21 15:51:00 +08:00
|
|
|
setSYNCHostimeCallback(request, response);
|
|
|
|
|
});
|
2025-06-27 14:37:03 +08:00
|
|
|
send_software_trigger_srv_ = node_->create_service<SetBool>(
|
|
|
|
|
"send_software_trigger", [this](const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
|
|
|
|
sendSoftwareTriggerCallback(request, response);
|
2025-06-23 15:11:53 +08:00
|
|
|
});
|
2026-01-07 15:28:17 +08:00
|
|
|
if (device_->getDeviceInfo()->getPid() == GEMINI_435Le_PID) {
|
|
|
|
|
write_customerdata_srv_ = node_->create_service<SetString>(
|
|
|
|
|
"write_customer_data", [this](const std::shared_ptr<SetString::Request> request,
|
|
|
|
|
std::shared_ptr<SetString::Response> response) {
|
|
|
|
|
writeCustomerDataCallback(request, response);
|
|
|
|
|
});
|
|
|
|
|
read_customerdata_srv_ = node_->create_service<GetString>(
|
|
|
|
|
"read_customer_data", [this](const std::shared_ptr<GetString::Request> request,
|
|
|
|
|
std::shared_ptr<GetString::Response> response) {
|
|
|
|
|
readCustomerDataCallback(request, response);
|
|
|
|
|
});
|
|
|
|
|
set_user_calib_params_srv_ = node_->create_service<SetUserCalibParams>(
|
|
|
|
|
"set_user_calib_params", [this](const std::shared_ptr<SetUserCalibParams::Request> request,
|
|
|
|
|
std::shared_ptr<SetUserCalibParams::Response> response) {
|
|
|
|
|
setUserCalibParamsCallback(request, response);
|
|
|
|
|
});
|
|
|
|
|
get_user_calib_params_srv_ = node_->create_service<GetUserCalibParams>(
|
|
|
|
|
"get_user_calib_params", [this](const std::shared_ptr<GetUserCalibParams::Request> request,
|
|
|
|
|
std::shared_ptr<GetUserCalibParams::Response> response) {
|
|
|
|
|
getUserCalibParamsCallback(request, response);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
set_ae_mode_srv_ = node_->create_service<SetString>(
|
|
|
|
|
"set_ae_mode", [this](const std::shared_ptr<SetString::Request> request,
|
|
|
|
|
std::shared_ptr<SetString::Response> response) {
|
|
|
|
|
setAEModeCallback(request, response);
|
2025-05-12 16:15:38 +08:00
|
|
|
});
|
2026-01-07 15:28:17 +08:00
|
|
|
set_sports_mode_srv_ = node_->create_service<SetBool>(
|
|
|
|
|
"set_sports_mode", [this](const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
|
|
|
|
setSportsModeCallback(request, response);
|
2025-05-12 16:15:38 +08:00
|
|
|
});
|
2025-08-28 21:51:42 +08:00
|
|
|
set_streams_enable_srv_ = node_->create_service<SetBool>(
|
2025-08-29 15:01:01 +08:00
|
|
|
"set_streams_enable", [this](const std::shared_ptr<SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<SetBool::Response> response) {
|
2025-08-28 21:51:42 +08:00
|
|
|
setStreamsEnableCallback(request, response);
|
|
|
|
|
});
|
|
|
|
|
get_streams_enable_srv_ = node_->create_service<GetBool>(
|
2025-08-29 15:01:01 +08:00
|
|
|
"get_streams_enable", [this](const std::shared_ptr<GetBool::Request> request,
|
|
|
|
|
std::shared_ptr<GetBool::Response> response) {
|
2025-08-28 21:51:42 +08:00
|
|
|
getStreamsEnableCallback(request, response);
|
|
|
|
|
});
|
2025-11-24 15:10:56 +08:00
|
|
|
set_point_cloud_decimation_srv_ = node_->create_service<SetInt32>(
|
|
|
|
|
"set_point_cloud_decimation", [this](const std::shared_ptr<SetInt32::Request> request,
|
2026-01-07 15:04:16 +08:00
|
|
|
std::shared_ptr<SetInt32::Response> response) {
|
2025-11-24 15:10:56 +08:00
|
|
|
setPointCloudDecimationCallback(request, response);
|
|
|
|
|
});
|
|
|
|
|
get_point_cloud_decimation_srv_ = node_->create_service<GetInt32>(
|
|
|
|
|
"get_point_cloud_decimation", [this](const std::shared_ptr<GetInt32::Request> request,
|
2026-01-07 15:04:16 +08:00
|
|
|
std::shared_ptr<GetInt32::Response> response) {
|
2025-11-24 15:10:56 +08:00
|
|
|
getPointCloudDecimationCallback(request, response);
|
|
|
|
|
});
|
2026-02-27 10:57:43 +08:00
|
|
|
set_disparity_range_mode_srv_ = node_->create_service<SetInt32>(
|
|
|
|
|
"set_disparity_range_mode", [this](const std::shared_ptr<SetInt32::Request> request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response> response) {
|
|
|
|
|
setDisparityRangeModeCallback(request, response);
|
|
|
|
|
});
|
2026-02-27 14:20:35 +08:00
|
|
|
set_disparity_search_offset_srv_ = node_->create_service<SetInt32>(
|
|
|
|
|
"set_disparity_search_offset", [this](const std::shared_ptr<SetInt32::Request> request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response> response) {
|
|
|
|
|
setDisparitySearchOffsetCallback(request, response);
|
|
|
|
|
});
|
2025-08-28 21:51:42 +08:00
|
|
|
}
|
2025-11-24 15:10:56 +08:00
|
|
|
|
|
|
|
|
void OBCameraNode::getPointCloudDecimationCallback(
|
|
|
|
|
const std::shared_ptr<GetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<GetInt32::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
response->data = point_cloud_decimation_filter_factor_;
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setPointCloudDecimationCallback(
|
|
|
|
|
const std::shared_ptr<SetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response>& response) {
|
|
|
|
|
if (!request) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "Invalid request";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (request->data <= 0 || request->data > 8) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "Decimation factor must be between 1 and 8";
|
|
|
|
|
RCLCPP_WARN_STREAM(logger_, "Invalid decimation factor: " << request->data);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
point_cloud_decimation_filter_factor_ = request->data;
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "Set point_cloud_decimation_filter_factor to "
|
2026-01-07 15:04:16 +08:00
|
|
|
<< point_cloud_decimation_filter_factor_);
|
2025-11-24 15:10:56 +08:00
|
|
|
response->success = true;
|
|
|
|
|
response->message = "Point cloud decimation factor updated successfully";
|
2026-01-07 15:04:16 +08:00
|
|
|
} catch (const std::exception& e) {
|
2025-11-24 15:10:56 +08:00
|
|
|
response->success = false;
|
|
|
|
|
response->message = std::string("Failed to set decimation factor: ") + e.what();
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, response->message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-27 10:57:43 +08:00
|
|
|
void OBCameraNode::setDisparityRangeModeCallback(const std::shared_ptr<SetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response>& response) {
|
|
|
|
|
if (!request) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "Invalid request";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (!device_->isPropertySupported(OB_PROP_DISP_SEARCH_RANGE_MODE_INT, OB_PERMISSION_WRITE)) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "OB_PROP_DISP_SEARCH_RANGE_MODE_INT is not supported";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool allow_set = isGemini435LePID(pid_) || enable_stream_[DEPTH];
|
|
|
|
|
if (!allow_set) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "Disparity range mode can only be set when depth stream is enabled";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-27 17:33:34 +08:00
|
|
|
if (isGemini330SeriesForDisparity(pid_) &&
|
|
|
|
|
!isSupportedDisparityResolutionForPid(pid_, width_[DEPTH], height_[DEPTH])) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "Current depth resolution " + std::to_string(width_[DEPTH]) + "x" +
|
|
|
|
|
std::to_string(height_[DEPTH]) + " is not supported. " +
|
|
|
|
|
getDisparityResolutionHintByPid(pid_);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-27 10:57:43 +08:00
|
|
|
auto range = device_->getIntPropertyRange(OB_PROP_DISP_SEARCH_RANGE_MODE_INT);
|
2026-02-27 11:29:18 +08:00
|
|
|
int requested_mode_value = request->data;
|
|
|
|
|
int hw_mode_index = requested_mode_value;
|
2026-02-27 10:57:43 +08:00
|
|
|
if (hw_mode_index < range.min || hw_mode_index > range.max) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message =
|
|
|
|
|
"Invalid disparity range mode. Allowed values:" + std::to_string(range.min) + " to " +
|
|
|
|
|
std::to_string(range.max);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device_->setIntProperty(OB_PROP_DISP_SEARCH_RANGE_MODE_INT, hw_mode_index);
|
|
|
|
|
disparity_range_mode_ = requested_mode_value;
|
|
|
|
|
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "Set disparity_range_mode to " << requested_mode_value);
|
|
|
|
|
response->success = true;
|
|
|
|
|
response->message = "disparity_range_mode updated";
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.getMessage();
|
2026-02-27 14:20:35 +08:00
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setDisparitySearchOffsetCallback(
|
|
|
|
|
const std::shared_ptr<SetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response>& response) {
|
|
|
|
|
if (!request) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "Invalid request";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (!device_->isPropertySupported(OB_PROP_DISP_SEARCH_OFFSET_INT, OB_PERMISSION_WRITE)) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "OB_PROP_DISP_SEARCH_OFFSET_INT is not supported";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool allow_set = isGemini435LePID(pid_) || enable_stream_[DEPTH];
|
|
|
|
|
if (!allow_set) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "Disparity search offset can only be set when depth stream is enabled";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-27 17:33:34 +08:00
|
|
|
if (isGemini330SeriesForDisparity(pid_) &&
|
|
|
|
|
!isSupportedDisparityResolutionForPid(pid_, width_[DEPTH], height_[DEPTH])) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "Current depth resolution " + std::to_string(width_[DEPTH]) + "x" +
|
|
|
|
|
std::to_string(height_[DEPTH]) + " is not supported. " +
|
|
|
|
|
getDisparityResolutionHintByPid(pid_);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-27 14:20:35 +08:00
|
|
|
auto range = device_->getIntPropertyRange(OB_PROP_DISP_SEARCH_OFFSET_INT);
|
|
|
|
|
if (request->data < range.min || request->data > range.max) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message =
|
|
|
|
|
"Invalid disparity search offset. Allowed values:" + std::to_string(range.min) + " to " +
|
|
|
|
|
std::to_string(range.max);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device_->setIntProperty(OB_PROP_DISP_SEARCH_OFFSET_INT, request->data);
|
|
|
|
|
disparity_search_offset_ = request->data;
|
|
|
|
|
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "Set disparity_search_offset to " << disparity_search_offset_);
|
|
|
|
|
response->success = true;
|
|
|
|
|
response->message = "disparity_search_offset updated";
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.getMessage();
|
2026-02-27 10:57:43 +08:00
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-28 21:51:42 +08:00
|
|
|
void OBCameraNode::setStreamsEnableCallback(
|
|
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request> request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response> response) {
|
|
|
|
|
try {
|
|
|
|
|
if (request->data) {
|
|
|
|
|
startStreams();
|
|
|
|
|
response->success = true;
|
|
|
|
|
response->message = "streams started";
|
|
|
|
|
} else {
|
|
|
|
|
stopStreams();
|
|
|
|
|
response->success = true;
|
|
|
|
|
response->message = "streams stopped";
|
|
|
|
|
}
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::getStreamsEnableCallback(
|
|
|
|
|
const std::shared_ptr<orbbec_camera_msgs::srv::GetBool::Request> request,
|
|
|
|
|
std::shared_ptr<orbbec_camera_msgs::srv::GetBool::Response> response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
response->data = pipeline_started_.load();
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setExposureCallback(const std::shared_ptr<SetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
|
|
|
|
auto stream = stream_index.first;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
|
|
|
|
switch (stream) {
|
2023-09-08 09:35:33 +08:00
|
|
|
case OB_STREAM_IR_LEFT:
|
|
|
|
|
case OB_STREAM_IR_RIGHT:
|
2022-06-07 18:09:17 +08:00
|
|
|
case OB_STREAM_IR:
|
|
|
|
|
device_->setIntProperty(OB_PROP_IR_EXPOSURE_INT, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_DEPTH:
|
|
|
|
|
device_->setIntProperty(OB_PROP_DEPTH_EXPOSURE_INT, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR:
|
2026-01-07 15:04:16 +08:00
|
|
|
case OB_STREAM_COLOR_LEFT:
|
|
|
|
|
case OB_STREAM_COLOR_RIGHT:
|
2022-06-07 18:09:17 +08:00
|
|
|
device_->setIntProperty(OB_PROP_COLOR_EXPOSURE_INT, request->data);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RCLCPP_ERROR(logger_, "%s NOT a video stream", __FUNCTION__);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
RCLCPP_ERROR(logger_, "%s unknown error %d", __FUNCTION__, __LINE__);
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = "unknown error";
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::getGainCallback(const std::shared_ptr<GetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<GetInt32::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
2022-06-13 14:58:47 +08:00
|
|
|
(void)request;
|
2022-06-06 19:00:12 +08:00
|
|
|
auto stream = stream_index.first;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
|
|
|
|
switch (stream) {
|
2023-09-08 09:35:33 +08:00
|
|
|
case OB_STREAM_IR_LEFT:
|
|
|
|
|
case OB_STREAM_IR_RIGHT:
|
2022-06-07 18:09:17 +08:00
|
|
|
case OB_STREAM_IR:
|
|
|
|
|
response->data = device_->getIntProperty(OB_PROP_IR_GAIN_INT);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_DEPTH:
|
|
|
|
|
response->data = device_->getIntProperty(OB_PROP_DEPTH_GAIN_INT);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR:
|
2026-01-07 15:04:16 +08:00
|
|
|
case OB_STREAM_COLOR_LEFT:
|
|
|
|
|
case OB_STREAM_COLOR_RIGHT:
|
2022-06-07 18:09:17 +08:00
|
|
|
response->data = device_->getIntProperty(OB_PROP_COLOR_GAIN_INT);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RCLCPP_ERROR(logger_, " %s NOT a video stream", __FUNCTION__);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (ob::Error& e) {
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = "unknown error";
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-07 15:18:19 +08:00
|
|
|
|
2022-06-06 19:00:12 +08:00
|
|
|
void OBCameraNode::setGainCallback(const std::shared_ptr<SetInt32 ::Request>& request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
|
|
|
|
auto stream = stream_index.first;
|
2024-04-29 09:56:02 +08:00
|
|
|
OBPropertyID prop_id = OB_PROP_IR_GAIN_INT;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
|
|
|
|
switch (stream) {
|
2023-09-08 09:35:33 +08:00
|
|
|
case OB_STREAM_IR_LEFT:
|
|
|
|
|
case OB_STREAM_IR_RIGHT:
|
2022-06-07 18:09:17 +08:00
|
|
|
case OB_STREAM_IR:
|
2024-04-29 09:56:02 +08:00
|
|
|
prop_id = OB_PROP_IR_GAIN_INT;
|
2022-06-07 18:09:17 +08:00
|
|
|
break;
|
|
|
|
|
case OB_STREAM_DEPTH:
|
2024-04-29 09:56:02 +08:00
|
|
|
prop_id = OB_PROP_DEPTH_GAIN_INT;
|
2022-06-07 18:09:17 +08:00
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR:
|
2026-01-07 15:04:16 +08:00
|
|
|
case OB_STREAM_COLOR_LEFT:
|
|
|
|
|
case OB_STREAM_COLOR_RIGHT:
|
2024-04-29 09:56:02 +08:00
|
|
|
prop_id = OB_PROP_COLOR_GAIN_INT;
|
2022-06-07 18:09:17 +08:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RCLCPP_ERROR(logger_, "%s NOT a video stream", __FUNCTION__);
|
2024-04-29 09:56:02 +08:00
|
|
|
response->success = false;
|
|
|
|
|
response->message = "NOT a video stream";
|
|
|
|
|
return;
|
2022-06-07 18:09:17 +08:00
|
|
|
}
|
2024-04-29 09:56:02 +08:00
|
|
|
auto range = device_->getIntPropertyRange(prop_id);
|
|
|
|
|
if (request->data < range.min || request->data > range.max) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "set gain value out of range");
|
|
|
|
|
response->message = "value out of range";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
device_->setIntProperty(prop_id, request->data);
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2025-03-21 09:28:42 +08:00
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setAeRoiCallback(const std::shared_ptr<SetArrays ::Request>& request,
|
|
|
|
|
std::shared_ptr<SetArrays::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
|
|
|
|
auto stream = stream_index.first;
|
2026-01-13 18:02:15 +08:00
|
|
|
if (device_->getDeviceInfo()->getPid() == GEMINI_305_PID &&
|
|
|
|
|
(stream != OB_STREAM_COLOR && ae_mode_ == "colorbased")) {
|
|
|
|
|
response->success = false;
|
2026-01-20 10:35:33 +08:00
|
|
|
response->message = "AE MODE is colorbased, other sensors setting is not supported";
|
2026-01-13 18:02:15 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (device_->getDeviceInfo()->getPid() == GEMINI_305_PID &&
|
|
|
|
|
(stream != OB_STREAM_DEPTH && ae_mode_ == "depthbased")) {
|
|
|
|
|
response->success = false;
|
2026-01-20 10:35:33 +08:00
|
|
|
response->message = "AE MODE is depthbased, other sensors sensor setting is not supported";
|
2026-01-13 18:02:15 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2025-03-21 09:28:42 +08:00
|
|
|
auto config = OBRegionOfInterest();
|
2025-04-23 16:36:25 +08:00
|
|
|
uint32_t data_size = sizeof(config);
|
2025-03-21 09:28:42 +08:00
|
|
|
try {
|
|
|
|
|
switch (stream) {
|
|
|
|
|
case OB_STREAM_IR_LEFT:
|
|
|
|
|
case OB_STREAM_IR_RIGHT:
|
|
|
|
|
case OB_STREAM_IR:
|
|
|
|
|
case OB_STREAM_DEPTH:
|
2025-04-23 16:36:25 +08:00
|
|
|
config.x0_left = (static_cast<short int>(request->data_param[0]) < 0)
|
|
|
|
|
? 0
|
|
|
|
|
: static_cast<short int>(request->data_param[0]);
|
|
|
|
|
config.x0_left = (static_cast<short int>(request->data_param[0]) > width_[DEPTH] - 1)
|
|
|
|
|
? width_[DEPTH] - 1
|
|
|
|
|
: config.x0_left;
|
|
|
|
|
config.y0_top = (static_cast<short int>(request->data_param[2]) < 0)
|
|
|
|
|
? 0
|
|
|
|
|
: static_cast<short int>(request->data_param[2]);
|
|
|
|
|
config.y0_top = (static_cast<short int>(request->data_param[2]) > height_[DEPTH] - 1)
|
|
|
|
|
? height_[DEPTH] - 1
|
|
|
|
|
: config.y0_top;
|
|
|
|
|
config.x1_right = (static_cast<short int>(request->data_param[1]) < 0)
|
|
|
|
|
? 0
|
|
|
|
|
: static_cast<short int>(request->data_param[1]);
|
|
|
|
|
config.x1_right = (static_cast<short int>(request->data_param[1]) > width_[DEPTH] - 1)
|
|
|
|
|
? width_[DEPTH] - 1
|
|
|
|
|
: config.x1_right;
|
|
|
|
|
config.y1_bottom = (static_cast<short int>(request->data_param[3]) < 0)
|
|
|
|
|
? 0
|
|
|
|
|
: static_cast<short int>(request->data_param[3]);
|
|
|
|
|
config.y1_bottom = (static_cast<short int>(request->data_param[3]) > height_[DEPTH] - 1)
|
|
|
|
|
? height_[DEPTH] - 1
|
|
|
|
|
: config.y1_bottom;
|
2025-03-21 09:28:42 +08:00
|
|
|
device_->setStructuredData(OB_STRUCT_DEPTH_AE_ROI,
|
|
|
|
|
reinterpret_cast<const uint8_t*>(&config), sizeof(config));
|
2025-04-23 16:36:25 +08:00
|
|
|
device_->getStructuredData(OB_STRUCT_DEPTH_AE_ROI, reinterpret_cast<uint8_t*>(&config),
|
|
|
|
|
&data_size);
|
2025-08-05 17:43:10 +08:00
|
|
|
RCLCPP_INFO_STREAM(
|
|
|
|
|
logger_, "set depth AE ROI : "
|
|
|
|
|
<< "[Left: " << config.x0_left << ", Right: " << config.x1_right
|
|
|
|
|
<< ", Top: " << config.y0_top << ", Bottom: " << config.y1_bottom << " ]");
|
2025-03-21 09:28:42 +08:00
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR:
|
2026-01-07 15:04:16 +08:00
|
|
|
case OB_STREAM_COLOR_LEFT:
|
|
|
|
|
case OB_STREAM_COLOR_RIGHT:
|
2025-04-23 16:36:25 +08:00
|
|
|
config.x0_left = (static_cast<short int>(request->data_param[0]) < 0)
|
|
|
|
|
? 0
|
|
|
|
|
: static_cast<short int>(request->data_param[0]);
|
|
|
|
|
config.x0_left = (static_cast<short int>(request->data_param[0]) > width_[COLOR] - 1)
|
|
|
|
|
? width_[COLOR] - 1
|
|
|
|
|
: config.x0_left;
|
|
|
|
|
config.y0_top = (static_cast<short int>(request->data_param[2]) < 0)
|
|
|
|
|
? 0
|
|
|
|
|
: static_cast<short int>(request->data_param[2]);
|
|
|
|
|
config.y0_top = (static_cast<short int>(request->data_param[2]) > height_[COLOR] - 1)
|
|
|
|
|
? height_[COLOR] - 1
|
|
|
|
|
: config.y0_top;
|
|
|
|
|
config.x1_right = (static_cast<short int>(request->data_param[1]) < 0)
|
|
|
|
|
? 0
|
|
|
|
|
: static_cast<short int>(request->data_param[1]);
|
|
|
|
|
config.x1_right = (static_cast<short int>(request->data_param[1]) > width_[COLOR] - 1)
|
|
|
|
|
? width_[COLOR] - 1
|
|
|
|
|
: config.x1_right;
|
|
|
|
|
config.y1_bottom = (static_cast<short int>(request->data_param[3]) < 0)
|
|
|
|
|
? 0
|
|
|
|
|
: static_cast<short int>(request->data_param[3]);
|
|
|
|
|
config.y1_bottom = (static_cast<short int>(request->data_param[3]) > height_[COLOR] - 1)
|
|
|
|
|
? height_[COLOR] - 1
|
|
|
|
|
: config.y1_bottom;
|
2025-03-21 09:28:42 +08:00
|
|
|
device_->setStructuredData(OB_STRUCT_COLOR_AE_ROI,
|
|
|
|
|
reinterpret_cast<const uint8_t*>(&config), sizeof(config));
|
2025-04-23 16:36:25 +08:00
|
|
|
device_->getStructuredData(OB_STRUCT_COLOR_AE_ROI, reinterpret_cast<uint8_t*>(&config),
|
|
|
|
|
&data_size);
|
2025-08-05 17:43:10 +08:00
|
|
|
RCLCPP_INFO_STREAM(
|
|
|
|
|
logger_, "set color AE ROI : "
|
|
|
|
|
<< "[Left: " << config.x0_left << ", Right: " << config.x1_right
|
|
|
|
|
<< ", Top: " << config.y0_top << ", Bottom: " << config.y1_bottom << " ]");
|
2025-03-21 09:28:42 +08:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RCLCPP_ERROR(logger_, "%s NOT a video stream", __FUNCTION__);
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "NOT a video stream";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = "unknown error";
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 14:58:47 +08:00
|
|
|
void OBCameraNode::getWhiteBalanceCallback(const std::shared_ptr<GetInt32::Request>& request,
|
2022-06-06 19:00:12 +08:00
|
|
|
std::shared_ptr<GetInt32::Response>& response) {
|
2022-06-13 14:58:47 +08:00
|
|
|
(void)request;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
|
|
|
|
response->data = device_->getIntProperty(OB_PROP_COLOR_WHITE_BALANCE_INT);
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
|
2022-06-13 14:58:47 +08:00
|
|
|
void OBCameraNode::setWhiteBalanceCallback(const std::shared_ptr<SetInt32 ::Request>& request,
|
2022-06-06 19:00:12 +08:00
|
|
|
std::shared_ptr<SetInt32 ::Response>& response) {
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
2024-04-29 09:56:02 +08:00
|
|
|
auto range = device_->getIntPropertyRange(OB_PROP_COLOR_WHITE_BALANCE_INT);
|
|
|
|
|
if (request->data < range.min || request->data > range.max) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "set white balance value out of range");
|
|
|
|
|
response->message = "value out of range";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
bool auto_white_balance = device_->getBoolProperty(OB_PROP_COLOR_AUTO_WHITE_BALANCE_BOOL);
|
|
|
|
|
if (auto_white_balance) {
|
|
|
|
|
RCLCPP_WARN(logger_, "auto white balance is enabled, set white balance will be ignored");
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "auto white balance is enabled";
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-06-07 18:09:17 +08:00
|
|
|
device_->setIntProperty(OB_PROP_COLOR_WHITE_BALANCE_INT, request->data);
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
|
2022-06-24 14:58:43 +08:00
|
|
|
void OBCameraNode::getAutoWhiteBalanceCallback(const std::shared_ptr<GetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<GetInt32::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
response->data = device_->getBoolProperty(OB_PROP_COLOR_AUTO_WHITE_BALANCE_BOOL);
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setAutoWhiteBalanceCallback(const std::shared_ptr<SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<SetBool::Response>& response) {
|
|
|
|
|
try {
|
|
|
|
|
device_->setBoolProperty(OB_PROP_COLOR_AUTO_WHITE_BALANCE_BOOL, request->data);
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-06 19:00:12 +08:00
|
|
|
void OBCameraNode::setAutoExposureCallback(
|
|
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
|
|
|
|
auto stream = stream_index.first;
|
2024-04-29 09:56:02 +08:00
|
|
|
OBPropertyID prop_id = OB_PROP_IR_AUTO_EXPOSURE_BOOL;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
|
|
|
|
switch (stream) {
|
2023-09-08 09:35:33 +08:00
|
|
|
case OB_STREAM_IR_LEFT:
|
|
|
|
|
case OB_STREAM_IR_RIGHT:
|
2022-06-07 18:09:17 +08:00
|
|
|
case OB_STREAM_IR:
|
2024-04-29 09:56:02 +08:00
|
|
|
prop_id = OB_PROP_IR_AUTO_EXPOSURE_BOOL;
|
2022-06-07 18:09:17 +08:00
|
|
|
break;
|
|
|
|
|
case OB_STREAM_DEPTH:
|
2024-04-29 09:56:02 +08:00
|
|
|
prop_id = OB_PROP_DEPTH_AUTO_EXPOSURE_BOOL;
|
2022-06-07 18:09:17 +08:00
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR:
|
2026-01-07 15:04:16 +08:00
|
|
|
case OB_STREAM_COLOR_LEFT:
|
|
|
|
|
case OB_STREAM_COLOR_RIGHT:
|
2024-04-29 09:56:02 +08:00
|
|
|
prop_id = OB_PROP_COLOR_AUTO_EXPOSURE_BOOL;
|
2022-06-07 18:09:17 +08:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RCLCPP_ERROR(logger_, "%s NOT a video stream", __FUNCTION__);
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
|
|
|
|
response->message = "NOT a video stream";
|
2024-04-29 09:56:02 +08:00
|
|
|
return;
|
2022-06-07 18:09:17 +08:00
|
|
|
}
|
2024-04-29 09:56:02 +08:00
|
|
|
auto range = device_->getIntPropertyRange(prop_id);
|
|
|
|
|
if (request->data < range.min || request->data > range.max) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
RCLCPP_INFO_STREAM(logger_, "set auto exposure value out of range");
|
|
|
|
|
response->message = "value out of range";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
device_->setIntProperty(prop_id, request->data);
|
|
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = "unknown error";
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-17 15:42:53 +08:00
|
|
|
void OBCameraNode::setFanWorkModeCallback(const std::shared_ptr<SetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response>& response) {
|
2022-06-06 19:00:12 +08:00
|
|
|
(void)response;
|
|
|
|
|
bool fan_mode = request->data;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
|
|
|
|
device_->setBoolProperty(OB_PROP_FAN_WORK_MODE_INT, fan_mode);
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setFloorEnableCallback(
|
|
|
|
|
const std::shared_ptr<rmw_request_id_t>& request_header,
|
|
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response>& response) {
|
|
|
|
|
(void)request_header;
|
|
|
|
|
(void)response;
|
|
|
|
|
bool floor_enable = request->data;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
|
|
|
|
device_->setBoolProperty(OB_PROP_FLOOD_BOOL, floor_enable);
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setLaserEnableCallback(
|
|
|
|
|
const std::shared_ptr<rmw_request_id_t>& request_header,
|
|
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response>& response) {
|
|
|
|
|
(void)request_header;
|
|
|
|
|
(void)response;
|
2024-10-28 18:53:27 +08:00
|
|
|
int laser_enable = request->data ? 1 : 0;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
2024-11-26 18:31:00 +08:00
|
|
|
if (device_->isPropertySupported(OB_PROP_LASER_CONTROL_INT, OB_PERMISSION_READ_WRITE)) {
|
2024-10-28 18:53:27 +08:00
|
|
|
device_->setIntProperty(OB_PROP_LASER_CONTROL_INT, laser_enable);
|
2024-11-26 18:31:00 +08:00
|
|
|
} else if (device_->isPropertySupported(OB_PROP_LASER_BOOL, OB_PERMISSION_READ_WRITE)) {
|
2024-10-28 18:53:27 +08:00
|
|
|
device_->setIntProperty(OB_PROP_LASER_BOOL, laser_enable);
|
|
|
|
|
}
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
|
2025-02-28 10:50:43 +08:00
|
|
|
void OBCameraNode::setLdpEnableCallback(
|
2022-06-06 19:00:12 +08:00
|
|
|
const std::shared_ptr<rmw_request_id_t>& request_header,
|
|
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response>& response) {
|
|
|
|
|
(void)request_header;
|
|
|
|
|
(void)response;
|
2025-02-28 10:50:43 +08:00
|
|
|
bool ldp_enable = request->data;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
2025-02-11 18:09:03 +08:00
|
|
|
if (device_->isPropertySupported(OB_PROP_LASER_CONTROL_INT, OB_PERMISSION_READ_WRITE)) {
|
|
|
|
|
auto laser_enable = device_->getIntProperty(OB_PROP_LASER_CONTROL_INT);
|
2025-02-28 10:50:43 +08:00
|
|
|
device_->setBoolProperty(OB_PROP_LDP_BOOL, ldp_enable);
|
2025-02-11 18:09:03 +08:00
|
|
|
device_->setIntProperty(OB_PROP_LASER_CONTROL_INT, laser_enable);
|
|
|
|
|
} else if (device_->isPropertySupported(OB_PROP_LASER_BOOL, OB_PERMISSION_READ_WRITE)) {
|
2025-02-28 10:50:43 +08:00
|
|
|
if (!ldp_enable) {
|
2025-02-27 15:40:41 +08:00
|
|
|
auto laser_enable = device_->getIntProperty(OB_PROP_LASER_BOOL);
|
2025-02-28 10:50:43 +08:00
|
|
|
device_->setBoolProperty(OB_PROP_LDP_BOOL, ldp_enable);
|
2025-02-27 15:40:41 +08:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
|
|
|
|
device_->setIntProperty(OB_PROP_LASER_BOOL, laser_enable);
|
|
|
|
|
} else {
|
2025-02-28 10:50:43 +08:00
|
|
|
device_->setBoolProperty(OB_PROP_LDP_BOOL, ldp_enable);
|
2025-02-27 15:40:41 +08:00
|
|
|
}
|
2025-02-11 18:09:03 +08:00
|
|
|
}
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
2022-06-07 18:22:46 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
2022-06-10 14:52:49 +08:00
|
|
|
|
2022-06-06 19:00:12 +08:00
|
|
|
void OBCameraNode::getExposureCallback(const std::shared_ptr<GetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<GetInt32 ::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
2022-06-13 14:58:47 +08:00
|
|
|
(void)request;
|
2022-06-06 19:00:12 +08:00
|
|
|
auto stream = stream_index.first;
|
2022-06-07 18:09:17 +08:00
|
|
|
try {
|
|
|
|
|
switch (stream) {
|
2023-10-23 11:28:42 +08:00
|
|
|
case OB_STREAM_IR_LEFT:
|
2023-09-08 09:35:33 +08:00
|
|
|
case OB_STREAM_IR_RIGHT:
|
2022-06-07 18:09:17 +08:00
|
|
|
case OB_STREAM_IR:
|
|
|
|
|
response->data = device_->getIntProperty(OB_PROP_IR_EXPOSURE_INT);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_DEPTH:
|
|
|
|
|
response->data = device_->getIntProperty(OB_PROP_DEPTH_EXPOSURE_INT);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR:
|
2026-01-07 15:04:16 +08:00
|
|
|
case OB_STREAM_COLOR_LEFT:
|
|
|
|
|
case OB_STREAM_COLOR_RIGHT:
|
2022-06-07 18:09:17 +08:00
|
|
|
response->data = device_->getIntProperty(OB_PROP_COLOR_EXPOSURE_INT);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
RCLCPP_ERROR(logger_, " %s NOT a video stream", __FUNCTION__);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = true;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-07 18:09:17 +08:00
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
2022-06-10 14:52:49 +08:00
|
|
|
response->success = false;
|
2022-06-06 19:00:12 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-10 14:52:49 +08:00
|
|
|
|
2022-06-13 14:58:47 +08:00
|
|
|
void OBCameraNode::getDeviceInfoCallback(const std::shared_ptr<GetDeviceInfo::Request>& request,
|
2022-06-07 21:21:43 +08:00
|
|
|
std::shared_ptr<GetDeviceInfo::Response>& response) {
|
2022-06-13 14:58:47 +08:00
|
|
|
(void)request;
|
2022-06-07 21:21:43 +08:00
|
|
|
try {
|
|
|
|
|
auto device_info = device_->getDeviceInfo();
|
2024-09-04 12:47:36 +08:00
|
|
|
response->info.name = device_info->getName();
|
|
|
|
|
response->info.serial_number = device_info->getSerialNumber();
|
|
|
|
|
response->info.firmware_version = device_info->getFirmwareVersion();
|
|
|
|
|
response->info.supported_min_sdk_version = device_info->getSupportedMinSdkVersion();
|
2025-08-25 21:46:06 +08:00
|
|
|
response->info.current_sdk_version = getObSDKVersion();
|
|
|
|
|
response->info.hardware_version = device_info->getHardwareVersion();
|
2022-06-07 21:21:43 +08:00
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-10 14:52:49 +08:00
|
|
|
|
2022-06-13 14:58:47 +08:00
|
|
|
void OBCameraNode::getSDKVersion(const std::shared_ptr<GetString::Request>& request,
|
2022-06-09 15:47:02 +08:00
|
|
|
std::shared_ptr<GetString::Response>& response) {
|
2022-06-13 14:58:47 +08:00
|
|
|
(void)request;
|
2022-06-09 15:47:02 +08:00
|
|
|
try {
|
|
|
|
|
auto device_info = device_->getDeviceInfo();
|
|
|
|
|
nlohmann::json data;
|
2024-09-04 12:47:36 +08:00
|
|
|
data["firmware_version"] = device_info->getFirmwareVersion();
|
|
|
|
|
data["supported_min_sdk_version"] = device_info->getSupportedMinSdkVersion();
|
2022-06-09 15:47:02 +08:00
|
|
|
data["ros_sdk_version"] = OB_ROS_VERSION_STR;
|
|
|
|
|
data["ob_sdk_version"] = getObSDKVersion();
|
|
|
|
|
response->data = data.dump(2);
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-13 16:02:49 +08:00
|
|
|
|
2023-02-17 15:42:53 +08:00
|
|
|
void OBCameraNode::setMirrorCallback(const std::shared_ptr<SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<SetBool::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
|
|
|
|
(void)request;
|
|
|
|
|
auto stream = stream_index.first;
|
|
|
|
|
try {
|
|
|
|
|
switch (stream) {
|
2023-09-08 09:35:33 +08:00
|
|
|
case OB_STREAM_IR_RIGHT:
|
2023-09-13 19:27:20 +08:00
|
|
|
device_->setBoolProperty(OB_PROP_IR_RIGHT_MIRROR_BOOL, request->data);
|
2023-09-13 19:51:33 +08:00
|
|
|
break;
|
2023-09-13 19:27:20 +08:00
|
|
|
case OB_STREAM_IR_LEFT:
|
2023-02-17 15:42:53 +08:00
|
|
|
case OB_STREAM_IR:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_IR_MIRROR_BOOL, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_DEPTH:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_DEPTH_MIRROR_BOOL, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_COLOR_MIRROR_BOOL, request->data);
|
|
|
|
|
break;
|
2026-01-07 15:04:16 +08:00
|
|
|
case OB_STREAM_COLOR_LEFT:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_COLOR_LEFT_MIRROR_BOOL, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR_RIGHT:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_COLOR_RIGHT_MIRROR_BOOL, request->data);
|
|
|
|
|
break;
|
2023-02-17 15:42:53 +08:00
|
|
|
default:
|
|
|
|
|
RCLCPP_ERROR(logger_, " %s NOT a video stream", __FUNCTION__);
|
2025-05-12 11:52:56 +08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setFlipCallback(const std::shared_ptr<SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<SetBool::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
|
|
|
|
(void)request;
|
|
|
|
|
auto stream = stream_index.first;
|
|
|
|
|
try {
|
|
|
|
|
switch (stream) {
|
|
|
|
|
case OB_STREAM_IR_RIGHT:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_IR_RIGHT_FLIP_BOOL, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_IR_LEFT:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_IR_FLIP_BOOL, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_IR:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_IR_FLIP_BOOL, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_DEPTH:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_DEPTH_FLIP_BOOL, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_COLOR_FLIP_BOOL, request->data);
|
|
|
|
|
break;
|
2026-01-07 15:04:16 +08:00
|
|
|
case OB_STREAM_COLOR_LEFT:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_COLOR_LEFT_FLIP_BOOL, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR_RIGHT:
|
|
|
|
|
device_->setBoolProperty(OB_PROP_COLOR_RIGHT_FLIP_BOOL, request->data);
|
|
|
|
|
break;
|
2025-05-12 11:52:56 +08:00
|
|
|
default:
|
|
|
|
|
RCLCPP_ERROR(logger_, " %s NOT a video stream", __FUNCTION__);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setRotationCallback(const std::shared_ptr<SetInt32::Request>& request,
|
|
|
|
|
std::shared_ptr<SetInt32::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
|
|
|
|
(void)request;
|
|
|
|
|
auto stream = stream_index.first;
|
|
|
|
|
try {
|
|
|
|
|
switch (stream) {
|
|
|
|
|
case OB_STREAM_IR_RIGHT:
|
|
|
|
|
device_->setIntProperty(OB_PROP_IR_RIGHT_ROTATE_INT, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_IR_LEFT:
|
|
|
|
|
device_->setIntProperty(OB_PROP_IR_ROTATE_INT, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_IR:
|
|
|
|
|
device_->setIntProperty(OB_PROP_IR_ROTATE_INT, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_DEPTH:
|
|
|
|
|
device_->setIntProperty(OB_PROP_DEPTH_ROTATE_INT, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR:
|
|
|
|
|
device_->setIntProperty(OB_PROP_COLOR_ROTATE_INT, request->data);
|
|
|
|
|
break;
|
2026-01-07 15:04:16 +08:00
|
|
|
case OB_STREAM_COLOR_LEFT:
|
|
|
|
|
device_->setIntProperty(OB_PROP_COLOR_LEFT_ROTATE_INT, request->data);
|
|
|
|
|
break;
|
|
|
|
|
case OB_STREAM_COLOR_RIGHT:
|
|
|
|
|
device_->setIntProperty(OB_PROP_COLOR_RIGHT_ROTATE_INT, request->data);
|
|
|
|
|
break;
|
2025-05-12 11:52:56 +08:00
|
|
|
default:
|
|
|
|
|
RCLCPP_ERROR(logger_, " %s NOT a video stream", __FUNCTION__);
|
2023-02-17 15:42:53 +08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-28 10:50:43 +08:00
|
|
|
void OBCameraNode::getLdpStatusCallback(const std::shared_ptr<GetBool::Request>& request,
|
2023-02-17 15:42:53 +08:00
|
|
|
std::shared_ptr<GetBool::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
response->data = device_->getBoolProperty(OB_PROP_LDP_STATUS_BOOL);
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
2025-11-03 14:24:53 +08:00
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::getLaserStatusCallback(const std::shared_ptr<GetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<GetBool::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
if (device_->isPropertySupported(OB_PROP_LASER_CONTROL_INT, OB_PERMISSION_READ_WRITE)) {
|
|
|
|
|
response->data = device_->getBoolProperty(OB_PROP_LASER_CONTROL_INT);
|
|
|
|
|
} else if (device_->isPropertySupported(OB_PROP_LASER_BOOL, OB_PERMISSION_READ_WRITE)) {
|
|
|
|
|
response->data = device_->getBoolProperty(OB_PROP_LASER_BOOL);
|
|
|
|
|
}
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
2023-02-17 15:42:53 +08:00
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-05 17:43:10 +08:00
|
|
|
void OBCameraNode::setPtpConfigCallback(
|
2025-08-05 06:58:54 -04:00
|
|
|
const std::shared_ptr<rmw_request_id_t>& request_header,
|
2025-08-05 17:43:10 +08:00
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response>& response) {
|
|
|
|
|
(void)request_header;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (!device_->isPropertySupported(OB_DEVICE_PTP_CLOCK_SYNC_ENABLE_BOOL,
|
|
|
|
|
OB_PERMISSION_READ_WRITE)) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
RCLCPP_ERROR(logger_, "OB_DEVICE_PTP_CLOCK_SYNC_ENABLE_BOOL not supported or not writable");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
device_->setBoolProperty(OB_DEVICE_PTP_CLOCK_SYNC_ENABLE_BOOL, request->data);
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::getPtpConfigCallback(const std::shared_ptr<GetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<GetBool::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
response->data = device_->getBoolProperty(OB_DEVICE_PTP_CLOCK_SYNC_ENABLE_BOOL);
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-25 11:32:50 +08:00
|
|
|
void OBCameraNode::getLrmMeasureDistanceCallback(const std::shared_ptr<GetInt32::Request>& request,
|
2024-07-10 19:57:17 +08:00
|
|
|
std::shared_ptr<GetInt32::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
response->data = device_->getIntProperty(OB_PROP_LDP_MEASURE_DISTANCE_INT);
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 16:02:49 +08:00
|
|
|
void OBCameraNode::toggleSensorCallback(const std::shared_ptr<SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<SetBool::Response>& response,
|
|
|
|
|
const stream_index_pair& stream_index) {
|
|
|
|
|
std::string msg;
|
|
|
|
|
if (request->data) {
|
2023-02-06 17:26:10 +08:00
|
|
|
if (enable_stream_[stream_index]) {
|
|
|
|
|
msg = stream_name_[stream_index] + " Already ON";
|
2022-06-13 16:02:49 +08:00
|
|
|
}
|
2023-02-06 17:26:10 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "toggling sensor " << stream_name_[stream_index] << " ON");
|
2022-06-13 16:02:49 +08:00
|
|
|
|
|
|
|
|
} else {
|
2023-02-06 17:26:10 +08:00
|
|
|
if (!enable_stream_[stream_index]) {
|
|
|
|
|
msg = stream_name_[stream_index] + " Already OFF";
|
2022-06-13 16:02:49 +08:00
|
|
|
}
|
2023-02-06 17:26:10 +08:00
|
|
|
RCLCPP_INFO_STREAM(logger_, "toggling sensor " << stream_name_[stream_index] << " OFF");
|
2022-06-13 16:02:49 +08:00
|
|
|
}
|
|
|
|
|
if (!msg.empty()) {
|
|
|
|
|
RCLCPP_ERROR_STREAM(logger_, msg);
|
2025-09-23 15:19:37 +08:00
|
|
|
response->success = true;
|
2022-06-13 16:02:49 +08:00
|
|
|
response->message = msg;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
response->success = toggleSensor(stream_index, request->data, response->message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool OBCameraNode::toggleSensor(const stream_index_pair& stream_index, bool enabled,
|
|
|
|
|
std::string& msg) {
|
2025-12-24 15:45:15 +08:00
|
|
|
std::lock_guard<decltype(device_lock_)> lock(device_lock_);
|
2022-06-13 16:02:49 +08:00
|
|
|
try {
|
|
|
|
|
pipeline_->stop();
|
2023-02-06 17:26:10 +08:00
|
|
|
enable_stream_[stream_index] = enabled;
|
2022-06-13 16:02:49 +08:00
|
|
|
setupProfiles();
|
2023-02-13 15:34:44 +08:00
|
|
|
startStreams();
|
2022-06-13 16:02:49 +08:00
|
|
|
return true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
msg = e.getMessage();
|
|
|
|
|
return false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
msg = e.what();
|
|
|
|
|
return false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
msg = "unknown error";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-20 14:46:02 +08:00
|
|
|
|
|
|
|
|
void OBCameraNode::saveImageCallback(const std::shared_ptr<std_srvs::srv::Empty::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::Empty::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
(void)response;
|
|
|
|
|
for (const auto& stream_index : IMAGE_STREAMS) {
|
|
|
|
|
if (enable_stream_[stream_index]) {
|
|
|
|
|
save_images_[stream_index] = true;
|
2024-01-30 11:21:18 +08:00
|
|
|
save_images_count_[stream_index] = 0;
|
2023-02-20 14:46:02 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::savePointCloudCallback(
|
|
|
|
|
const std::shared_ptr<std_srvs::srv::Empty::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::Empty::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
(void)response;
|
|
|
|
|
if (enable_point_cloud_) {
|
|
|
|
|
save_point_cloud_ = true;
|
|
|
|
|
}
|
|
|
|
|
if (enable_colored_point_cloud_) {
|
|
|
|
|
save_colored_point_cloud_ = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-27 14:02:23 +08:00
|
|
|
void OBCameraNode::switchIRCameraCallback(const std::shared_ptr<SetString::Request>& request,
|
|
|
|
|
std::shared_ptr<SetString::Response>& response) {
|
|
|
|
|
if (request->data != "left" && request->data != "right") {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "invalid ir camera name";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
int data = request->data == "left" ? 0 : 1;
|
|
|
|
|
device_->setIntProperty(OB_PROP_IR_CHANNEL_DATA_SOURCE_INT, data);
|
|
|
|
|
response->success = true;
|
|
|
|
|
return;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-12 16:15:21 +08:00
|
|
|
void OBCameraNode::setIRLongExposureCallback(
|
|
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response>& response) {
|
|
|
|
|
try {
|
|
|
|
|
device_->setBoolProperty(OB_PROP_IR_LONG_EXPOSURE_BOOL, request->data);
|
|
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
2024-10-31 20:48:56 +08:00
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::setRESETTimestampCallback(
|
|
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
2024-11-18 14:18:07 +08:00
|
|
|
device_->setBoolProperty(OB_PROP_TIMER_RESET_TRIGGER_OUT_ENABLE_BOOL, true);
|
2024-12-06 09:57:31 +08:00
|
|
|
device_->setBoolProperty(OB_PROP_TIMER_RESET_SIGNAL_BOOL, true);
|
2024-10-31 20:48:56 +08:00
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-11-21 15:51:00 +08:00
|
|
|
void OBCameraNode::setSYNCInterleaveLaserCallback(
|
|
|
|
|
const std::shared_ptr<SetInt32 ::Request>& request,
|
|
|
|
|
std::shared_ptr<SetInt32 ::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
2024-11-28 18:36:33 +08:00
|
|
|
device_->setIntProperty(OB_PROP_FRAME_INTERLEAVE_LASER_PATTERN_SYNC_DELAY_INT, request->data);
|
2024-11-21 15:51:00 +08:00
|
|
|
response->success = true;
|
|
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void OBCameraNode::setSYNCHostimeCallback(
|
|
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
device_->timerSyncWithHost();
|
|
|
|
|
response->success = true;
|
2025-06-23 15:11:53 +08:00
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-27 14:37:03 +08:00
|
|
|
void OBCameraNode::sendSoftwareTriggerCallback(
|
2025-06-23 15:11:53 +08:00
|
|
|
const std::shared_ptr<std_srvs::srv::SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<std_srvs::srv::SetBool::Response>& response) {
|
|
|
|
|
try {
|
2025-06-27 14:37:03 +08:00
|
|
|
if (request->data) {
|
|
|
|
|
device_->triggerCapture();
|
|
|
|
|
}
|
2025-06-23 15:11:53 +08:00
|
|
|
response->success = true;
|
2024-11-21 15:51:00 +08:00
|
|
|
} catch (const ob::Error& e) {
|
|
|
|
|
response->message = e.getMessage();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
response->message = e.what();
|
|
|
|
|
response->success = false;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->message = "unknown error";
|
|
|
|
|
response->success = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-11 17:22:07 +08:00
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
bool OBCameraNode::writeCustomerData(const std::string& data) {
|
|
|
|
|
if (data.empty()) return false;
|
2025-08-28 21:59:50 +08:00
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
std::string md5_value = calcMD5(data);
|
|
|
|
|
uint32_t data_len_net = htonl(static_cast<uint32_t>(data.size()));
|
|
|
|
|
std::string len_bytes(reinterpret_cast<char*>(&data_len_net), sizeof(data_len_net));
|
2025-08-28 21:59:50 +08:00
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
std::string write_buffer = len_bytes + md5_value + data;
|
|
|
|
|
device_->writeCustomerData(write_buffer.c_str(), write_buffer.size());
|
2025-08-28 21:59:50 +08:00
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
std::vector<uint8_t> read_buffer(write_buffer.size() + 8);
|
|
|
|
|
uint32_t read_len = 0;
|
|
|
|
|
device_->readCustomerData(read_buffer.data(), &read_len);
|
2025-08-28 21:59:50 +08:00
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
if (read_len < sizeof(uint32_t) + 32) return false;
|
2025-08-28 21:59:50 +08:00
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
uint32_t read_data_len_net = 0;
|
|
|
|
|
memcpy(&read_data_len_net, read_buffer.data(), sizeof(uint32_t));
|
|
|
|
|
uint32_t read_data_len = ntohl(read_data_len_net);
|
2025-08-28 21:59:50 +08:00
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
std::string md5_read(reinterpret_cast<char*>(read_buffer.data() + sizeof(uint32_t)), 32);
|
|
|
|
|
std::string data_read(reinterpret_cast<char*>(read_buffer.data() + sizeof(uint32_t) + 32),
|
|
|
|
|
read_data_len);
|
2025-08-28 21:59:50 +08:00
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
return calcMD5(data_read) == md5_read;
|
2025-05-12 16:15:38 +08:00
|
|
|
}
|
2025-08-28 21:59:50 +08:00
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
bool OBCameraNode::readCustomerData(std::string& out_data) {
|
|
|
|
|
std::vector<uint8_t> read_buffer(40960);
|
|
|
|
|
uint32_t read_len = 0;
|
|
|
|
|
device_->readCustomerData(read_buffer.data(), &read_len);
|
|
|
|
|
if (read_len < sizeof(uint32_t) + 32) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
uint32_t read_data_len_net = 0;
|
|
|
|
|
memcpy(&read_data_len_net, read_buffer.data(), sizeof(uint32_t));
|
|
|
|
|
uint32_t read_data_len = ntohl(read_data_len_net);
|
|
|
|
|
std::string md5_read(reinterpret_cast<char*>(read_buffer.data() + sizeof(uint32_t)), 32);
|
|
|
|
|
std::string data_read(reinterpret_cast<char*>(read_buffer.data() + sizeof(uint32_t) + 32),
|
|
|
|
|
read_data_len);
|
|
|
|
|
if (calcMD5(data_read) == md5_read) {
|
|
|
|
|
out_data = std::move(data_read);
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBCameraNode::writeCustomerDataCallback(const std::shared_ptr<SetString::Request>& request,
|
|
|
|
|
std::shared_ptr<SetString::Response>& response) {
|
|
|
|
|
if (request->data.empty()) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "data empty";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (writeCustomerData(request->data)) {
|
|
|
|
|
write_customer_data_success_ = true;
|
|
|
|
|
response->success = true;
|
|
|
|
|
response->message = "write and verify success";
|
|
|
|
|
user_calibration_ready_ = true;
|
2025-08-28 21:59:50 +08:00
|
|
|
} else {
|
2025-08-29 15:01:01 +08:00
|
|
|
write_customer_data_success_ = false;
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "write failed: MD5 mismatch or read too short";
|
|
|
|
|
user_calibration_ready_ = false;
|
2025-08-28 21:59:50 +08:00
|
|
|
}
|
2025-08-29 15:01:01 +08:00
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "write exception";
|
|
|
|
|
}
|
2025-08-28 21:59:50 +08:00
|
|
|
}
|
|
|
|
|
|
2025-08-29 15:01:01 +08:00
|
|
|
void OBCameraNode::readCustomerDataCallback(const std::shared_ptr<GetString::Request>& request,
|
|
|
|
|
std::shared_ptr<GetString::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
std::string data;
|
|
|
|
|
if (readCustomerData(data)) {
|
|
|
|
|
response->success = true;
|
|
|
|
|
response->data = std::move(data);
|
|
|
|
|
response->message = "read success";
|
|
|
|
|
} else {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "read failed: MD5 mismatch or data too short";
|
2025-08-28 21:59:50 +08:00
|
|
|
}
|
2025-08-29 15:01:01 +08:00
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "read exception";
|
|
|
|
|
}
|
2025-08-28 21:59:50 +08:00
|
|
|
}
|
2025-08-29 15:01:01 +08:00
|
|
|
void OBCameraNode::setUserCalibParamsCallback(
|
|
|
|
|
const std::shared_ptr<SetUserCalibParams::Request>& request,
|
|
|
|
|
std::shared_ptr<SetUserCalibParams::Response>& response) {
|
|
|
|
|
try {
|
|
|
|
|
std::ostringstream ss;
|
|
|
|
|
for (const auto& v : request->k) ss << v << " ";
|
|
|
|
|
for (const auto& v : request->d) ss << v << " ";
|
|
|
|
|
for (const auto& v : request->rotation) ss << v << " ";
|
|
|
|
|
for (const auto& v : request->translation) ss << v << " ";
|
|
|
|
|
std::string serialized_data = ss.str();
|
|
|
|
|
if (writeCustomerData(serialized_data)) {
|
|
|
|
|
response->success = true;
|
|
|
|
|
response->message = "write and verify success";
|
|
|
|
|
} else {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "write failed";
|
2025-08-28 21:59:50 +08:00
|
|
|
}
|
2025-08-29 15:01:01 +08:00
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "exception occurred";
|
|
|
|
|
}
|
2025-08-28 21:59:50 +08:00
|
|
|
}
|
2025-08-29 15:01:01 +08:00
|
|
|
void OBCameraNode::getUserCalibParamsCallback(
|
|
|
|
|
const std::shared_ptr<GetUserCalibParams::Request>& request,
|
|
|
|
|
std::shared_ptr<GetUserCalibParams::Response>& response) {
|
|
|
|
|
(void)request;
|
|
|
|
|
try {
|
|
|
|
|
std::string data_read;
|
|
|
|
|
if (!readCustomerData(data_read)) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "read failed";
|
|
|
|
|
return;
|
2025-08-28 21:59:50 +08:00
|
|
|
}
|
2025-08-29 15:01:01 +08:00
|
|
|
std::istringstream ss(data_read);
|
|
|
|
|
for (size_t i = 0; i < 9; ++i) ss >> response->k[i];
|
|
|
|
|
for (size_t i = 0; i < 8; ++i) ss >> response->d[i];
|
|
|
|
|
for (size_t i = 0; i < 9; ++i) ss >> response->rotation[i];
|
|
|
|
|
for (size_t i = 0; i < 3; ++i) ss >> response->translation[i];
|
|
|
|
|
response->success = true;
|
|
|
|
|
response->message = "read success";
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "exception occurred";
|
|
|
|
|
}
|
2025-05-12 16:15:38 +08:00
|
|
|
}
|
2026-01-07 15:28:17 +08:00
|
|
|
void OBCameraNode::setAEModeCallback(const std::shared_ptr<SetString::Request>& request,
|
|
|
|
|
std::shared_ptr<SetString::Response>& response) {
|
|
|
|
|
try {
|
2026-01-19 23:41:40 +08:00
|
|
|
if (device_->isPropertySupported(OB_PROP_DEVICE_AE_REFERENCE_INT, OB_PERMISSION_WRITE) &&
|
2026-01-07 15:28:17 +08:00
|
|
|
(request->data == "depthbased" || request->data == "colorbased")) {
|
2026-01-19 23:41:40 +08:00
|
|
|
device_->setIntProperty(OB_PROP_DEVICE_AE_REFERENCE_INT,
|
|
|
|
|
request->data == "depthbased" ? 0 : 1);
|
2026-01-20 10:35:33 +08:00
|
|
|
ae_mode_ = request->data;
|
2026-01-07 15:28:17 +08:00
|
|
|
response->success = true;
|
|
|
|
|
response->message = "set AE mode success";
|
|
|
|
|
} else {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "set AE mode failed";
|
|
|
|
|
}
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "exception occurred";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void OBCameraNode::setSportsModeCallback(const std::shared_ptr<SetBool::Request>& request,
|
|
|
|
|
std::shared_ptr<SetBool::Response>& response) {
|
|
|
|
|
try {
|
2026-01-19 23:41:40 +08:00
|
|
|
if (device_->isPropertySupported(OB_PROP_DEVICE_AE_STRATEGY_INT, OB_PERMISSION_WRITE)) {
|
|
|
|
|
device_->setIntProperty(OB_PROP_DEVICE_AE_STRATEGY_INT, request->data ? 1 : 0);
|
2026-01-07 15:28:17 +08:00
|
|
|
response->success = true;
|
|
|
|
|
response->message = "set sports mode success";
|
|
|
|
|
} else {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "set sports mode failed";
|
|
|
|
|
}
|
|
|
|
|
} catch (...) {
|
|
|
|
|
response->success = false;
|
|
|
|
|
response->message = "exception occurred";
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-06 19:00:12 +08:00
|
|
|
} // namespace orbbec_camera
|