pulse / vibration motor when abs is active ?

simhub shakeit has ABS effect. I don't know if it works in rF2, but Watever is amazing guy, he would answer your questions about that (try SH Discord). SH uses my plugin. Also, yes, rF2 does not expose ABS active flag, but I suspect you could derive that info (from speed dropping, brake input, wheel rotation speed, assuming rF2 simulates ABS properly). How I would go about it is I would plot wheel RPS using SH and see how graph looks like when ABS is engaged (available properites window).

that was the approach I was thinking, I can get the speed in rads/sec from your plugin :)

(I think Rf2 does simulate ABS - I can feel the pulsing in my motion sim when you brake very hard)
 
Hi Guys i have been making some progress - code is attached below for my Hello World App to talk to the memory map

there are some odd things happening


the first few variables are :

mID : integer ;// # slot ID (note that it can be re-used in multiplayer after someone leaves)
mDeltaTime : double ;// # time since last update (seconds)
mElapsedTime : double ;// # game session time
mLapNumber : integer ;// # current lap number
mLapStartET : double ;// # time this lap was started
mVehicleName : array[0..63] of byte ; // # current vehicle name
mTrackName : array[0..63] of byte ; // # current track name
mPos : rF2Vec3 ; // # world position in meters


should mID constantly change ? - the first 3 numbers seem to increment slowly but the last 3 are a bit random
mDeltaTime - this number seem to stay the same is it to do with a previous lap time ?
mElapsedTime - this number is jumping from a positive to a negative number
mLapNumber - seems to stay at zero
etc

the Vehicle name and track Name seem to be padded with random characters in front and behind that change

is this normal - or have I done something wrong ?

(the mpos for track position x,y,z seems ok for example)







------------------------------------------------------------------------------------------------------------------------



unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
BtnRead: TButton;
ListBox1: TListBox;
Timer1: TTimer;
Edit1: TEdit;
Edit2: TEdit;
Memo1: TMemo;
Memo2: TMemo;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
procedure Button1Click(Sender: TObject);
procedure BtnReadClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public




{ Public declarations }
end;


type
rF2Vec3 = Record
x : double ;
y : double ;
z : double ;
end ;

type
rF2Wheel = Record
mSuspensionDeflection : double ;// # meters
mRideHeight: double ;// # meters
mSuspForce : double ;// # pushrod load in Newtons
mBrakeTemp : double ;// # Celsius
mBrakePressure : double ;// # currently 0.0-1.0, depending on driver input and brake balance; will convert to true brake pressure (kPa) in future
mRotation : double ;// # radians/sec
mLateralPatchVel : double ;// # lateral velocity at contact patch
mLongitudinalPatchVel : double ;// # longitudinal velocity at contact patch
mLateralGroundVel : double ;// # lateral velocity at contact patch
mLongitudinalGroundVel : double ;// # longitudinal velocity at contact patch
mCamber : double ;// # radians (positive is left for left-side wheels, right for right-side wheels)
mLateralForce : double ; // # Newtons
mLongitudinalForce : double ; // # Newtons
mTireLoad : double ; // # Newtons
mGripFract : double ; // # an approximation of what fraction of the contact patch is sliding
mPressure : double ;// # kPa (tire pressure)
mTemperature : array[0..3] of double ; // # Kelvin (subtract 273.15 to get Celsius), left/center/right (not to be confused with inside/center/outside!)
mWear : double ; // # wear (0.0-1.0, fraction of maximum) ... this is not necessarily proportional with grip loss
mTerrainName : integer ; // # the material prefixes from the TDF file
mSurfaceType : byte ; // # 0=dry, 1=wet, 2=grass, 3=dirt, 4=gravel, 5=rumblestrip, 6 = special
mFlat : byte ;// # whether tire is flat
mDetached : byte ; // # whether wheel is detached
mStaticUndeflectedRadius : byte ;// # tire radius in centimeters
mVerticalTireDeflection : double ;// # how much is tire deflected from its (speed-sensitive) radius
mWheelYLocation : double ;// # wheel's y location relative to vehicle y location
mToe : double ;// # current toe angle w.r.t. the vehicle
mTireCarcassTemperature : double ;// # rough average of temperature samples from carcass (Kelvin)
mTireInnerLayerTemperature : array[0..3] of double ; // # rough average of temperature samples from innermost layer of rubber (before carcass) (Kelvin)
mExpansion : integer ;// # for future use
end;






