示例#1
0
        private void Update(iRacingSDK sdk, Simulation sim)
        {
            sim.DataMutex.WaitOne();

            var sessionInfoUpdate = sdk.Header.SessionInfoUpdate;
            var updateSessionInfo = false;

            if (sessionInfoUpdate != LastSessionInfoUpdate)
            {
                LastSessionInfoUpdate = sessionInfoUpdate;
                updateSessionInfo     = true;
            }

            string sessionInfo = null;

            if (updateSessionInfo)
            {
                sessionInfo = sdk.GetSessionInfo();
            }

            try
            {
                Update(sim, sessionInfo, updateSessionInfo);
                ((SimEventManager)sim.EventManager).ExecuteEvents();
            }
            finally
            {
                sim.DataMutex.ReleaseMutex();
            }
        }
示例#2
0
        /**
         * Very hacky/not robust regex fudge to 'discover' camera groups!  Only called once per track
         */
        private static void DiscoverCameras()
        {
            String yaml   = sdk.GetSessionInfo();
            int    length = yaml.Length;
            int    start  = yaml.IndexOf("CameraInfo:\n", 0, length);
            int    end    = yaml.IndexOf("\n\n", start, length - start);

            string CameraInfo = yaml.Substring(start, end - start);

            length = CameraInfo.Length;
            start  = CameraInfo.IndexOf(" Groups:\n", 0, length);
            end    = length;

            string Cameras = CameraInfo.Substring(start, end - start - 1);

            string[] cameraList = Cameras.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries);
            int      groupNum;

            foreach (string camera in cameraList)
            {
                Regex    groupNumReg    = new Regex("^GroupNum: ([0-9]+)");
                string[] groupNumResult = (from Match match in groupNumReg.Matches(camera) select match.Groups[1].Value).ToArray();
                if (groupNumResult.Length < 1)
                {
                    continue;
                }
                groupNum = Convert.ToInt16(groupNumResult[0]);
                Regex    groupNameReg    = new Regex("GroupName: ([\\w ]+)");
                string[] groupNameResult = (from Match match in groupNameReg.Matches(camera) select match.Groups[1].Value).ToArray();
                cameras.Add(groupNameResult[0], groupNum);
            }
        }
