Validate tool checks per-point time stamps. (#737)
Checks for per-point timing issues in a bag file. Feature is tracked in #529.master
parent
5251634d3d
commit
be592f55fa
|
@ -149,7 +149,31 @@ class RangeDataChecker {
|
||||||
template <typename MessageType>
|
template <typename MessageType>
|
||||||
void CheckMessage(const MessageType& message) {
|
void CheckMessage(const MessageType& message) {
|
||||||
const std::string& frame_id = message.header.frame_id;
|
const std::string& frame_id = message.header.frame_id;
|
||||||
RangeChecksum current_checksum = ComputeRangeChecksum(message);
|
ros::Time current_time_stamp = message.header.stamp;
|
||||||
|
RangeChecksum current_checksum;
|
||||||
|
ros::Duration range_duration;
|
||||||
|
ReadRangeMessage(message, ¤t_checksum, &range_duration);
|
||||||
|
ros::Time current_time_first_point = current_time_stamp - range_duration;
|
||||||
|
auto previous_time_stamp_it =
|
||||||
|
frame_id_to_previous_time_stamp_.find(frame_id);
|
||||||
|
if (previous_time_stamp_it != frame_id_to_previous_time_stamp_.end() &&
|
||||||
|
previous_time_stamp_it->second >= current_time_first_point) {
|
||||||
|
LOG_FIRST_N(WARNING, 3)
|
||||||
|
<< "Sensor with frame_id \"" << frame_id
|
||||||
|
<< "\" measurements overlap in time "
|
||||||
|
<< "Previous range message, ending at time stamp "
|
||||||
|
<< previous_time_stamp_it->second
|
||||||
|
<< ", must finish before current range message, "
|
||||||
|
<< "which ranges from " << current_time_first_point << " to "
|
||||||
|
<< current_time_stamp;
|
||||||
|
double overlap =
|
||||||
|
(previous_time_stamp_it->second - current_time_first_point).toSec();
|
||||||
|
auto it = frame_id_to_max_overlap_duration_.find(frame_id);
|
||||||
|
if (it == frame_id_to_max_overlap_duration_.end() ||
|
||||||
|
overlap > frame_id_to_max_overlap_duration_.at(frame_id)) {
|
||||||
|
frame_id_to_max_overlap_duration_[frame_id] = overlap;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (current_checksum.first == 0) {
|
if (current_checksum.first == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -160,11 +184,21 @@ class RangeDataChecker {
|
||||||
LOG_FIRST_N(ERROR, 3)
|
LOG_FIRST_N(ERROR, 3)
|
||||||
<< "Sensor with frame_id \"" << frame_id
|
<< "Sensor with frame_id \"" << frame_id
|
||||||
<< "\" sends exactly the same range measurements multiple times. "
|
<< "\" sends exactly the same range measurements multiple times. "
|
||||||
<< "Range data at time " << message.header.stamp
|
<< "Range data at time " << current_time_stamp
|
||||||
<< " equals preceding data.";
|
<< " equals preceding data with " << current_checksum.first
|
||||||
|
<< " points.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
frame_id_to_range_checksum_[frame_id] = current_checksum;
|
frame_id_to_range_checksum_[frame_id] = current_checksum;
|
||||||
|
frame_id_to_previous_time_stamp_[frame_id] = message.header.stamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintReport() {
|
||||||
|
for (auto& it : frame_id_to_max_overlap_duration_) {
|
||||||
|
LOG(WARNING) << "Sensor with frame_id \"" << it.first
|
||||||
|
<< "\" range measurements have longest overlap of "
|
||||||
|
<< it.second << " s";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -172,7 +206,9 @@ class RangeDataChecker {
|
||||||
RangeChecksum;
|
RangeChecksum;
|
||||||
|
|
||||||
template <typename MessageType>
|
template <typename MessageType>
|
||||||
RangeChecksum ComputeRangeChecksum(const MessageType& message) {
|
static void ReadRangeMessage(const MessageType& message,
|
||||||
|
RangeChecksum* range_checksum,
|
||||||
|
ros::Duration* range_duration) {
|
||||||
auto point_cloud_with_intensities = ToPointCloudWithIntensities(message);
|
auto point_cloud_with_intensities = ToPointCloudWithIntensities(message);
|
||||||
const cartographer::sensor::TimedPointCloud& point_cloud =
|
const cartographer::sensor::TimedPointCloud& point_cloud =
|
||||||
std::get<0>(point_cloud_with_intensities).points;
|
std::get<0>(point_cloud_with_intensities).points;
|
||||||
|
@ -180,10 +216,29 @@ class RangeDataChecker {
|
||||||
for (const Eigen::Vector4f& point : point_cloud) {
|
for (const Eigen::Vector4f& point : point_cloud) {
|
||||||
points_sum += point;
|
points_sum += point;
|
||||||
}
|
}
|
||||||
return {point_cloud.size(), points_sum};
|
if (point_cloud.size() > 0) {
|
||||||
|
double first_point_relative_time = point_cloud[0][3];
|
||||||
|
double last_point_relative_time = (*point_cloud.rbegin())[3];
|
||||||
|
if (first_point_relative_time > 0) {
|
||||||
|
LOG_FIRST_N(ERROR, 1)
|
||||||
|
<< "Sensor with frame_id \"" << message.header.frame_id
|
||||||
|
<< "\" has range data that has positive relative time "
|
||||||
|
<< first_point_relative_time << " s, must negative or zero.";
|
||||||
|
}
|
||||||
|
if (last_point_relative_time != 0) {
|
||||||
|
LOG_FIRST_N(ERROR, 1)
|
||||||
|
<< "Sensor with frame_id \"" << message.header.frame_id
|
||||||
|
<< "\" has range data whose last point has relative time "
|
||||||
|
<< last_point_relative_time << " s, must be zero.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*range_checksum = {point_cloud.size(), points_sum};
|
||||||
|
*range_duration = ros::Duration(-point_cloud[0][3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, RangeChecksum> frame_id_to_range_checksum_;
|
std::map<std::string, RangeChecksum> frame_id_to_range_checksum_;
|
||||||
|
std::map<std::string, ros::Time> frame_id_to_previous_time_stamp_;
|
||||||
|
std::map<std::string, double> frame_id_to_max_overlap_duration_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Run(const std::string& bag_filename, const bool dump_timing) {
|
void Run(const std::string& bag_filename, const bool dump_timing) {
|
||||||
|
@ -292,6 +347,8 @@ void Run(const std::string& bag_filename, const bool dump_timing) {
|
||||||
}
|
}
|
||||||
bag.close();
|
bag.close();
|
||||||
|
|
||||||
|
range_data_checker.PrintReport();
|
||||||
|
|
||||||
if (num_imu_messages > 0) {
|
if (num_imu_messages > 0) {
|
||||||
double average_imu_acceleration = sum_imu_acceleration / num_imu_messages;
|
double average_imu_acceleration = sum_imu_acceleration / num_imu_messages;
|
||||||
if (std::isnan(average_imu_acceleration) ||
|
if (std::isnan(average_imu_acceleration) ||
|
||||||
|
|
Loading…
Reference in New Issue