Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/controllers/Feedforward2Dof.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ If the system were already tracking perfectly ($y = r = 0.5$), then $e = 0$, $u_
- **Feedforward does not aid disturbance rejection.** If $u_{ff}$ is tuned for tracking and a disturbance enters the plant, only $u_{fb}$ responds.
- **Inverse-plant feedforward for non-minimum-phase systems** is non-causal; use a truncated or approximate inverse.
- **Sign convention.** The error passed to feedback is $r - y$, not $y - r$. Swapping signs destabilises positive-gain plants.
- **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.

## Variants & Generalizations

Expand Down
4 changes: 3 additions & 1 deletion numerical/controllers/implementations/Feedforward2Dof.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ namespace controllers
static_assert(std::is_floating_point_v<T>, "Feedforward supports floating-point types");

virtual ~Feedforward() = default;
virtual T Evaluate(T reference) const = 0;
virtual T Evaluate(T reference) = 0;
virtual void Reset() = 0;
};

template<typename T>
Expand Down Expand Up @@ -68,6 +69,7 @@ namespace controllers
template<typename T>
void Feedforward2Dof<T>::Reset()
{
feedforward.Reset();
feedback.Reset();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ namespace
: public controllers::Feedforward<float>
{
public:
MOCK_METHOD(float, Evaluate, (float), (const, override));
MOCK_METHOD(float, Evaluate, (float), (override));
MOCK_METHOD(void, Reset, (), (override));
};

class MockFeedbackLaw
Expand Down Expand Up @@ -109,8 +110,9 @@ TEST_F(TestFeedforward2Dof, zero_feedback_reduces_to_feedforward)
EXPECT_NEAR(result, 0.4f, math::Tolerance<float>());
}

TEST_F(TestFeedforward2Dof, reset_delegates_to_feedback)
TEST_F(TestFeedforward2Dof, reset_delegates_to_feedforward_and_feedback)
{
EXPECT_CALL(ff, Reset()).Times(1);
EXPECT_CALL(fb, Reset()).Times(1);

controller.Reset();
Expand Down
Loading