Skip to content

Commit eccdecb

Browse files
committed
Merge remote-tracking branch 'upstream/master' into ros2-master
2 parents f0087b2 + 7e8f0a1 commit eccdecb

File tree

12 files changed

+393
-77
lines changed

12 files changed

+393
-77
lines changed

.pre-commit-config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ repos:
3636

3737
# Python hooks
3838
- repo: https://github.com/asottile/pyupgrade
39-
rev: v3.20.0
39+
rev: v3.21.2
4040
hooks:
4141
- id: pyupgrade
4242
args: [--py36-plus]
@@ -49,7 +49,7 @@ repos:
4949
args: ["--ignore=D100,D101,D102,D103,D104,D105,D106,D107,D203,D212,D404"]
5050

5151
- repo: https://github.com/psf/black
52-
rev: 25.9.0
52+
rev: 25.12.0
5353
hooks:
5454
- id: black
5555
args: ["--line-length=99"]
@@ -62,7 +62,7 @@ repos:
6262

6363
# CPP hooks
6464
- repo: https://github.com/pre-commit/mirrors-clang-format
65-
rev: v21.1.2
65+
rev: v21.1.8
6666
hooks:
6767
- id: clang-format
6868
args: ['-fallback-style=none', '-i']
@@ -136,7 +136,7 @@ repos:
136136
exclude: CHANGELOG\.rst|\.(svg|pyc)$
137137

138138
- repo: https://github.com/python-jsonschema/check-jsonschema
139-
rev: 0.34.0
139+
rev: 0.36.0
140140
hooks:
141141
- id: check-github-workflows
142142
args: ["--verbose"]

control_toolbox/CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
Changelog for package control_toolbox
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
6.1.0 (2025-12-01)
6+
------------------
7+
* Exponantial filter refactoring (`#493 <https://github.com/ros-controls/control_toolbox/issues/493>`_)
8+
* Replace deprecated rclcpp::spin_some() (`#541 <https://github.com/ros-controls/control_toolbox/issues/541>`_)
9+
* No need for the specialization of update() (`#509 <https://github.com/ros-controls/control_toolbox/issues/509>`_)
10+
* Contributors: Abdullah, Christoph Fröhlich, silanus
11+
512
6.0.0 (2025-10-16)
613
------------------
714

control_toolbox/include/control_filters/exponential_filter.hpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818
#include <limits>
1919
#include <memory>
2020
#include <string>
21+
#include <vector>
2122

2223
#include "filters/filter_base.hpp"
2324

25+
#include "control_toolbox/exponential_filter.hpp"
2426
#include "control_toolbox/exponential_filter_parameters.hpp"
25-
#include "control_toolbox/filters.hpp"
2627

2728
namespace control_filters
2829
{
@@ -67,7 +68,7 @@ class ExponentialFilter : public filters::FilterBase<T>
6768
std::shared_ptr<rclcpp::Logger> logger_;
6869
std::shared_ptr<exponential_filter::ParamListener> parameter_handler_;
6970
exponential_filter::Params parameters_;
70-
T last_smoothed_value;
71+
std::shared_ptr<control_toolbox::ExponentialFilter<T>> expo_;
7172
};
7273

7374
template <typename T>
@@ -100,16 +101,20 @@ bool ExponentialFilter<T>::configure()
100101
}
101102
}
102103
parameters_ = parameter_handler_->get_params();
104+
expo_ = std::make_shared<control_toolbox::ExponentialFilter<T>>(parameters_.alpha);
103105

104-
last_smoothed_value = std::numeric_limits<double>::quiet_NaN();
105-
106-
return true;
106+
bool configured = expo_->configure();
107+
if (!configured)
108+
{
109+
RCLCPP_ERROR((*logger_), "ExponentialFilter: Failed to configure underlying filter instance.");
110+
}
111+
return configured;
107112
}
108113

