robot_localization_estimator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, TNO IVS Helmond.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following
13  * disclaimer in the documentation and/or other materials provided
14  * with the distribution.
15  * 3. Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
34 #include "robot_localization/ekf.h"
35 #include "robot_localization/ukf.h"
36 
37 #include <vector>
38 
39 namespace RobotLocalization
40 {
42  FilterType filter_type,
43  const Eigen::MatrixXd& process_noise_covariance,
44  const std::vector<double>& filter_args)
45 {
46  state_buffer_.set_capacity(buffer_capacity);
47 
48  // Set up the filter that is used for predictions
49  if ( filter_type == FilterTypes::EKF )
50  {
51  filter_ = new Ekf;
52  }
53  else if ( filter_type == FilterTypes::UKF )
54  {
55  filter_ = new Ukf(filter_args);
56  }
57 
58  filter_->setProcessNoiseCovariance(process_noise_covariance);
59 }
60 
62 {
63  delete filter_;
64 }
65 
67 {
68  // If newly received state is newer than any in the buffer, push back
69  if ( state_buffer_.empty() || state.time_stamp > state_buffer_.back().time_stamp )
70  {
71  state_buffer_.push_back(state);
72  }
73  // If it is older, put it in the right position
74  else
75  {
76  for ( boost::circular_buffer<EstimatorState>::iterator it = state_buffer_.begin(); it != state_buffer_.end(); ++it )
77  {
78  if ( state.time_stamp < it->time_stamp )
79  {
80  state_buffer_.insert(it, state);
81  return;
82  }
83  }
84  }
85 }
86 
88  EstimatorState& state) const
89 {
90  // If there's nothing in the buffer, there's nothing to give.
91  if ( state_buffer_.size() == 0 )
92  {
94  }
95 
96  // Set state to the most recent one for now
97  state = state_buffer_.back();
98 
99  // Go through buffer from new to old
100  EstimatorState last_state_before_time = state_buffer_.front();
101  EstimatorState next_state_after_time = state_buffer_.back();
102  bool previous_state_found = false;
103  bool next_state_found = false;
104 
105  for (boost::circular_buffer<EstimatorState>::const_reverse_iterator it = state_buffer_.rbegin();
106  it != state_buffer_.rend(); ++it)
107  {
108  /* If the time stamp of the current state from the buffer is
109  * older than the requested time, store it as the last state
110  * before the requested time. If it is younger, save it as the
111  * next one after, and go on to find the last one before.
112  */
113  if ( it->time_stamp == time )
114  {
115  state = *it;
117  }
118  else if ( it->time_stamp <= time )
119  {
120  last_state_before_time = *it;
121  previous_state_found = true;
122  break;
123  }
124  else
125  {
126  next_state_after_time = *it;
127  next_state_found = true;
128  }
129  }
130 
131  // If we found a previous state and a next state, we can do interpolation
132  if ( previous_state_found && next_state_found )
133  {
134  interpolate(last_state_before_time, next_state_after_time, time, state);
136  }
137 
138  // If only a previous state is found, we can do extrapolation into the future
139  else if ( previous_state_found )
140  {
141  extrapolate(last_state_before_time, time, state);
143  }
144 
145  // If only a next state is found, we'll have to extrapolate into the past.
146  else if ( next_state_found )
147  {
148  extrapolate(next_state_after_time, time, state);
150  }
151 
152  else
153  {
155  }
156 }
157 
159 {
160  state_buffer_.set_capacity(capacity);
161 }
162 
164 {
165  state_buffer_.clear();
166 }
167 
169 {
170  return state_buffer_.capacity();
171 }
172 
174 {
175  return state_buffer_.size();
176 }
177 
179  const double requested_time,
180  EstimatorState& state_at_req_time) const
181 {
182  // Set up the filter with the boundary state
183  filter_->setState(boundary_state.state);
185 
186  // Calculate how much time we need to extrapolate into the future
187  double delta = requested_time - boundary_state.time_stamp;
188 
189  // Use the filter to predict
190  filter_->predict(boundary_state.time_stamp, delta);
191 
192  state_at_req_time.time_stamp = requested_time;
193  state_at_req_time.state = filter_->getState();
194  state_at_req_time.covariance = filter_->getEstimateErrorCovariance();
195 
196  return;
197 }
198 
200  const EstimatorState& given_state_2,
201  const double requested_time,
202  EstimatorState& state_at_req_time) const
203 {
204  /*
205  * TODO: Right now, we only extrapolate from the last known state before the requested time. But as the state after
206  * the requested time is also known, we may want to perform interpolation between states.
207  */
208  extrapolate(given_state_1, requested_time, state_at_req_time);
209  return;
210 }
211 
212 } // namespace RobotLocalization
void setProcessNoiseCovariance(const Eigen::MatrixXd &processNoiseCovariance)
Sets the process noise covariance for the filter.
Extended Kalman filter class.
Definition: ekf.h:53
Unscented Kalman filter class.
Definition: ukf.h:60
const Eigen::VectorXd & getState()
Gets the filter state.
void clearBuffer()
Clears the internal state buffer.
void setEstimateErrorCovariance(const Eigen::MatrixXd &estimateErrorCovariance)
Manually sets the filter&#39;s estimate error covariance.
void setBufferCapacity(const int capacity)
Sets the buffer capacity.
virtual ~RobotLocalizationEstimator()
Destructor for the RobotLocalizationListener class.
void interpolate(const EstimatorState &given_state_1, const EstimatorState &given_state_2, const double requested_time, EstimatorState &state_at_req_time) const
Interpolates the given state to a requested time stamp.
double time_stamp
Time at which this state is/was achieved.
void setState(const EstimatorState &state)
Sets the current internal state of the listener.
boost::circular_buffer< EstimatorState > state_buffer_
The buffer holding the system states that have come in. Interpolation and extrapolation is done start...
EstimatorResult getState(const double time, EstimatorState &state) const
Returns the state at a given time.
Eigen::VectorXd state
System state at time = time_stamp.
virtual void predict(const double referenceTime, const double delta)=0
Carries out the predict step in the predict/update cycle. Projects the state and error matrices forwa...
Eigen::MatrixXd covariance
System state covariance at time = time_stamp.
FilterBase * filter_
A pointer to the filter instance that is used for extrapolation.
void extrapolate(const EstimatorState &boundary_state, const double requested_time, EstimatorState &state_at_req_time) const
Extrapolates the given state to a requested time stamp.
unsigned int getSize() const
Returns the current buffer size.
Robot Localization Estimator State.
const Eigen::MatrixXd & getEstimateErrorCovariance()
Gets the estimate error covariance.
void setState(const Eigen::VectorXd &state)
Manually sets the filter&#39;s state.
RobotLocalizationEstimator(unsigned int buffer_capacity, FilterType filter_type, const Eigen::MatrixXd &process_noise_covariance, const std::vector< double > &filter_args=std::vector< double >())
Constructor for the RobotLocalizationListener class.
unsigned int getBufferCapacity() const
Returns the buffer capacity.


robot_localization
Author(s): Tom Moore
autogenerated on Wed Feb 3 2021 03:34:02