Beispiel #1
0
        async private void StreamBtn_Click(object sender, EventArgs e)
        {
            if (!IsStreamingMQTT)
            {
                recordingCount++;

                long startTime = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeMilliseconds(); //current start time when we button is clicked

                var topic      = mqttTopic;
                var factory    = new MqttFactory();
                var mqttClient = factory.CreateMqttClient();

                string mqttText = MQTTIPTextBox.Text;

                // Use WebSocket connection.
                var options = new MqttClientOptionsBuilder()
                              .WithClientId("Tobii RET")
                              .WithWebSocketServer(mqttText)                    //"broker.hivemq.com:8000/mqtt"
                              .WithTls()                                        //For wss
                              .Build();
                await mqttClient.ConnectAsync(options, CancellationToken.None); // Since 3.0.5 with CancellationToken



                //TODO figure out how to setup the disconnect handler to reconnect as needed.
                //The wiki seems to not be updated on this point

                /*mqttClient.UseDisconnectedHandler = (async e =>
                 * {
                 *  Console.WriteLine("### DISCONNECTED FROM SERVER ###");
                 *  await Task.Delay(TimeSpan.FromSeconds(5));
                 *
                 *  try
                 *  {
                 *      await mqttClient.ConnectAsync(options, CancellationToken.None); // Since 3.0.5 with CancellationToken
                 *  }
                 *  catch
                 *  {
                 *      Console.WriteLine("### RECONNECTING FAILED ###");
                 *  }
                 * });*/

                SelectedTracker.GazeDataReceived += HandleGazeData;
                IsStreamingMQTT = true;



                Form FixationForm = new Form();
                FixationForm.ControlBox = false;

                FixationForm.WindowState     = FormWindowState.Normal;
                FixationForm.FormBorderStyle = FormBorderStyle.None;
                FixationForm.WindowState     = FormWindowState.Maximized;

                FixationForm.Show();

                Panel AnimatedPointPanel = new Panel();
                AnimatedPointPanel.Width  = FixationForm.Width;
                AnimatedPointPanel.Height = FixationForm.Height;
                Graphics AnimatedPointGraphics = AnimatedPointPanel.CreateGraphics();
                FixationForm.Controls.Add(AnimatedPointPanel);
                int w = FixationForm.Width;
                int h = FixationForm.Height;


                MQTTThread = new Thread(async() => {
                    int sampleCount = 0;
                    var dataList    = new List <object>(); //for later adding object in
                    GazeDataEventArgs prevGazeDataEvent = null;
                    while (IsStreamingMQTT)
                    {
                        try
                        {
                            while (GazeEventQueue.Any())
                            {
                                GazeDataEventArgs currentgazeEvent;
                                GazeEventQueue.TryDequeue(out currentgazeEvent);
                                double velocity = VelocityCalculation.CalculateVelocity(prevGazeDataEvent, currentgazeEvent, "Average");
                                Console.WriteLine(velocity);

                                float gazeX = 0;
                                float gazeY = 0;
                                if (currentgazeEvent.LeftEye.GazePoint.Validity == Validity.Valid &&
                                    currentgazeEvent.RightEye.GazePoint.Validity == Validity.Valid)
                                {
                                    gazeX = (currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X + currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X) / 2;
                                    gazeY = (currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y + currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y) / 2;
                                }
                                else if (currentgazeEvent.LeftEye.GazePoint.Validity == Validity.Valid)
                                {
                                    gazeX = currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X;
                                    gazeY = currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y;
                                }
                                else if (currentgazeEvent.RightEye.GazePoint.Validity == Validity.Valid)
                                {
                                    gazeX = currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X;
                                    gazeY = currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y;
                                }

                                if (velocity >= Threshold)
                                {
                                    int radius = 10;
                                    Console.Write("--> Fixation ");
                                    Console.WriteLine(gazeX.ToString() + "\t" + gazeY.ToString());
                                    Console.WriteLine(gazeX * w);
                                    Console.WriteLine(gazeY * h);

                                    AnimatedPointGraphics.DrawEllipse(CalBrush, gazeX * w - radius, gazeY * h - radius, radius + radius, radius + radius);
                                }



                                if (currentgazeEvent.LeftEye.Pupil.PupilDiameter != -1 || currentgazeEvent.RightEye.Pupil.PupilDiameter != -1)
                                {
                                    CurrentPupilDiameters[0] = Double.IsNaN(currentgazeEvent.LeftEye.Pupil.PupilDiameter) ? -1 : currentgazeEvent.LeftEye.Pupil.PupilDiameter;
                                    CurrentPupilDiameters[1] = Double.IsNaN(currentgazeEvent.RightEye.Pupil.PupilDiameter) ? -1 : currentgazeEvent.RightEye.Pupil.PupilDiameter;
                                }

                                var dataObject = new Dictionary <string, object>();

                                dataObject.Add("timestamp", currentgazeEvent.DeviceTimeStamp);
                                dataObject.Add("sampleCount", sampleCount);
                                dataObject.Add("gaze", new Dictionary <string, float>
                                {
                                    { "x", gazeX },
                                    { "y", gazeY }
                                }
                                               );

                                dataObject.Add("pupilDiameter", new Dictionary <string, double>
                                {
                                    { "LeftEye", CurrentPupilDiameters[0] },
                                    { "RightEye", CurrentPupilDiameters[1] }
                                }
                                               );



                                //GazePoint in data
                                var GazePointObject = new Dictionary <string, object>();
                                GazePointObject.Add("LeftEye", new Dictionary <string, float>
                                {
                                    { "x", float.IsNaN(currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X) ? float.NaN : currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X },
                                    { "y", float.IsNaN(currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y) ? float.NaN : currentgazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y }
                                }
                                                    );

                                GazePointObject.Add("RightEye", new Dictionary <string, float>
                                {
                                    { "x", float.IsNaN(currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X) ? float.NaN : currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X },
                                    { "y", float.IsNaN(currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y) ? float.NaN : currentgazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y }
                                }
                                                    );
                                dataObject.Add("GazePoint_PositionOnDisplayArea", GazePointObject);

                                //GazeOrigin in data
                                var GazeOriginObject = new Dictionary <string, object>();
                                GazeOriginObject.Add("LeftEye", new Dictionary <string, float>
                                {
                                    { "x", float.IsNaN(currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.X) ? float.NaN :  currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.X },
                                    { "y", float.IsNaN(currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Y) ? float.NaN :  currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Y },
                                    { "z", float.IsNaN(currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Z) ? float.NaN :  currentgazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Z }
                                }
                                                     );

                                GazeOriginObject.Add("RightEye", new Dictionary <string, float>
                                {
                                    { "x", float.IsNaN(currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.X) ? float.NaN :  currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.X },
                                    { "y", float.IsNaN(currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Y) ? float.NaN :  currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Y },
                                    { "z", float.IsNaN(currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Z) ? float.NaN :  currentgazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Z }
                                }
                                                     );
                                dataObject.Add("GazeOrigin_PositionInUserCoordinates", GazeOriginObject);
                                sampleCount++;


                                dataList.Add(dataObject); //append to the list

                                prevGazeDataEvent = currentgazeEvent;


                                if (dataList.Count == BatchSize)
                                {
                                    //create a dict-shape message, later will be serialized as a json object
                                    var msg = new Dictionary <string, object>();
                                    msg.Add("user", new Dictionary <string, Guid>
                                    {
                                        { "uid", guid }
                                    }
                                            );
                                    msg.Add("eyeTrackerSerialNumber", SelectedTracker.SerialNumber);

                                    msg.Add("startTime", startTime);
                                    msg.Add("recordingCount", recordingCount);

                                    msg.Add("data", dataList);

                                    var settings       = new JsonSerializerSettings();
                                    var floatConverter = new StandardJsonConverter();
                                    settings.Converters.Add(floatConverter);
                                    string jsonMSG = JsonConvert.SerializeObject(msg, settings);


                                    var message = new MqttApplicationMessageBuilder()
                                                  .WithTopic(topic)
                                                  .WithPayload(jsonMSG)
                                                  .WithExactlyOnceQoS()
                                                  .WithRetainFlag(false)
                                                  .Build();
                                    await mqttClient.PublishAsync(message, CancellationToken.None); // Since 3.0.5 with CancellationToken

                                    dataList.Clear();
                                }
                            }
                        }
                        catch (Exception exp)
                        {
                            //do nothing, skip
                            Console.Write(exp);
                        }
                    }
                });
                MQTTThread.Start();

                if (StreamBtn.InvokeRequired)
                {
                    StreamBtn.BeginInvoke((MethodInvoker) delegate() { this.StreamBtn.Text = "Stop"; });
                }
                else
                {
                    StreamBtn.Text = "Stop";
                }
            }
            else
            {
                IsStreamingMQTT = false;
                SelectedTracker.GazeDataReceived -= HandleGazeData;
                if (StreamBtn.InvokeRequired)
                {
                    StreamBtn.BeginInvoke((MethodInvoker) delegate() { this.StreamBtn.Text = "Stream"; });
                }
                else
                {
                    StreamBtn.Text = "Stream";
                }
                MQTTThread.Join();
            }
        }
        async private void StreamBtn_Click(object sender, EventArgs e)
        {
            if (!IsStreamingToWAMP)
            {
                //maybe check if the connection before start wamp
                string CrossbarAddress = CrossbarIPTextBox.Text + "/ws";
                string CrossbarRealm   = RealmTextbox.Text;

                //This was the old code, might have to do some kind of hybrid depending on the url written.

                /*DefaultWampChannelFactory channelFactory = new DefaultWampChannelFactory();
                 * IWampChannel channel = channelFactory.CreateJsonChannel("wss://syn.ife.no/crossbarproxy/ws", CrossbarRealm); //CrossbarAddress
                 *
                 * channel.Open().Wait();
                 * //Task openTask = channel.Open()
                 * //openTask.Wait(5000);*/

                //if (CrossbarAddress.Contains("wss://")){
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                //}

                WampChannelFactory factory = new WampChannelFactory();

                IWampChannel channel = factory.ConnectToRealm(CrossbarRealm)
                                       .WebSocketTransport(new Uri(CrossbarAddress + "/ws"))
                                       .JsonSerialization()
                                       .Build();

                IWampRealmProxy realmProxy = channel.RealmProxy;

                channel.RealmProxy.Monitor.ConnectionEstablished +=
                    (sender_inner, arg) =>
                {
                    Console.WriteLine("connected session with ID " + arg.SessionId);

                    dynamic details = arg.WelcomeDetails.OriginalValue.Deserialize <dynamic>();

                    Console.WriteLine("authenticated using method '{0}' and provider '{1}'", details.authmethod,
                                      details.authprovider);

                    Console.WriteLine("authenticated with authid '{0}' and authrole '{1}'", details.authid,
                                      details.authrole);
                };

                channel.RealmProxy.Monitor.ConnectionBroken +=
                    (sender_inner, arg) =>
                {
                    dynamic details = arg.Details.OriginalValue.Deserialize <dynamic>();
                    Console.WriteLine("disconnected " + arg.Reason + " " + details.reason + details);
                    Console.WriteLine("disconnected " + arg.Reason);
                };

                await channel.Open().ConfigureAwait(false);

                WAMPSubject = realmProxy.Services.GetSubject("RETDataSample");

                SelectedTracker.GazeDataReceived += HandleGazeData;
                IsStreamingToWAMP = true;
                WAMPThread        = new Thread(() => {
                    while (IsStreamingToWAMP)
                    {
                        try
                        {
                            while (GazeEventQueue.Any())
                            {
                                GazeDataEventArgs gazeEvent;
                                GazeEventQueue.TryDequeue(out gazeEvent);
                                float gazeX = 0;
                                float gazeY = 0;
                                if (gazeEvent.LeftEye.GazePoint.Validity == Validity.Valid &&
                                    gazeEvent.RightEye.GazePoint.Validity == Validity.Valid)
                                {
                                    gazeX = (gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X + gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X) / 2;
                                    gazeY = (gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y + gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y) / 2;
                                }
                                else if (gazeEvent.LeftEye.GazePoint.Validity == Validity.Valid)
                                {
                                    gazeX = gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X;
                                    gazeY = gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y;
                                }
                                else if (gazeEvent.RightEye.GazePoint.Validity == Validity.Valid)
                                {
                                    gazeX = gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X;
                                    gazeY = gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y;
                                }

                                if (gazeEvent.LeftEye.Pupil.PupilDiameter != -1 || gazeEvent.RightEye.Pupil.PupilDiameter != -1)
                                {
                                    CurrentPupilDiameters[0] = Double.IsNaN(gazeEvent.LeftEye.Pupil.PupilDiameter) ? -1 : gazeEvent.LeftEye.Pupil.PupilDiameter;
                                    CurrentPupilDiameters[1] = Double.IsNaN(gazeEvent.RightEye.Pupil.PupilDiameter) ? -1 : gazeEvent.RightEye.Pupil.PupilDiameter;
                                }

                                WampEvent evt = new WampEvent();
                                evt.Arguments = new object[] { SelectedTracker.SerialNumber,
                                                               new object[] { CurrentPupilDiameters[0],
                                                                              gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.X,
                                                                              gazeEvent.LeftEye.GazePoint.PositionOnDisplayArea.Y,
                                                                              CurrentPupilDiameters[1],
                                                                              gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.X,
                                                                              gazeEvent.RightEye.GazePoint.PositionOnDisplayArea.Y,
                                                                              gazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.X,
                                                                              gazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Y,
                                                                              gazeEvent.LeftEye.GazeOrigin.PositionInUserCoordinates.Z,
                                                                              gazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.X,
                                                                              gazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Y,
                                                                              gazeEvent.RightEye.GazeOrigin.PositionInUserCoordinates.Z,
                                                                              gazeX, gazeY } };
                                WAMPSubject.OnNext(evt);
                            }
                        }
                        catch (Exception exp)
                        {
                            //do nothing, skip
                            Console.Write(exp);
                        }
                    }
                });
                WAMPThread.Start();

                if (StreamBtn.InvokeRequired)
                {
                    StreamBtn.BeginInvoke((MethodInvoker) delegate() { this.StreamBtn.Text = "Stop"; });
                }
                else
                {
                    StreamBtn.Text = "Stop";
                }
            }
            else
            {
                IsStreamingToWAMP = false;
                SelectedTracker.GazeDataReceived -= HandleGazeData;
                if (StreamBtn.InvokeRequired)
                {
                    StreamBtn.BeginInvoke((MethodInvoker) delegate() { this.StreamBtn.Text = "Stream"; });
                }
                else
                {
                    StreamBtn.Text = "Stream";
                }
                WAMPThread.Join();
            }
        }