The model presented here is based on the model described here:
https://plot.ly/ipython-notebooks/bicycle-control-design/
eval_bicycle_rhs
The file eval_bicycle_rhs.m encodes the 1st order ordinary differential equations that govern the steer-roll dynamics of a bicycle. The steer and steer rate inputs are set to constants.
function xdot = eval_bicycle_rhs(t, x, r, p)
% unpack states
omega = x(1);
theta = x(2);
psi = x(3);
% unpack inputs
beta = r(1); % steer rate
delta = r(2); % steer angle
% unpack parameters
m = p(1);
g = p(2);
h = p(3);
a = p(4);
b = p(5);
v = p(6);
I = p(7);
% calculate the state derivatives
omegadot = (m*g*h*theta - m*h/b*(a*v*beta + v^2*delta))/(I + m*h^2);
thetadot = omega;
psidot = v/b*tan(delta);
% pack up the results
xdot = [omegadot; thetadot; psidot];
end
eval_bicycle_rhs2
The file eval_bicycle_rhs2.m encodes the 1st order ordinary differential equations that govern the steer-roll dynamics of a bicycle. The steer and steer rate inputs are calculated by an input function.
function xdot = eval_bicycle_rhs2(t, x, w, p)
% unpack states
omega = x(1);
theta = x(2);
psi = x(3);
% calculate r with the passed in function w(t, x, p)
r = w(t, x, p);
% unpack inputs
beta = r(1); % steer rate
delta = r(2); % steer angle
% unpack parameters
m = p(1);
g = p(2);
h = p(3);
a = p(4);
b = p(5);
v = p(6);
I = p(7);
% calculate the state derivatives
omegadot = (m*g*h*theta - m*h/b*(a*v*beta + v^2*delta))/(I + m*h^2);
thetadot = omega;
psidot = v/b*tan(delta);
% pack up the results
xdot = [omegadot; thetadot; psidot];
end
eval_steer_control_input.m
The file eval_steer_control_input.m encodes a PD controller that generates the steer and steer rate inputs.
function r = eval_steer_control_input(t, x, p)
% unpack the states
omega = x(1);
theta = x(2);
% unpack the control gains
kp = p(8);
kd = p(9);
% calculate the inputs
beta = kp*omega;
delta = kp*theta + kd*omega;
% pack up the inputs
r = [beta; delta];
end
bicycle_main.m
The file bicycle_main.m runs the simulation with the constant inputs and the inputs from the controller.
% this is the simulation we did in class of the bicycle balance model
x0 = [0; 0; 0]; % one initial condition for each state
ts = linspace(0, 4, 200); % time values
r = [0; 5*pi/180]; % using constant values for the inputs
p = [87; 9.81; 1.0; 0.5; 1.0; 5.0; 3.28]; % pick numbers for parameters
eval_bicycle_rhs_anon = @(t, x) eval_bicycle_rhs(t, x, r, p);
[ts, xs] = ode45(eval_bicycle_rhs_anon, ts, x0);
figure(1)
plot(ts, xs*180/pi)
xlabel('Time [s]')
legend('\omega [deg/s]', '\theta [deg]', '\psi [deg]')
% this is a second simulation of the same model but it has an input function
x0 = [0; 5*pi/180; 0];
% add two more parameters for the control input (PD controller)
p(8) = 2.5; # proportional gain
p(9) = 0.5; # derivative gain
eval_bicycle_rhs_anon2 = ...
@(t, x) eval_bicycle_rhs2(t, x, @eval_steer_control_input, p);
[ts, xs] = ode45(eval_bicycle_rhs_anon2, ts, x0);
figure(2)
plot(ts, xs*180/pi)
xlabel('Time [s]')
legend('\omega [deg/s]', '\theta [deg]', '\psi [deg]')