> restart:
read MBSymba package for multibody modeling
(Ref. R. Lot, M. Da Lio, A Symbolic Approach for Automatic Generation of the Equations of Motion of Multibody Systems, Multibody System Dynamics n° 12, Kluwer Academic Publishers. pp. 147-172, 2004)
> libname:="C:\libs",libname:with(MBSymba_r4):
MBSymba release 4.1 - Copyright (C) 2006 - by Roberto.Lot@unipd.it & Matteo.Massaro@unipd.it
Warning, Non-Linear Modeling option has been choosen
use compact form for cos and sin
> alias(s=sin,c=cos);
![]()
Motorcycle Model

Degrees of Fredom (dof)
> u(t),v(t), longitudinal and lateral velocity (dof 1, 2)
> z(t), vertical motion of the chassis (dof 3)
> psi(t), phi(t),mu(t), yaw, roll and pitch angles of the chassis (dof 4,5,6)
> zsr(t), rear suspension travel (dof 7)
> delta(t), steering angle (dof 8)
> beta(t), twist deflection (dof 9)
> zsf(t); front suspension travel (10)
> PDEtools[declare](%,prime=t,quiet):
![]()
Inputs
> uvars:=[tau(t), steering torque
Mr(t), rear wheel torque
Mf(t) front wheel torque
];PDEtools[declare](%,prime=t,quiet):
![]()
the following variables are assumed "small"
> linear_modeling({ delta(t), psi4(t), phi4(t)=phi(t), beta(t) });
Warning, Linear Modeling option has been choosen for the following variables:
![]()
Frames and Bodies
Define a moving reference frame with longitudinal velocity u(t), lateral velocity v(t) and angular velocity psi[dot](t). Note that this is not an inertial frame.
> USE_master_frame(u(t),v(t),0, 0,0,psi[dot](t));
> T1 := master_frame:
Warning, The base frame <moving_frame> has been selected. The moving velocity matrix is:

define a proceure for compensating the inertia already included in the body "motorcycle"
> anti_body := proc(BB::BODY)
local anti_BB:
anti_BB := copy(BB):
anti_BB[frame] := map(eval,subs( seq(args[i],i=2..nargs), evalm(BB[frame]))):
anti_BB[mass] := -BB[mass]:
anti_BB[inertia] := evalm(-BB[inertia]):
copy(anti_BB):
end:
body "motorcycle"
> T2 := T1 * rotate('X',phi(t)) * translate(0,0,z(t)-H) * rotate('Y',mu(t)):
> G := origin(T2): #show(G);
> CYZ := 0: CXY:=0:because of the simmetry with respect XY plane
> motorcycle := make_BODY(G,M,IX,IY,IZ,CYZ,CXZ,CXY): show(motorcycle);


body "rear_vheel"
> TWR0 := T2 * translate(-B,0,H-Rr+zsr(t)) * rotate('Y',-mu(t)):
> TWR := TWR0 * rotate('Y',theta1(t)):
> rear_wheel := make_BODY(TWR,umr,0,iry,0): show(rear_wheel,'synthetic');
> anti_rear_wheel := anti_body(rear_wheel, zsr(t)=0, theta1(t)=0): #show(anti_rear_wheel);

body "front_chassis"
> T4 := T2 * rotate('Y',-mu(t))* rotate('Y',mu(t)+epsilon) * translate(a1,0,0) * rotate('X',beta(t)) * rotate('Z',delta(t)):
> T40:= T2 * rotate('Y',-mu(t))* rotate('Y',mu(t)+epsilon) * translate(a1,0,0) * rotate('X',beta(t)):
> Gf := make_POINT(T4,gfx,0,gfz): show(Gf,'syntetic');
> front_chassis := make_BODY(Gf,mf,Ifx,Ify,Ifz): show(front_chassis,'syntetic');
> anti_front_chassis := anti_body(front_chassis,delta(t)=0,beta(t)=0): #show(anti_front_chassis);


body "front_wheel"
> psi4(t):='psi4(t)':front wheel yaw
> phi4(t):='phi4(t)':front wheel roll
> T4p := rotate('Z',psi4(t)) * rotate('X',phi4(t)): #show(T4p);
> zero := project( make_VECTOR(T4,0,1,0)-make_VECTOR(T4p,0,1,0), T2 ):
front wheel yaw and roll as a function of other dof
> front_angles := combine (solve ( {Xcomp(zero),Zcomp(zero)} , {psi4(t),phi4(t)}));
> WF := make_POINT(T4,lx,0,lz+zsf(t)): WF := project(WF,T1):
> TWF0 := translate( Comps(WF) ) * linearize( evalm(T4p )):
> TWF := TWF0 * rotate('Y',theta4(t)):
> front_wheel := make_BODY(TWF,umf,0,ify,0): show(front_wheel,'syntethic');
> anti_front_wheel := anti_body(front_wheel, zsf(t)=0,theta4(t)=0):
![]()

