One-Dimensional Modeling and Analysis of Porpoising of Formula 1 Cars using MATLAB
(thumbnail)
- porpoising theory (It includes some of my own guesses so... it could be wrong.)
Now we can guess the conditions for porpoising.
- Due to some circumstances, floor stall has to be provoked. Inappropriate spring rate and pre-load, bumps on the road, and rolling of the car can be the cause of it.
- If there is no F_sus that can practically balance F_aero, porpoising must happens. It means the range of F_sus is in between the non-stalled and fully stalled region of F_aero. This always guarantee the underfloor entering stall. It is definately not desirable and therefore the spring rate and pre-load have to be adjusted. Using extreme rocker arm geometry, it might be possible to balance F_sus and stalled F_aero, but it is suspected to require really extreme spring rate, rocker arm radius and pre-load. Most of all, it is never a good idea to keep the underfloor stalled.
- Even if F_sus and F_aero can be matched, porpoising still can be triggered. If there is any chance for the absolute value of the work done by damper and the work done by aero package, which are the resistance and the power source of porpoising, to be matched through a cycle, porpoising can happen. If the work(absolute value) done by damper always exceed the work done by the aero package, it will be damped through some cycles.
- about simulation
: polynomials used to model the downforce characteristics when the floor is stalled and not stalled.
One may argue that porpoising should be modeled at least in two-dimension considering front suspension movement, but here is my opinion.
- Observing actual footage, whole car almost pivots around front axle while porpoising and it seems that there is not much front suspension movement.
- The frequency of porpoising is quite consistent and no weird interaction between front and rear suspension was observed.
- simulation results
: stall starting-ending: 0.06-0.08 m, intended ride height: 0.055 m, kdmp=2000 N/(mps)Above is the condition 2. mentioned in the beginning of this article.
: stall starting-ending: 0.06-0.08 m, intended ride height: 0.065 m, kdmp=2000 N/(mps), porpoising triggered(1 bump, 0.02 m, 10 Hz)
: stall starting-ending: 0.06-0.08 m, intended ride height: 0.065 m, kdmp=4200 N/(mps), porpoising triggered(1 bump, 0.02 m, 10 Hz(Note that speed is 85m/s)) but damped through cycles
Above is the condition 3.
Only kdmp is different compared to the condition 3. but porpoising is continuously happening. Note that it can endure some small disturbance not causing floor stall like the very beginning.
The condition 3. and this may imply the track dependency of porpoising(e.g. Mercedes W13). There are two possibilities.
- Porpoising can be damped through some cycles, but many bumps keep triggering it.
- Porpoising is triggered by a bump and does not damped enough.
- effects of aerodynamic characteristics, spring rate, spring pre-load(ride height), and damping rate
case | Base | 1. Relaxed Stall Hysterisis | 2. Decreased Spring Rate | 3. Increased Ride Height | 4. Increased Damping Rate |
displacement frequency (1/s) | 4.03 | 4.31 | 3.64 | 3.80 | 3.96 |
amplitude total (m) | 0.034873 | 0.023384 | 0.036592 | 0.035805 | 0.02677 |
amplitude upper (m) | 0.091043 | 0.081983 | 0.09335 | 0.094815 | 0.086191 |
amplitude lower (m) | 0.05617 | 0.058600 | 0.056758 | 0.05901 | 0.059421 |
acceleration amplitude total (m/s^2) | 24.46 | 19.93 | 22.01 | 24.40 | 23.65 |
acceleration amplitude upper (m/s^2) | 13.45 | 12.39 | 12.70 | 14.49 | 12.56 |
acceleration amplitude lower (m/s^2) | -11.01 | -7.54 | -9.31 | -9.91 | -11.09 |
case_Base: (stall starting-ending: 0.06-0.08 m, kspr=800000 N/m, rdh=0.065 m, kdmp=2000 N/(mps), porpoising triggered and continued)
Red for increased, blue for decreased factors.
Case 1. is a modeling of reducing stall hysteresis(0.06-0.07 m). Comparing this with the base case, we can observe that both displacement and acceleration amplitude have reduced and the frequency has increased. This agrees well with the F1TV Tech Talks data.
Reducing the amplitude of displacement and acceleration is indeed very desirable and we can understand why every team is so obsessed with floor design and cut-outs. In addition of my personal note, I believe the rounded Redbull underfloor and lots of corotating vortex generating shape can also help reducing stall hysteresis.
If we completely remove stall hysteresis(e.g. 0.06-0.06 m), porpoising is removed or damped, which is understandable.
The spring rate is decreased in the case 2. As a result, the displacement amplitude has slightly increased and the acceleration amplitude and the frequency have decreased. Note that the minimum and maximum displacement has moved higher.
If we increase the spring rate up to 1200000, exactly opposite happens.
I should mention that spring rate is not that free to adjust as it is related to many other factors such as vehicles attitude in acceleration, braking, bumps and speed-ride height relation.
By adjusting the spring pre-load only, ride height is increased up to 0.07 m. We can see that the acceleration amplitude and frequency has reduced while the displacement amplitude increasing slightly. So this can be another way to improve porpoising.
If we raise the ride height up to 0.075 m, the porpoising is not triggered with the bump.
Of course, raising ride height is not good for overall aerodynamics.
Increasing damping rate can improve every parameters, obviously. However, I should mention that damping rate is closely related to vehicle dynamics, which means there will be some compromises.
[MATLAB code]
Aware that I'm just a university student now and there can be lots of inaccurate coefficients and errors below.
[representative code - porpoising triggered by a bump, ride height = 0.065 m]
! All rights reserved !
% porpoising simulator
% numerics
delt=0.0001;
yini=0.07;
vini=0;
tend=10;
exmmod=1;
texms=6;
std=4;
exms=int64(fix(texms/delt));
itr=int64(fix(tend/delt));
bmpmod=1;
bmps=(itr/tend)*(2);
bmpe=(itr/tend)*(2+0.05);
Ab=0.02;
k=((2*pi)/(double(itr)/tend))*(10);
kela=0.8; % COR
% suspension geometry
th1=(pi/180)*(-35);
th2=(pi/180)*(0);
th3=(pi/180)*(35);
r1=0.08;
r2=0.1;
r3=0.6;
kspr=800000;
kdmp=2000;
rdh=0.065;
% C.G. info
m=795;
g=9.8;
kdst=(65/100);
% aero info
p=1.225;
Cl=4.5;
A=2*0.5;
V=85;
a0=(-0.452);
b0=(47.4);
c0=(-539);
d0=(2520);
e0=(-4210);
as=(0.6);
bs=(0.0274);
cs=(9.11);
ds=(-202);
es=(1790);
stalls=0.06;
stalle=0.08;
rdhref=0.1;
ddec=(0.1/rdhref);
% spring preload
Fdwn=(0.5*p*Cl*A*(V^2))*(1-ddec*(rdh-rdhref))*(a0+b0*rdh+c0*(rdh^2)+d0*(rdh^3)+e0*(rdh^4));
%Fdwn=0;
sprpre=(kdst*(m*g+Fdwn)*r1*sin(pi/2-th3-th1))/(2*kspr*r2*cos(th2)*sin(th3));
% ------- END OF SET-UP SECTION -------
t=linspace(0,tend,itr);
y=zeros(1,itr);
v=zeros(1,itr);
a=zeros(1,itr);
ydiff=zeros(1,itr);
Fw=zeros(1,itr);
Fd=zeros(1,itr);
Fspr=zeros(1,itr);
Fdmp=zeros(1,itr);
Fnet=zeros(1,itr);
y(1)=yini;
v(1)=vini;
a(1)=0;
% before run disp
fprintf('spring preload: %f m \n',sprpre);
fprintf('iteration scheduled: %f \n',itr);
cnt=1;
stl=0;
bttmitr=0;
for i=2:itr
Fw(i-1)=kdst*m*g;
Fdtemp=(0.5*p*Cl*A*(V^2))*kdst;
if y(i-1)<0.2
if (y(i-1)<stalls)||((stl==1)&&(y(i-1)<stalle))
Fd(i-1)=Fdtemp*(1-ddec*(y(i-1)-rdhref))*(as+bs*y(i-1)+cs*(y(i-1)^2)+ds*(y(i-1)^3)+es*(y(i-1)^4));
stl=1;
else
Fd(i-1)=Fdtemp*(1-ddec*(y(i-1)-rdhref))*(a0+b0*y(i-1)+c0*(y(i-1)^2)+d0*(y(i-1)^3)+e0*(y(i-1)^4));
stl=0;
end
else
Fd(i-1)=Fdtemp*(1-ddec*(0.2-rdhref))*0.91;
end
Fspr(i-1)=2*kspr*(r2*(sin(th2+(rdh-y(i-1))/r3)-sin(th2))+sprpre)*r2*cos(th2+(rdh-y(i-1))/r3)*sin(th3)/(r1*sin(pi/2-th3-th1-(rdh-y(i-1))/3));
Fdmp(i-1)=2*kdmp*v(i-1);
Fnet(i-1)=Fspr(i-1)-Fw(i-1)-Fd(i-1)-Fdmp(i-1);
a(i)=Fnet(i-1)/(m*kdst);
v(i)=v(i-1)+a(i)*delt;
y(i)=y(i-1)+v(i-1)*delt+0.5*a(i)*(delt^2);
% bump sim
if (bmpmod==1)&&((i>=bmps)&&(i<=bmpe))
ydiff(i)=Ab*sin(k*double(i));
end
y(i)=y(i)-(ydiff(i)-ydiff(i-1));
% bottoming sim
if (y(i)<0)
%{
if bttmitr==0
disp(i)
disp(ydiff(i))
disp(y(i))
disp(v(i))
disp(v(i)-(ydiff(i)-ydiff(i-1))/delt)
end
%}
temp=v(i)-(ydiff(i)-ydiff(i-1))/delt;
v(i)=(-1)*temp*kela;
a(i)=(v(i)-temp)/delt;
y(i)=0;
bttmitr=bttmitr+1;
end
cnt=cnt+1;
end
% post processing
pycnt=0;
if exmmod==1
mod=0;
chku=0;
chkl=0;
memtu=zeros(1,std);
memtl=zeros(1,std);
memsu=zeros(1,std);
memsl=zeros(1,std);
prdsum=0;
% displacement examination
for i=exms:itr
if y(i-1)<y(i)
switch mod
case 0
mod=1;
case (-1)
mod=1;
chkl=chkl+1;
memtl(chkl)=(i-1);
memsl(chkl)=y(i-1);
otherwise
mod=1;
end
else
switch mod
case 0
mod=(-1);
case 1
mod=(-1);
chku=chku+1;
memtu(chku)=(i-1);
memsu(chku)=y(i-1);
otherwise
mod=(-1);
end
end
if (chku==std)&&(chkl==std)
break;
end
pycnt=pycnt+1;
end
if (chku~=std)||(chkl~=std)
fprintf('not enough local maxima and local minima of y to meet the examination standard.');
end
for j=2:std
prdsum=prdsum+delt*((memtu(j)-memtu(j-1))+(memtl(j)-memtl(j-1)));
end
frqs=(2*(std-1))/prdsum;
ampu=mean(memsu);
ampl=mean(memsl);
% resetting variables
mod=0;
chku=0;
chkl=0;
memtu=zeros(1,std);
memtl=zeros(1,std);
memau=zeros(1,std);
memal=zeros(1,std);
prdsum=0;
% acceleration examination
pacnt=0;
for i=exms:itr
if a(i-1)<a(i)
switch mod
case 0
mod=1;
case (-1)
mod=1;
chkl=chkl+1;
memtl(chkl)=(i-1);
memal(chkl)=a(i-1);
otherwise
mod=1;
end
else
switch mod
case 0
mod=(-1);
case 1
mod=(-1);
chku=chku+1;
memtu(chku)=(i-1);
memau(chku)=a(i-1);
otherwise
mod=(-1);
end
end
if (chku==std)&&(chkl==std)
break;
end
pacnt=pacnt+1;
end
if (chku~=std)||(chkl~=std)
fprintf('not enough local maxima and local minima of to meet the examination standard.');
end
for j=2:std
prdsum=prdsum+delt*((memtu(j)-memtu(j-1))+(memtl(j)-memtl(j-1)));
end
frqa=(2*(std-1))/prdsum;
ampaccu=mean(memau);
ampaccl=mean(memal);
end
% after run disp
fprintf('actual iteration: %d \n',cnt);
fprintf('bottoming iteration: %d \n\n',bttmitr);
if exmmod==1
fprintf('displacement frequency: %f 1/s \n',frqs);
fprintf('amplitude upper: %f m \n',ampu);
fprintf('amplitude lower: %f m \n',ampl);
fprintf('amplitude total: %f m \n',ampu-ampl);
fprintf('y counter: %d \n\n',pycnt);
fprintf('acceleration frequency: %f 1/s \n',frqa);
fprintf('acceleration amplitude upper: %f m/s^2 \n',ampaccu);
fprintf('acceleration amplitude lower: %f m/s^2 \n',ampaccl);
fprintf('acceleration amplitude total: %f m/s^2 \n',ampaccu-ampaccl);
fprintf('a counter: %d \n\n',pacnt);
end
subplot(3,1,1);
plot(t,y);
ylim([0, 0.1]);
xlabel('(sec)');
ylabel('(m)');
title('ride height');
subplot(3,1,2);
hold all
plot(t,Fspr+Fdmp);
plot(t,Fd+Fw);
hold off
ylim([0, inf]);
xlabel('(sec)');
ylabel('(N)');
title('net F_{sus} and F_{ext}');
legend('F_{sus}', 'F_{ext}', 'Location', 'eastoutside');
%{
subplot(2,3,2);
plot(t,Fspr);
ylim([0, inf]);
title('Fspring');
%}
%{
subplot(2,3,3);
plot(t,Fd);
ylim([0, 15000]);
title('Fdownforce');
%}
%{
subplot(2,3,4);
plot(t,ydiff);
ylim([-Ab*1.1, Ab*1.1]);
title('gnd fluc');
%}
%{
subplot(2,3,5);
plot(t,Fdmp);
ylim([-inf, inf]);
title('Fdmp');
%}
%%{
subplot(3,1,3);
plot(t,a);
ylim([-15, 15]);
xlabel('(sec)');
ylabel('(m/s^2)');
title('vert. acceleration');
%%}
%{
subplot(2,3,6);
plot(t,Fnet);
ylim([-inf, inf]);
title('Fnet');
%}
[raw data]
>> case_PwTrgrd_Base (stall starting-ending: 0.06-0.08 m, kspr=800000 N/m, rdh=0.065 m, kdmp=2000 N/(mps), porpoising triggered and continued)
spring preload: 0.015727 m
displacement frequency: 4.030091 1/s
amplitude upper: 0.091043 m
amplitude lower: 0.056170 m
amplitude total: 0.034873 m
y counter: 9430
acceleration frequency: 4.030091 1/s
acceleration amplitude upper: 13.453712 m/s^2
acceleration amplitude lower: -11.006198 m/s^2
acceleration amplitude total: 24.459909 m/s^2
a counter: 9214
>> case_PwTrgrd_1. (stall starting-ending: 0.06-0.07 m, kspr=800000 N/m, rdh=0.065 m, kdmp=2000 N/(mps), porpoising triggered and continued)
spring preload: 0.015727 m
displacement frequency: 4.305705 1/s
amplitude upper: 0.081983 m
amplitude lower: 0.058600 m
amplitude total: 0.023384 m
y counter: 8718
acceleration frequency: 4.306014 1/s
acceleration amplitude upper: 12.393746 m/s^2
acceleration amplitude lower: -7.540462 m/s^2
acceleration amplitude total: 19.934208 m/s^2
a counter: 8566
>> case_PwTrgrd_2. (stall starting-ending: 0.06-0.08 m, kspr=600000 N/m, rdh=0.065 m, kdmp=2000 N/(mps), porpoising triggered and continued)
spring preload: 0.020969 m
displacement frequency: 3.639010 1/s
amplitude upper: 0.093350 m
amplitude lower: 0.056758 m
amplitude total: 0.036592 m
y counter: 10553
acceleration frequency: 3.639010 1/s
acceleration amplitude upper: 12.696526 m/s^2
acceleration amplitude lower: -9.314362 m/s^2
acceleration amplitude total: 22.010888 m/s^2
a counter: 10220
>> case_PwTrgrd_3. (stall starting-ending: 0.06-0.08 m, kspr=800000 N/m, rdh=0.07 m, kdmp=2000 N/(mps), porpoising triggered and continued)
spring preload: 0.015899 m
displacement frequency: 3.800836 1/s
amplitude upper: 0.094815 m
amplitude lower: 0.059010 m
amplitude total: 0.035805 m
y counter: 9803
acceleration frequency: 3.800836 1/s
acceleration amplitude upper: 14.493527 m/s^2
acceleration amplitude lower: -9.909946 m/s^2
acceleration amplitude total: 24.403473 m/s^2
a counter: 9685
>> case_PwTrgrd_4. (stall starting-ending: 0.06-0.08 m, kspr=800000 N/m, rdh=0.07 m, kdmp=3500 N/(mps), porpoising triggered and continued)
spring preload: 0.015727 m
iteration scheduled: 100000.000000
actual iteration: 100000
bottoming iteration: 0
displacement frequency: 3.957262 1/s
amplitude upper: 0.086191 m
amplitude lower: 0.059421 m
amplitude total: 0.026770 m
y counter: 8966
acceleration frequency: 3.957262 1/s
acceleration amplitude upper: 12.561485 m/s^2
acceleration amplitude lower: -11.092781 m/s^2
acceleration amplitude total: 23.654267 m/s^2
a counter: 8608
Comments
Post a Comment