The online racing simulator
Detecting understeer/oversteer from RAF data
Hi,

After years of playing LFS, I've now started looking into the programming side of it.

For a vehicle dynamics class at uni I'm developing an algorithm to detect if a car is understeerin / oversteering. Something modern ABS and ESP system uses. For that I need the lateral acceleration and yaw speed.

In order to generate some data to test the algorithm I figured I could use LFS. I've started playing with the RAF files and the RAF-tyre-extract software. From that I've been able to extract the positions (X,Y,Z) and by differentiating the signal get velocities (thus the heading). After another differentiation I get the accelerations in the global coordinate system. By calculating a rotational transformation matrix using the angle between the heading and the global coordinate system, I can convert the global acceleration vector to a traditional long/lat acceleration vector.

However, I also need the to know the rotation around it's own axis (yaw speed). I've noticed how F1perfViewer can plot a "slip angle". Do anyone know how this is calculated? I also noticed in the RAF file format on the help LFS website how the heading can be calculating use trigonometry on the tire forces? Is the wheel always travelling in the same direction as described by the tire forces? Will that give me the heading in the global coordinate system?

I am doing all the calculations and plotting in MATLAB, and I import *.csv created in F1perfViewer and RAF-tyre-extractor. Unfortunatley I don't know how to go about and get the data straight from the RAF-file.

Any help or suggestions will be greatly appreciated!

I'm attaching some graphs I've been able to generate.
One is the track map with the color changing with the speed (can be any variable, lat acc, long acc, brake, throttle etc etc)
The other graph is just some estimations of the yaw speed and yaw acceleration using the trajectory change. Thus not telling me anything about oversteer and understeer.
Attached images
dataspels_data.jpg
map_speed.jpg
afaik for the slip angle, what you have to do is work out which direction the car is going with 2 consecutive positions and then calculate the angle between that and the forward vector
then you add the steer angle from the wheel info and you should get each wheels slip angle

for you purposes using outsim packages (/data/insim.txt somewhere down at the end) might be better
Ok, thanks!

The way I've been doing the position/velocity/acceleration determinations is by looking at two consecutive points and the time difference between them (typically 0.01 s in *.RAFs).

My question then is how do I determine the forward direction? I would personally like another position point on the car and thereby determining the forward direction of the car, is that possible? For instance the position of a wheel in comparison to the track reference point.
im not sure what you mean exactly since the raf output will give you a position vector and 2 vectors on the car that point forward and to the right
so what exactly is missing?
I'm sorry I wasn't very clear. I'm not able to open up the *.RAFs as they are (lack of programming skills), I need to rely on the RAF->CSV conversions done by F1perfview and RAFtyreextractor. From what I've seen none of the heading vectors are in there?

And yes, with those vectors I should be able to do what I want to do
The slipangle is defined in F1perfview, is it just the difference between the heading vector and the trajectory(x,y,z vel)?

The slip angle in F1perfview is the same for all wheels, thats what makes me draw that conclusion, am I right? In that case I could use the slip angle in combination with the trajectory to calculate the yaw speed. (Which is what you get from a gyro which is used by ESP/ABS systems).

S
might be ive never really worked with f1perfview

but i really do think that a outsim datalogger will be a quicker and more accurate solution to get the data youre looking for
The following page documents the RAF file format: http://www.lfs.net/?page=RAF. From that page, you can see that the RAF file contains three variables that denote the forward vector: FX, FY and FZ. The forward vector is a unit vector that points in the direction the car is pointing.

In Matlab you can work out the heading (in radians) by doing: heading = atan2(-FX, FY);

The rate of change is: rate = diff(heading) / sampling_period;


To read the FX and FY values from the RAF file you should look at the Matlab functions: fopen, fread and fseek. All of the byte offsets you need can be found in the page that I linked to above.

The command you need to read the FX and FY values from the file will look something like this: fx = fread(fid, 1, 'int16');

You just need to find the correct offsets in the file and use fseek to skip to them.


You might want to look at the other information that is stored in the RAF file. Some of it may be useful to you.
So, I've tried to get MATLAB to read straight from the RAF file, starting of easy by trying to read the throttle input (0-->1). Here's the code, but all I get is a really spikey/noisy plot that has a maximum of 10^38.

What am I doing wrong? I don't think I messed up the offsets (or did I?), steping the first 1024 steps to pass the static header block, then reading the first byte in the dynamic block, then steping another 192 steps (size of dynamic block), and then doing that till I reach the end of the file.

Help!



