Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de73eb10 authored by Okan Arikan's avatar Okan Arikan Committed by Android (Google) Code Review
Browse files

Merge "Fix the latency model." into oc-dev

parents 5bbb45e0 5e4b792b
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -6,23 +6,21 @@
namespace android {
namespace dvr {

// This class holds a rolling average of the sensor latency.
// This class models the latency from sensors. It will look at the first
// window_size measurements and return their average after that.
class LatencyModel {
 public:
  LatencyModel(size_t window_size, double weight_mass_in_window);
  LatencyModel(size_t window_size);
  ~LatencyModel() = default;

  void AddLatency(int64_t latency_ns);
  int64_t CurrentLatencyEstimate() const {
    return static_cast<int64_t>(rolling_average_);
  }
  int64_t CurrentLatencyEstimate() const { return latency_; }

 private:
  // The rolling average of the latencies.
  double rolling_average_ = 0;

  // The alpha parameter for an exponential moving average.
  double alpha_;
  size_t window_size_;
  int64_t latency_sum_ = 0;
  size_t num_summed_ = 0;
  int64_t latency_ = 0;
};

}  // namespace dvr
+11 −20
Original line number Diff line number Diff line
@@ -5,28 +5,19 @@
namespace android {
namespace dvr {

LatencyModel::LatencyModel(size_t window_size, double weight_mass_in_window) {
  // Compute an alpha so the weight of the last window_size measurements is
  // weight_mass_in_window of the total weights.
LatencyModel::LatencyModel(size_t window_size) : window_size_(window_size) {}

  // The weight in a series of k measurements:
  // alpha + (1 + (1 - alpha) + (1 - alpha)^2 + ... (1 - alpha)^k-1)
  // = alpha x (1 - (1 - alpha) ^ k) / alpha
  // = 1 - (1 - alpha) ^ k
  // weight_mass_in_window = 1 - (1 - alpha) ^ k / lim_k->inf (1 - alpha) ^ k
  // weight_mass_in_window = 1 - (1 - alpha) ^ k / 1
  // 1 - weight_mass_in_window = (1 - alpha) ^ k
  // log(1 - weight_mass_in_window) = k * log(1 - alpha)
  // 10 ^ (log(1 - weight_mass_in_window) / k) = 1 - alpha
  // alpha = 1 - 10 ^ (log(1 - weight_mass_in_window) / k)
  // alpha = 1 - 10 ^ (log(1 - weight_mass_in_window) / window_size)
void LatencyModel::AddLatency(int64_t latency_ns) {
  // Not enough samples yet?
  if (num_summed_ < window_size_) {
    // Accumulate.
    latency_sum_ += latency_ns;

  alpha_ = 1 - std::pow(10.0, std::log10(1 - weight_mass_in_window) /
                                  static_cast<double>(window_size));
    // Have enough samples for latency estimate?
    if (++num_summed_ == window_size_) {
      latency_ = latency_sum_ / window_size_;
    }
  }

void LatencyModel::AddLatency(int64_t latency_ns) {
  rolling_average_ = latency_ns * alpha_ + rolling_average_ * (1 - alpha_);
}

}  // namespace dvr
+2 −3
Original line number Diff line number Diff line
@@ -65,8 +65,7 @@ static constexpr char kPoseRingBufferName[] = "PoseService:RingBuffer";
static constexpr int kDatasetIdLength = 36;
static constexpr char kDatasetIdChars[] = "0123456789abcdef-";

static constexpr int kLatencyWindowSize = 100;
static constexpr double kLatencyWindowMass = 0.5;
static constexpr int kLatencyWindowSize = 200;

// These are the flags used by BufferProducer::CreatePersistentUncachedBlob,
// plus PRIVATE_ADSP_HEAP to allow access from the DSP.
@@ -115,7 +114,7 @@ PoseService::PoseService(SensorThread* sensor_thread)
      photon_timestamp_(0),
      // Will be updated by external service, but start with a non-zero value:
      display_period_ns_(16000000),
      sensor_latency_(kLatencyWindowSize, kLatencyWindowMass) {
      sensor_latency_(kLatencyWindowSize) {
  last_known_pose_ = {
      .orientation = {1.0f, 0.0f, 0.0f, 0.0f},
      .translation = {0.0f, 0.0f, 0.0f, 0.0f},