1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-31 17:53:32 +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 Artemis.Modules.Abstract;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
@ -21,14 +22,14 @@ namespace Artemis.Modules.Games.FormulaOne2017
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct UdpPacketData public struct UdpPacketData
{ {
public float m_time; // Total seconds driven from start line public float m_time;
public float m_lapTime; // Total seconds of current lap public float m_lapTime;
public float m_lapDistance; // Total distance through lap in meters public float m_lapDistance;
public float m_totalDistance; // Total distance driven from start line public float m_totalDistance;
public float m_x; // World space position public float m_x; // World space position
public float m_y; // World space position public float m_y; // World space position
public float m_z; // World space position public float m_z; // World space position
public float m_speed; // Meters/sec public float m_speed; // Speed of car in MPH
public float m_xv; // Velocity in world space public float m_xv; // Velocity in world space
public float m_yv; // Velocity in world space public float m_yv; // Velocity in world space
public float m_zv; // 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_xd; // World space forward direction
public float m_yd; // World space forward direction public float m_yd; // World space forward direction
public float m_zd; // World space forward direction public float m_zd; // World space forward direction
public float m_susp_pos_bl; // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public float m_susp_pos_br; // public float[] m_susp_pos; // Note: All wheel arrays have the order:
public float m_susp_pos_fl; // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public float m_susp_pos_fr; // public float[] m_susp_vel; // RL, RR, FL, FR
public float m_susp_vel_bl; // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public float m_susp_vel_br; // public float[] m_wheel_speed;
public float m_susp_vel_fl; // public float m_throttle;
public float m_susp_vel_fr; // public float m_steer;
public float m_wheel_speed_bl; // public float m_brake;
public float m_wheel_speed_br; // public float m_clutch;
public float m_wheel_speed_fl; // public float m_gear;
public float m_wheel_speed_fr; // public float m_gforce_lat;
public float m_throttle; // Throttle input public float m_gforce_lon;
public float m_steer; // Steering input (-1 left to +1 right) public float m_lap;
public float m_brake; // Brake input public float m_engineRate;
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
public float m_sli_pro_native_support; // SLI Pro support 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_level; // kers energy left
public float m_kers_max_level; // kers maximum energy public float m_kers_max_level; // kers maximum energy
public float m_drs; // 0 = off, 1 = on public float m_drs; // 0 = off, 1 = on
public float m_traction_control; // 0 (off) - 2 (high) public float m_traction_control; // 0 (off) - 2 (high)
public float m_anti_lock_brakes; // 0 (off) - 1 (on) public float m_anti_lock_brakes; // 0 (off) - 1 (on)
public float m_fuel_in_tank; // current fuel mass public float m_fuel_in_tank; // current fuel mass
public float m_fuel_capacity; // fuel capacity public float m_fuel_capacity; // fuel capacity
public float m_in_pits; // 0 = none, 1 = pitting, 2 = in pit area 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_sector; // 0 = sector1, 1 = sector2, 2 = sector3
public float m_sector1_time; // time of sector1 (or 0) public float m_sector1_time; // time of sector1 (or 0)
public float m_sector2_time; // time of sector2 (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)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public float[] m_wheels_pressure; // wheels pressure PSI public float[] m_brakes_temp; // brakes temperature (centigrade)
public float m_team_info; // team ID [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_total_laps; // total number of laps in this race
public float m_track_size; // track size meters public float m_track_size; // track size meters
public float m_last_lap_time; // last lap time 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_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_idle_rpm; // cars idle RPM
public float m_max_gears; // maximum number of gears public float m_max_gears; // maximum number of gears
public float m_sessionType; // 0 = unknown, 1 = practice, 2 = qualifying, 3 = race 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_drsAllowed; // 0 = not allowed, 1 = allowed, -1 = invalid / unknown
public float m_track_number; // -1 for unknown, 0-21 for tracks 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_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 #endregion
} }
[MoonSharpUserData]
public class Car public class Car
{ {
public Car() public Car()
@ -101,21 +166,24 @@ namespace Artemis.Modules.Games.FormulaOne2017
public CarOverview Overview { get; set; } public CarOverview Overview { get; set; }
public CarDetails Details { 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 Steering { get; set; }
public float Throttle { get; set; } public float Throttle { get; set; }
public float Brake { get; set; } public float Brake { get; set; }
public float Clutch { get; set; } public float Clutch { get; set; }
public bool Drs { get; set; } public bool Drs { get; set; }
} }
[MoonSharpUserData]
public class CarDetails public class CarDetails
{ {
public float Rpm { get; set; } public float Rpm { get; set; }
public float MaxRpm { get; set; } public float MaxRpm { get; set; }
public float IdleRpm { get; set; } public float IdleRpm { get; set; }
public int RevLightsPercent { get; set; }
public int Gear { get; set; } public int Gear { get; set; }
public int MaxGear { get; set; } public int MaxGear { get; set; }
@ -127,7 +195,7 @@ namespace Artemis.Modules.Games.FormulaOne2017
public float MaxFuel { get; set; } public float MaxFuel { get; set; }
public float LateralG { get; set; } public float LateralG { get; set; }
public float LongitudeG { get; set; } public float LongitudinalG { get; set; }
public float WheelSpeedFrontLeft { get; set; } public float WheelSpeedFrontLeft { get; set; }
public float WheelSpeedFrontRight { get; set; } public float WheelSpeedFrontRight { get; set; }
@ -135,21 +203,53 @@ namespace Artemis.Modules.Games.FormulaOne2017
public float WheelSpeedRearRight { get; set; } public float WheelSpeedRearRight { get; set; }
} }
[MoonSharpUserData]
public class CarOverview public class CarOverview
{ {
public TractionControl TractionControl { get; set; } public F1Team Team { get; set; }
public AssistLevel TractionControl { get; set; }
public bool AntiLockBrakes { 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, RedBull = 0,
Medium = 1, Ferrari = 1,
High = 2 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 class Session
{ {
public F1Track Track { get; set; }
public SessionType SessionType { get; set; } public SessionType SessionType { get; set; }
public bool DrsEnabled { get; set; } public bool DrsEnabled { get; set; }
public SessionFlag Flags { get; set; } public SessionFlag Flags { get; set; }
@ -161,10 +261,39 @@ namespace Artemis.Modules.Games.FormulaOne2017
public float TotalDistance { get; set; } public float TotalDistance { get; set; }
public float LapDistance { 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 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 public enum SessionFlag
{ {
Unknown = -1, Unknown = -1,

View File

@ -1,18 +1,21 @@
using System; using System;
using System.Net.Sockets; using System.Net.Sockets;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Artemis.DAL; using Artemis.DAL;
using Artemis.Managers; using Artemis.Managers;
using Artemis.Modules.Abstract; using Artemis.Modules.Abstract;
namespace Artemis.Modules.Games.FormulaOne2017 namespace Artemis.Modules.Games.FormulaOne2017
{ {
public class FormulaOne2017Model : ModuleModel public class FormulaOne2017Model : ModuleModel
{ {
private UdpClient _udpListener;
private bool _mustListen; private bool _mustListen;
private UdpClient _udpClient;
private UdpClient _udpListener;
private DateTime _lastUpdate;
private int _revAtZeroFrames;
public FormulaOne2017Model(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager) public FormulaOne2017Model(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager)
{ {
@ -27,6 +30,9 @@ namespace Artemis.Modules.Games.FormulaOne2017
public override void Update() 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() public override void Enable()
@ -34,15 +40,19 @@ namespace Artemis.Modules.Games.FormulaOne2017
_mustListen = true; _mustListen = true;
Task.Run(async () => Task.Run(async () =>
{ {
using (var udpClient = new UdpClient(20777)) _udpClient = new UdpClient(20777);
while (_mustListen)
{ {
string loggingEvent = ""; //IPEndPoint object will allow us to read datagrams sent from any source.
while (_mustListen) 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); HandleGameData(receivedResults);
} }
catch (ObjectDisposedException)
{
// ignored, happens when shutting the module down
}
} }
}); });
base.Enable(); base.Enable();
@ -50,19 +60,82 @@ namespace Artemis.Modules.Games.FormulaOne2017
private void HandleGameData(UdpReceiveResult receivedResults) private void HandleGameData(UdpReceiveResult receivedResults)
{ {
_lastUpdate = DateTime.Now;
var dataModel = (FormulaOne2017DataModel) DataModel; var dataModel = (FormulaOne2017DataModel) DataModel;
var pinnedPacket = GCHandle.Alloc(receivedResults.Buffer, GCHandleType.Pinned); var pinnedPacket = GCHandle.Alloc(receivedResults.Buffer, GCHandleType.Pinned);
var msg = (FormulaOne2017DataModel.UdpPacketData) Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(FormulaOne2017DataModel.UdpPacketData)); var msg = (FormulaOne2017DataModel.UdpPacketData) Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(FormulaOne2017DataModel.UdpPacketData));
pinnedPacket.Free(); pinnedPacket.Free();
// dataModel.Rpm = msg.m_engineRate; dataModel.Car.SpeedKph = msg.m_speed * 1.609344;
// dataModel.MaxRpm = msg.m_max_rpm; dataModel.Car.SpeedMph = msg.m_speed;
// dataModel.IdleRpm = msg.m_idle_rpm;
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() public override void Dispose()
{ {
_mustListen = false; _mustListen = false;
_udpClient.Dispose();
_udpClient = null;
base.Dispose(); base.Dispose();
} }
} }