Forces
> _gravity := make_VECTOR(master_frame,0,0,+g): show(_gravity);

rider steering torque + steering damper
> steering_torque := make_TORQUE(T4, STX,STY,tau(t)-Cdelta*diff(delta(t),t), front_chassis,motorcycle):
> show(steering_torque,'syntetic');

drag Force
> CA := make_POINT(T2,0,0,H-HCA): show(CA,'synthetic');
> drag_force := make_FORCE(T1,-kD*VX(t)^2,0,0,CA,motorcycle):
> show(drag_force);


suspensions
> v0 :=1/20:
> cr := (crc+cre)/2 +(cre-crc)*arctan(diff(zsr(t),t)/v0)/Pi:
> cf := (cfc+cfe)/2 +(cfe-cfc)*arctan(diff(zsf(t),t)/v0)/Pi:
> - ( RSZ0 + kr*zsr(t) + cr*diff(zsr(t),t) ): molla + ammortizzatore
> RSZ(t) := subs(diff(zsr(t),t)=zsr_dot(t), %):
> - ( FSZ0 + kf*zsf(t) + cf*diff(zsf(t),t) ): molla + ammortizzatore
> FSZ(t) := subs(diff(zsf(t),t)=zsf_dot(t), %):
> rear_suspension := make_FORCE(T2, RSX,RSY,RSZ(t), origin(rear_wheel [frame]), rear_wheel ): show(rear_suspension,synthetic);
> front_suspension := make_FORCE(T4, FSX,FSY,FSZ(t), origin(front_wheel[frame]), front_wheel): show(front_suspension,synthetic);






rear tyre
> Fr(t) := fr(t)*M*g: Sr(t) := -Mr(t)/Rr:
> rear_tire_geometry := [YT1 = rt1*sin(phi(t)), ZT1 = rho1 + rt1*cos(phi(t))]: carcass_geometry=Vector(%);
> rear_tire := make_TIRE(TWR0,theta1(t), YT1,ZT1, 0,0 ,Sr(t),Fr(t),-Nr(t), 0,
uR*Nr(t),rolling resistance
mrR * phi(t) *Nr(t)* (1+twR* phi(t)^2) +Mzsar twisting torque + self-aligning torque
,phi(t),0):
show(rear_tire,synthetic);
![]()


front tyre
> Ff(t):=ff(t)*M*g: Sf(t):=-Mf(t)*M*g:
front_tire_geometry := [YT4 = rt4*sin(phi4(t)), ZT4 = rho4 + rt4*cos(phi4(t)) ]:
front_tire_geometry := linearize( subs(front_angles,front_tire_geometry) , small_vars union {mu(t)},t):
'carcass_geometry'=Vector(%);
> front_tire := make_TIRE(TWF0,theta4(t), YT4,ZT4, 0,0 ,Sf(t),Ff(t),-Nf(t), 0,
uF*Nf(t),
mrF * subs(front_angles,phi4(t)) *Nf(t)* (1+twF* subs(front_angles,phi4(t))^2)+Mzsaf
,subs(front_angles,phi4(t)),0):
show(front_tire,synthetic);
![]()



twist torque
> flex_torque := make_TORQUE(T40, -kb*beta(t)-cb*diff(beta(t),t) ,0,0,front_chassis,motorcycle):show(flex_torque,'synthetic');

