Implement fixed size transform interpolation buffer. (#1581)

master
Michael Grupp 2020-06-23 10:34:01 +02:00 committed by GitHub
parent 21a8299caa
commit a5aa03b776
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 3 deletions

View File

@ -40,8 +40,17 @@ void TransformInterpolationBuffer::Push(const common::Time time,
CHECK_GE(time, latest_time()) << "New transform is older than latest."; CHECK_GE(time, latest_time()) << "New transform is older than latest.";
} }
timestamped_transforms_.push_back(TimestampedTransform{time, transform}); timestamped_transforms_.push_back(TimestampedTransform{time, transform});
RemoveOldTransformsIfNeeded();
} }
void TransformInterpolationBuffer::SetSizeLimit(
const size_t buffer_size_limit) {
buffer_size_limit_ = buffer_size_limit;
RemoveOldTransformsIfNeeded();
}
void TransformInterpolationBuffer::Clear() { timestamped_transforms_.clear(); }
bool TransformInterpolationBuffer::Has(const common::Time time) const { bool TransformInterpolationBuffer::Has(const common::Time time) const {
if (timestamped_transforms_.empty()) { if (timestamped_transforms_.empty()) {
return false; return false;
@ -65,6 +74,12 @@ transform::Rigid3d TransformInterpolationBuffer::Lookup(
return Interpolate(*start, *end, time).transform; return Interpolate(*start, *end, time).transform;
} }
void TransformInterpolationBuffer::RemoveOldTransformsIfNeeded() {
while (timestamped_transforms_.size() > buffer_size_limit_) {
timestamped_transforms_.pop_front();
}
}
common::Time TransformInterpolationBuffer::earliest_time() const { common::Time TransformInterpolationBuffer::earliest_time() const {
CHECK(!empty()) << "Empty buffer."; CHECK(!empty()) << "Empty buffer.";
return timestamped_transforms_.front().time; return timestamped_transforms_.front().time;
@ -79,5 +94,13 @@ bool TransformInterpolationBuffer::empty() const {
return timestamped_transforms_.empty(); return timestamped_transforms_.empty();
} }
size_t TransformInterpolationBuffer::size_limit() const {
return buffer_size_limit_;
}
size_t TransformInterpolationBuffer::size() const {
return timestamped_transforms_.size();
}
} // namespace transform } // namespace transform
} // namespace cartographer } // namespace cartographer

View File

@ -17,7 +17,8 @@
#ifndef CARTOGRAPHER_TRANSFORM_TRANSFORM_INTERPOLATION_BUFFER_H_ #ifndef CARTOGRAPHER_TRANSFORM_TRANSFORM_INTERPOLATION_BUFFER_H_
#define CARTOGRAPHER_TRANSFORM_TRANSFORM_INTERPOLATION_BUFFER_H_ #define CARTOGRAPHER_TRANSFORM_TRANSFORM_INTERPOLATION_BUFFER_H_
#include <vector> #include <deque>
#include <limits>
#include "cartographer/common/time.h" #include "cartographer/common/time.h"
#include "cartographer/mapping/proto/trajectory.pb.h" #include "cartographer/mapping/proto/trajectory.pb.h"
@ -27,18 +28,28 @@
namespace cartographer { namespace cartographer {
namespace transform { namespace transform {
constexpr size_t kUnlimitedBufferSize = std::numeric_limits<size_t>::max();
// A time-ordered buffer of transforms that supports interpolated lookups. // A time-ordered buffer of transforms that supports interpolated lookups.
// Unless explicitly set, the buffer size is unlimited.
class TransformInterpolationBuffer { class TransformInterpolationBuffer {
public: public:
TransformInterpolationBuffer() = default; TransformInterpolationBuffer() = default;
explicit TransformInterpolationBuffer( explicit TransformInterpolationBuffer(
const mapping::proto::Trajectory& trajectory); const mapping::proto::Trajectory& trajectory);
// Sets the transform buffer size limit and removes old transforms
// if it is exceeded.
void SetSizeLimit(size_t buffer_size_limit);
// Adds a new transform to the buffer and removes the oldest transform if the // Adds a new transform to the buffer and removes the oldest transform if the
// buffer size limit is exceeded. // buffer size limit is exceeded.
void Push(common::Time time, const transform::Rigid3d& transform); void Push(common::Time time, const transform::Rigid3d& transform);
// Returns true if an interpolated transfrom can be computed at 'time'. // Clears the transform buffer.
void Clear();
// Returns true if an interpolated transform can be computed at 'time'.
bool Has(common::Time time) const; bool Has(common::Time time) const;
// Returns an interpolated transform at 'time'. CHECK()s that a transform at // Returns an interpolated transform at 'time'. CHECK()s that a transform at
@ -56,8 +67,17 @@ class TransformInterpolationBuffer {
// Returns true if the buffer is empty. // Returns true if the buffer is empty.
bool empty() const; bool empty() const;
// Returns the maximum allowed size of the transform buffer.
size_t size_limit() const;
// Returns the current size of the transform buffer.
size_t size() const;
private: private:
std::vector<TimestampedTransform> timestamped_transforms_; void RemoveOldTransformsIfNeeded();
std::deque<TimestampedTransform> timestamped_transforms_;
size_t buffer_size_limit_ = kUnlimitedBufferSize;
}; };
} // namespace transform } // namespace transform

View File

@ -70,6 +70,22 @@ TEST(TransformInterpolationBufferTest, testLookupSingleTransform) {
EXPECT_THAT(interpolated, IsNearly(transform::Rigid3d::Identity(), 1e-6)); EXPECT_THAT(interpolated, IsNearly(transform::Rigid3d::Identity(), 1e-6));
} }
TEST(TransformInterpolationBufferTest, testSetSizeLimit) {
TransformInterpolationBuffer buffer;
EXPECT_EQ(buffer.size_limit(), kUnlimitedBufferSize);
buffer.Push(common::FromUniversal(0), transform::Rigid3d::Identity());
buffer.Push(common::FromUniversal(1), transform::Rigid3d::Identity());
buffer.Push(common::FromUniversal(2), transform::Rigid3d::Identity());
EXPECT_EQ(buffer.size(), 3);
buffer.SetSizeLimit(2);
EXPECT_EQ(buffer.size_limit(), 2);
EXPECT_EQ(buffer.size(), 2);
EXPECT_FALSE(buffer.Has(common::FromUniversal(0)));
buffer.Push(common::FromUniversal(3), transform::Rigid3d::Identity());
EXPECT_EQ(buffer.size(), 2);
EXPECT_FALSE(buffer.Has(common::FromUniversal(1)));
}
} // namespace } // namespace
} // namespace transform } // namespace transform
} // namespace cartographer } // namespace cartographer