Чтение из последовательного порта с Vive (SteamVR), что приводит к огромному отставанию - PullRequest
1 голос
/ 17 июня 2019

Я разрабатываю имитацию Forklift в HTC Vive с использованием новейшего плагина SteamVR (V 2.3.0). Я хочу добавить изготовленный на заказ руль симу, который дает значений, основанных на его вращении . Я уже реализовал управление симуляцией, используя контроллеры Vive и клавиатуру. Но в тот момент, когда я добавил код чтения последовательного соединения, симуляция начинает отставание плохо. 15-20 кадров в секунду - это то, что я получаю только чтением с последовательного порта

void Awake ()
        {
            InitializeCOMport();
            StartCoroutine(ReadData());
        }

    void InitializeCOMport()
        {
             port = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);

            try
            {
                port.Open();
                System.Threading.Thread.Sleep(1000);
                port.Handshake = Handshake.None;
                Debug.Log("Port open");
            }
            catch (Exception ex)
            {
                Debug.Log("Exception " + ex.Message);
            }
    }
    IEnumerator ReadData()
        {
            yield return null;
            do
            {
                yield return new WaitForSeconds(0.15f);
                try
                {
                    datareceived = port.ReadLine().Trim();
                    char[] charsToTrim = { 'd', 'a', 't', ' ', '=' };
                    datareceived = datareceived.Trim(charsToTrim);
                    //Debug.Log("Steering port: " + datareceived);
                    currSteeringValue = int.Parse(datareceived);

                }
                catch(System.Exception ex)
                {
                    Debug.Log("Exception " + ex.Message);
                }
            } while (true);
        }

Мне пришлось читать данные последовательного порта таким образом, потому что, когда я пытаюсь сделать это, используя событие SerialPort.DataReceived, я получаю исключение тайм-аута. С вышеупомянутым Coroutine ReadData () я могу получить данные порта COMM, но не используя событие DataRectained. Вот код, который читает буфер, используя событие-

port.DataReceived += new SerialDataReceivedEventHandler(Port_DataReceived);

     private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                Debug.Log("received");   //This function is fired with
                try
                {
                    datareceived = port.ReadLine().Trim();
                    char[] charsToTrim = { 'd', 'a', 't', ' ', '=' };
                    datareceived = datareceived.Trim(charsToTrim);
                    Debug.Log("Steering port: " + datareceived);
                    currSteeringValue = int.Parse(datareceived);

                }
                catch (System.Exception ex)
                {
                    Debug.Log("Exception " + ex.Message);
                }
                Debug.Log("received");
            }

Вышеуказанная функция Port_DataReceived () приводит к исключению тайм-аута, и элемент управления никогда не достигает Debug.Log("Steering port: " + datareceived); этой точки, поскольку он не регистрируется.

Это задержка, потому что я использую последовательные порты с Vive? У кого-нибудь есть идеи, как мне это решить?

ОБНОВЛЕНИЕ: На самом деле я тоже пытался использовать нить, но это также приводит к исключению тайм-аута. Вот код функции потока, и здесь тоже элемент управления не достигает строки Debug.Log (routing), и есть исключение тайм-аута.

serialThread = new System.Threading.Thread(RecordData);
serialThread.Start();
void RecordData()
{
    while (true)
    {
        try
        {
            Debug.Log("Trying to read data");
            datareceived = port.ReadLine().Trim();
            //Debug.Log(datareceived);
            char[] charsToTrim = { 'd', 'a', 't', ' ', '=' };
            datareceived = datareceived.Trim(charsToTrim);
            Debug.Log("Steering port: " + datareceived);
            currSteeringValue = int.Parse(datareceived);
            System.Threading.Thread.Sleep(10);
        }
        catch (System.Exception ex)
        {
            Debug.Log("Exception " + ex.Message);
        }
    }
}

1 Ответ

0 голосов
/ 17 июня 2019

Обратный вызов DataReceived не реализован в Mono, к сожалению, он просто не работает, а метод пула по умолчанию действительно блокирует поток.Решение состоит в том, чтобы запустить другой поток только для обработки com-порта.

...