Other F1 2018 (PS/4) - UDP-Capture - Share my Code and request for help

DonManfred

Expert
Licensed User
Longtime User
This is a Example of Capturing UDP-Packets which comes from a PS/4 game while doing a race.
It is using RandomAccessfile to parse the Different UDP-Packets.

You can find the UDP-Specifications here.
Each of the described UDP-Packets are parsed by the Class into different CustomTypes and holding two Global Maps.

B4X:
    Public glData As Map
    Public RaceDriverMap As Map

glData: This Map contains a Live capture of the active Session.
There is a Session key which holds Information about the Session itself.

And for each driver in the race there is a Map with all additional infos about this Driver/Car.
All the Carsetup-Infos, Car-Status, Car Telemetry Data, Raceposition, best lap time and so on.

RaceDriverMap: Holds a Map for each RaceDriver(customtype). This map is used to get all drivers, sort them by Position (in the race) using list.sorttype and then update the Table in the other window.



It seems that is does work fine with local games captured... It is me who is playing the game on my Playstation.

But i fear it does not work correctly with a Online Race. Basically one should be able to recognize a driver with the given Grid-Position. It should not change while in session.

---- Setup PS/4 - F1 2018 Settings ------
- In the Game you need to go to the game settings. Here you find a Telemetry setting



Use the IP from your PC running the B4J Project.
- Port 20777
- UDP-Format should be set to 2018


I´m not sure if everything is working as expected ;-)

Dependencies:
- It is only interesting if you own the Codemasters Game F1 2018 for your Playstation.
- It may be possible to use it in the PC-Version of the Game too.
- You must have configured the game to send the UDP Telemetry Data to your PC.

What i did not understand as of now (need help with it).
- I get in the Data all drivers WorldPositionX/Y/Z
The values ranged from -xxx.xxxx to +xxx.xxxx
and i´m wondering if i could "paint" the position on a Canvas but i´m not able to convert the positions into a canvas position to draw something like a track.
Unfortunately i do not have any Trackgraphics which i could use. Also if i had them; i still needed to underastand how to convert the WorldPositions to a Bitmap-Pixelposition.
For ex:
B4X:
 SELECT max( `live_worldPositionX` ) AS maxX, max( `live_worldPositionY` ) AS maxY, max( `live_worldPositionZ` ) AS maxZ, min( `live_worldPositionX` ) AS minX, min( `live_worldPositionY` ) AS minY, min( `live_worldPositionZ` ) AS minZ
FROM `f1_live_data`
WHERE `live_sessionID` =458
results in

maxX maxY maxZ minX minY minZ
1022.2056 3.7142 1047.0760 -819.6987 -143.0191 -603.8157

Any help rthis regarding is higly appreciated. I´m doing this project for a friend.

Feel free to play with the tool. If you find any problem and know a Fix for it. Post the fix so anyone can apply them.

Have fun!
 

Attachments

  • F12018udpEx.zip
    47.2 KB · Views: 477
Last edited:

Daestrum

Expert
Licensed User
Longtime User
Looking at the IDE image you posted, you already have the x,y,z position of each car.

I would guess the 2 values you need are the x and z, as I suspect the y value would be the altitude of the vehicle, as it is in 3D.

I don't understand why you get the max and min values, if the data is from all 20 cars, then you are calculating a 3D volume that contains all the cars, which I suspect is not what you want.

I would try using the x and z values (scaled down) from only one car and plot them on a canvas to see if they produce a track type path.

I do not have PS4 so cannot try it.

If you could save the output of the position from a single car (similar to what is shown in the IDE image) for a lap, I will have a play with it and see if I can work out exactly which values to use, and how to translate them to plot on a canvas.
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Looking at the IDE image you posted, you already have the x,y,z position of each car.
yes
if the data is from all 20 cars, then you are calculating a 3D volume that contains all the cars, which I suspect is not what you want.
the min and max are just to find out what are the minimum and maximum values i have captured during one race on one track.
So i did expect them to give me infos about the bounds somehow.
I would try using the x and z values (scaled down)
This is what i do not understand how to do that. I´m not familar with such calculations. That´s why i am asking for help
If you could save the output of the position from a single car (similar to what is shown in the IDE image) for a lap, I will have a play with it and see if I can work out exactly which values to use, and how to translate them to plot on a canvas.
I´ll try to do some queries on the database to find the results you want and export them for you.

With this DB-Dump download you can, if you want, insert all Data in your local mysql-Database