示例#3
0
        public void updateData()
        {
            // Check if the SDK is connected
            if (sdk.IsConnected())
            {
                // telemetry
                gear           = (Int32)sdk.GetData("Gear");
                rpm            = (Int32)(Single)sdk.GetData("RPM");
                speed          = (Int32)((Single)sdk.GetData("Speed") * 3.6);
                fuel           = (Int32)((Single)sdk.GetData("FuelLevel"));
                shiftindicator = (Single)sdk.GetData("ShiftIndicatorPct");


                Int32 enwarn = (Int32)sdk.GetData("EngineWarnings");
                if (((Int32)sdk.GetData("EngineWarnings") & 0x10) > 0)
                {
                    pitlimiter = true;
                }
                else
                {
                    pitlimiter = false;
                }

                lap     = (Int32)sdk.GetData("Lap");
                lapsrem = (Int32)sdk.GetData("SessionLapsRemain");

                Double sessionTime = new Double();

                Boolean curontrack = (Boolean)sdk.GetData("IsOnTrack");
                if (curontrack == false && ontrack == true)
                {
                    SaveBestLap();
                }

                ontrack = curontrack;

                if (ontrack)
                {
                    sessionTime = (Double)sdk.GetData("SessionTime");
                }
                else
                {
                    sessionTime = (Double)sdk.GetData("ReplaySessionTime");
                }

                if (carIdx >= 0) // skip things that require caridx if we don't have it
                {
                    Int32[] driverLaps = new Int32[64];
                    driverLaps = (Int32[])sdk.GetData("CarIdxLap");

                    Single[] driverTrkPos = new Single[64];
                    driverTrkPos = (Single[])sdk.GetData("CarIdxLapDistPct");

                    Int32 lapPointer = (Int32)Math.Floor((driverTrkPos[carIdx] % 1) * (trackLength / 10));

                    timedelta.Update(sessionTime, driverTrkPos);

                    if (driverTrkPos[carIdx] < 0.1 && lastTickTrackPos > 0.9)
                    {
                        Double distance       = (1 - lastTickTrackPos) + driverTrkPos[carIdx];
                        Double time           = sessionTime - lastTickTime;
                        Double tickCorrection = (1 - lastTickTrackPos) / distance;

                        // save lap time
                        if (lapTimeValid)
                        {
                            Double laptime = (sessionTime - (1 - tickCorrection) * time) - lapStartTime;
                            prevlap = new TimeSpan(0, 0, 0, (Int32)Math.Floor(laptime), (Int32)Math.Floor((laptime % 1) * 1000));

                            fuelcons[fuelconsPtr % fuelcons.Length] = (Single)sdk.GetData("FuelLevel");

                            // update fuel consumption after one full lap
                            if (fuelconsPtr > 0)
                            {
                                if (fuelconsPtr >= fuelcons.Length)
                                {
                                    Single[] consrate = new Single[fuelcons.Length - 1];
                                    Int32    j        = 0;
                                    for (int i = fuelconsPtr; i < fuelconsPtr + consrate.Length; i++)
                                    {
                                        consrate[j++] = fuelcons[(i + 1) % fuelcons.Length] - fuelcons[(i + 2) % fuelcons.Length];
                                    }
                                    fuelneed        = (Int32)(fuelcons[fuelconsPtr % fuelcons.Length] - (lapsrem * consrate.Average()));
                                    fuelconsumption = consrate.Average();
                                }
                                else if (fuelconsPtr > 0)
                                {
                                    fuelneed        = (Int32)(fuelcons[fuelconsPtr % fuelcons.Length] - (lapsrem * fuelcons[(fuelconsPtr - 1) % fuelcons.Length]));
                                    fuelconsumption = fuelcons[(fuelconsPtr - 1) % fuelcons.Length] - fuelcons[fuelconsPtr % fuelcons.Length];
                                }
                            }
                            fuelconsPtr++;
                        }

                        // start new lap
                        lapStartTime = sessionTime - (1 - tickCorrection) * time;
                        lapTimeValid = true;
                    }
                    else if (Math.Abs(driverTrkPos[carIdx] - lastTickTrackPos) > 0.1)
                    {
                        // invalidate lap time if jumping too much
                        lapTimeValid = false;
                    }

                    // reset fuel consumption when in pits
                    TrackLocation[] trackSurface = (iRSDKSharp.TrackLocation[])sdk.GetData("CarIdxTrackSurface");
                    if (trackSurface[carIdx] == TrackLocation.irsdk_InPitStall)
                    {
                        fuelcons    = new Single[fuelconslaps];
                        fuelconsPtr = 0;
                    }

                    lastTickTrackPos = driverTrkPos[carIdx]; // save for next tick
                    lastTickTime     = sessionTime;

                    Int32[] driverCarIdx = new Int32[64];

                    if (sessiontype == SessionTypes.race)
                    {
                        // in race calculate who is infront using trackpct and lap number
                        for (Int32 i = 0; i < 64; i++)
                        {
                            driverTrkPos[i] += (Single)driverLaps[i];
                            driverCarIdx[i]  = i;
                        }

                        Array.Sort(driverTrkPos, driverCarIdx);
                        Array.Reverse(driverCarIdx);
                        position = (Int32)(Array.IndexOf(driverCarIdx, carIdx) + 1);

                        delta = timedelta.GetDelta(carIdx, driverCarIdx[Math.Max(position - 2, 0)]);
                    }
                    else
                    {
                        if (sdk.Header.SessionInfoUpdate != lastSesInfoUpdate)
                        {
                            // parse position
                            String yaml = sdk.GetSessionInfo();

                            Int32 sessionmatch  = yaml.IndexOf(" - SessionNum: " + ((Int32)sdk.GetData("SessionNum")).ToString());
                            Int32 carmatch      = yaml.IndexOf("CarIdx: " + carIdx.ToString(), sessionmatch);
                            Int32 positionmatch = yaml.LastIndexOf("Position:", carmatch);
                            if (positionmatch < 0)
                            {
                                position = 0;
                            }
                            else
                            {
                                position = Int32.Parse(yaml.Substring(positionmatch + "Position:".Length, 2));
                            }
                        }

                        delta = timedelta.GetBestLapDelta(driverTrkPos[carIdx] % 1);
                    }
                }

                lastSesInfoUpdate = sdk.Header.SessionInfoUpdate;
            }
            else
            {
                init = false;
            }
        }
