@@ -56,6 +56,7 @@ K4AROSDevice::K4AROSDevice(const NodeHandle& n, const NodeHandle& p)
56
56
// clang-format off
57
57
#if defined(K4A_BODY_TRACKING)
58
58
k4abt_tracker_ (nullptr ),
59
+ k4abt_tracker_queue_size_(0 ),
59
60
#endif
60
61
// clang-format on
61
62
node_ (n),
@@ -312,6 +313,13 @@ K4AROSDevice::~K4AROSDevice()
312
313
// Start tearing down the publisher threads
313
314
running_ = false ;
314
315
316
+ #if defined(K4A_BODY_TRACKING)
317
+ // Join the publisher thread
318
+ ROS_INFO (" Joining body publisher thread" );
319
+ body_publisher_thread_.join ();
320
+ ROS_INFO (" Body publisher thread joined" );
321
+ #endif
322
+
315
323
// Join the publisher thread
316
324
ROS_INFO (" Joining camera publisher thread" );
317
325
frame_publisher_thread_.join ();
@@ -388,6 +396,9 @@ k4a_result_t K4AROSDevice::startCameras()
388
396
389
397
// Start the thread that will poll the cameras and publish frames
390
398
frame_publisher_thread_ = thread (&K4AROSDevice::framePublisherThread, this );
399
+ #if defined(K4A_BODY_TRACKING)
400
+ body_publisher_thread_ = thread (&K4AROSDevice::bodyPublisherThread, this );
401
+ #endif
391
402
392
403
return K4A_RESULT_SUCCEEDED;
393
404
}
@@ -596,7 +607,6 @@ k4a_result_t K4AROSDevice::getRgbPointCloudInDepthFrame(const k4a::capture& capt
596
607
597
608
point_cloud->header .frame_id = calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_ ;
598
609
point_cloud->header .stamp = timestampToROS (k4a_depth_frame.get_device_timestamp ());
599
- printTimestampDebugMessage (" RGB point cloud" , point_cloud->header .stamp );
600
610
601
611
return fillColorPointCloud (calibration_data_.point_cloud_image_ , calibration_data_.transformed_rgb_image_ ,
602
612
point_cloud);
@@ -629,7 +639,6 @@ k4a_result_t K4AROSDevice::getRgbPointCloudInRgbFrame(const k4a::capture& captur
629
639
630
640
point_cloud->header .frame_id = calibration_data_.tf_prefix_ + calibration_data_.rgb_camera_frame_ ;
631
641
point_cloud->header .stamp = timestampToROS (k4a_depth_frame.get_device_timestamp ());
632
- printTimestampDebugMessage (" RGB point cloud" , point_cloud->header .stamp );
633
642
634
643
return fillColorPointCloud (calibration_data_.point_cloud_image_ , k4a_bgra_frame, point_cloud);
635
644
}
@@ -646,7 +655,6 @@ k4a_result_t K4AROSDevice::getPointCloud(const k4a::capture& capture, sensor_msg
646
655
647
656
point_cloud->header .frame_id = calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_ ;
648
657
point_cloud->header .stamp = timestampToROS (k4a_depth_frame.get_device_timestamp ());
649
- printTimestampDebugMessage (" Point cloud" , point_cloud->header .stamp );
650
658
651
659
// Tranform depth image to point cloud
652
660
calibration_data_.k4a_transformation_ .depth_image_to_point_cloud (k4a_depth_frame, K4A_CALIBRATION_TYPE_DEPTH,
@@ -758,7 +766,6 @@ k4a_result_t K4AROSDevice::getImuFrame(const k4a_imu_sample_t& sample, sensor_ms
758
766
{
759
767
imu_msg->header .frame_id = calibration_data_.tf_prefix_ + calibration_data_.imu_frame_ ;
760
768
imu_msg->header .stamp = timestampToROS (sample.acc_timestamp_usec );
761
- printTimestampDebugMessage (" IMU" , imu_msg->header .stamp );
762
769
763
770
// The correct convention in ROS is to publish the raw sensor data, in the
764
771
// sensor coordinate frame. Do that here.
@@ -989,7 +996,6 @@ void K4AROSDevice::framePublisherThread()
989
996
else if (result == K4A_RESULT_SUCCEEDED)
990
997
{
991
998
capture_time = timestampToROS (capture.get_ir_image ().get_device_timestamp ());
992
- printTimestampDebugMessage (" IR image" , capture_time);
993
999
994
1000
// Re-sychronize the timestamps with the capture timestamp
995
1001
ir_raw_camera_info.header .stamp = capture_time;
@@ -1021,7 +1027,6 @@ void K4AROSDevice::framePublisherThread()
1021
1027
else if (result == K4A_RESULT_SUCCEEDED)
1022
1028
{
1023
1029
capture_time = timestampToROS (capture.get_depth_image ().get_device_timestamp ());
1024
- printTimestampDebugMessage (" Depth image" , capture_time);
1025
1030
1026
1031
// Re-sychronize the timestamps with the capture timestamp
1027
1032
depth_raw_camera_info.header .stamp = capture_time;
@@ -1053,7 +1058,6 @@ void K4AROSDevice::framePublisherThread()
1053
1058
else if (result == K4A_RESULT_SUCCEEDED)
1054
1059
{
1055
1060
capture_time = timestampToROS (capture.get_depth_image ().get_device_timestamp ());
1056
- printTimestampDebugMessage (" Depth image" , capture_time);
1057
1061
1058
1062
depth_rect_frame->header .stamp = capture_time;
1059
1063
depth_rect_frame->header .frame_id = calibration_data_.tf_prefix_ + calibration_data_.rgb_camera_frame_ ;
@@ -1067,11 +1071,9 @@ void K4AROSDevice::framePublisherThread()
1067
1071
1068
1072
#if defined(K4A_BODY_TRACKING)
1069
1073
// Publish body markers when body tracking is enabled and a depth image is available
1070
- if (params_.body_tracking_enabled &&
1074
+ if (params_.body_tracking_enabled && k4abt_tracker_queue_size_ < 3 &&
1071
1075
(body_marker_publisher_.getNumSubscribers () > 0 || body_index_map_publisher_.getNumSubscribers () > 0 ))
1072
1076
{
1073
- capture_time = timestampToROS (capture.get_depth_image ().get_device_timestamp ());
1074
-
1075
1077
if (!k4abt_tracker_.enqueue_capture (capture))
1076
1078
{
1077
1079
ROS_ERROR (" Error! Add capture to tracker process queue failed!" );
@@ -1080,56 +1082,7 @@ void K4AROSDevice::framePublisherThread()
1080
1082
}
1081
1083
else
1082
1084
{
1083
- k4abt::frame body_frame = k4abt_tracker_.pop_result ();
1084
- if (body_frame == nullptr )
1085
- {
1086
- ROS_ERROR_STREAM (" Pop body frame result failed!" );
1087
- ros::shutdown ();
1088
- return ;
1089
- }
1090
- else
1091
- {
1092
- if (body_marker_publisher_.getNumSubscribers () > 0 )
1093
- {
1094
- // Joint marker array
1095
- MarkerArrayPtr markerArrayPtr (new MarkerArray);
1096
- auto num_bodies = body_frame.get_num_bodies ();
1097
- for (size_t i = 0 ; i < num_bodies; ++i)
1098
- {
1099
- k4abt_body_t body = body_frame.get_body (i);
1100
- for (int j = 0 ; j < (int ) K4ABT_JOINT_COUNT; ++j)
1101
- {
1102
- MarkerPtr markerPtr (new Marker);
1103
- getBodyMarker (body, markerPtr, j, capture_time);
1104
- markerArrayPtr->markers .push_back (*markerPtr);
1105
- }
1106
- }
1107
- body_marker_publisher_.publish (markerArrayPtr);
1108
- }
1109
-
1110
- if (body_index_map_publisher_.getNumSubscribers () > 0 )
1111
- {
1112
- // Body index map
1113
- ImagePtr body_index_map_frame (new Image);
1114
- result = getBodyIndexMap (body_frame, body_index_map_frame);
1115
-
1116
- if (result != K4A_RESULT_SUCCEEDED)
1117
- {
1118
- ROS_ERROR_STREAM (" Failed to get body index map" );
1119
- ros::shutdown ();
1120
- return ;
1121
- }
1122
- else if (result == K4A_RESULT_SUCCEEDED)
1123
- {
1124
- // Re-sychronize the timestamps with the capture timestamp
1125
- body_index_map_frame->header .stamp = capture_time;
1126
- body_index_map_frame->header .frame_id =
1127
- calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_ ;
1128
-
1129
- body_index_map_publisher_.publish (body_index_map_frame);
1130
- }
1131
- }
1132
- }
1085
+ ++k4abt_tracker_queue_size_;
1133
1086
}
1134
1087
}
1135
1088
#endif
@@ -1155,7 +1108,6 @@ void K4AROSDevice::framePublisherThread()
1155
1108
}
1156
1109
1157
1110
capture_time = timestampToROS (capture.get_color_image ().get_device_timestamp ());
1158
- printTimestampDebugMessage (" Color image" , capture_time);
1159
1111
1160
1112
rgb_jpeg_frame->header .stamp = capture_time;
1161
1113
rgb_jpeg_frame->header .frame_id = calibration_data_.tf_prefix_ + calibration_data_.rgb_camera_frame_ ;
@@ -1181,7 +1133,6 @@ void K4AROSDevice::framePublisherThread()
1181
1133
}
1182
1134
1183
1135
capture_time = timestampToROS (capture.get_color_image ().get_device_timestamp ());
1184
- printTimestampDebugMessage (" Color image" , capture_time);
1185
1136
1186
1137
rgb_raw_frame->header .stamp = capture_time;
1187
1138
rgb_raw_frame->header .frame_id = calibration_data_.tf_prefix_ + calibration_data_.rgb_camera_frame_ ;
@@ -1209,7 +1160,6 @@ void K4AROSDevice::framePublisherThread()
1209
1160
}
1210
1161
1211
1162
capture_time = timestampToROS (capture.get_color_image ().get_device_timestamp ());
1212
- printTimestampDebugMessage (" Color image" , capture_time);
1213
1163
1214
1164
rgb_rect_frame->header .stamp = capture_time;
1215
1165
rgb_rect_frame->header .frame_id = calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_ ;
@@ -1276,6 +1226,76 @@ void K4AROSDevice::framePublisherThread()
1276
1226
}
1277
1227
}
1278
1228
1229
+ #if defined(K4A_BODY_TRACKING)
1230
+ void K4AROSDevice::bodyPublisherThread ()
1231
+ {
1232
+ while (running_ && ros::ok () && !ros::isShuttingDown ())
1233
+ {
1234
+ if (k4abt_tracker_queue_size_ > 0 )
1235
+ {
1236
+ k4abt::frame body_frame = k4abt_tracker_.pop_result ();
1237
+ --k4abt_tracker_queue_size_;
1238
+
1239
+ if (body_frame == nullptr )
1240
+ {
1241
+ ROS_ERROR_STREAM (" Pop body frame result failed!" );
1242
+ ros::shutdown ();
1243
+ return ;
1244
+ }
1245
+ else
1246
+ {
1247
+ auto capture_time = timestampToROS (body_frame.get_device_timestamp ());
1248
+
1249
+ if (body_marker_publisher_.getNumSubscribers () > 0 )
1250
+ {
1251
+ // Joint marker array
1252
+ MarkerArrayPtr markerArrayPtr (new MarkerArray);
1253
+ auto num_bodies = body_frame.get_num_bodies ();
1254
+ for (size_t i = 0 ; i < num_bodies; ++i)
1255
+ {
1256
+ k4abt_body_t body = body_frame.get_body (i);
1257
+ for (int j = 0 ; j < (int ) K4ABT_JOINT_COUNT; ++j)
1258
+ {
1259
+ MarkerPtr markerPtr (new Marker);
1260
+ getBodyMarker (body, markerPtr, j, capture_time);
1261
+ markerArrayPtr->markers .push_back (*markerPtr);
1262
+ }
1263
+ }
1264
+ body_marker_publisher_.publish (markerArrayPtr);
1265
+ }
1266
+
1267
+ if (body_index_map_publisher_.getNumSubscribers () > 0 )
1268
+ {
1269
+ // Body index map
1270
+ ImagePtr body_index_map_frame (new Image);
1271
+ auto result = getBodyIndexMap (body_frame, body_index_map_frame);
1272
+
1273
+ if (result != K4A_RESULT_SUCCEEDED)
1274
+ {
1275
+ ROS_ERROR_STREAM (" Failed to get body index map" );
1276
+ ros::shutdown ();
1277
+ return ;
1278
+ }
1279
+ else if (result == K4A_RESULT_SUCCEEDED)
1280
+ {
1281
+ // Re-sychronize the timestamps with the capture timestamp
1282
+ body_index_map_frame->header .stamp = capture_time;
1283
+ body_index_map_frame->header .frame_id =
1284
+ calibration_data_.tf_prefix_ + calibration_data_.depth_camera_frame_ ;
1285
+
1286
+ body_index_map_publisher_.publish (body_index_map_frame);
1287
+ }
1288
+ }
1289
+ }
1290
+ }
1291
+ else
1292
+ {
1293
+ std::this_thread::sleep_for (std::chrono::milliseconds{ 20 });
1294
+ }
1295
+ }
1296
+ }
1297
+ #endif
1298
+
1279
1299
k4a_imu_sample_t K4AROSDevice::computeMeanIMUSample (const std::vector<k4a_imu_sample_t >& samples)
1280
1300
{
1281
1301
// Compute mean sample
@@ -1503,33 +1523,3 @@ void K4AROSDevice::updateTimestampOffset(const std::chrono::microseconds& k4a_de
1503
1523
std::floor (alpha * (device_to_realtime - device_to_realtime_offset_).count ())));
1504
1524
}
1505
1525
}
1506
-
1507
- void printTimestampDebugMessage (const std::string& name, const ros::Time& timestamp)
1508
- {
1509
- ros::Duration lag = ros::Time::now () - timestamp;
1510
- static std::map<const std::string, std::pair<ros::Duration , ros::Duration >> map_min_max;
1511
- auto it = map_min_max.find (name);
1512
- if (it == map_min_max.end ())
1513
- {
1514
- map_min_max[name] = std::make_pair (lag, lag);
1515
- it = map_min_max.find (name);
1516
- }
1517
- else
1518
- {
1519
- auto & min_lag = it->second .first ;
1520
- auto & max_lag = it->second .second ;
1521
- if (lag < min_lag)
1522
- {
1523
- min_lag = lag;
1524
- }
1525
- if (lag > max_lag)
1526
- {
1527
- max_lag = lag;
1528
- }
1529
- }
1530
-
1531
- ROS_DEBUG_STREAM (name << " timestamp lags ros::Time::now() by\n "
1532
- << std::setw (23 ) << lag.toSec () * 1000.0 << " ms. "
1533
- << " The lag ranges from " << it->second .first .toSec () * 1000.0 << " ms"
1534
- << " to " << it->second .second .toSec () * 1000.0 << " ms." );
1535
- }
0 commit comments