Skip to content
This repository has been archived by the owner on Nov 23, 2023. It is now read-only.

Commit

Permalink
Add Documentation and work on easier building.
Browse files Browse the repository at this point in the history
  • Loading branch information
patmagauran committed Dec 26, 2021
1 parent 6f3230e commit 925992f
Show file tree
Hide file tree
Showing 33 changed files with 329 additions and 86 deletions.
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/ForzaCore/bin/Debug/net6.0/ForzaCore.exe",
"program": "${workspaceFolder}/ForzaDualSense/bin/Debug/net6.0/ForzaDualSense.exe",
"args": [],
"cwd": "${workspaceFolder}/ForzaCore",
"cwd": "${workspaceFolder}/ForzaDualSense",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
Expand Down
6 changes: 3 additions & 3 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"type": "process",
"args": [
"build",
"${workspaceFolder}/ForzaCore/ForzaCore.csproj",
"${workspaceFolder}/ForzaDualSense/ForzaDualSense.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
Expand All @@ -19,7 +19,7 @@
"type": "process",
"args": [
"publish",
"${workspaceFolder}/ForzaCore/ForzaCore.csproj",
"${workspaceFolder}/ForzaDualSense/ForzaDualSense.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
Expand All @@ -32,7 +32,7 @@
"args": [
"watch",
"run",
"${workspaceFolder}/ForzaCore/ForzaCore.csproj",
"${workspaceFolder}/ForzaDualSense/ForzaDualSense.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
Expand Down
2 changes: 1 addition & 1 deletion ForzaDualSense/DataPacket.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ForzaCore
namespace ForzaDualSense
{
public class DataPacket
{
Expand Down
4 changes: 2 additions & 2 deletions ForzaDualSense/FMData.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using static ForzaCore.PacketParse;
using static ForzaDualSense.PacketParse;

namespace ForzaCore
namespace ForzaDualSense
{
public static class FMData
{
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion ForzaDualSense/PacketParse.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;

namespace ForzaCore
namespace ForzaDualSense
{
public static class PacketParse
{
Expand Down
172 changes: 103 additions & 69 deletions ForzaDualSense/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,76 @@
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace ForzaCore
namespace ForzaDualSense
{
class Program
{
private const int recordRateMS = 100;
private static bool recordingData = false;
private static bool isRaceOn = false;
private static DataPacket data = new DataPacket();
private const int FORZA_DATA_OUT_PORT = 5300;
private const int FORZA_HOST_PORT = 5200;
private static string currentFilename = "./data/" + DateTime.Now.ToFileTime() + ".csv";
static UdpClient senderClient;
static IPEndPoint endPoint;
static void Connect()
//This sends the data to DualSenseX based on the input parsed data from Forza.
//See DataPacket.cs for more details about what forza parameters can be accessed.
//See the Enums at the bottom of this file for details about commands that can be sent to DualSenseX
//Also see the Test Function below to see examples about those commands
static void SendData(DataPacket data)
{
senderClient = new UdpClient();
endPoint = new IPEndPoint(Triggers.localhost, 6750);
}
Packet p = new Packet();

static void Send(Packet data)
{
var RequestData = Encoding.ASCII.GetBytes(Triggers.PacketToJson(data));
senderClient.Send(RequestData, RequestData.Length, endPoint);
}
//Set the controller to do this for
int controllerIndex = 0;

//Initialize our array of instructions
p.instructions = new Instruction[4];

//Update the left(Brake) trigger
p.instructions[0].type = InstructionType.TriggerUpdate;
//By default, it should be uniform hard resistance
p.instructions[0].parameters = new object[] { controllerIndex, Trigger.Left, TriggerMode.Resistance, 0, 8 };

//Get average tire slippage. This value runs from 0.0 upwards with a value of 1.0 or greater meaning total loss of grip.
float combinedTireSlip = (data.TireCombinedSlipFrontLeft + data.TireCombinedSlipFrontRight + data.TireCombinedSlipRearLeft + data.TireCombinedSlipRearRight) / 4;

//All grip lost, trigger should be loose
if (combinedTireSlip > 1)
{
//Set left trigger to normal mode(i.e no resistance)
p.instructions[0].parameters = new object[] { controllerIndex, Trigger.Left, TriggerMode.Normal, 0, 0 };

}
//Some grip lost, begin to vibrate according to the amount of grip lost
else if (combinedTireSlip > 0.25)
{
int freq = 35 - (int)Math.Floor(Map(combinedTireSlip, 0.25f, 1, 0, 35));
//Set left trigger to the custom mode VibrateResitance with values of Frequency = freq, Stiffness = 104, startPostion = 76.
p.instructions[0].parameters = new object[] { controllerIndex, Trigger.Left, TriggerMode.CustomTriggerValue, CustomTriggerValueMode.VibrateResistance, freq, 104, 76, 0, 0, 0, 0 };

}

//Set the updates for the right Trigger(Throttle)
p.instructions[2].type = InstructionType.TriggerUpdate;
//It should probably always be uniformly stiff
p.instructions[2].parameters = new object[] { controllerIndex, Trigger.Right, TriggerMode.Resistance, 0, 8 };

// if (combinedTireSlip > 1)
// {
// p.instructions[2].parameters = new object[] { controllerIndex, Trigger.Right, TriggerMode.Normal, 0, 0 };

// }
// else if (combinedTireSlip > 0.25)
// {
// int freq = 35 - (int)Math.Floor(Map(combinedTireSlip, 0.25f, 1, 0, 35));
// p.instructions[2].parameters = new object[] { controllerIndex, Trigger.Right, TriggerMode.CustomTriggerValue, CustomTriggerValueMode.VibrateResistance, freq, 104, 76, 0, 0, 0, 0 };

// }

//Update the light bar
p.instructions[1].type = InstructionType.RGBUpdate;
//Currently registers intensity on the green channel based on engnine RPM as a percantage of the maxium.
p.instructions[1].parameters = new object[] { controllerIndex, 0, (int)Math.Floor((data.CurrentEngineRpm / data.EngineMaxRpm) * 255), 0 };

//Send the commands to DualSenseX
Send(p);


}
//This is the same test method from the UDPExample in DualSenseX. It just provides a basic overview of the different commands that can be used with DualSenseX.
static void test(string[] args)
{

Expand Down Expand Up @@ -145,27 +190,57 @@ static void test(string[] args)
Console.ReadKey();
}
}
//Maps floats from one range to another.
public static float Map(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

private static DataPacket data = new DataPacket();
private const int FORZA_DATA_OUT_PORT = 5300;
static UdpClient senderClient;
static IPEndPoint endPoint;
//Connect to DualSenseX
static void Connect()
{
senderClient = new UdpClient();
endPoint = new IPEndPoint(Triggers.localhost, 6750);
}
//Send Data to DualSenseX
static void Send(Packet data)
{
var RequestData = Encoding.ASCII.GetBytes(Triggers.PacketToJson(data));
senderClient.Send(RequestData, RequestData.Length, endPoint);
}

//Main running thread of program.
static async Task Main(string[] args)
{
#region udp stuff
//Connect to DualSenseX
Connect();

//Connect to Forza
var ipEndPoint = new IPEndPoint(IPAddress.Loopback, FORZA_DATA_OUT_PORT);
var client = new UdpClient(FORZA_DATA_OUT_PORT);

Console.WriteLine("The Program is running. Please set the Forza data out to 127.0.0.1, port 5300 and the DualSenseX UDP Port to 6750");

var client = new UdpClient(FORZA_DATA_OUT_PORT);
//Main loop, go until killed
while (true)
{
//If Forza sends an update
await client.ReceiveAsync().ContinueWith(receive =>
{
//parse data
var resultBuffer = receive.Result.Buffer;
if (!AdjustToBufferType(resultBuffer.Length))
{
// return;
}
// send data to node here

data = ParseData(resultBuffer);

//Process and send data to DualSenseX
SendData(data);

});
Expand All @@ -176,52 +251,7 @@ await client.ReceiveAsync().ContinueWith(receive =>

}

static void SendData(DataPacket data)
{
Packet p = new Packet();

int controllerIndex = 0;


p.instructions = new Instruction[4];
p.instructions[0].type = InstructionType.TriggerUpdate;
p.instructions[0].parameters = new object[] { controllerIndex, Trigger.Left, TriggerMode.Resistance, 0, 8 };
float combinedTireSlip = (data.TireCombinedSlipFrontLeft + data.TireCombinedSlipFrontRight + data.TireCombinedSlipRearLeft + data.TireCombinedSlipRearRight) / 4;
if (combinedTireSlip > 1)
{
p.instructions[0].parameters = new object[] { controllerIndex, Trigger.Left, TriggerMode.Normal, 0, 0 };

}
else if (combinedTireSlip > 0.25)
{
int freq = 35 - (int)Math.Floor(Map(combinedTireSlip, 0.25f, 1, 0, 35));
p.instructions[0].parameters = new object[] { controllerIndex, Trigger.Left, TriggerMode.CustomTriggerValue, CustomTriggerValueMode.VibrateResistance, freq, 104, 76, 0, 0, 0, 0 };

}
p.instructions[2].type = InstructionType.TriggerUpdate;
p.instructions[2].parameters = new object[] { controllerIndex, Trigger.Right, TriggerMode.Resistance, 0, 8 };
// if (combinedTireSlip > 1)
// {
// p.instructions[2].parameters = new object[] { controllerIndex, Trigger.Right, TriggerMode.Normal, 0, 0 };

// }
// else if (combinedTireSlip > 0.25)
// {
// int freq = 35 - (int)Math.Floor(Map(combinedTireSlip, 0.25f, 1, 0, 35));
// p.instructions[2].parameters = new object[] { controllerIndex, Trigger.Right, TriggerMode.CustomTriggerValue, CustomTriggerValueMode.VibrateResistance, freq, 104, 76, 0, 0, 0, 0 };

// }
p.instructions[1].type = InstructionType.RGBUpdate;
p.instructions[1].parameters = new object[] { controllerIndex, 0, (int)Math.Floor((data.CurrentEngineRpm / data.EngineMaxRpm) * 255), 0 };
Send(p);


}

public static float Map(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
//Parses data from Forza into a DataPacket
static DataPacket ParseData(byte[] packet)
{
DataPacket data = new DataPacket();
Expand Down Expand Up @@ -318,6 +348,7 @@ static DataPacket ParseData(byte[] packet)
return data;
}

//Support different standards
static bool AdjustToBufferType(int bufferLength)
{
switch (bufferLength)
Expand All @@ -337,6 +368,8 @@ static bool AdjustToBufferType(int bufferLength)


}

//Needed to communicate with DualSenseX
public static class Triggers
{
public static IPAddress localhost = new IPAddress(new byte[] { 127, 0, 0, 1 });
Expand All @@ -352,7 +385,7 @@ public static Packet JsonToPacket(string json)
}
}


//The different trigger Modes. These correlate the values in the DualSenseX UI
public enum TriggerMode
{
Normal = 0,
Expand All @@ -376,6 +409,7 @@ public enum TriggerMode
Machine = 18
}

//Custom Trigger Values. These correspond to the values in the DualSenseX UI
public enum CustomTriggerValueMode
{
OFF = 0,
Expand Down
41 changes: 41 additions & 0 deletions ForzaDualSense/bin/Debug/net6.0/ForzaDualSense.deps.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v6.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v6.0": {
"ForzaDualSense/1.0.0": {
"dependencies": {
"Newtonsoft.Json": "13.0.1"
},
"runtime": {
"ForzaDualSense.dll": {}
}
},
"Newtonsoft.Json/13.0.1": {
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.1.25517"
}
}
}
}
},
"libraries": {
"ForzaDualSense/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Newtonsoft.Json/13.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==",
"path": "newtonsoft.json/13.0.1",
"hashPath": "newtonsoft.json.13.0.1.nupkg.sha512"
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"runtimeOptions": {
"tfm": "net6.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "6.0.0"
}
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = ForzaCore
build_property.ProjectDir = C:\Data\Development\ForzaDualSense\ForzaDualSense\
build_property.ProjectDir = c:\Data\Development\ForzaDualSense\ForzaDualSense\
Binary file modified ForzaDualSense/obj/Debug/net6.0/ForzaCore.assets.cache
Binary file not shown.
22 changes: 22 additions & 0 deletions ForzaDualSense/obj/Debug/net6.0/ForzaDualSense.AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Reflection;

[assembly: System.Reflection.AssemblyCompanyAttribute("ForzaDualSense")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("ForzaDualSense")]
[assembly: System.Reflection.AssemblyTitleAttribute("ForzaDualSense")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

// Generated by the MSBuild WriteCodeFragment class.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
c40fb05441ae189bc750e1d83012b955f862c382
Loading

0 comments on commit 925992f

Please sign in to comment.