Newton-Euler Equations of Motion
assembly multibody model
> Nr:='Nr': Nf:='Nf':
> bodies := {motorcycle,front_chassis, anti_front_chassis, rear_wheel, anti_rear_wheel, front_wheel, anti_front_wheel};
> forces := {rear_tire, front_tire, drag_force, rear_wheel_torque,front_wheel_torque, flex_torque};
![]()
![]()
Newton Equations for the Whole Vehicle
> eqnsN := newton_equations(bodies union forces,verbose):
BODIES:
1 - anti_rear_wheel
2 - rear_tire_body
3 - motorcycle
4 - rear_wheel
5 - front_chassis
6 - anti_front_chassis
7 - anti_front_wheel
8 - front_wheel
9 - front_tire_body
EXTERNAL FORCES:
10 - front_tire_force
11 - rear_tire_force
12 - drag_force
WARNING: the following objects will not appear in the equations of motion:
13 - rear_wheel_torque
14 - front_wheel_torque
15 - flex_torque
store equilibrium in the X direction
> eqn_X := Xcomp(eqnsN,master_frame):
store equilibrium in the Y direction
> eqn_Y := Ycomp(eqnsN,master_frame):
store equilibrium in the Z direction
> eqn_Z := Zcomp(eqnsN,master_frame):
Euler Equations for the Whole Vehicle
> eqnsE := euler_equations(bodies union forces, G, verbose): eqnsE := project(eqnsE, motorcycle[frame]):
BODIES:
1 - anti_rear_wheel
2 - motorcycle
3 - rear_wheel
4 - front_chassis
5 - rear_tire_bodyT
6 - front_tire_bodyF
7 - rear_tire_bodyF
8 - anti_front_chassis
9 - anti_front_wheel
10 - front_wheel
11 - front_tire_bodyT
EXTERNAL FORCES:
12 - front_tire_force
13 - rear_tire_force
14 - drag_force
EXTERNAL TORQUES:
15 - rear_tire_torque
16 - front_tire_torque
WARNING: the following objects will not appear in the equations of motion:
17 - rear_wheel_torque
18 - front_wheel_torque
19 - flex_torque
store roll equilibrium
> eqn_phi := Xcomp(eqnsE):
store pitch equilibrium
> eqn_mu := Ycomp(eqnsE):
store yaw equilibrium
> eqn_psi := Zcomp(eqnsE):
kinematic equations for 1st order formulation
collect equations
> eqns_NE := [ eqn_X,eqn_Y,eqn_Z, eqn_phi, eqn_mu, eqn_psi]: #Vector(%);
linear velocities of th chassis
> VG2 := velocity(origin(T2)): #show(VG2);
angular velocities of the chassis
> Omega := angular_velocity(motorcycle[frame]): #show(Omega, synthetic);
"kinematic equations" for the 1st order formulation
> equ_omega := [
VX(t) - Xcomp(VG2),
VY(t) - Ycomp(VG2),
VZ(t) - Zcomp(VG2),
omega_X(t) - Xcomp(Omega),
omega_Y(t) - Ycomp(Omega),
omega_Z(t) - Zcomp(Omega)
]:
> Sspeed := expand(op(solve(equ_omega, [u(t),v(t),diff(z(t),t),diff(phi(t),t), diff(mu(t),t), psi[dot](t)]))):
> Sspeed := Sspeed[1..6]:Vector(%);
> simplify_speed := x -> expand(simplify(subs(Sspeed,expand(subs(Sspeed,x))))):



> eqns_NE0 := expand(subs(front_angles, eqns_NE)):
> eqns_NE0 := simplify(subs(expand(map(simplify_speed, eqns_NE0)))):
Euler Equations about the steering axis and twist axis
> eqnsE_steer := euler_equations( {front_chassis, front_wheel, anti_front_wheel, steering_torque,front_tire,
flex_torque}, origin(T4),verbose): eqnsE_steer := project(eqnsE_steer,T4):
BODIES:
1 - front_chassis
2 - front_tire_bodyF
3 - anti_front_wheel
4 - front_wheel
5 - front_tire_bodyT
EXTERNAL FORCES:
6 - front_tire_force
EXTERNAL TORQUES:
7 - steering_torque
8 - front_tire_torque
9 - flex_torque
equation related to twist dof
> eqn_beta:= Xcomp(eqnsE_steer,T4):
eqn_beta:= expand( subs(front_angles, eqn_beta)):
eqn_beta:= simplify(subs(expand(map(simplify_speed, eqn_beta)))):
equation related to steer dof
> eqn_delta := simplify(expand(Zcomp(eqnsE_steer,T4))):
> eqn_delta0 := expand( subs(front_angles, eqn_delta)):
> eqn_delta0 := simplify(subs(expand(map(simplify_speed, eqn_delta0)))):
Newton Equations for suspensions
rear
> eqnsN_r_wheel := newton_equations({rear_wheel,rear_suspension,rear_tire},verbose):
store equation
> eqn_zsr := Zcomp(eqnsN_r_wheel,T2):
BODIES:
1 - rear_tire_body
2 - rear_wheel
EXTERNAL FORCES:
3 - rear_tire_force
4 - rear_suspension
front
> eqnsN_f_wheel := newton_equations({front_wheel,front_suspension,front_tire},verbose):
store equation
> eqn_zsf := Zcomp(eqnsN_f_wheel,T4):
eqn_zsf := expand( subs(front_angles, eqn_zsf)):
BODIES:
1 - front_wheel
2 - front_tire_body
EXTERNAL FORCES:
3 - front_tire_force
4 - front_suspension
Tyre Equations
rear
kinematics
> (CC1, wC1,VS1,VN1,VR1) := tire_kinematics(rear_tire):
contact point
> CC1 := project(CC1,T1): show(CC1);