示例#4
0
        public void initialize()
        {
            sdk = new iRacingSDK();
            sdk.Startup();

            // check connection
            if (sdk.IsConnected())
            {
                String yaml = sdk.GetSessionInfo();

                // caridx
                Int32 start = yaml.IndexOf("DriverCarIdx: ") + "DriverCarIdx: ".Length;
                Int32 end   = yaml.IndexOf("\n", start);
                carIdx = Int32.Parse(yaml.Substring(start, end - start));

                // carname
                start = yaml.IndexOf("CarIdx: " + carIdx.ToString(), start);
                start = yaml.IndexOf("CarPath: ", start) + "CarPath: ".Length;
                end   = yaml.IndexOf("\n", start);
                if (start < 0)
                {
                    carname = "unknown";
                }
                else
                {
                    carname = yaml.Substring(start, end - start);
                }

                // track name
                start = yaml.IndexOf("TrackName: ") + "TrackName: ".Length;
                end   = yaml.IndexOf("\n", start);
                if (start < 0)
                {
                    trackname = "unknown";
                }
                else
                {
                    trackname = yaml.Substring(start, end - start);
                }

                // track length
                start = yaml.IndexOf("TrackLength: ") + "TrackLength: ".Length;
                end   = yaml.IndexOf("km\n", start);
                String dbg = yaml.Substring(start, end - start);
                trackLength = (Int32)(Single.Parse(yaml.Substring(start, end - start)) * 1000);

                // session types
                RegexOptions    options = RegexOptions.IgnoreCase | RegexOptions.Compiled;
                MatchCollection sessionNums, sessionTypes;
                Regex           optionRegex = new Regex(@"SessionNum: (\d+)", options);

                // Get matches of pattern in yaml
                sessionNums = optionRegex.Matches(yaml);

                optionRegex  = new Regex(@"SessionType: (\w+)", options);
                sessionTypes = optionRegex.Matches(yaml);

                Int32 currentSessionNum = (Int32)sdk.GetData("SessionNum");

                // Iterate matches
                for (Int32 ctr = 0; ctr < Math.Min(sessionNums.Count, sessionTypes.Count); ctr++)
                {
                    if (Int32.Parse(sessionNums[ctr].Value.Substring(12)) == currentSessionNum)
                    {
                        switch (sessionTypes[ctr].Value.Substring(13).Trim())
                        {
                        case "Practice":
                            sessiontype = iRacing.SessionTypes.practice;
                            break;

                        case "Qualify":
                            sessiontype = iRacing.SessionTypes.qualify;
                            break;

                        case "Race":
                            sessiontype = iRacing.SessionTypes.race;
                            break;

                        default:
                            sessiontype = iRacing.SessionTypes.invalid;
                            break;
                        }
                    }
                }

                // reset laptimes
                lapStartTime = (Double)sdk.GetData("ReplaySessionTime");
                lapTimeValid = false;

                // fuel consumption, last 5 lap rolling
                fuelcons    = new Single[fuelconslaps];
                fuelconsPtr = 0;

                // init timedelta
                timedelta = new TimeDelta(trackLength);
                timedelta.SaveBestLap(carIdx);
                LoadBestLap();

                init = true;
            }
            else // retry next tick
            {
                init = false;
            }
        }
