Skip to content
This repository was archived by the owner on Jul 26, 2024. It is now read-only.

Commit 5886d77

Browse files
authored
Merge pull request #162 from zchenpds/body_tracking_delay_foxy
Use a separate thread to pop k4abt_tracker result. Fix #109.
2 parents 7ff003e + a3ce796 commit 5886d77

File tree

2 files changed

+89
-94
lines changed

2 files changed

+89
-94
lines changed

include/azure_kinect_ros_driver/k4a_ros_device.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ class K4AROSDevice : public rclcpp::Node
8686
std::shared_ptr<sensor_msgs::msg::PointCloud2>& point_cloud);
8787

8888
void framePublisherThread();
89+
#if defined(K4A_BODY_TRACKING)
90+
void bodyPublisherThread();
91+
#endif
8992
void imuPublisherThread();
9093

9194
// Gets a timestap from one of the captures images
@@ -152,6 +155,8 @@ class K4AROSDevice : public rclcpp::Node
152155
#if defined(K4A_BODY_TRACKING)
153156
// Body tracker
154157
k4abt::tracker k4abt_tracker_;
158+
std::atomic_int16_t k4abt_tracker_queue_size_;
159+
std::thread body_publisher_thread_;
155160
#endif
156161

157162
std::chrono::nanoseconds device_to_realtime_offset_{0};

src/k4a_ros_device.cpp

Lines changed: 84 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ K4AROSDevice::K4AROSDevice()
4141
// clang-format off
4242
#if defined(K4A_BODY_TRACKING)
4343
k4abt_tracker_(nullptr),
44+
k4abt_tracker_queue_size_(0),
4445
#endif
4546
// clang-format on
4647
last_capture_time_usec_(0),
@@ -298,6 +299,14 @@ K4AROSDevice::~K4AROSDevice()
298299
// Start tearing down the publisher threads
299300
running_ = false;
300301

302+
#if defined(K4A_BODY_TRACKING)
303+
// Join the publisher thread
304+
RCLCPP_INFO(this->get_logger(),"Joining body publisher thread");
305+
body_publisher_thread_.join();
306+
RCLCPP_INFO(this->get_logger(),"Body publisher thread joined");
307+
#endif
308+
309+
// Join the publisher thread
301310
RCLCPP_INFO(this->get_logger(),"Joining camera publisher thread");
302311
frame_publisher_thread_.join();
303312
RCLCPP_INFO(this->get_logger(),"Camera publisher thread joined");
@@ -373,6 +382,9 @@ k4a_result_t K4AROSDevice::startCameras()
373382

374383
// Start the thread that will poll the cameras and publish frames
375384
frame_publisher_thread_ = thread(&K4AROSDevice::framePublisherThread, this);
385+
#if defined(K4A_BODY_TRACKING)
386+
body_publisher_thread_ = thread(&K4AROSDevice::bodyPublisherThread, this);
387+
#endif
376388

