pulse / vibration motor when abs is active ?

Discussion in 'Plugins' started by Gadget11, Feb 28, 2021.

  1. Gadget11

    Gadget11 Registered

    Joined:
    Jun 17, 2016
    Messages:
    82
    Likes Received:
    14
    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)
     
    The Iron Wolf likes this.
  2. Gadget11

    Gadget11 Registered

    Joined:
    Jun 17, 2016
    Messages:
    82
    Likes Received:
    14
    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.
     
  3. Gadget11

    Gadget11 Registered

    Joined:
    Jun 17, 2016
    Messages:
    82
    Likes Received:
    14
    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: Mar 9, 2021
  4. Gadget11

    Gadget11 Registered

    Joined:
    Jun 17, 2016
    Messages:
    82
    Likes Received:
    14
    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 ?
     

Share This Page