示例#5
0
        private void Loop(CancellationToken cancellationToken)
        {
            int  lastUpdate   = -1;
            bool hasConnected = false;

            while (!cancellationToken.IsCancellationRequested)
            {
                // Check if we can find the sim
                if (sdk.IsConnected())
                {
                    if (!IsConnected)
                    {
                        // If this is the first time, raise the Connected event
                        RaiseEvent(OnStarted, EventArgs.Empty);
                        connectionSource.TrySetResult();
                    }

                    hasConnected = true;
                    IsConnected  = true;

                    readMutex.WaitOne(8);

                    // Update telemetry info

                    TelemetryData = new TelemetryData(sdk);

                    // Update session info

                    int newUpdate = sdk.Header.SessionInfoUpdate;
                    if (newUpdate != lastUpdate)
                    {
                        RawSessionData = sdk.GetSessionInfo();
                        SessionData    = deserializer.Deserialize <SessionData>(RawSessionData);

                        var args = new SessionInfoChangedEventArgs(SessionData, (double)sdk.GetData("SessionTime"));
                        RaiseEvent(OnSessionInfoChanged, args);

                        if (lastUpdate == -1)
                        {
                            firstDataSource.TrySetResult();
                        }

                        lastUpdate = newUpdate;
                    }

                    // Send telemetry event now to make sure both data is updated when either event is thrown

                    var telArgs = new TelemetryInfoChangedEventArgs(TelemetryData, (double)sdk.GetData("SessionTime"));
                    RaiseEvent(OnTelemetryInfoChanged, telArgs);
                }
                else if (hasConnected)
                {
                    // We have already been initialized before, so the sim is closing
                    RaiseEvent(OnStopped, EventArgs.Empty);

                    SessionData   = null;
                    TelemetryData = null;

                    sdk.Shutdown();
                    lastUpdate   = -1;
                    IsConnected  = false;
                    hasConnected = false;
                }
                else
                {
                    // Have not been initialized before and there is no connection. Try to find the sim.
                    IsConnected  = false;
                    hasConnected = false;

                    sdk.Startup();
                }

                // Sleep for a short amount of time until the next update is available
                if (IsConnected)
                {
                    if (waitTime <= 0 || waitTime > 1000)
                    {
                        waitTime = 15;
                    }

                    Thread.Sleep(waitTime);
                }
                else
                {
                    // Not connected yet, no need to check every 16 ms, let's try again in some time
                    Thread.Sleep(ConnectSleepTime);
                }
            }

            sdk.Shutdown();
            IsConnected = false;
        }
示例#6
0
        private static string callbackCamera = "TV1";   // camera group to switch to when the client requests it
        static void Main(string[] args)
        {
            sdk = new iRacingSDK();
            int lastUpdate = -1;

            //setup WebSocketServer
            var allSockets = new List <IWebSocketConnection>();
            var server     = new WebSocketServer("ws://localhost:8181");

            server.Start(socket =>
            {
                socket.OnOpen = () =>
                {
                    Console.WriteLine("Client Connected");
                    allSockets.Add(socket);
                };
                socket.OnClose = () =>
                {
                    Console.WriteLine("Client Disconnected");
                    allSockets.Remove(socket);
                };
                socket.OnMessage = message =>
                {
                    Console.WriteLine("Received -> " + message);
                    int groupNum = cameras[callbackCamera];
                    sdk.BroadcastMessage(BroadcastMessageTypes.CamSwitchNum, Convert.ToInt32(message), groupNum, 0);
                };
            });

            while (true)
            {
                if (sdk.IsConnected())
                {
                    //If it is connected then see if the Session Info has been updated
                    int newUpdate = sdk.Header.SessionInfoUpdate;
                    if (telemData.getTrackId() == 0)
                    {
                        telemData.setTrackId(Convert.ToInt32(YamlParser.Parse(sdk.GetSessionInfo(), "WeekendInfo:TrackID:")));
                        DiscoverCameras();
                    }

                    if (newUpdate != lastUpdate)
                    {
                        // Session Info updated (e.g. perhaps a client has connected/disconnected)
                        lastUpdate = newUpdate;
                        // Update the current Driver list
                        string yaml = sdk.GetSessionInfo();
                        length = yaml.Length;
                        start  = yaml.IndexOf("DriverInfo:\n", 0, length);
                        end    = yaml.IndexOf("\n\n", start, length - start);
                        string DriverInfo = yaml.Substring(start, end - start);
                        ParseDrivers(DriverInfo);
                    }
                    UpdateDriverPositions(drivers);
                    foreach (var socket in allSockets.ToList())
                    {
                        Console.WriteLine("Broadcast sent...");
                        Console.WriteLine(telemData.toJson());
                        socket.Send(telemData.toJson());
                    }
                }
                else if (sdk.IsInitialized)
                {
                    drivers.Clear();
                    cameras.Clear();
                    telemData.setTrackId(0);
                    sdk.Shutdown();
                    lastUpdate = -1;
                }
                else
                {
                    drivers.Clear();
                    cameras.Clear();
                    telemData.setTrackId(0);
                    Console.WriteLine("NOT CONNECTED!");
                    sdk.Startup();
                }
                System.Threading.Thread.Sleep(1000);
            }
        }