377389
return K4A_RESULT_SUCCEEDED;
378390
}
@@ -581,7 +593,6 @@ k4a_result_t K4AROSDevice::getRgbPointCloudInDepthFrame(const k4a::capture& capt
581593

582594
point_cloud->header.frame_id = calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_;
583595
point_cloud->header.stamp = timestampToROS(k4a_depth_frame.get_device_timestamp());
584-
printTimestampDebugMessage("RGB point cloud", point_cloud->header.stamp);
585596

586597
return fillColorPointCloud(calibration_data_.point_cloud_image_, calibration_data_.transformed_rgb_image_,
587598
point_cloud);
@@ -614,7 +625,6 @@ k4a_result_t K4AROSDevice::getRgbPointCloudInRgbFrame(const k4a::capture& captur
614625

615626
point_cloud->header.frame_id = calibration_data_.tf_prefix_ + calibration_data_.rgb_camera_frame_;
616627
point_cloud->header.stamp = timestampToROS(k4a_depth_frame.get_device_timestamp());
617-
printTimestampDebugMessage("RGB point cloud", point_cloud->header.stamp);
618628

619629
return fillColorPointCloud(calibration_data_.point_cloud_image_, k4a_bgra_frame, point_cloud);
620630
}
@@ -631,7 +641,6 @@ k4a_result_t K4AROSDevice::getPointCloud(const k4a::capture& capture, std::share
631641

632642
point_cloud->header.frame_id = calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_;
633643
point_cloud->header.stamp = timestampToROS(k4a_depth_frame.get_device_timestamp());
634-
printTimestampDebugMessage("Point cloud", point_cloud->header.stamp);
635644

636645
// Tranform depth image to point cloud
637646
calibration_data_.k4a_transformation_.depth_image_to_point_cloud(k4a_depth_frame, K4A_CALIBRATION_TYPE_DEPTH,
@@ -743,7 +752,6 @@ k4a_result_t K4AROSDevice::getImuFrame(const k4a_imu_sample_t& sample, std::shar
743752
{
744753
imu_msg->header.frame_id = calibration_data_.tf_prefix_ + calibration_data_.imu_frame_;
745754
imu_msg->header.stamp = timestampToROS(sample.acc_timestamp_usec);
746-
printTimestampDebugMessage("IMU", imu_msg->header.stamp);
747755

748756
// The correct convention in ROS is to publish the raw sensor data, in the
749757
// sensor coordinate frame. Do that here.
@@ -958,7 +966,6 @@ void K4AROSDevice::framePublisherThread()
958966
else if (result == K4A_RESULT_SUCCEEDED)
959967
{
960968
capture_time = timestampToROS(capture.get_ir_image().get_device_timestamp());
961-
printTimestampDebugMessage("IR image", capture_time);
962969

963970
// Re-sychronize the timestamps with the capture timestamp
964971
ir_raw_camera_info.header.stamp = capture_time;
@@ -991,7 +998,6 @@ void K4AROSDevice::framePublisherThread()
991998
else if (result == K4A_RESULT_SUCCEEDED)
992999
{
9931000
capture_time = timestampToROS(capture.get_depth_image().get_device_timestamp());
994-
printTimestampDebugMessage("Depth image", capture_time);
9951001

9961002
// Re-sychronize the timestamps with the capture timestamp
9971003
depth_raw_camera_info.header.stamp = capture_time;
@@ -1024,7 +1030,6 @@ void K4AROSDevice::framePublisherThread()
10241030
else if (result == K4A_RESULT_SUCCEEDED)
10251031
{
10261032
capture_time = timestampToROS(capture.get_depth_image().get_device_timestamp());
1027-
printTimestampDebugMessage("Depth image", capture_time);
10281033

10291034
depth_rect_frame->header.stamp = capture_time;
10301035
depth_rect_frame->header.frame_id = calibration_data_.tf_prefix_ + calibration_data_.rgb_camera_frame_;
@@ -1038,11 +1043,9 @@ void K4AROSDevice::framePublisherThread()
10381043

10391044
#if defined(K4A_BODY_TRACKING)
10401045
// Publish body markers when body tracking is enabled and a depth image is available
1041-
if (params_.body_tracking_enabled &&
1046+
if (params_.body_tracking_enabled && k4abt_tracker_queue_size_ < 3 &&
10421047
(this->count_subscribers("body_tracking_data") > 0 || this->count_subscribers("body_index_map/image_raw") > 0))
10431048
{
1044-
capture_time = timestampToROS(capture.get_depth_image().get_device_timestamp());
1045-
10461049
if (!k4abt_tracker_.enqueue_capture(capture))
10471050
{
10481051
RCLCPP_ERROR(this->get_logger(),"Error! Add capture to tracker process queue failed!");
@@ -1051,56 +1054,7 @@ void K4AROSDevice::framePublisherThread()
10511054
}
10521055
else
10531056
{
1054-
k4abt::frame body_frame = k4abt_tracker_.pop_result();
1055-
if (body_frame == nullptr)
1056-
{
1057-
RCLCPP_ERROR_STREAM(this->get_logger(),"Pop body frame result failed!");
1058-
rclcpp::shutdown();
1059-
return;
1060-
}
1061-
else
1062-
{
1063-
if (this->count_subscribers("body_tracking_data") > 0)
1064-
{
1065-
// Joint marker array
1066-
MarkerArray::SharedPtr markerArrayPtr(new MarkerArray);
1067-
auto num_bodies = body_frame.get_num_bodies();
1068-
for (size_t i = 0; i < num_bodies; ++i)
1069-
{
1070-
k4abt_body_t body = body_frame.get_body(i);
1071-
for (int j = 0; j < (int) K4ABT_JOINT_COUNT; ++j)
1072-
{
1073-
Marker::SharedPtr markerPtr(new Marker);
1074-
getBodyMarker(body, markerPtr, j, capture_time);
1075-
markerArrayPtr->markers.push_back(*markerPtr);
1076-
}
1077-
}
1078-
body_marker_publisher_->publish(*markerArrayPtr);
1079-
}
1080-
1081-
if (this->count_subscribers("body_index_map/image_raw") > 0)
1082-
{
1083-
// Body index map
1084-
Image::SharedPtr body_index_map_frame(new Image);
1085-
result = getBodyIndexMap(body_frame, body_index_map_frame);
1086-
1087-
if (result != K4A_RESULT_SUCCEEDED)
1088-
{
1089-
RCLCPP_ERROR_STREAM(this->get_logger(),"Failed to get body index map");
1090-
rclcpp::shutdown();
1091-
return;
1092-
}
1093-
else if (result == K4A_RESULT_SUCCEEDED)
1094-
{
1095-
// Re-sychronize the timestamps with the capture timestamp
1096-
body_index_map_frame->header.stamp = capture_time;
1097-
body_index_map_frame->header.frame_id =
1098-
calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_;
1099-
1100-
body_index_map_publisher_.publish(body_index_map_frame);
1101-
}
1102-
}
1103-
}
1057+
++k4abt_tracker_queue_size_;
11041058
}
11051059
}
11061060
#endif
@@ -1126,7 +1080,6 @@ void K4AROSDevice::framePublisherThread()
11261080
}
11271081

11281082
capture_time = timestampToROS(capture.get_color_image().get_device_timestamp());
1129-
printTimestampDebugMessage("Color image", capture_time);
11301083

11311084
rgb_jpeg_frame->header.stamp = capture_time;
11321085
rgb_jpeg_frame->header.frame_id = calibration_data_.tf_prefix_ + calibration_data_.rgb_camera_frame_;
@@ -1152,7 +1105,6 @@ void K4AROSDevice::framePublisherThread()
11521105
}
11531106

11541107
capture_time = timestampToROS(capture.get_color_image().get_device_timestamp());
1155-
printTimestampDebugMessage("Color image", capture_time);
11561108

11571109
rgb_raw_frame->header.stamp = capture_time;
11581110
rgb_raw_frame->header.frame_id = calibration_data_.tf_prefix_ + calibration_data_.rgb_camera_frame_;
@@ -1181,7 +1133,6 @@ void K4AROSDevice::framePublisherThread()
11811133
}
11821134

11831135
capture_time = timestampToROS(capture.get_color_image().get_device_timestamp());
1184-
printTimestampDebugMessage("Color image", capture_time);
11851136

11861137
rgb_rect_frame->header.stamp = capture_time;
11871138
rgb_rect_frame->header.frame_id = calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_;
@@ -1241,6 +1192,76 @@ void K4AROSDevice::framePublisherThread()
12411192
}
12421193
}
12431194

1195+
#if defined(K4A_BODY_TRACKING)
1196+
void K4AROSDevice::bodyPublisherThread()
1197+
{
1198+
while (running_ && rclcpp::ok())
1199+
{
1200+
if (k4abt_tracker_queue_size_ > 0)
1201+
{
1202+
k4abt::frame body_frame = k4abt_tracker_.pop_result();
1203+
--k4abt_tracker_queue_size_;
1204+
1205+
if (body_frame == nullptr)
1206+
{
1207+
RCLCPP_ERROR_STREAM(this->get_logger(),"Pop body frame result failed!");
1208+
rclcpp::shutdown();
1209+
return;
1210+
}
1211+
else
1212+
{
1213+
auto capture_time = timestampToROS(body_frame.get_device_timestamp());
1214+
1215+
if (this->count_subscribers("body_tracking_data") > 0)
1216+
{
1217+
// Joint marker array
1218+
MarkerArray::SharedPtr markerArrayPtr(new MarkerArray);
1219+
auto num_bodies = body_frame.get_num_bodies();
1220+
for (size_t i = 0; i < num_bodies; ++i)
1221+
{
1222+
k4abt_body_t body = body_frame.get_body(i);
1223+
for (int j = 0; j < (int) K4ABT_JOINT_COUNT; ++j)
1224+
{
1225+
Marker::SharedPtr markerPtr(new Marker);
1226+
getBodyMarker(body, markerPtr, j, capture_time);
1227+
markerArrayPtr->markers.push_back(*markerPtr);
1228+
}
1229+
}
1230+
body_marker_publisher_->publish(*markerArrayPtr);
1231+
}
1232+
1233+
if (this->count_subscribers("body_index_map/image_raw") > 0)
1234+
{
1235+
// Body index map
1236+
Image::SharedPtr body_index_map_frame(new Image);
1237+
auto result = getBodyIndexMap(body_frame, body_index_map_frame);
1238+
1239+
if (result != K4A_RESULT_SUCCEEDED)
1240+
{
1241+
RCLCPP_ERROR_STREAM(this->get_logger(),"Failed to get body index map");
1242+
rclcpp::shutdown();
1243+
return;
1244+
}
1245+
else if (result == K4A_RESULT_SUCCEEDED)
1246+
{
1247+
// Re-sychronize the timestamps with the capture timestamp
1248+
body_index_map_frame->header.stamp = capture_time;
1249+
body_index_map_frame->header.frame_id =
1250+
calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_;
1251+
1252+
body_index_map_publisher_.publish(body_index_map_frame);
1253+
}
1254+
}
1255+
}
1256+
}
1257+
else
1258+
{
1259+
std::this_thread::sleep_for(std::chrono::milliseconds{ 20 });
1260+
}
1261+
}
1262+
}
1263+
#endif
1264+
12441265
k4a_imu_sample_t K4AROSDevice::computeMeanIMUSample(const std::vector<k4a_imu_sample_t>& samples)
12451266
{
12461267
// Compute mean sample
@@ -1465,34 +1486,3 @@ void K4AROSDevice::updateTimestampOffset(const std::chrono::microseconds& k4a_de
14651486
std::floor(alpha * (device_to_realtime - device_to_realtime_offset_).count())));
14661487
}
14671488
}
1468-
1469-
void K4AROSDevice::printTimestampDebugMessage(const std::string& name, const rclcpp::Time& timestamp)
1470-
{
1471-
rclcpp::Duration lag = this->get_clock()->now() - timestamp;
1472-
static std::map<const std::string, std::vector<rclcpp::Duration>> map_min_max;
1473-
auto it = map_min_max.find(name);
1474-
if (it == map_min_max.end())
1475-
{
1476-
vector<rclcpp::Duration> v(2, lag);
1477-
map_min_max[name] = v;
1478-
it = map_min_max.find(name);
1479-
}
1480-
else
1481-
{
1482-
auto& min_lag = it->second[0];
1483-
auto& max_lag = it->second[1];
1484-
if (lag < min_lag)
1485-
{
1486-
min_lag = lag;
1487-
}
1488-
if (lag > max_lag)
1489-
{
1490-
max_lag = lag;
1491-
}
1492-
}
1493-
1494-
RCLCPP_DEBUG_STREAM(this->get_logger(), name << " timestamp lags rclcpp::Clock::now() by\n"
1495-
<< std::setw(23) << lag.seconds() * 1000.0 << " ms. "
1496-
<< "The lag ranges from " << it->second[0].seconds() * 1000.0 << "ms"
1497-
<< " to " << it->second[1].seconds() * 1000.0 << "ms.");
1498-
}

0 commit comments

Comments
 (0)