Skip to content

Commit 6e1dcd2

Browse files
committed
Add the possibility to use a bag file instead of a physical device
A bag_filename can now be specified as parameter to the orbbec_camera_node, that will be replayed using the PlaybackDevice interface. A bag_replay_loop boolean parameter is added to allow replaying the bag in a loop. The format of the bag file is the one generated when recording from the OrbbecViewer tool.
1 parent c0c14f5 commit 6e1dcd2

6 files changed

Lines changed: 66 additions & 3 deletions

File tree

orbbec_camera/include/orbbec_camera/ob_camera_node_driver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class OBCameraNodeDriver : public rclcpp::Node {
6161

6262
void connectNetDevice(const std::string& net_device_ip, int net_device_port);
6363

64+
void openPlaybackDevice(const std::string &bagfile_path, bool bag_replay_loop);
65+
6466
void onDeviceConnected(const std::shared_ptr<ob::DeviceList>& device_list);
6567

6668
void onDeviceDisconnected(const std::shared_ptr<ob::DeviceList>& device_list);
@@ -128,6 +130,8 @@ class OBCameraNodeDriver : public rclcpp::Node {
128130
// net config
129131
std::string net_device_ip_;
130132
int net_device_port_ = 0;
133+
std::string bag_filename_;
134+
bool bag_replay_loop_ = false;
131135
int connection_delay_ = 100;
132136
bool enable_sync_host_time_ = true;
133137
std::chrono::milliseconds time_sync_period_{6000};

orbbec_camera/include/orbbec_camera/utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,6 @@ double getScanAngleIncrement(OBLiDARScanRate fps);
222222
double deg2rad(double deg);
223223

224224
double rad2deg(double rad);
225+
226+
bool is_physical_device(std::shared_ptr<ob::Device> device);
225227
} // namespace orbbec_camera

orbbec_camera/launch/gemini_330_series.launch.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ def generate_launch_description():
188188
DeclareLaunchArgument('enumerate_net_device', default_value='true'),
189189
DeclareLaunchArgument('net_device_ip', default_value=''),
190190
DeclareLaunchArgument('net_device_port', default_value='0'),
191+
DeclareLaunchArgument('bag_filename', default_value=''),
192+
DeclareLaunchArgument('bag_replay_loop', default_value='false'),
191193
DeclareLaunchArgument('device_access_mode', default_value='Default'), # Default, EA or CA . only for 335le
192194
DeclareLaunchArgument('exposure_range_mode', default_value='default'),#default, ultimate or regular
193195
DeclareLaunchArgument('log_level', default_value='none'),

orbbec_camera/src/ob_camera_node.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ void OBCameraNode::setupDevices() {
443443
RCLCPP_INFO_STREAM(logger_, "Setting laser control to " << enable_laser_);
444444
TRY_TO_SET_PROPERTY(setIntProperty, OB_PROP_LASER_BOOL, enable_laser_);
445445
}
446-
if (!sync_mode_str_.empty()) {
446+
if (!sync_mode_str_.empty() && is_physical_device(device_)) {
447447
auto sync_config = device_->getMultiDeviceSyncConfig();
448448
RCLCPP_INFO_STREAM(logger_,
449449
"Current sync mode: " << magic_enum::enum_name(sync_config.syncMode));
@@ -2225,7 +2225,7 @@ void OBCameraNode::getParameters() {
22252225
if (isOpenNIDevice(pid_)) {
22262226
time_domain_ = "system";
22272227
}
2228-
if (time_domain_ == "global") {
2228+
if (time_domain_ == "global" && is_physical_device(device_)) {
22292229
device_->enableGlobalTimestamp(true);
22302230
}
22312231
setAndGetNodeParameter<int>(frames_per_trigger_, "frames_per_trigger", 2);
@@ -2405,7 +2405,7 @@ void OBCameraNode::onTemperatureUpdate(diagnostic_updater::DiagnosticStatusWrapp
24052405
}
24062406

24072407
void OBCameraNode::setupDiagnosticUpdater() {
2408-
if (diagnostic_period_ <= 0.0) {
2408+
if (diagnostic_period_ <= 0.0 || !is_physical_device(device_)) {
24092409
return;
24102410
}
24112411
try {

orbbec_camera/src/ob_camera_node_driver.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,8 @@ void OBCameraNodeDriver::init() {
275275
usb_port_ = declare_parameter<std::string>("usb_port", "");
276276
net_device_ip_ = declare_parameter<std::string>("net_device_ip", "");
277277
net_device_port_ = static_cast<int>(declare_parameter<int>("net_device_port", 0));
278+
bag_filename_ = declare_parameter<std::string>("bag_filename", "");
279+
bag_replay_loop_ = static_cast<int>(declare_parameter<bool>("bag_replay_loop", true));
278280
enumerate_net_device_ = declare_parameter<bool>("enumerate_net_device", false);
279281
uvc_backend_ = declare_parameter<std::string>("uvc_backend", "libuvc");
280282
device_access_mode_str_ = declare_parameter<std::string>("device_access_mode", "Default");
@@ -456,6 +458,8 @@ void OBCameraNodeDriver::queryDevice() {
456458

457459
if (!enumerate_net_device_ && !net_device_ip_.empty() && net_device_port_ != 0) {
458460
connectNetDevice(net_device_ip_, net_device_port_);
461+
} else if (!bag_filename_.empty()) {
462+
openPlaybackDevice(bag_filename_, bag_replay_loop_);
459463
} else {
460464
auto device_list = ctx_->queryDeviceList();
461465
if (device_list->getCount() != 0) {
@@ -1227,6 +1231,51 @@ void OBCameraNodeDriver::connectNetDevice(const std::string &net_device_ip, int
12271231
}
12281232
}
12291233

1234+
void OBCameraNodeDriver::openPlaybackDevice(const std::string &bagfile_path, bool bag_replay_loop) {
1235+
if (bagfile_path.empty() || !std::filesystem::exists(bagfile_path)) {
1236+
RCLCPP_ERROR_STREAM(logger_, "Invalid bag file path " << bagfile_path);
1237+
return;
1238+
}
1239+
1240+
auto playback_device = std::make_shared<ob::PlaybackDevice>(bagfile_path.c_str());
1241+
if (playback_device == nullptr) {
1242+
RCLCPP_ERROR_STREAM(logger_, "Failed to open playback device " << bagfile_path);
1243+
return;
1244+
}
1245+
try {
1246+
RCLCPP_INFO_STREAM(logger_, "Opening bag file " << bagfile_path);
1247+
1248+
// Automatically restart playback when reaching file end
1249+
playback_device->setPlaybackStatusChangeCallback([&](OBPlaybackStatus status)
1250+
{
1251+
RCLCPP_INFO(logger_, "Playback status changed to %d", status);
1252+
1253+
if (status == OB_PLAYBACK_STOPPED) {
1254+
if (bag_replay_loop && is_alive_ && rclcpp::ok()) {
1255+
// restart bag file
1256+
ob_camera_node_->clean();
1257+
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
1258+
initializeDevice(playback_device);
1259+
} else {
1260+
// stop it here
1261+
rclcpp::shutdown();
1262+
}
1263+
}
1264+
});
1265+
1266+
initializeDevice(playback_device);
1267+
if (!device_connected_) {
1268+
RCLCPP_ERROR_STREAM(logger_, "Failed to initialize playback device " << bagfile_path);
1269+
}
1270+
} catch (const std::exception &e) {
1271+
RCLCPP_ERROR_STREAM(logger_, "Exception during playback device initialization: " << e.what());
1272+
device_connected_ = false;
1273+
} catch (...) {
1274+
RCLCPP_ERROR_STREAM(logger_, "Unknown exception during playback device initialization");
1275+
device_connected_ = false;
1276+
}
1277+
}
1278+
12301279
void OBCameraNodeDriver::startDevice(const std::shared_ptr<ob::DeviceList> &list) {
12311280
if (device_connected_.load()) {
12321281
return;

orbbec_camera/src/utils.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,4 +1016,10 @@ double rad2deg(double rad) {
10161016
return angle_degrees;
10171017
}
10181018

1019+
bool is_physical_device(std::shared_ptr<ob::Device> device)
1020+
{
1021+
// any non PlaybackDevice is supposed to be a physical one
1022+
return (dynamic_cast<ob::PlaybackDevice*>(device.get()) == nullptr);
1023+
}
1024+
10191025
} // namespace orbbec_camera

0 commit comments

Comments
 (0)