contact point velocity
> VS1 := VX(t);
> VN1 := subs( diff(zsr(t),t)=zsr_dot(t),simplify_speed(VN1));
![]()

vertical deflection and load
> xir := Zcomp(CC1,master_frame);
> Nr(t) := M*g*(1-B/p) + kpr * xir:
> nr(t) := (1-B/p) + kpr * xir /(M*g);
![]()
![]()
non-linear force
> mgcfr(t) := Dr*sin( Crl*arctan(Brl*'slipR'-Erl*(Brl*'slipR'-arctan(Brl*'slipR')))
+ Crp*arctan(Brp* phi(t) -Erp*(Brp* phi(t) -arctan(Brp* phi(t) ))) );
![]()
relaxation equation
> eqn_rtire :=(sigmaR0+dsigmaR*(nr(t)-nr0)*M*g)/VS1*diff(fr(t),t) + fr(t) - nr(t) * ( mgcfr(t)-iphi*mgcfr[phi](t) );

![]()
yaw torque
> Mzsar:= Nr(t)*Drsa*sin(Crsa*atan(Brsa*slipR-Ersa*(Brsa*slipR-atan(Brsa*slipR))));

front
> (CC4, wC4,VS4,VN4,VR4) := tire_kinematics(front_tire):
> CC4 := project(CC4,T1): #show(CC4,synthetic); #show(wC4);
> VS4 := VX(t):
> VN4 := expand(subs(front_angles,VN4)):
> xif := subs(front_angles,Zcomp(CC4,master_frame)):
> Nf(t) := M*g*B/p + kpf * xif :
> nf(t) := B/p + kpf * xif / (M*g):
> mgcff(t) := Df*sin( Cfl*arctan(Bfl*'slipF'-Efl*(Bfl*'slipF'-arctan(Bfl*'slipF')))
+ Cfp*arctan(Bfp*subs(front_angles,phi4(t))-Efp*(Bfp*subs(front_angles,phi4(t))-arctan(Bfp*subs(front_angles,phi4(t)) ))) ):
> eqn_ftire := (sigmaF0+dsigmaF*(nf(t)-nf0)*M*g)/VS4*diff(ff(t),t) + ff(t) - nf(t) * ( mgcff(t) -iphi*mgcff[phi](t)):
> Mzsaf:= Nf(t)*Dfsa*sin(Cfsa*atan(Bfsa*slipF-Efsa*(Bfsa*slipF-atan(Bfsa*slipF)))):
Assembly Equations and Variables
state variables
> tvars0 := [VX(t),z(t),VZ(t),mu(t),omega_Y(t),
VY(t),omega_Z(t), phi(t),omega_X(t), delta(t), delta_dot(t),
beta(t),beta_dot(t),
fr(t), ff(t),
zsr(t), zsr_dot(t), zsf(t), zsf_dot(t)];
![]()
> acc_vars := [delta(t), zsr(t), zsf(t),beta(t)]:
collect equations
> teqns0 :=
map(numer, [ lhs(Sspeed[3])-rhs(Sspeed[3]), lhs(Sspeed[4])-rhs(Sspeed[4]), lhs(Sspeed[5])-rhs(Sspeed[5])])kinematic equation
union down_order(eqns_NE0, acc_vars, t) whole vehicle equations
union [diff(delta(t),t)-delta[dot](t) , down_order(eqn_delta0,acc_vars, t)]steer equation
union [diff(beta(t),t)-beta[dot](t) , down_order(eqn_beta,acc_vars, t)]twist equation
union down_order([eqn_rtire, eqn_ftire],acc_vars,t)tyre equations
union [diff(zsr(t),t)-zsr_dot(t)] union down_order([eqn_zsr],acc_vars,t)rear suspension equation
union [diff(zsf(t),t)-zsf_dot(t)] union down_order([eqn_zsf],acc_vars,t):front suspension equation
nops(teqns0);
![]()
compute wheel spin acceleration
> tire_geometry := rear_tire_geometry union subs(delta(t)=0,front_tire_geometry): Vector(%);
> wheels_spin := subs(tire_geometry,[
diff(theta1(t),t,t) = -diff(VX(t),t)/ZT1, diff(theta1(t),t) = -VX(t)/ZT1,
diff(theta4(t),t,t) = -diff(VX(t),t)/ZT4, diff(theta4(t),t) = -VX(t)/ZT1
]): Vector(%);