type
PRecordInfo = ^TRecordInfo;
TRecordInfo = packed record
mID : integer ;// # slot ID (note that it can be re-used in multiplayer after someone leaves)
mDeltaTime : double ;// # time since last update (seconds)
mElapsedTime : double ;// # game session time
mLapNumber : integer ;// # current lap number
mLapStartET : double ;// # time this lap was started
mVehicleName : array[0..63] of byte ; // # current vehicle name
mTrackName : array[0..63] of byte ; // # current track name
mPos : rF2Vec3 ; // # world position in meters
mLocalVel : rF2Vec3 ; // # velocity (meters/sec) in local vehicle coordinates
mLocalAccel : rF2Vec3 ; // # acceleration (meters/sec^2) in local vehicle coordinates
mOri : array [0..2] of RF2Vec3 ; // , # rows of orientation matrix (use TelemQuat conversions if desired), also converts local
mLocalRot : rF2Vec3 ; // # rotation (radians/sec) in local vehicle coordinates
mLocalRotAccel : rF2Vec3 ; //), # rotational acceleration (radians/sec^2) in local vehicle coordinates
mGear : integer ; // # -1=reverse, 0=neutral, 1+ = forward gears
mEngineRPM : double ; // # engine RPM
mEngineWaterTemp : double ; // # Celsius
mEngineOilTemp : double ; // # Celsius
mClutchRPM : double ; // # clutch RPM
mUnfilteredThrottle : double ; // # ranges 0.0-1.0
mUnfilteredBrake : double ; // # ranges 0.0-1.0
mUnfilteredSteering : double ; // # ranges -1.0-1.0 (left to right)
mUnfilteredClutch : double ; // # ranges 0.0-1.0
mFilteredThrottle : double ; //
mFilteredBrake : double ;// # ranges 0.0-1.0
mFilteredSteering : double ; // # ranges -1.0-1.0 (left to right)
mFilteredClutch : double ; // # ranges 0.0-1.0
mSteeringShaftTorque : double ; // # torque around steering shaft (used to be mSteeringArmForce, but that is not necessarily accurate for feedback purposes)
mFront3rdDeflection : double ; // # deflection at front 3rd spring
mRear3rdDeflection : double ; // # deflection at rear 3rd spring
mFrontWingHeight : double ; // # front wing height
mFrontRideHeight : double ; // # front ride height
mRearRideHeight : double ; // # rear ride height
mDrag : double ; // # drag
mFrontDownforce : double ;// # front downforce
mRearDownforce : double ;// # rear downforce
mFuel : double ; // # amount of fuel (liters)
mEngineMaxRPM : double ; // # rev limit
mScheduledStops : byte ; // # number of scheduled pitstops
mOverheating : byte ; // # whether overheating icon is shown
mDetached : byte ; // # whether any parts (besides wheels) have been detached
mHeadlights :byte ; // # whether headlights are on
mDentSeverity : array [0..7] of integer ; // # dent severity at 8 locations around the car (0=none, 1=some, 2=more)
mLastImpactET : double ; // # time of last impact
mLastImpactMagnitude : double ; // # magnitude of last impact
mLastImpactPos : rF2Vec3 ; // # location of last impact
mEngineTorque : double ; // # current engine torque (including additive torque) (used to be mEngineTq, but there's little reason to abbreviate it)
mCurrentSector : integer ; // # the current sector (zero-based) with the pitlane stored in the sign bit (example: entering pits from third sector gives 0x80000002)
mSpeedLimiter : byte ; // # whether speed limiter is on
mMaxGears : byte ;// # maximum forward gears
mFrontTireCompoundIndex : integer ;// # index within brand
mRearTireCompoundIndex : integer ; // # index within brand
mFuelCapacity : double ;// # capacity in liters
mFrontFlapActivated : integer ;// # whether front flap is activated
mRearFlapActivated : integer ; // # whether rear flap is activated
mRearFlapLegalStatus : integer ; // # 0=disallowed, 1=criteria detected but not allowed quite yet, 2 = allowed
mIgnitionStarter : integer ; // # 0=off 1=ignition 2 = ignition+starter
mFrontTireCompoundName : array [0..17] of integer ; // # name of front tire compound
mRearTireCompoundName : array [0..17] of integer ; // # name of rear tire compound
mSpeedLimiterAvailable : integer ; // # whether speed limiter is available
mAntiStallActivated : integer ; // # whether (hard) anti-stall is activated
mUnused : integer ; // #
mVisualSteeringWheelRange : double ; // # the *visual* steering wheel range
mRearBrakeBias : double ; // # fraction of brakes on rear
mTurboBoostPressure : double ; // # current turbo boost pressure if available
mPhysicsToGraphicsOffset : array [0..2] of double ; // # offset from static CG to graphical center
mPhysicalSteeringWheelRange : double ; // # the *physical* steering wheel range
mExpansion : array [0..151] of integer ; // # for future use (note that the slot ID has been moved to mID above)
mWheels : array[0..3] of rF2Wheel ; // # wheel info (front left, front right, rear left, rear right)


end;




var
Form1: TForm1;

