Search Unity

Problem with a bluetooth GPS project on the Hololens

Discussion in 'Editor & General Support' started by LuGar, Jul 8, 2019.

  1. LuGar

    LuGar

    Joined:
    Jun 13, 2019
    Posts:
    4
    Hi, I just upgraded my project from unity version 2018.1.5f1 in a Windows UWP project with c# in backend to unity version 2018.4.3f1 in a Windows UWP project with IL2CPP in backend. The project connects a GPS to a Hololens via bluetooth to give it coordinates, so this bit of code used to work, but now since I upgraded it, it gets stuck on this :
    Code (CSharp):
    1. RfcommDeviceServicesResult services = await device.GetRfcommServicesAsync();
    The rest is this :

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Globalization;
    4. using System.Linq;
    5. using System.Text;
    6. using System.Threading.Tasks;
    7. using UnityEngine;
    8. using UnityEngine.UI;
    9. using System.Collections;
    10. using TMPro;
    11. #if WINDOWS_UWP
    12. using Windows.Devices.Bluetooth;
    13. using Windows.Devices.Enumeration;
    14. using Windows.Devices.Bluetooth.Rfcomm;
    15. using Windows.Networking.Sockets;
    16. using Windows.Storage.Streams;
    17. #endif
    18.  
    19. public class ArrowGPSReceiver : MonoBehaviour, ICoordinateProvider
    20. {
    21.     public bool hasGPS { get; set; }
    22.  
    23.     public TextMeshPro text;
    24.  
    25.     public event EventHandler GPSInfoReceived;
    26.  
    27.     public string projectionParameters = "+proj=lcc +lat_1=49 +lat_2=77 +lat_0=63.390675 +lon_0=-91.86666666666666 +x_0=6200000 +y_0=3000000 +ellps=GRS80 +datum=NAD83 +units=m +no_defs";
    28.  
    29.     private bool wantGPS = true;
    30.  
    31.     private int transactionId;
    32.  
    33. #if WINDOWS_UWP
    34.     DeviceWatcher deviceWatcher;
    35.     DataWriter tx;
    36.     DataReader rx;
    37.     StreamSocket stream;
    38.     RfcommDeviceService theService;
    39. #endif
    40.  
    41.     private void Start()
    42.     {
    43.         StartCoroutine(EventLoop());
    44.         text.text = "init";
    45. #if WINDOWS_UWP
    46.         text.text = "uwp";
    47.         deviceWatcher = DeviceInformation.CreateWatcher(BluetoothDevice.GetDeviceSelector());
    48.         deviceWatcher.Added += DeviceWatcher_Added;
    49.         deviceWatcher.Start();
    50. #endif
    51.     }
    52.  
    53.     private volatile GPSInfoReceivedEventArg eventToSend = null;
    54.  
    55.     private IEnumerator EventLoop()
    56.     {
    57.         while (true)
    58.         {
    59.             if (eventToSend != null && GPSInfoReceived != null)
    60.             {
    61.                 text.text = "eventloopif";
    62.                 GPSInfoReceived?.Invoke(this, eventToSend);
    63.  
    64.                 eventToSend = null;
    65.                 yield return new WaitForSeconds(.1f);
    66.             }
    67.             else
    68.             {
    69.                 yield return new WaitForSeconds(.1f);
    70.             }
    71.         }
    72.     }
    73.  
    74.     event EventHandler ICoordinateProvider.GPSInfoReceived
    75.     {
    76.         add
    77.         {
    78.             GPSInfoReceived += value;
    79.             transactionId++;
    80.             if (!wantGPS)
    81.             {
    82.                 text.text = "received";
    83.                 ConnectGPS();
    84.                 wantGPS = true;
    85.             }
    86.  
    87.         }
    88.  
    89.         remove
    90.         {
    91.             GPSInfoReceived -= value;
    92.  
    93.             if (GPSInfoReceived == null)
    94.             {
    95.                 wantGPS = false;
    96.                 StartCoroutine(DisconnectGPS(transactionId));
    97.             }
    98.         }
    99.     }
    100.  
    101.     private IEnumerator DisconnectGPS(int currentId)
    102.     {
    103.         yield return new WaitForSeconds(0.1f);
    104. #if WINDOWS_UWP
    105.         if (!wantGPS && currentId == transactionId)
    106.         {
    107.             if(tx != null)
    108.             {
    109.                 tx.DetachStream();
    110.                 tx.Dispose();
    111.                 tx = null;
    112.             }
    113.             if(rx != null)
    114.             {
    115.                 rx.DetachStream();
    116.                 rx.Dispose();
    117.                 rx = null;
    118.             }
    119.             if(stream != null)
    120.             {
    121.                 stream.Dispose();
    122.                 stream = null;
    123.             }
    124.         }
    125. #endif
    126.     }
    127.  
    128.     private void ConnectGPS()
    129.     {
    130. #if WINDOWS_UWP
    131.         text.text = "connect";
    132.         if (theService == null)
    133.         {
    134.             deviceWatcher = DeviceInformation.CreateWatcher(BluetoothDevice.GetDeviceSelector());
    135.             deviceWatcher.Added += DeviceWatcher_Added;
    136.             deviceWatcher.Start();
    137.         }
    138.         else
    139.         {
    140.             InitBluetoothDevice(theService);
    141.         }
    142. #endif
    143.     }
    144.  
    145. #if WINDOWS_UWP
    146.     private async void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation Args)
    147.     {
    148.         try
    149.         {
    150.  
    151.             if (Args.Id.Contains("00:07:80:fa:fb:5b"))
    152.             {
    153.  
    154.                 text.text = "beforeBlue";
    155.  
    156.                 BluetoothDevice device = await BluetoothDevice.FromIdAsync(Args.Id);
    157.  
    158.                 text.text = "lastWorkingDbug";
    159.        
    160.                 RfcommDeviceServicesResult services = await device.GetRfcommServicesAsync();
    161.                    
    162.                 text.text = "afterRfcomm";
    163.  
    164.                 if (services.Services.Count > 0)
    165.                 {
    166.                     InitBluetoothDevice(services.Services[0]);
    167.                 }
    168.                 else
    169.                 {
    170.                     System.Diagnostics.Debug.WriteLine("no service in endpoint");
    171.                 }
    172.             }
    173.         }
    174.         catch (Exception e)
    175.         {
    176.             text.text = e.ToString();
    177.             System.Diagnostics.Debug.WriteLine(e.ToString());
    178.         }
    179.  
    180.     }
    181.  
    182.     Windows.Storage.StorageFolder storageFolder = null;
    183.     Windows.Storage.StorageFile sampleFile = null;
    184.  
    185.     private async void InitBluetoothDevice(RfcommDeviceService service)
    186.     {
    187.         try
    188.         {
    189.             storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
    190.  
    191.             sampleFile = await storageFolder.CreateFileAsync("sample.txt", Windows.Storage.CreationCollisionOption.OpenIfExists);
    192.  
    193.             text.text = "streamSocket";
    194.  
    195.             stream = new StreamSocket();
    196.  
    197.             bool isConnected = false;
    198.  
    199.             while (!isConnected)
    200.             {
    201.                 try
    202.                 {
    203.                     await stream.ConnectAsync(service.ConnectionHostName,
    204.                     service.ConnectionServiceName);
    205.                     isConnected = true;
    206.                     text.text = "connected";
    207.                 }
    208.                 catch
    209.                 {
    210.                     await Task.Delay(1000);
    211.                 }
    212.             }
    213.             rx = new DataReader(stream.InputStream);
    214.  
    215.             tx = new DataWriter(stream.OutputStream);
    216.  
    217.             deviceWatcher.Stop();
    218.  
    219.             deviceWatcher.Added -= DeviceWatcher_Added;
    220.  
    221. #pragma warning disable CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
    222.             Task.Run(() => GPSReceiveLoop());
    223. #pragma warning restore CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
    224.         }
    225.         catch (Exception e)
    226.         {
    227.             System.Diagnostics.Debug.WriteLine(e.ToString());
    228.         }
    229.  
    230.     }
    231. #endif
    232.  
    233.     private async void GPSReceiveLoop()
    234.     {
    235.         while (true)
    236.         {
    237.             try
    238.             {
    239. #if WINDOWS_UWP
    240.                 text.text = "buf";
    241.                 var bufSize = await rx.LoadAsync(1000);
    242.                 var content = rx.ReadString(bufSize);
    243. #endif
    244.  
    245.                
    246.  
    247. #if WINDOWS_UWP
    248.                 text.text = "process";
    249.                 ProcessGpsInfo(content);
    250.                 text.text = "afterProcess";
    251. #endif
    252.                 Task.Delay(100).Wait();
    253.             }
    254.             catch (Exception e)
    255.             {
    256.                 System.Diagnostics.Debug.WriteLine(e.ToString());
    257. #if WINDOWS_UWP
    258.                 await Windows.Storage.FileIO.WriteTextAsync(sampleFile, e.ToString() + "\r\n");
    259. #endif
    260.                 break;
    261.             }
    262.         }
    263.     }
    264.  
    265.     private double FromDegreeMinuteToDecimal(double coordinate, string direction)
    266.     {
    267.         var degrees = Math.Truncate(coordinate / 100);
    268.  
    269.         var minutes = coordinate - degrees * 100;
    270.  
    271.         return (direction == "N" || direction == "E" ? 1 : -1) * (degrees + minutes / 60);
    272.     }
    273.  
    274.     private async void ProcessGpsInfo(string content)
    275.     {
    276.         text.text = "processgps";
    277.         var lines = content.Split('$').Where(s => s.Contains("GPGLL")).ToList();
    278.  
    279.         if (lines.Count < 2) return;
    280.  
    281.         text.text = "lines>2";
    282.  
    283.         var values = lines[lines.Count - 2].Split(',');
    284. #if WINDOWS_UWP
    285.         await Windows.Storage.FileIO.AppendTextAsync(sampleFile, values.ToString());
    286.        
    287.         text.text = "storage";
    288.  
    289.         await Windows.Storage.FileIO.AppendTextAsync(sampleFile, $"values[6]:{values[6]}");
    290.        
    291.         text.text = "storage2";
    292. #endif
    293.  
    294.         if (values.Length >= 6 && values[6] == "A")
    295.         {
    296.             text.text = ">=6 and A";
    297.  
    298.             //GPS info provided in english culture
    299.             var culture = new CultureInfo("en-US");
    300.  
    301.             var lat = double.Parse(values[1], culture);
    302.             var latDir = values[2];
    303.  
    304.             var lon = double.Parse(values[3], culture);
    305.             var lonDir = values[4];
    306.  
    307.             var finalLat = FromDegreeMinuteToDecimal(lat, latDir);
    308.  
    309.             var finalLon = FromDegreeMinuteToDecimal(lon, lonDir);
    310.  
    311.             text.text = "beforeProj4net";
    312.  
    313.             Proj4Net.CoordinateReferenceSystem referenceSystem = new Proj4Net.CoordinateReferenceSystemFactory().CreateFromParameters("", projectionParameters);
    314.  
    315.             text.text = "Proj4NetDone";
    316.  
    317.             text.text = referenceSystem.Name;
    318.  
    319.             GeoAPI.Geometries.Coordinate projectedPosition = referenceSystem.Projection.Project(
    320.                 new GeoAPI.Geometries.Coordinate(finalLon, finalLat),
    321.                 new GeoAPI.Geometries.Coordinate());
    322.  
    323.             hasGPS = true;
    324.  
    325.             var args = new GPSInfoReceivedEventArg()
    326.             {
    327.                 X = (float)projectedPosition.X,
    328.                 Y = (float)projectedPosition.Y,
    329.                 Z = (float)projectedPosition.Z
    330.             };
    331.  
    332.             eventToSend = args;
    333.         }
    334.     }
    335. }