update equations
> teqns0 := subs(tire_geometry,wheels_spin,teqns0):
rear_rolling_radius:=rho1+rt1*cos(phi(t));
front_rolling_radius:=rho4+rt4*cos(phi(t));
![]()
![]()
display equations
> for i from 1 to nops(teqns0) do i=tvars0[i]; teqns0[i]; end do;
![]()
![]()
![]()
![]()
![]()
![]()
![]()





![]()






![]()
![]()






![]()
![]()




































































![]()





























































![]()




























































![]()
![]()
![]()
![]()











































































![]()
![]()
![]()





















































































![]()
![]()


![]()



![]()
![]()
![]()





![]()
![]()
![]()
![]()



















M(t)*dx/dt = F(x,u)
> (MM,FF) := LinearAlgebra[GenerateMatrix](teqns0 , diff(tvars0,t)):
plots[sparsematrixplot](MM);display mass matrix

> Example of Vehicle Parameters and Vibration Modes
g = 9.8070E+00
p = 1.4150E+00
epsilon = 4.1840E-01
an = 9.1240E-02
M = 2.5560E+02
B = 7.0980E-01
H = 6.3980E-01
CXZ =-1.1300E+00
IX = 1.8650E+01
IY = 5.0460E+01
IZ = 3.7140E+01
mf = 3.4630E+01
bf = 1.3150E+00
hf = 4.8170E-01
Ifx = 2.1410E+00
Ify = 2.1980E+00
Ifz = 5.0840E-01
Rr = 3.1670E-01
rho1 = 2.2270E-01
rt1 = 9.4000E-02
KlambdaR = 1.0020E+01
KphiR = 1.2170E+00
umr = 2.5260E+01
mwr = 5.3341E+00
Rf = 2.9100E-01
rho4 = 2.3100E-01
rt4 = 6.0000E-02
umf = 2.5880E+01
mwf = 5.3849E+00
KlambdaF = 1.2880E+01
KphiF = 1.0390E+00
HCA = 8.3270E-01
kD = 3.0000E-01
kpr = 1.3500E+05
kpf = 1.4000E+05
RSZ0 =-1.0630E+03
kr = 2.1320E+04
crc = 9.2840E+02
cre = 2.4836E+03
FSZ0 =-9.1720E+02
kf = 1.8500E+04
cfc = 5.2530E+02
cfe = 9.7470E+02
sigmaR0 = 1.0430E-01
dsigmaR = 7.0000E-05
nr0 = 5.7367E-01
sigmaF0 = 1.0800E-01
dsigmaF = 1.0000E-04
nf0 = 4.2646E-01
Cdelta = 5.0000E+00
Brsa = 7.1500E-01
Crsa = 1.9960E+01
Drsa =-2.0000E-02
Ersa = 1.1000E-01
Bfsa = 4.6650E+00
Cfsa = 4.6510E+00
Dfsa =-1.7000E-02
Efsa = 5.4980E+00
Brl = 8.1628E-01
Crl = 9.4280E+00
Dr = 1.3020E+00
Erl =-1.9000E-01
Brp = 7.4302E-01
Crp = 1.2580E+00
Erp = 3.3400E-01
Bfl = 1.4340E+00
Cfl = 7.2550E+00
Df = 1.2380E+00
Efl = 7.5500E-01
Bfp = 9.1983E-02
Cfp = 9.1240E+00
Efp =-1.5400E+00
kb = 4.5100E+04
cb = 2.5000E+01
uR = 1.1000E-02
uF = 1.1000E-02
mrF = 2.1000E-02
twF = 5.5300E-01
mrR = 2.1000E-02
twR = 2.0430E+00
a1 = 4.7566E-01
lz = 6.0523E-01
gfz = 3.9035E-01
gfx = 1.3100E-02
lx = 2.6993E-02

Root-locus for speeds from 20 to 40 m/s.
-black crosses: lateral acceleration = longitudinal acceleration = 0
-blue circles: lateral acceleration = 5 m/s2
-red triangles: longitudinal acceleration = 5 m/s2
-green squares: longitudinal deceleration = 5 m/s2 (only front wheel braking torque used)
All of the most important vehicle vibration modes are visible.
For additional details on vibration modes see e.g.
V. Cossalter, Motorcycle Dynamics, Lulu.com, 2006, ISBN: 978-1-4303-0861-4, http://www.lulu.com/content/paperback-book/motorcycle-dynamics/221690