FMappingHandle : THandle = 0;
FRecordInfo : PRecordInfo= nil;
FMappingName : String = '$rFactor2SMMP_Telemetry$';




implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);


begin


//{ To Create a Mapping File }
//FMappingHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TRecordInfo), @FMappingName[1]);
//FRecordInfo := MapViewOfFile(FMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TRecordInfo));
//FRecordInfo.Field1 := 'Value 1';
//FRecordInfo.Field2 := 0;
//FRecordInfo.Field3 := 1;



end;

procedure TForm1.BtnReadClick(Sender: TObject);

var

I : integer ;
TempStr : String ;

begin

{ To Open the Memory Map File }
FMappingName := '$rFactor2SMMP_Telemetry$';
FMappingHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, false, @FMappingName[1]);

{ To Read the File Contents}
FRecordInfo := MapViewOfFile(FMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TRecordInfo));
//edit1.Text := FRecordInfo^.Field1;//Read the Contents
//edit2.Text := FRecordInfo^.Field2;//Read the Contents
//edit3.Text := FRecordInfo^.Field3;//Read the Contents


listbox1.Clear ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mID)) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mLapNumber)) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mGear)) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mScheduledStops)) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mOverheating)) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mDetached)) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mHeadlights)) ;
listbox1.Items.Add(char(FRecordInfo^.mDentSeverity[0])) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mCurrentSector)) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mSpeedLimiter)) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mMaxGears)) ;
listbox1.Items.Add(inttoStr(FRecordInfo^.mSpeedLimiterAvailable)) ;
listbox1.Items.Add(floattoStr(FRecordInfo^.mEngineWaterTemp)) ;
listbox1.Items.Add(floattoStr(FRecordInfo^.mEngineRPM)) ;



TempStr := '' ;
memo1.Text := '' ;

for I := 0 to 63 do
begin
TempStr := Char(FRecordInfo^.mVehicleName) ;
memo1.Text := Memo1.Text + char((FRecordInfo^.mVehicleName) );
end ;

Edit1.Text := TempStr ;


TempStr := '' ;
memo2.Text := '' ;

for I := 0 to 63 do
begin
TempStr := char(FRecordInfo^.mTrackName) ;
memo2.Text := Memo2.Text + char((FRecordInfo^.mTrackName) );
end ;

Edit2.Text := TempStr ;


edit3.Text := floattostr(FRecordInfo^.mpos.x);
edit4.text := floattoStr(FRecordInfo^.mpos.y);
edit5.text := floattoStr(FRecordInfo^.mpos.z);


end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
BtnRead.Click ;
end;

end.
 
i did not get a reply to my last post - so i hope a video might spark a reply

we are looking at the first few items of the memorymap

mID : integer ;// # slot ID (note that it can be re-used in multiplayer after someone leaves)
mDeltaTime : double ;// # time since last update (seconds)
mElapsedTime : double ;// # game session time
mLapNumber : integer ;// # current lap number
mLapStartET : double ;// # time this lap was started
mVehicleName : array[0..63] of byte ; // # current vehicle name
mTrackName : array[0..63] of byte ; // # current track name


pls take a look at the video to see what i am talking about

interestingly brake seems to come out as Engine rpm !

 
Last edited:
finally some progress !

by padding the memory map with an extra field of 8 bytes, the vehicle description and track name seem to line up and from that point forwards the data appears to correspond to the item it is supposed to be rpm etc etc

.......

pad1 : array[0..7] of byte ; //
mID : Integer ;// # slot ID (note that it can be re-used in multiplayer after someone leaves)
mDeltaTime : double ;// # time since last update (seconds)
mElapsedTime : double ;//
mLapNumber : Integer ;// # current lap number
mLapStartET : double ;// # time this lap was started
mVehicleName : array[0..63] of byte ; // # current vehicle name
mTrackName : array[0..63] of byte ; // # current track name
mPos : rF2Vec3 ; // # world position in meters
mLocalVel : rF2Vec3 ; // # velocity (meters/sec) in local vehicle coordinates
mLocalAccel : rF2Vec3 ; // # acceleration (meters/sec^2) in local vehicle coordinates
mOri : array [0..2] of RF2Vec3 ; // , # rows of orientation matrix (use TelemQuat conversions if desired), also converts local
mLocalRot : rF2Vec3 ; // # rotation (radians/sec) in local vehicle coordinates
mLocalRotAccel : rF2Vec3 ; //), # rotational acceleration (radians/sec^2) in local vehicle coordinates
mGear : integer ; // # -1=reverse, 0=neutral, 1+ = forward gears
mEngineRPM : double ; // # engine RPM
etc etc



so why did i have to add this pad to space the data out ??

I guess a delphi data type and a C++ data type are different in the number of bytes they use

Any suggestion ?
 
Back
Top