串行通信在Unity中运行缓慢

时间:2015-04-25 00:42:14

标签: c# unity3d serial-port serial-communication

我已将IMU(陀螺仪和Acc&磁力计)连接到我的Unity3D项目并通过USB进行串行通信。

问题是,当我的脚本对游戏代码变得不那么沉重时,串行通信会变慢 - 当IMU的值在某个时间点发生变化时,它们会在几秒后发生变化,随着时间的推移,数据流不能赶上游戏。

我从myPort.ReadLine()函数调用Update来从COM端口读取串行数据。

解决方案是什么? - 如果我理解问题,我希望串行数据读取不要等到我的应用程序的下一帧以接收新值。

可能会降低IMU设备的波特率吗?

2 个答案:

答案 0 :(得分:3)

您可以采取以下措施来优化项目:

1)您可以更改通信参数。如果您要发送音高,偏航或滚动,请不要将它们作为字符串发送,而是使用IEEE 754格式,将它们作为字节发送。此外,如果您获得四元数值,请不要浪费时间将它们转换为欧拉角。

2)尝试在设置中更改Unity中的更新速率,但要小心更新速率=较慢的统一帧速率。

3)尝试使用高波特率,例如115200或更高。如果降低波特率,IMU中的数据可能会损坏。

4)在IMU代码中,您可以切换串口通信(您可能不想连续发送所有数据,您可能会偷偷地发送数据)。我的意思是,您可以对数据进行下采样。

5)我不知道您的数据大小,但您可以使用Coroutines&收益或调用。如您所知,Unity不允许我们使用数据接收事件,但您可以创建自己的事件以了解是否已收到所有数据。 (如果您遇到流式传输问题,请尝试discardInBuffer)

6)你可以编写自己的dll(c#dll不会做任何更大的改动,所以使用C ++)。如果您使用的是Windows,则可以使用kernel32.Dll和ws2_32.dll开始搜索。

答案 1 :(得分:0)

所以我认为这个问题的最佳解决方案是线程化。

由于串行数据具有自己的速度,并且不能依赖于游戏更新频率(否则会导致串行流缓冲和大量滞后),以下解决方案对我有用:

在初始化函数(init)中,我调用invokeRepeating - 每0.01秒重复一次的计时器,在那个计时器中,我调用一个线程来读取串行数据。

这是计时器功能的伪代码:

 void timerfunction ()
 {
   if (! threadAlive){
     Start new thread - SerialThread ()
     threadAlive = true;
   }
}

void SerialThread ()
{
  Read the Serial Data..
  threadAlive = false:
}

这样,当串口内部出现问题时,游戏不会滞后,因为线程会对自身施加压力。

InvokeRepeating将确保在每个固定(理想)的时间内尝试调用线程(读取数据),因此串行数据不会缓冲。

对我来说工作得很好。串行数据速度约为16Hz,游戏帧速率为-10-100 fps。