Skip to content

Commit 741f823

Browse files
committed
add feedforward control to the simulation
1 parent 2a76e96 commit 741f823

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

agents/matlab/matlab_agent/docs/examples/trajectory-planning-robotic-arm/README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This MATLAB simulation generates smooth trajectories for a Universal Robots UR10
88

99
- **Quintic Polynomial Trajectory Generation**: Ensures smooth motion with continuous position, velocity, and acceleration
1010
- **Proportional Feedback Control**: Tracks the desired trajectory using a simple P-controller
11+
- **Velocity Feedforward**: The controller adds the desired joint velocity to the command to reduce lag and tracking error during motion
1112
- **Real-time Visualization**: Displays robot motion, joint trajectories, and tracking errors
1213
- **Configurable Parameters**: Customize start/goal poses, duration, and time step
1314

@@ -69,18 +70,25 @@ Boundary conditions enforce:
6970

7071
### 2. Control Law
7172

72-
A proportional controller tracks the desired trajectory:
73+
The controller uses **proportional feedback with velocity feedforward**:
7374

7475
```
75-
u = K · (qd - q)
76+
u = dqd + K · (qd - q)
7677
```
7778

7879
Where:
7980

80-
- `K = 100·I₆` is the proportional gain matrix
81-
- `qd` is the desired position from the trajectory
82-
- `q` is the current joint position
83-
- `u` is the control input (commanded velocity)
81+
- `qd` and `dqd` are the desired joint position and velocity from the quintic trajectory;
82+
- `q` is the current joint position;
83+
- `K = 100·I₆` is the proportional gain matrix;
84+
- `u` is the commanded joint velocity.
85+
86+
**Why feedforward?**
87+
The proportional term `K(qd - q)` corrects the error, but introduces delay (lag) when the trajectory is moving. Adding the **feedforward** term `dqd` provides the control chain with the "right" velocity that the trajectory requires at that instant, reducing:
88+
89+
- lag during the tracking phase,
90+
- transient tracking error,
91+
- error peaks during accelerations/slope changes.
8492

8593
### 3. Integration
8694

@@ -90,6 +98,7 @@ Joint positions are updated using Euler integration:
9098
q(t+Δt) = q(t) + u·Δt
9199
```
92100

101+
With `u = dqd + K(qd - q)`, the `dqd` part anticipates the movement required by the trajectory, while `K(qd - q)` cancels the residual error.
93102
The simulation continues until the trajectory time is reached **and** the final error is below threshold (`1e-5` rad).
94103

95104
## Visualization

agents/matlab/matlab_agent/docs/examples/trajectory-planning-robotic-arm/simulation.m

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767

6868
% Evaluate polynomial at each time step
6969
Qd(i, :) = polyval(A, time);
70+
dQd(i, :) = polyval(polyder(A), time);
7071
end
7172

7273
%% ========== VISUALIZE START AND GOAL POSES ==========
@@ -96,8 +97,8 @@
9697
% Compute tracking error
9798
e = Qd(:, counter) - q;
9899

99-
% Proportional control law
100-
u = K * e;
100+
% Feedforward + Proportional Control law
101+
u = dQd(:, counter) + K * e;
101102

102103
% Integrate joint positions (Euler method)
103104
dq = u;
@@ -124,7 +125,9 @@
124125

125126
% Extend desired trajectory to match simulation length
126127
Qd_extended = [Qd, repmat(Qd(:, end), 1, length(time_sim) - size(Qd, 2))];
127-
128+
% Extend desired velocities to match simulation length
129+
dQd_extended = [dQd, repmat(dQd(:, end), 1, length(time_sim) - size(dQd, 2))];
130+
128131
% Compute tracking error for each time step
129132
error_history = zeros(1, length(time_sim));
130133
for k = 1:length(time_sim)
@@ -139,7 +142,8 @@
139142
outputs.tracking_error = error_history; % Tracking error norm over time
140143
outputs.final_error = norm(q - qg); % Final tracking error [rad]
141144
outputs.final_position = q; % Final joint configuration [rad]
142-
145+
outputs.desired_velocities = dQd; % Desired Velocities
146+
143147
%% ========== RESULTS VISUALIZATION ==========
144148

145149
if showGui
@@ -166,6 +170,19 @@
166170
ylabel('Tracking Error (norm) [rad]');
167171
title('Tracking Error vs Time');
168172
grid on;
173+
174+
% Plot joint velocities: commanded vs desired
175+
figure;
176+
plot(time_sim, dQhistory, 'LineWidth', 1.5); % commanded/actual (6 curves)
177+
hold on;
178+
plot(time_sim, dQd_extended, '--', 'LineWidth', 1.2); % desired (dashed)
179+
xlabel('Time [s]');
180+
ylabel('Joint Velocity [rad/s]');
181+
title('Joint Velocities: Commanded vs Desired');
182+
grid on;
183+
legend({'\omega_1','\omega_2','\omega_3','\omega_4','\omega_5','\omega_6', ...
184+
'\omega_{1,d}','\omega_{2,d}','\omega_{3,d}','\omega_{4,d}','\omega_{5,d}','\omega_{6,d}'}, ...
185+
'Location','bestoutside');
169186

170187
% Animate robot motion
171188
figure;

0 commit comments

Comments
 (0)