109114
template <typename T>
110115
bool ExponentialFilter<T>::update(const T & data_in, T & data_out)
111116
{
112-
if (!this->configured_)
117+
if (!this->configured_ || !expo_ || !expo_->is_configured())
113118
{
114119
throw std::runtime_error("Filter is not configured");
115120
}
@@ -118,18 +123,12 @@ bool ExponentialFilter<T>::update(const T & data_in, T & data_out)
118123
if (parameter_handler_->is_old(parameters_))
119124
{
120125
parameters_ = parameter_handler_->get_params();
126+
expo_->set_params(parameters_.alpha);
121127
}
122128

123-
if (std::isnan(last_smoothed_value))
124-
{
125-
last_smoothed_value = data_in;
126-
}
127-
128-
data_out = last_smoothed_value =
129-
filters::exponentialSmoothing(data_in, last_smoothed_value, parameters_.alpha);
130-
return true;
129+
// Delegate filtering to toolbox filter instance
130+
return expo_->update(data_in, data_out);
131131
}
132-
133132
} // namespace control_filters
134133

135134
#endif // CONTROL_FILTERS__EXPONENTIAL_FILTER_HPP_

control_toolbox/include/control_filters/low_pass_filter.hpp

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -134,46 +134,6 @@ bool LowPassFilter<T>::configure()
134134
return lpf_->configure();
135135
}
136136