示例#7
0
        public void initialize()
        {
            sdk = new iRacingSDK();
            sdk.Startup();

            // check connection
            if (sdk.IsConnected())
            {
                String yaml = sdk.GetSessionInfo();

                // caridx
                Int32 start = yaml.IndexOf("DriverCarIdx: ") + "DriverCarIdx: ".Length;
                Int32 end = yaml.IndexOf("\n", start);
                carIdx = Int32.Parse(yaml.Substring(start, end - start));

                // carname
                start = yaml.IndexOf("CarIdx: " + carIdx.ToString(), start);
                start = yaml.IndexOf("CarPath: ", start) + "CarPath: ".Length;
                end = yaml.IndexOf("\n", start);
                if (start < 0)
                    carname = "unknown";
                else
                    carname = yaml.Substring(start, end - start);

                // track name
                start = yaml.IndexOf("TrackName: ") + "TrackName: ".Length;
                end = yaml.IndexOf("\n", start);
                if (start < 0)
                    trackname = "unknown";
                else
                    trackname = yaml.Substring(start, end - start);

                // track length
                start = yaml.IndexOf("TrackLength: ") + "TrackLength: ".Length;
                end = yaml.IndexOf("km\n", start);
                String dbg = yaml.Substring(start, end - start);
                trackLength = (Int32)(Single.Parse(yaml.Substring(start, end - start)) * 1000);

                // session types
                RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Compiled;
                MatchCollection sessionNums, sessionTypes;
                Regex optionRegex = new Regex(@"SessionNum: (\d+)", options);

                // Get matches of pattern in yaml
                sessionNums = optionRegex.Matches(yaml);

                optionRegex = new Regex(@"SessionType: (\w+)", options);
                sessionTypes = optionRegex.Matches(yaml);

                Int32 currentSessionNum = (Int32)sdk.GetData("SessionNum");

                // Iterate matches
                for (Int32 ctr = 0; ctr < Math.Min(sessionNums.Count, sessionTypes.Count); ctr++)
                {
                    if (Int32.Parse(sessionNums[ctr].Value.Substring(12)) == currentSessionNum)
                    {
                        switch (sessionTypes[ctr].Value.Substring(13).Trim())
                        {
                            case "Practice":
                                sessiontype = iRacing.SessionTypes.practice;
                                break;
                            case "Qualify":
                                sessiontype = iRacing.SessionTypes.qualify;
                                break;
                            case "Race":
                                sessiontype = iRacing.SessionTypes.race;
                                break;
                            default:
                                sessiontype = iRacing.SessionTypes.invalid;
                                break;
                        }
                    }
                }

                // reset laptimes
                lapStartTime = (Double)sdk.GetData("ReplaySessionTime");
                lapTimeValid = false;

                // fuel consumption, last 5 lap rolling
                fuelcons = new Single[fuelconslaps];
                fuelconsPtr = 0;

                // init timedelta
                timedelta = new TimeDelta(trackLength);
                timedelta.SaveBestLap(carIdx);
                LoadBestLap();

                init = true;
            }
            else // retry next tick
            {
                init = false;
            }
        }