clear [FONT=Courier New][SIZE=2][COLOR=#a020f0]all
[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2][filename,pathname]=uigetfile([/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#a020f0]'C:\'[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2],[/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#a020f0]'Select RAF-file'[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2],[/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#a020f0]'*.raf'[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2]);
cd(pathname);
fid=fopen(filename);

status=fseek(fid,1024,-1); [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#228b22]%step 1024 steps from file start

[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2]counter=1;
[/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2] status==0;
t2(counter)= fread(fid,1,[/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#a020f0]'float'[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2]);
status=fseek(fid,192,0); [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#228b22]%step 192 steps from current position
[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2]counter=1+counter;
[/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff]end

[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2]plot(t2)
[/SIZE][/FONT]

#11 - w126
That's probably because fread() changes current position in the file and then you fseek() from that changed position, not from the beginning of a data block.
1) you forgot about the static wheel info block
2) fread increases the file pointer by 1
Ok, but in the fread(fid, X, 'float') the X stands for how many bytes it should read, so in the code I posted, it read 1 byte. So if instead step forward 191 steps, it would work?

I'm trying it now.

Ok, you were right. I changed my fseek to always count from the beginning of the file: 1024+192*counter, and it seems to work pretty nicely, I get numbers between 0 and 1.

Thanks a lot!
whoops forget about the static wheel info rubbish
fseek(,191,0) should work as well and save a bit of time
Just some more thoughts/questions here.

Since I'm pretty much have to redo what F1perfview did for me, I just want to confirm with you guys that I'm doing it the right way.

Lateral acceleration calc:
1) Get X force from all tires (forces to the right, positive sign)
2) Sum all these forces
3) Read total mass of car from header
4) F = m*a

So one question here, is the tire's X force in relation to the car heading or in relation to the where the tire is pointing. So do I need to take the steering angle of the (front) tire into account when calculating the force component that adds to the lateral forces?

Edit: I should also be able to simulate the use of two accelerometers (one on each axle) and use the static normal loads (Fz on tires) to detect over/understeer since I can look at the forces on the front and rear axles and then calculate the lateral accelerations on the each axle and then estimate the yaw rate. Thoughts/comments?
One more questions, anyone know which order the wheels come in the dynamic wheel info? I could figure it out by generating a new replay but since im on my laptop right now I dont have LFS. Cheers
#17 - w126
The forces in RAF are oriented alongside car body axes. However, most probably they are all not tyre forces, but the forces between the suspension and the wheels.
There is some discussion of RAF data in this thread http://www.lfsforum.net/showthread.php?t=4375 .
The order of wheel data is: FL, FR, RL, RR
Ok, it still means I could use it to calculate the lateral accelerations. I might even do a comparison with the differentiation of the position to see which one is better... Forces should be...

And, I guess right on the order of the wheels... yay

Once again, thanks a lot for the quick replies!
Quote from w126 :The order of wheel data is: FL, FR, RL, RR

Unfortunately, this is not true for all cars. For FWDs you get the rear wheels first (RL, RR, FL, FR). AWD cars are like RWDs.

The correct way to determine it is to read the X and Y position of each wheel from the static wheel info block. If X < 0 then it's a left wheel, if Y < 0 then it's a rear wheel.
#20 - w126
Oops, sorry, I guess I've never been interested enough in FWD cars.
So, I'm still having troubles with the lateral tire forces. The fronts won't go over zero. I think I'm measuring the longitudinal (RWD car). The offset I'm using:

1024 for header

192 for each timestep

64 for the car related logged data

32 for each wheel

12 to get to the lateral (righthand) tire force.

I've been staring at this for too long now

Any help is greatly appreciated!


status=fseek(fid,1024+192*(ii-1)+64+12,-1);
latF.LF(ii)=fread(fid,1,'float');

status=fseek(fid,1024+192*(ii-1)+64+32+12,-1);
latF.RF(ii)=fread(fid,1,'float');

status=fseek(fid,1024+192*(ii-1)+64+32+32+12,-1);
latF.LR(ii)=fread(fid,1,'float');

status=fseek(fid,1024+192*(ii-1)+64+32+32+32+12,-1);
latF.RR(ii)=fread(fid,1,'float');
Here's a plot of the tire forces I'm getting (with the above code). Doesn't look like lateral forces to me?
Attached images
tireforces.jpg
#23 - w126
There is a mistake in this part of RAF spec, just notice the strange order of offsets. The above code reads forward (Y) forces. Use the offset of 8 inside dynamic wheel info block to get X forces.
Hmm...

In the RAF format docs it says
1 float 0 suspension deflect : compression from unloaded
1 float 4 steer : including Ackermann and toe
1 float 12 X force : force right
1 float 16 Y force : force forward
1 float 8 vertical load : perpendicular to surface

(Why are the fields out of sequence?)

LRA, my replay analyser, reads the data in the order
0 suspension deflect
4 steer
8 lateral force
12 longitudinal force
16 tyre load

So the lateral force should be at offset 8. At offset 12 you'll find the longitudinal force.
If you load the file into F1PerfView or LRA you can check for yourself. Or you can post your RAF file here.

EDIT: Beaten by w126!
Alright, thanks a lot!

wsinda, while your here, do you use the tire forces to calculate lateral acceleration? Or what is your approach?

Doing that would give the acceleration perpendicular to the heading, so with a car slip angle (not tyre slip angle), the lat acc calculated would not be as big as the lat acc of the CG. Instead you would see a component in the long direction.

On real race cars this is the case (with an accelerometer mounted), so that's why I'm planning to use it.

The other option of differentiating the position data, will probably give a lot of noise due to the slow sampling rate.

Once again, thanks a lot. Do Scawen or the other programmers know about the error in the RAF description?
1

Detecting understeer/oversteer from RAF data
(28 posts, started )
FGED GREDG RDFGDR GSFDG