Apollo 10.0
自动驾驶开放平台
mean_filter.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <limits>
20
21#include "cyber/common/log.h"
22
23namespace apollo {
24namespace common {
25
26using MF = MeanFilter;
27using uint8 = std::uint_fast8_t;
28using TimedValue = std::pair<uint8, double>;
29
30const uint8 kMaxWindowSize = std::numeric_limits<uint8>::max() / 2;
31
32MF::MeanFilter(const uint8 window_size) : window_size_(window_size) {
33 CHECK_GT(window_size_, 0);
34 CHECK_LE(window_size_, kMaxWindowSize);
35 initialized_ = true;
36}
37
38double MF::GetMin() const {
39 if (min_candidates_.empty()) {
40 return std::numeric_limits<double>::infinity();
41 } else {
42 return min_candidates_.front().second;
43 }
44}
45
46double MF::GetMax() const {
47 if (max_candidates_.empty()) {
48 return -std::numeric_limits<double>::infinity();
49 } else {
50 return max_candidates_.front().second;
51 }
52}
53
54double MF::Update(const double measurement) {
55 ACHECK(initialized_);
56 CHECK_LE(values_.size(), window_size_);
57 CHECK_LE(min_candidates_.size(), window_size_);
58 CHECK_LE(max_candidates_.size(), window_size_);
59 ++time_;
60 time_ %= static_cast<std::uint_fast8_t>(2 * window_size_);
61 if (values_.size() == window_size_) {
62 RemoveEarliest();
63 }
64 Insert(measurement);
65 if (values_.size() > 2) {
66 return (sum_ - GetMin() - GetMax()) /
67 static_cast<double>(values_.size() - 2);
68 } else {
69 return sum_ / static_cast<double>(values_.size());
70 }
71}
72
73bool MF::ShouldPopOldestCandidate(const uint8 old_time) const {
74 if (old_time < window_size_) {
75 CHECK_LE(time_, old_time + window_size_);
76 return old_time + window_size_ == time_;
77 } else if (time_ < window_size_) {
78 CHECK_GE(old_time, time_ + window_size_);
79 return old_time == time_ + window_size_;
80 } else {
81 return false;
82 }
83}
84
85void MF::RemoveEarliest() {
86 CHECK_EQ(values_.size(), window_size_);
87 double removed = values_.front();
88 values_.pop_front();
89 sum_ -= removed;
90 if (ShouldPopOldestCandidate(min_candidates_.front().first)) {
91 min_candidates_.pop_front();
92 }
93 if (ShouldPopOldestCandidate(max_candidates_.front().first)) {
94 max_candidates_.pop_front();
95 }
96}
97
98void MF::Insert(const double value) {
99 values_.push_back(value);
100 sum_ += value;
101 while (min_candidates_.size() > 0 && min_candidates_.back().second > value) {
102 min_candidates_.pop_back();
103 }
104 min_candidates_.push_back(std::make_pair(time_, value));
105 while (max_candidates_.size() > 0 && max_candidates_.back().second < value) {
106 max_candidates_.pop_back();
107 }
108 max_candidates_.push_back(std::make_pair(time_, value));
109}
110
111} // namespace common
112} // namespace apollo
The MeanFilter class is used to smoothen a series of noisy numbers, such as sensor data or the output...
Definition mean_filter.h:45
double Update(const double measurement)
Processes a new measurement in amortized constant time.
MeanFilter()=default
Default constructor; defers initialization.
#define ACHECK(cond)
Definition log.h:80
Defines the MeanFilter class.
std::pair< uint8, double > TimedValue
std::uint_fast8_t uint8
const uint8 kMaxWindowSize
class register implement
Definition arena_queue.h:37