在Unity3D中记录时间序列数据的有效方法?

时间:2015-01-06 22:56:31

标签: c# unity3d

我想在每次更新时以.csv格式记录几个项目。以前我用两种不同的方式做到了这一点:

  1. 打开并附加文件,然后在每次更新时关闭它。
  2. 存储多个样本并定期批量记录。
  3. 这两种方法都达到了我想要的水平,但我想知道其中任何一种方法是否存在效率问题。

    我应该完全使用其他方法吗?

2 个答案:

答案 0 :(得分:1)

Hy,

另一种方法可能是使用数据采集框架,例如" LabStreamingLayer"。您可以在github account上找到一个小实现。

我知道这个问题很陈旧,但LSL很酷,值得一试! 此实现仍在开发中,但应该开箱即用。

[编辑]你是绝对正确的。抱歉快拍...所以这里有更全面的答案:

LabStreamingLayer(LSL)框架是高分辨率时间序列的数据采集框架。主要用于流EEG(Brainsignals ... :))数据通过网络来保存和分析它们。它通过网络实现时间同步,因此可以组合数据流以进行进一步分析。 例如,我使用框架来获取3D中对象的方向和位置数据,这些数据稍后将与EEG数据相关联。

要使用该框架,您需要将C#api(实际上只是LSL.cs文件)和liblsl.dll包含到您的c#项目中,而且只需要一对就可以将数据推送到LSL代码行。

using LSL;

public class LSLOutlet : MonoBehaviour
{
private liblsl.StreamOutlet outlet;
private liblsl.StreamInfo streamInfo;
private float[] currentSample;

public string StreamName = "Unity.ExampleStream";
public string StreamType = "Unity.Random01f";
public int ChannelCount = 4;

void Start()
{
    currentSample = new float[ChannelCount];

    streamInfo = new liblsl.StreamInfo(StreamName, StreamType, ChannelCount, Time.fixedDeltaTime);

    outlet = new liblsl.StreamOutlet(streamInfo);
}

public void FixedUpdate()
{ 
    currentSample[0] = Random.value;
    currentSample[1] = Random.value;
    currentSample[2] = Random.value;
    currentSample[3] = Random.value; 
    outlet.push_sample(currentSample);
}
}

outlet.push_sample(currentSample)会自动为样本集添加时间戳。关于Unity的固定更新方法,两个样本之间的时间应该或多或少appStartTime + tn -1 + Time.fixedDeltaTime。

另一方面,你需要一个实现的应用程序:

public class LSLInlet : MonoBehaviour {

liblsl.StreamInfo[] results;
liblsl.StreamInlet inlet;

int expectedChannels = 0;

void Start () {

    // wait until the expected stream shows up
    results = liblsl.resolve_stream("type", "Unity.Random01f");
    // open an inlet and print some interesting info about the stream (meta-data, etc.)
    inlet = new liblsl.StreamInlet(results[0]);

    expectedChannels = inlet.info().channel_count();

    Debug.Log(inlet.info().as_xml());
}

void FixedUpdate()
{
    // read samples
    float[] sample = new float[expectedChannels];

    while (inlet.samples_available() > 0)
    {
        inlet.pull_sample(sample);

        foreach (float f in sample)
            Debug.Log(string.Format("\t{0}", f));

    }
}

}

所以你会得到一个时间序列。您可以自己保存数据,也可以使用LabRecorder - 将流保存在基于xml的简单文件中。有关更多信息,请参阅自述文件。

有关更多示例,请参阅SDK中的示例,该示例链接自LSL4Unity存储库的自述文件。 (抱歉,由于我的声誉很低,我无法直接链接这些东西)。

所以,我希望这可能会有所帮助...... :)请考虑LSL(github wiki等)的文档。整个事情都有详细记载!

答案 1 :(得分:0)

建议使用记录稳定/可靠的库,如NLog或log4net

如果使用NLog,则特定于CSV布局设置的链接:https://github.com/NLog/NLog/wiki/CsvLayout

提供格式化的灵活性。效率是您需要根据比较测试运行来衡量的。此外,还可根据您的需求提供归档日志文件的选项。