1

我正在使用最新的SteamVR 插件 (V 2.3.0)在 HTC Vive 中开发叉车模拟。我想在 sim中添加一个定制的方向盘,它根据它的旋转给出值。我已经使用 Vive 控制器和键盘实现了模拟控制。但是自从我添加串行连接读取代码的那一刻起,模拟就开始滞后了。15-20 fps 是我从串口读取得到的。

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 端口数据,但不能使用 DataRecieved 事件。这是使用事件读取缓冲区的代码-

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(steering) 行,并且存在超时异常。

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);
        }
    }
}
4

1 回答 1

0

不幸的是,DataReceived 回调没有在 Mono 中实现,它根本不起作用,并且默认的池方法确实阻塞了线程。解决方案是启动另一个线程仅用于 com 端口处理。

于 2019-06-17T12:23:39.630 回答