137-
template <>
138-
inline bool LowPassFilter<geometry_msgs::msg::WrenchStamped>::update(
139-
const geometry_msgs::msg::WrenchStamped & data_in, geometry_msgs::msg::WrenchStamped & data_out)
140-
{
141-
if (!this->configured_ || !lpf_ || !lpf_->is_configured())
142-
{
143-
throw std::runtime_error("Filter is not configured");
144-
}
145-
146-
// Update internal parameters if required
147-
if (parameter_handler_->is_old(parameters_))
148-
{
149-
parameters_ = parameter_handler_->get_params();
150-
lpf_->set_params(
151-
parameters_.sampling_frequency, parameters_.damping_frequency, parameters_.damping_intensity);
152-
}
153-
154-
return lpf_->update(data_in, data_out);
155-
}
156-
157-
template <>
158-
inline bool LowPassFilter<std::vector<double>>::update(
159-
const std::vector<double> & data_in, std::vector<double> & data_out)
160-
{
161-
if (!this->configured_ || !lpf_ || !lpf_->is_configured())
162-
{
163-
throw std::runtime_error("Filter is not configured");
164-
}
165-
166-
// Update internal parameters if required
167-
if (parameter_handler_->is_old(parameters_))
168-
{
169-
parameters_ = parameter_handler_->get_params();
170-
lpf_->set_params(
171-
parameters_.sampling_frequency, parameters_.damping_frequency, parameters_.damping_intensity);
172-
}
173-
174-
return lpf_->update(data_in, data_out);
175-
}
176-
177137
template <typename T>
178138
bool LowPassFilter<T>::update(const T & data_in, T & data_out)
179139
{
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright (c) 2023, Stogl Robotics Consulting UG (haftungsbeschränkt)
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef CONTROL_TOOLBOX__EXPONENTIAL_FILTER_HPP_
16+
#define CONTROL_TOOLBOX__EXPONENTIAL_FILTER_HPP_
17+
18+
#include <cmath>
19+
#include <limits>
20+
#include <memory>
21+
#include <stdexcept>
22+
#include <string>
23+
#include <type_traits>
24+
#include <vector>
25+
26+
#include "control_toolbox/filter_traits.hpp"
27+
#include "control_toolbox/filters.hpp"
28+
29+
namespace control_toolbox
30+
{
31+
template <typename T>
32+
class ExponentialFilter
33+
{
34+
public:
35+
// Default constructor
36+
ExponentialFilter();
37+
explicit ExponentialFilter(double alpha) { set_params(alpha); }
38+
39+
~ExponentialFilter();
40+
41+
bool configure();
42+
43+
bool update(const T & data_in, T & data_out);
44+
45+
bool is_configured() const { return configured_; }
46+
47+
void set_params(double alpha) { alpha_ = alpha; }
48+
49+
private:
50+
double alpha_;
51+
52+
// Define the storage type based on T
53+
using Traits = FilterTraits<T>;
54+
using StorageType = typename Traits::StorageType;
55+
56+
StorageType old_value_;
57+
58+
bool configured_ = false;
59+
};
60+
61+
template <typename T>
62+
ExponentialFilter<T>::ExponentialFilter() : alpha_(0.5)
63+
{
64+
}
65+
66+
template <typename T>
67+
ExponentialFilter<T>::~ExponentialFilter()
68+
{
69+
}
70+
71+
template <typename T>
72+
bool ExponentialFilter<T>::configure()
73+
{
74+
Traits::initialize(old_value_);
75+
76+
return configured_ = true;
77+
}
78+
79+
template <typename T>
80+
bool ExponentialFilter<T>::update(const T & data_in, T & data_out)
81+
{
82+
if (!configured_)
83+
{
84+
throw std::runtime_error("Filter is not configured");
85+
}
86+
87+
// First call: initialize filter state
88+
if (Traits::is_nan(old_value_) || Traits::is_empty(old_value_))
89+
{
90+
if (!Traits::is_finite(data_in))
91+
{
92+
return false;
93+
}
94+
Traits::assign(old_value_, data_in);
95+
}
96+
else
97+
{
98+
Traits::validate_input(data_in, old_value_, data_out);
99+
}
100+
101+
// Convert data_in to StorageType for arithmetic
102+
StorageType storage_in;
103+
Traits::assign(storage_in, data_in);
104+
105+
// Exponential filter update using the templated exponentialSmoothing function
106+
old_value_ = filters::exponentialSmoothing(storage_in, old_value_, alpha_);
107+
108+
Traits::assign(data_out, old_value_);
109+
Traits::add_metadata(data_out, data_in);
110+
111+
return true;
112+
}
113+
114+
} // namespace control_toolbox
115+
116+
#endif // CONTROL_TOOLBOX__EXPONENTIAL_FILTER_HPP_

control_toolbox/include/control_toolbox/filters.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ namespace filters
4040
/** Exponential smoothing filter. Alpha is between 0 and 1.
4141
* Values closer to 0 weight the last smoothed value more heavily */
4242

43-
static inline double exponentialSmoothing(
44-
double current_raw_value, double last_smoothed_value, double alpha)
43+
template <typename T>
44+
static inline T exponentialSmoothing(
45+
const T & current_raw_value, const T & last_smoothed_value, double alpha)
4546
{
4647
return alpha * current_raw_value + (1 - alpha) * last_smoothed_value;
4748
}
4849
} // namespace filters
4950

50-
#endif // CONTROL_TOOLBOX__FILTERS_HPP_"
51+
#endif // CONTROL_TOOLBOX__FILTERS_HPP_

control_toolbox/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<package format="3">
33
<name>control_toolbox</name>
4-
<version>6.0.0</version>
4+
<version>6.1.0</version>
55
<description>The control toolbox contains modules that are useful across all controllers.</description>
66

77
<maintainer email="bence.magyar.robotics@gmail.com">Bence Magyar</maintainer>

control_toolbox/src/control_filters/exponential_filter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,10 @@
1717
#include "pluginlib/class_list_macros.hpp"
1818

1919
PLUGINLIB_EXPORT_CLASS(control_filters::ExponentialFilter<double>, filters::FilterBase<double>)
20+
21+
PLUGINLIB_EXPORT_CLASS(
22+
control_filters::ExponentialFilter<std::vector<double>>, filters::FilterBase<std::vector<double>>)
23+
24+
PLUGINLIB_EXPORT_CLASS(
25+
control_filters::ExponentialFilter<geometry_msgs::msg::WrenchStamped>,
26+
filters::FilterBase<geometry_msgs::msg::WrenchStamped>)

0 commit comments

Comments
 (0)