Using a SQL like
B4X:
SELECT `live_worldPositionX`,`live_worldPositionY`,`live_worldPositionZ` FROM `f1_live_data` WHERE `live_sessionID` = 458 and live_driverID=58 ORDER by live_timestamp ASC
Should give you all the entries from one driver in one event in order of occurence during the race.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
It was the x and z values you need to use.
I simply scaled them down by a factor of 5, this gave a 'sensible' sized plot.

This was the code I used (it can plot in 3d or onto a canvas) but shows the mechanics.
B4X:
Sub Process_Globals
 Private fx As JFX
 Private MainForm As Form
 Dim c As Canvas
 Dim c1 As Canvas
End Sub
Sub AppStart (Form1 As Form, Args() As String)
 MainForm = Form1
 MainForm.Show
 c.Initialize("can")
 MainForm.RootPane.AddNode(c,0,0,1600,900)
 c1.Initialize("can1")
 MainForm.RootPane.AddNode(c1,-39,98,600,600) 'canvas over map for drawing on
'canvas for the map image 
c.DrawImage(fx.LoadImage("c:/temp","circuit-mel.png"),216,282,412,234) ' track
 ' cba to use a database so I just read txt the file
 Dim tr As TextReader
 tr.Initialize(File.OpenInput("c:/temp","f1livedata.txt"))
 Dim data As List
 data = tr.ReadList
 tr.Close
 Dim drawmode As JavaObject
 Dim group As JavaObject
 Dim point3D As JavaObject
 point3D.InitializeNewInstance("javafx.geometry.Point3D",Array(0.0,0.0,1.0))
 group.InitializeNewInstance("javafx.scene.Group",Null)
 drawmode.InitializeStatic("javafx.scene.shape.DrawMode")
 ' have to rotate the group to make it horozontal
 group.RunMethod("setRotationAxis",Array(point3D))
 group.RunMethod("setRotate",Array(-44.00))
 ' rotate the top canvas so it matches the map
 asJO(c1).RunMethod("setRotate",Array(-44.00))
 'MainForm.RootPane.AddNode(group,0,0,2000,2000) ' enable for 3d sphere on map
 For Each item As String In data
  ' the file contained all drivers so I just chose one to plot
  ' data lines start with (
  If item.StartsWith("(") And item.Contains("VETTEL") Then
   Dim posData() As String = Regex.Split(",",item) 
   Dim scale As Double = 5.0
   ' 400 added to put near center of screen
   Dim x As Double = 400+posData(63)/scale
   Dim y As Double = 400+posData(64)/scale
   Dim z As Double = 400+posData(65)/scale
   ' the next few lines are for the 3d plotting
   Dim ob As JavaObject
   ob.InitializeNewInstance("javafx.scene.shape.Sphere",Array(5.0))
   ob.RunMethod("setDrawMode",Array(drawmode.GetField("FILL")))
   ob.RunMethod("setTranslateX",Array(x))
   ob.RunMethod("setTranslateY",Array(z)) '<< notice z is used as y coord
   ob.RunMethod("setTranslateZ",Array(y))
   ' end of 3d plot stuff
   group.RunMethodJO("getChildren",Null).RunMethod("add",Array(ob))
   c1.DrawCircle(x,z,3,fx.Colors.cyan,True,1.0) ' again z used as y coord
   Log($"x ${x} y ${y} z ${z}"$)
  End If
 Next
End Sub
Sub asJO(o As JavaObject)As JavaObject
 Return o
End Sub
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Thank you very much for your code... It gives me mechanics and i´m able to adapt a Trackgraphic to show it right under the driver locations. (x/w/w/h/rotation)

This was the code I used (it can plot in 3d or onto a canvas) but shows the mechanics.
I´ve removed the 3D Plotting code and only using the Canvas.

I fear i need to understand how to work with Canvas. It does not be cleared.
while in a race i only want to show each driver position ONCE on a Track.


B4X:
Sub UpdateDriverList(drList As List, driverspec As RaceDriver)
   
    ' Trying to "clear" the Canvas.
    track.c.DrawRect(0,0,track.c.Width,track.c.Height,cnvx.GetPaint("blue"),True,1)
    track.c.DrawImageRotated(track.trimg,track.trackx,track.tracky,track.trackw,track.trackh,track.trackrot)

    For o = 0 To drList.Size-1
        Dim driver As RaceDriver = drList.Get(o)
        Dim scale As Double = 4.0
        ' 400 added to put near center of screen
        Dim x As Double = 400+driver.PosX/scale
        Dim y As Double = 400+driver.PosY/scale
        Dim z As Double = 400+driver.PosZ/scale
        track.c1.DrawCircle(x,z,3,fx.Colors.ARGB(255,Rnd(20, 255),Rnd(80, 160),Rnd(161, 255)),True,1.0) ' again z used as y coord
        Log($"x ${x} y ${y} z ${z}"$)

    Next

