Skip to content

Commit 13fba55

Browse files
fix(controllers): allow stateful feedforward in Feedforward2Dof (#277) (#281)
Remove const from Feedforward::Evaluate(), add pure-virtual Reset() to the interface (consistent with FeedbackLaw::Reset()), and delegate feedforward.Reset() from Feedforward2Dof::Reset() so dynamic pre-filters that carry internal state are correctly cleared on reset. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 7809292 commit 13fba55

3 files changed

Lines changed: 8 additions & 3 deletions

File tree

‎doc/controllers/Feedforward2Dof.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ If the system were already tracking perfectly ($y = r = 0.5$), then $e = 0$, $u_
5555
- **Feedforward does not aid disturbance rejection.** If $u_{ff}$ is tuned for tracking and a disturbance enters the plant, only $u_{fb}$ responds.
5656
- **Inverse-plant feedforward for non-minimum-phase systems** is non-causal; use a truncated or approximate inverse.
5757
- **Sign convention.** The error passed to feedback is $r - y$, not $y - r$. Swapping signs destabilises positive-gain plants.
58+
- **Stateful feedforward must implement `Reset()`.** Dynamic pre-filters (e.g. reference model filters) carry internal state that must be cleared on `Reset()`. Both the feedforward and feedback components are reset when `Feedforward2Dof::Reset()` is called; any feedforward implementation that holds state must override `Reset()` to clear it.
5859

5960
## Variants & Generalizations
6061

‎numerical/controllers/implementations/Feedforward2Dof.hpp‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ namespace controllers
1717
static_assert(std::is_floating_point_v<T>, "Feedforward supports floating-point types");
1818

1919
virtual ~Feedforward() = default;
20-
virtual T Evaluate(T reference) const = 0;
20+
virtual T Evaluate(T reference) = 0;
21+
virtual void Reset() = 0;
2122
};
2223

2324
template<typename T>
@@ -68,6 +69,7 @@ namespace controllers
6869
template<typename T>
6970
void Feedforward2Dof<T>::Reset()
7071
{
72+
feedforward.Reset();
7173
feedback.Reset();
7274
}
7375

‎numerical/controllers/implementations/test/TestFeedforward2Dof.cpp‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ namespace
99
: public controllers::Feedforward<float>
1010
{
1111
public:
12-
MOCK_METHOD(float, Evaluate, (float), (const, override));
12+
MOCK_METHOD(float, Evaluate, (float), (override));
13+
MOCK_METHOD(void, Reset, (), (override));
1314
};
1415

1516
class MockFeedbackLaw
@@ -109,8 +110,9 @@ TEST_F(TestFeedforward2Dof, zero_feedback_reduces_to_feedforward)
109110
EXPECT_NEAR(result, 0.4f, math::Tolerance<float>());
110111
}
111112

112-
TEST_F(TestFeedforward2Dof, reset_delegates_to_feedback)
113+
TEST_F(TestFeedforward2Dof, reset_delegates_to_feedforward_and_feedback)
113114
{
115+
EXPECT_CALL(ff, Reset()).Times(1);
114116
EXPECT_CALL(fb, Reset()).Times(1);
115117

116118
controller.Reset();

0 commit comments

Comments
 (0)