1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Added F1 2017 mapping

This commit is contained in:
SpoinkyNL 2017-10-15 15:57:40 +02:00
parent 0eda28424f
commit 53b88be937
2 changed files with 271 additions and 69 deletions

View File

@ -1,4 +1,5 @@
using System.Runtime.InteropServices;
using System;
using System.Runtime.InteropServices;
using Artemis.Modules.Abstract;
using MoonSharp.Interpreter;
@ -21,14 +22,14 @@ namespace Artemis.Modules.Games.FormulaOne2017
[StructLayout(LayoutKind.Sequential)]
public struct UdpPacketData
{
public float m_time; // Total seconds driven from start line
public float m_lapTime; // Total seconds of current lap
public float m_lapDistance; // Total distance through lap in meters
public float m_totalDistance; // Total distance driven from start line
public float m_x; // World space position
public float m_y; // World space position
public float m_z; // World space position
public float m_speed; // Meters/sec
public float m_time;
public float m_lapTime;
public float m_lapDistance;
public float m_totalDistance;
public float m_x; // World space position
public float m_y; // World space position
public float m_z; // World space position
public float m_speed; // Speed of car in MPH
public float m_xv; // Velocity in world space
public float m_yv; // Velocity in world space
public float m_zv; // Velocity in world space
@ -38,58 +39,122 @@ namespace Artemis.Modules.Games.FormulaOne2017
public float m_xd; // World space forward direction
public float m_yd; // World space forward direction
public float m_zd; // World space forward direction
public float m_susp_pos_bl; //
public float m_susp_pos_br; //
public float m_susp_pos_fl; //
public float m_susp_pos_fr; //
public float m_susp_vel_bl; //
public float m_susp_vel_br; //
public float m_susp_vel_fl; //
public float m_susp_vel_fr; //
public float m_wheel_speed_bl; //
public float m_wheel_speed_br; //
public float m_wheel_speed_fl; //
public float m_wheel_speed_fr; //
public float m_throttle; // Throttle input
public float m_steer; // Steering input (-1 left to +1 right)
public float m_brake; // Brake input
public float m_clutch; // Clutch input
public float m_gear; // 0 - R | 1 - N | 2-9 - 1-8
public float m_gforce_lat; // Lateral G's
public float m_gforce_lon; // Longiitude G's
public float m_lap; // Current lap number
public float m_engineRate; // Engine RPM
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public float[] m_susp_pos; // Note: All wheel arrays have the order:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public float[] m_susp_vel; // RL, RR, FL, FR
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public float[] m_wheel_speed;
public float m_throttle;
public float m_steer;
public float m_brake;
public float m_clutch;
public float m_gear;
public float m_gforce_lat;
public float m_gforce_lon;
public float m_lap;
public float m_engineRate;
public float m_sli_pro_native_support; // SLI Pro support
public float m_car_position; // car race position
public float m_car_position; // car race position
public float m_kers_level; // kers energy left
public float m_kers_max_level; // kers maximum energy
public float m_drs; // 0 = off, 1 = on
public float m_traction_control; // 0 (off) - 2 (high)
public float m_anti_lock_brakes; // 0 (off) - 1 (on)
public float m_fuel_in_tank; // current fuel mass
public float m_fuel_capacity; // fuel capacity
public float m_in_pits; // 0 = none, 1 = pitting, 2 = in pit area
public float m_sector; // 0 = sector1, 1 = sector2; 2 = sector3
public float m_sector1_time; // time of sector1 (or 0)
public float m_sector2_time; // time of sector2 (or 0)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public float[] m_brakes_temp; // brakes temperature (centigrade)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public float[] m_wheels_pressure; // wheels pressure PSI
public float m_team_info; // team ID
public float m_drs; // 0 = off, 1 = on
public float m_traction_control; // 0 (off) - 2 (high)
public float m_anti_lock_brakes; // 0 (off) - 1 (on)
public float m_fuel_in_tank; // current fuel mass
public float m_fuel_capacity; // fuel capacity
public float m_in_pits; // 0 = none, 1 = pitting, 2 = in pit area
public float m_sector; // 0 = sector1, 1 = sector2, 2 = sector3
public float m_sector1_time; // time of sector1 (or 0)
public float m_sector2_time; // time of sector2 (or 0)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public float[] m_brakes_temp; // brakes temperature (centigrade)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public float[] m_tyres_pressure; // tyres pressure PSI
public float m_team_info; // team ID
public float m_total_laps; // total number of laps in this race
public float m_track_size; // track size meters
public float m_last_lap_time; // last lap time
public float m_max_rpm; // cars max RPM, at which point the rev limiter will kick in
public float m_idle_rpm; // cars idle RPM
public float m_max_gears; // maximum number of gears
public float m_sessionType; // 0 = unknown, 1 = practice, 2 = qualifying, 3 = race
public float m_last_lap_time; // last lap time
public float m_max_rpm; // cars max RPM, at which point the rev limiter will kick in
public float m_idle_rpm; // cars idle RPM
public float m_max_gears; // maximum number of gears
public float m_sessionType; // 0 = unknown, 1 = practice, 2 = qualifying, 3 = race
public float m_drsAllowed; // 0 = not allowed, 1 = allowed, -1 = invalid / unknown
public float m_track_number; // -1 for unknown, 0-21 for tracks
public float m_vehicleFIAFlags; // -1 = invalid/unknown, 0 = none, 1 = green, 2 = blue, 3 = yellow, 4 = red
public float m_track_number; // -1 for unknown, 0-21 for tracks
public float m_vehicleFIAFlags; // -1 = invalid/unknown, 0 = none, 1 = green, 2 = blue, 3 = yellow, 4 = red
public float m_era; // era, 2017 (modern) or 1980 (classic)
public float m_engine_temperature; // engine temperature (centigrade)
public float m_gforce_vert; // vertical g-force component
public float m_ang_vel_x; // angular velocity x-component
public float m_ang_vel_y; // angular velocity y-component
public float m_ang_vel_z; // angular velocity z-component
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] m_tyres_temperature; // tyres temperature (centigrade)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] m_tyres_wear; // tyre wear percentage
public byte m_tyre_compound; // compound of tyre 0 = ultra soft, 1 = super soft, 2 = soft, 3 = medium, 4 = hard, 5 = inter, 6 = wet
public byte m_front_brake_bias; // front brake bias (percentage)
public byte m_fuel_mix; // fuel mix - 0 = lean, 1 = standard, 2 = rich, 3 = max
public byte m_currentLapInvalid; // current lap invalid - 0 = valid, 1 = invalid
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] m_tyres_damage; // tyre damage (percentage)
public byte m_front_left_wing_damage; // front left wing damage (percentage)
public byte m_front_right_wing_damage; // front right wing damage (percentage)
public byte m_rear_wing_damage; // rear wing damage (percentage)
public byte m_engine_damage; // engine damage (percentage)
public byte m_gear_box_damage; // gear box damage (percentage)
public byte m_exhaust_damage; // exhaust damage (percentage)
public byte m_pit_limiter_status; // pit limiter status 0 = off, 1 = on
public byte m_pit_speed_limit; // pit speed limit in mph
public float m_session_time_left; // NEW: time left in session in seconds
public byte m_rev_lights_percent; // NEW: rev lights indicator (percentage)
public byte m_is_spectating; // NEW: whether the player is spectating
public byte m_spectator_car_index; // NEW: index of the car being spectated
// Car data
public byte m_num_cars; // number of cars in data
public byte m_player_car_index; // index of player's car in the array
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public CarUDPData[] m_car_data; // data for all cars on track
public float m_yaw; // NEW (v1.8)
public float m_pitch; // NEW (v1.8)
public float m_roll; // NEW (v1.8)
public float m_x_local_velocity; // NEW (v1.8) Velocity in local space
public float m_y_local_velocity; // NEW (v1.8) Velocity in local space
public float m_z_local_velocity; // NEW (v1.8) Velocity in local space
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public float[] m_susp_acceleration; // NEW (v1.8) RL, RR, FL, FR
public float m_ang_acc_x; // NEW (v1.8) angular acceleration x-component
public float m_ang_acc_y; // NEW (v1.8) angular acceleration y-component
public float m_ang_acc_z; // NEW (v1.8) angular acceleration z-component
}
public struct CarUDPData
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] m_worldPosition; // world co-ordinates of vehicle
public float m_lastLapTime;
public float m_currentLapTime;
public float m_bestLapTime;
public float m_sector1Time;
public float m_sector2Time;
public float m_lapDistance;
public byte m_driverId;
public byte m_teamId;
public byte m_carPosition; // UPDATED: track positions of vehicle
public byte m_currentLapNum;
public byte m_tyreCompound; // compound of tyre 0 = ultra soft, 1 = super soft, 2 = soft, 3 = medium, 4 = hard, 5 = inter, 6 = wet
public byte m_inPits; // 0 = none, 1 = pitting, 2 = in pit area
public byte m_sector; // 0 = sector1, 1 = sector2, 2 = sector3
public byte m_currentLapInvalid; // current lap invalid - 0 = valid, 1 = invalid
public byte m_penalties; // NEW: accumulated time penalties in seconds to be added
};
#endregion
}
[MoonSharpUserData]
public class Car
{
public Car()
@ -101,21 +166,24 @@ namespace Artemis.Modules.Games.FormulaOne2017
public CarOverview Overview { get; set; }
public CarDetails Details { get; set; }
public float SpeedMps { get; set; }
public double SpeedKph { get; set; }
public double SpeedMph { get; set; }
public float Steering { get; set; }
public float Throttle { get; set; }
public float Brake { get; set; }
public float Clutch { get; set; }
public bool Drs { get; set; }
}
[MoonSharpUserData]
public class CarDetails
{
public float Rpm { get; set; }
public float MaxRpm { get; set; }
public float IdleRpm { get; set; }
public int RevLightsPercent { get; set; }
public int Gear { get; set; }
public int MaxGear { get; set; }
@ -127,7 +195,7 @@ namespace Artemis.Modules.Games.FormulaOne2017
public float MaxFuel { get; set; }
public float LateralG { get; set; }
public float LongitudeG { get; set; }
public float LongitudinalG { get; set; }
public float WheelSpeedFrontLeft { get; set; }
public float WheelSpeedFrontRight { get; set; }
@ -135,21 +203,53 @@ namespace Artemis.Modules.Games.FormulaOne2017
public float WheelSpeedRearRight { get; set; }
}
[MoonSharpUserData]
public class CarOverview
{
public TractionControl TractionControl { get; set; }
public F1Team Team { get; set; }
public AssistLevel TractionControl { get; set; }
public bool AntiLockBrakes { get; set; }
public static AssistLevel FloatToAssistLevel(float input)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
if (input == 0)
return AssistLevel.Off;
if (input == 0.5)
return AssistLevel.Medium;
if (input == 1)
return AssistLevel.High;
// ReSharper restore CompareOfFloatsByEqualityOperator
return AssistLevel.Off;
}
}
public enum TractionControl
public enum F1Team
{
Off = 0,
Medium = 1,
High = 2
RedBull = 0,
Ferrari = 1,
McLaren = 2,
Renault = 3,
Mercedes = 4,
Sauber = 5,
ForceIndia = 6,
Williams = 7,
TorroRosso = 8,
Haas = 11
}
public enum AssistLevel
{
Off,
Medium,
High
}
[MoonSharpUserData]
public class Session
{
public F1Track Track { get; set; }
public SessionType SessionType { get; set; }
public bool DrsEnabled { get; set; }
public SessionFlag Flags { get; set; }
@ -161,10 +261,39 @@ namespace Artemis.Modules.Games.FormulaOne2017
public float TotalDistance { get; set; }
public float LapDistance { get; set; }
public int LabNumber { get; set; }
public int LapNumber { get; set; }
public int TotalLaps { get; set; }
public int Position { get; set; }
}
public enum F1Track
{
Australia = 0,
China = 2,
Bahrain = 3,
BahrainShort = 21,
Russia = 18,
Spain = 4,
Monaco = 5,
Canada = 6,
Azerbaijan = 20,
Austria = 17,
Britain = 7,
BritainShort = 22,
Hungary = 9,
Belgium = 10,
Italy = 11,
Singapore = 12,
Malaysia = 1,
Japan = 13,
JapanShort = 24,
USA = 15,
USAShort = 23,
Mexico = 19,
Brazil = 16,
AbuDhabi = 14
}
public enum SessionFlag
{
Unknown = -1,

View File

@ -1,18 +1,21 @@
using System;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Artemis.DAL;
using Artemis.Managers;
using Artemis.Modules.Abstract;
namespace Artemis.Modules.Games.FormulaOne2017
{
public class FormulaOne2017Model : ModuleModel
{
private UdpClient _udpListener;
private bool _mustListen;
private UdpClient _udpClient;
private UdpClient _udpListener;
private DateTime _lastUpdate;
private int _revAtZeroFrames;
public FormulaOne2017Model(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager)
{
@ -27,6 +30,9 @@ namespace Artemis.Modules.Games.FormulaOne2017
public override void Update()
{
// If we're not receiving updates, assume the game is paused/in the main menu
if (DateTime.Now - _lastUpdate > TimeSpan.FromSeconds(1))
((FormulaOne2017DataModel) DataModel).Session.SessionType = SessionType.Unknown;
}
public override void Enable()
@ -34,15 +40,19 @@ namespace Artemis.Modules.Games.FormulaOne2017
_mustListen = true;
Task.Run(async () =>
{
using (var udpClient = new UdpClient(20777))
_udpClient = new UdpClient(20777);
while (_mustListen)
{
string loggingEvent = "";
while (_mustListen)
//IPEndPoint object will allow us to read datagrams sent from any source.
try
{
//IPEndPoint object will allow us to read datagrams sent from any source.
var receivedResults = await udpClient.ReceiveAsync();
var receivedResults = await _udpClient.ReceiveAsync();
HandleGameData(receivedResults);
}
catch (ObjectDisposedException)
{
// ignored, happens when shutting the module down
}
}
});
base.Enable();
@ -50,19 +60,82 @@ namespace Artemis.Modules.Games.FormulaOne2017
private void HandleGameData(UdpReceiveResult receivedResults)
{
_lastUpdate = DateTime.Now;
var dataModel = (FormulaOne2017DataModel) DataModel;
var pinnedPacket = GCHandle.Alloc(receivedResults.Buffer, GCHandleType.Pinned);
var msg = (FormulaOne2017DataModel.UdpPacketData) Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(FormulaOne2017DataModel.UdpPacketData));
pinnedPacket.Free();
// dataModel.Rpm = msg.m_engineRate;
// dataModel.MaxRpm = msg.m_max_rpm;
// dataModel.IdleRpm = msg.m_idle_rpm;
dataModel.Car.SpeedKph = msg.m_speed * 1.609344;
dataModel.Car.SpeedMph = msg.m_speed;
dataModel.Car.Steering = msg.m_steer;
dataModel.Car.Throttle = msg.m_throttle;
dataModel.Car.Brake = msg.m_brake;
dataModel.Car.Clutch = msg.m_clutch;
dataModel.Car.Drs = msg.m_drs > 0;
dataModel.Car.Overview.Team = (F1Team) msg.m_team_info;
dataModel.Car.Overview.TractionControl = CarOverview.FloatToAssistLevel(msg.m_traction_control);
dataModel.Car.Overview.AntiLockBrakes = msg.m_anti_lock_brakes > 0;
dataModel.Car.Details.Rpm = msg.m_engineRate;
dataModel.Car.Details.MaxRpm = msg.m_max_rpm;
dataModel.Car.Details.IdleRpm = msg.m_idle_rpm;
// The one the game provides is all over the place at max rev causing blinking etc
// easily fixed by simply ignoring rapid changes from 100 to 0
if (msg.m_rev_lights_percent == 0)
_revAtZeroFrames++;
else
_revAtZeroFrames = 0;
if (_revAtZeroFrames > 2 || msg.m_rev_lights_percent != 0 || dataModel.Car.Details.RevLightsPercent != 100)
dataModel.Car.Details.RevLightsPercent = msg.m_rev_lights_percent;
dataModel.Car.Details.Gear = (int) msg.m_gear;
dataModel.Car.Details.MaxGear = (int) msg.m_max_gears;
dataModel.Car.Details.Kers = msg.m_kers_level;
dataModel.Car.Details.MaxKers = msg.m_kers_max_level;
dataModel.Car.Details.Fuel = msg.m_fuel_in_tank;
dataModel.Car.Details.MaxFuel = msg.m_fuel_capacity;
dataModel.Car.Details.LateralG = msg.m_gforce_lat;
dataModel.Car.Details.LongitudinalG = msg.m_gforce_lon;
// dataModel.Car.Details.WheelSpeedFrontLeft = msg.m_wheel_speed_fl;
// dataModel.Car.Details.WheelSpeedFrontRight = msg.m_wheel_speed_fr;
// dataModel.Car.Details.WheelSpeedRearLeft = msg.m_wheel_speed_bl;
// dataModel.Car.Details.WheelSpeedRearRight = msg.m_wheel_speed_br;
dataModel.Session.SessionType = (SessionType) msg.m_sessionType;
// It's unknown in time trial but lets overwrite that to race
if (dataModel.Session.SessionType == SessionType.Unknown && dataModel.Car.SpeedMph > 0)
dataModel.Session.SessionType = SessionType.Race;
dataModel.Session.DrsEnabled = msg.m_drsAllowed > 0;
dataModel.Session.Flags = (SessionFlag) msg.m_vehicleFIAFlags;
dataModel.Session.TotalSeconds = msg.m_time;
dataModel.Session.LapSeconds = msg.m_lapTime;
dataModel.Session.Track = (F1Track) msg.m_track_number;
dataModel.Session.TrackLength = msg.m_track_size;
dataModel.Session.TotalDistance = msg.m_totalDistance;
dataModel.Session.LapDistance = msg.m_lapDistance;
dataModel.Session.LapNumber = (int) msg.m_lap;
dataModel.Session.TotalLaps = (int) msg.m_total_laps;
dataModel.Session.Position = (int) msg.m_car_position;
}
public override void Dispose()
{
_mustListen = false;
_udpClient.Dispose();
_udpClient = null;
base.Dispose();
}
}