End Sub

UpdateDriverList is called repeatly while in a race (around 2 times in a second). It should draw the 20 Positions of the driver. But only once on the map.

As of now it results in something like


So, the old positions of all drivers are still on the Canvas :-(
 
Last edited:
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
nice project.
my idea for this long ago was to make a help for brake and maximum speed at corners. (computer aided driving at limit)
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
thes idea here is more that the tool does capture the UDP Packets and Upload the data to our Database hosted online. And then to be able to show the "live" Racestandings on the website. The showing there is just a moment-capture... But during the race it was live somehow...
In the Captureclass i am using a timer with 2500ms. In this timer i do a complete upload of all the data into the Database.

B4X:
Sub GobalTimer_Tick
    'osglobal = File.OpenOutput(File.DirApp,"UDP_Globals.LOG",True)
    Dim timestamp As Long = DateTime.Now
   
    Log($"GobalTimer_Tick($date{timestamp} $time{timestamp})"$)
    If mglData.ContainsKey("Session") Then
        Dim sessmap As Map = mglData.Get("Session")
        If sessmap.ContainsKey("SessionPKT") Then
            Dim sess As pktSession = sessmap.Get("SessionPKT")
            'Log($"GobalTimer_Tick(${sess})"$)

            'MZStart_1
            'MZFlag_1
            'Log(timestamp)
            mdb.ExecNonQuery2($"INSERT INTO f1_live_session
            SET sess_timestamp=?,
            sess_sessionID=?,
            sess_uuid=?,
            sess_Weather=?,
            sess_AirTemperature=?,
            sess_Era=?,
            sess_GamePaused=?,
            sess_IsSpectating=?,
            sess_NetworkGame=?,
            sess_NumMarshalZones=?,
            sess_PitSpeedLimit=?,
            sess_safetyCarStatus=?,
            sess_SessionDuration=?,
            sess_SessionTimeLeft=?,
            sess_SessionType=?,
            sess_sliProNativeSupport=?,
            sess_SpectatorCarIndex=?,
            sess_TotalLaps=?,
            sess_TrackID=?,
            sess_TrackLength=?,
            sess_TrackTemperature=?,
            sess_MZStart1=?,
            sess_MZFlag1=?,
            sess_MZStart2=?,
            sess_MZFlag2=?,
            sess_MZStart3=?,
            sess_MZFlag3=?,
            sess_MZStart4=?,
            sess_MZFlag4=?,
            sess_MZStart5=?,
            sess_MZFlag5=?,
            sess_MZStart6=?,
            sess_MZFlag6=?,
            sess_MZStart7=?,
            sess_MZFlag7=?,
            sess_MZStart8=?,
            sess_MZFlag8=?,
            sess_MZStart9=?,
            sess_MZFlag9=?,
            sess_MZStart10=?,
            sess_MZFlag10=?,
            sess_MZStart11=?,
            sess_MZFlag11=?,
            sess_MZStart12=?,
            sess_MZFlag12=?,
            sess_MZStart13=?,
            sess_MZFlag13=?,
            sess_MZStart14=?,
            sess_MZFlag14=?,
            sess_MZStart15=?,
            sess_MZFlag15=?,
            sess_MZStart16=?,
            sess_MZFlag16=?,
            sess_MZStart17=?,
            sess_MZFlag17=?,
            sess_MZStart18=?,
            sess_MZFlag18=?,
            sess_MZStart19=?,
            sess_MZFlag19=?,
            sess_MZStart20=?,
            sess_MZFlag20=?
            "$, Array As Object(timestamp, mRaceID, sessmap.Get("SessionUUID"), Weather(sess.Weather), sess.AirTemperature, sess.Era, sess.GamePaused, sess.IsSpectating, sess.NetworkGame, sess.NumMarshalZones, sess.PitSpeedLimit, sess.safetyCarStatus, sess.SessionDuration, sess.SessionTimeLeft, SessionType(sess.SessionType), sess.sliProNativeSupport, sess.SpectatorCarIndex, sess.TotalLaps, sess.TrackID, sess.TrackLength, sess.TrackTemperature, sessmap.Get("MZStart_1"), sessmap.Get("MZFlag_1"), sessmap.Get("MZStart_2"), sessmap.Get("MZFlag_2"), sessmap.Get("MZStart_3"), sessmap.Get("MZFlag_3"), sessmap.Get("MZStart_4"), sessmap.Get("MZFlag_4"), sessmap.Get("MZStart_5"), sessmap.Get("MZFlag_5"), sessmap.Get("MZStart_6"), sessmap.Get("MZFlag_6"), sessmap.Get("MZStart_7"), sessmap.Get("MZFlag_7"), sessmap.Get("MZStart_8"), sessmap.Get("MZFlag_8"), sessmap.Get("MZStart_8"), sessmap.Get("MZFlag_9"), sessmap.Get("MZStart_10"), sessmap.Get("MZFlag_10"), sessmap.Get("MZStart_11"), sessmap.Get("MZFlag_11"), sessmap.Get("MZStart_12"), sessmap.Get("MZFlag_12"), sessmap.Get("MZStart_13"), sessmap.Get("MZFlag_13"), sessmap.Get("MZStart_14"), sessmap.Get("MZFlag_14"), sessmap.Get("MZStart_15"), sessmap.Get("MZFlag_15"), sessmap.Get("MZStart_16"), sessmap.Get("MZFlag_16"), sessmap.Get("MZStart_17"), sessmap.Get("MZFlag_17"), sessmap.Get("MZStart_18"), sessmap.Get("MZFlag_18"), sessmap.Get("MZStart_19"), sessmap.Get("MZFlag_19"), sessmap.Get("MZStart_20"), sessmap.Get("MZFlag_20") ))
        End If
        '
    End If

    For i= 0 To 19
        Dim m As Map = mglData.Get("Driver"&i)
        If m.IsInitialized Then
            If m.ContainsKey("CarMotionPKT") Then
                'Log("CarMotionPKT gefunden")
            Else
                'Log("CarMotionPKT FEHLT!!")
            End If
            If m.ContainsKey("LapDataPKT") Then
                'Log("LapDataPKT gefunden")
            Else
                Log("LapDataPKT FEHLT!!")
            End If
            If m.ContainsKey("ParticipantPKT") Then
                'Log("ParticipantPKT gefunden")
            Else
                'Log("ParticipantPKT FEHLT!!")
            End If
            If m.ContainsKey("CarSetupPKT") Then
                'Log("CarSetupPKT gefunden")
            Else
                'Log("CarSetupPKT FEHLT!!")
            End If
            If m.ContainsKey("CarTelemetryPKT") Then
            If m.ContainsKey("CarTelemetryPKT") Then
                'Log("CarTelemetryPKT gefunden")
            Else
                'Log("CarTelemetryPKT FEHLT!!")
            End If
            If m.ContainsKey("CarStatusPKT") Then
                'Log("CarStatusPKT gefunden")
            Else
                'Log("CarStatusPKT FEHLT!!")
            End If

            If m.ContainsKey("CarMotionPKT") And m.ContainsKey("LapDataPKT") And m.ContainsKey("ParticipantPKT") And m.ContainsKey("CarSetupPKT")And m.ContainsKey("CarTelemetryPKT") And m.ContainsKey("CarStatusPKT") Then
                Dim motion As CarMotion = m.Get("CarMotionPKT")
                Dim lapdata As pktLapData = m.Get("LapDataPKT")
                Dim part As  pktParticipant = m.Get("ParticipantPKT")
                Dim setup As  CarSetup = m.Get("CarSetupPKT")
                Dim telemtry As CarTelemetry = m.Get("CarTelemetryPKT")
                Dim status As CarStatus = m.Get("CarStatusPKT")
                mdb.ExecNonQuery2($"INSERT INTO f1_live_data SET
                live_uuid=?, live_timestamp=?, live_sessionID=?,
                live_DriverID=?, live_AIControlled=?, live_Name=?, live_Nationality=?, live_raceNumber=?,
                live_TeamID=?, live_Ballast=?, live_brakeBias=?, live_brakePressure=?, live_frontAntiRollBar=?,
                live_frontCamber=?, live_frontSuspension=?, live_frontSuspensionHeight=?, live_frontToe=?,
                live_frontTyrePressure=?, live_frontWing=?, live_rearAntiRollBar=?, live_rearCamber=?,
                live_rearSuspension=?, live_rearSuspensionHeight=?, live_rearToe=?, live_rearTyrePressure=?,
                live_rearWing=?, live_fuelLoad=?, live_offThrottle=?, live_onThrottle=?, live_bestLapTime=?,
                live_carPosition=?, live_currentLapInvalid=?, live_currentLapNum=?, live_currentLapTime=?,
                live_driverStatus=?, live_gridPosition=?, live_lapDistance=?, live_lastLapTime=?, live_penalties=?,
                live_pitStatus=?, live_resultStatus=?, live_safetyCarDelta=?, live_Sector=?,
                live_sector1Time=?, live_sector2Time=?, live_totalDistance=?, live_Pitch=?,
                live_Roll=?, live_worldPositionX=?, live_worldPositionY=?, live_worldPositionZ=?,
                live_gForceLateral=?, live_gForceLongitudinal=?, live_gForceVertical=?,
                live_worldForwardDirX=?, live_worldForwardDirY=?, live_worldForwardDirZ=?,
                live_worldRightDirX=?, live_worldRightDirY=?, live_worldRightDirZ=?,
                live_worldVelocityX=?, live_worldVelocityY=?, live_worldVelocityZ=?,
                live_yaw=?, live_Brake=?,
                live_brakesTemperature1=?, live_brakesTemperature2=?,  live_brakesTemperature3=?, live_brakesTemperature4=?,
                live_Clutch=?, live_drs=?, live_engineRPM=?, live_engineTemperature=?,
                live_Gear=?, live_revLightsPercent=?, live_Speed=?, live_Steer=?, live_throttle=?,
                live_antiLockBrakes=?, live_drsAllowed=?, live_engineDamage=?,
                live_ersDeployedThisLap=?, live_ersDeployMode=?,
                live_ersHarvestedThisLapMGUH=?, live_ersHarvestedThisLapMGUK=?, live_ersStoreEnergy=?,
                live_exhaustDamage=?, live_frontBrakeBias=?, live_frontLeftWingDamage=?, live_frontRightWingDamage=?,
                live_fuelCapacity=?, live_fuelInTank=?, live_fuelMix=?, live_gearBoxDamage=?, live_idleRPM=?,
                live_maxGears=?, live_maxRPM=?, live_pitLimiterStatus=?, live_rearWingDamage=?,
                live_tractionControl=?, live_tyreCompound=?,
                live_tyresDamage1=?, live_tyresDamage2=?, live_tyresDamage3=?, live_tyresDamage4=?,
                live_tyresWear1=?, live_tyresWear2=?, live_tyresWear3=?, live_tyresWear4=?, live_vehicleFiaFlags=?, live_sector1TimeF=?, live_sector2TimeF=?, live_currentLapTimeF=?, live_lastLapTimeF=?, live_bestLapTimeF=?"$, Array As Object(sessmap.Get("SessionUUID"),timestamp, mRaceID, part.DriverID, part.AIControlled, part.Name, part.Nationality, part.raceNumber, part.TeamID, setup.ballast, setup.brakeBias, setup.brakePressure, setup.frontAntiRollBar, setup.frontCamber, setup.frontSuspension, setup.frontSuspensionHeight, setup.frontToe, setup.frontTyrePressure, setup.frontWing, setup.rearAntiRollBar, setup.rearCamber, setup.rearSuspension, setup.rearSuspensionHeight, setup.rearToe, setup.rearTyrePressure, setup.rearWing, setup.fuelLoad, setup.offThrottle, setup.onThrottle, lapdata.bestLapTime, lapdata.carPosition, lapdata.currentLapInvalid, lapdata.currentLapNum, lapdata.currentLapTime, driverStatus(lapdata.driverStatus), lapdata.gridPosition, lapdata.lapDistance, lapdata.lastLapTime, lapdata.penalties, PitStatus(lapdata.PitStatus), ResultStatus(lapdata.ResultStatus),    lapdata.safetyCarDelta, lapdata.sector, lapdata.sector1Time, lapdata.sector2Time, lapdata.totalDistance,motion.Pitch, motion.Roll,     motion.worldPositionX, motion.worldPositionY, motion.worldPositionZ, motion.gForceLateral, motion.gForceLongitudinal, motion.gForceVertical, motion.worldForwardDirX, motion.worldForwardDirY, motion.worldForwardDirZ, motion.worldRightDirX, motion.worldRightDirY, motion.worldRightDirZ, motion.worldVelocityX, motion.worldVelocityY, motion.worldVelocityZ, motion.yaw, telemtry.Brake, telemtry.brakesTemperature(0), telemtry.brakesTemperature(1), telemtry.brakesTemperature(2), telemtry.brakesTemperature(3), telemtry.Clutch, telemtry.drs, telemtry.engineRPM, telemtry.engineTemperature, telemtry.Gear, telemtry.revLightsPercent, telemtry.Speed, telemtry.Steer, telemtry.throttle, status.antiLockBrakes, status.drsAllowed, status.engineDamage, status.ersDeployedThisLap, status.ersDeployMode, status.ersHarvestedThisLapMGUH, status.ersHarvestedThisLapMGUK, status.ersStoreEnergy, status.exhaustDamage, status.frontBrakeBias, status.frontLeftWingDamage, status.frontRightWingDamage, status.fuelCapacity, status.fuelInTank, FuelMix(status.fuelMix), status.gearBoxDamage, status.idleRPM, status.maxGears, status.maxRPM, status.pitLimiterStatus, status.rearWingDamage, status.tractionControl, TyreCompound(status.TyreCompound), status.tyresDamage1, status.tyresDamage2, status.tyresDamage3, status.tyresDamage4, status.tyresWear1, status.tyresWear2, status.tyresWear3, status.tyresWear4, status.vehicleFiaFlags, m.Get("sector1TimeF"), m.Get("sector2TimeF"),m.Get("currentLapTimeF"),m.Get("lastLapTimeF"),m.Get("bestLapTimeF")))
            End If
        End If
        End If
    Next

End Sub

NOW, with the new addition of the generating the Graphic with the live positions of the driver on the track. I´ll upload a PNG with the Trackview to the webspace too.

We buyed a Adobe Stock .AI Document with all the Tracks. My friend is just doing to extracting the Tracks into single Documents to build the needed PNGs for all Tracks needed.

I´ll keep you informed about Updates
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
In GPS coords, normally X & Y are lat & lon & Z is elevation (altitude).

- Colin.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
Perhaps the issue has been resolved, but let me add the following, as I believe it offers a more general approach:

Using a mapping application API (many available), you can download a racing track or any other shape on a static map with its geographic bounds. If you have gps coordinates of any location within those bounds, you can show the position of that location on a canvas over the static map.

The easiest use, of course, would be to position yourself on that map using your device's GPS (or Google's location services). If you ran a server to receive and relay geographic coordinates, you could have a multi-participant game.

Before incorporating Leaflet and Slippy Maps into my first B4A project a few years back, I was able to follow myself around various cities I was visiting by plotting my current location on static maps of those cities. It's still useful today as a lightweight, offline positioning aid, even though mapping companies like Google have finally caught up to me and now offer similar offline solutions. But I'm not bitter...

The formulae needed to convert geographic X/Y coordinates to pixels on a bitmap are available and easily translated to B4A. I don't know if there is any interest in this, as the responses to Donmanfred's problem were specific to it. But since there was the slightest hint of how some of the techniques needed to solve his situation can be used elsewhere, I wanted to mention that the information needed to perform those calculations is out there, should it have occurred to someone that racetracks were not the only background possible for some type of group participation
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
The easiest use, of course, would be to position yourself on that map using your device's GPS (or Google's location services). If you ran a server to receive and relay geographic coordinates, you could have a multi-participant game.
How does the GPS Object help here? I do NOT have GPS-Positions of the drivers. MY GPS Position is not relevant. I´m living in germany. and the race is for example in Monaco. How can my GPS Position help to show my position on the Monaco track? My GPS position is not relevant here. <- It does not change while racing. It is even the same position if i race on Monaco and also the same position if i race in Silverstone or Brazil or Hungary (or any other Trsck).
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
GPS is for the real world, in a 3D world x is width, z is depth and y is height.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User

your gps position is definitely irrelevant. i hope i didn't imply otherwise.

my comments were meant to show that a static map of a racetrack could be extended to a static map of anything in the world and a dot (or dots) positioned correctly on that map using similar techniques. if someone were interested in that, but not sure how to proceed , the required formulae for calculating such positions are available and can be used in B4A, not just in a gaming box.

but thanks for the inspiration!
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Snapshot from within a race. Each driver is one black point.



How we did it.

We did a race on each track with a blank canvas. Each position of the drivers are pointed and the canvas was not cleared.

At the end we had an image like this

from each track. Here Abu Dhabi. Based on this we did a Document in Adobe Illustrator (finetuning). And then an export for the new Graphic which is now used to get painted on the canvas too. But now only one point is made for each driver.
 
Last edited:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…