【问题标题】:How to plot real time data from text file in MATLAB如何在 MATLAB 中从文本文件中绘制实时数据
【发布时间】:2013-12-24 00:53:55
【问题描述】:

我是 matlab 编码的新手,所以我仍在努力解决问题。 几乎我正在使用每 10 毫秒输出传感器方向数据的 interia 传感器。我能够将这些数据存储到一个不断更新的文本文件中。

我现在的任务是实时绘制这些数据。这涉及连续访问和读取文本文件(如果可能,每 10 毫秒),并根据时间绘制此数据。 你们中的任何人都可以给我一些指导,告诉我什么是最有效的方法。

此时,文本文件仅存储有关一个参数(传感器的 x 坐标)的数据。我可以通过 2 种方式存储这些数据: 方法1:每10ms新数据。每个都存储在一个新行中。 方法2:我可以让文本文件只有最近的一条数据(擦除以前的数据) 我可以使用这两种方法中的任何一种.. 任何你们认为更容易的方法。

我尝试使用其他 3rd 方软件从文本文件中绘制这些数据,但它们看起来都非常跳跃,并且无法足够快地从文本文件中读取。

谢谢。

【问题讨论】:

    标签: matlab plot text-files real-time real-time-data


    【解决方案1】:

    MATLAB 计时器对象会有所帮助。例如,请参阅此链接Using MATLAB to process files in real-time after every instance a file is created by a separate program

    可能会担心同时写入(您的其他进程)和读取 (MATLAB) 到单个文件。您的情况可能更适合管道而不是文件:Pipe vs. Temporary File 但我将继续使用基于 MATLAB 的解决方案来进行定时文件读取和绘图更新。

    我模仿了你的情况并学到了一些东西:

    • MATLAB 文件句柄存储当前位置。但是,如果为文件 ID 设置了文件结束标志,则在随后调用 fread 时,MATLAB 将不会查找新数据。在下面的readFile 函数中查看使用fseek 的变通方法。
    • 10 毫秒是乐观的。 MATLAB 不会遗漏点,但每次更新通常会添加四个或更多数据点,而不仅仅是一个。
    • 如果数据源使用缓冲文件写入,则 MATLAB 在缓冲区刷新到磁盘之前不会看到新数据。下面的 python 代码用于模拟数据源。该文件已打开以写入而没有缓冲:fobj = open('test.dat', 'wb', 0)

    MATLAB 代码如下:

    function [t] = livePlot(period, filename)
        //%   inputs : period : update rate in seconds
        //%            filename : name of the file to get data from
        //%
        //%   outputs: t      : the timer object
        //%                     >> stop(t) 
        //%                     ends streaming
        //%%
    
        close all;        
        t = timer('StartDelay', 1, 'Period', period, ...
                  'ExecutionMode', 'fixedRate');
        //%% timer object callback functions
        t.StopFcn  = {@stopFigure};
        t.TimerFcn = {@updateFigure};
        //%% initialize timer object user data
        d = get(t, 'UserData');
        d.data = []; % array for the data to plot
        axes('Position', [0 0 1 1], 'Visible', 'off');
        d.axes_handle = axes('Position', [.2 .1 .7 .8]);
        d.line_handle = plot(NaN,NaN);
        d.fid = fopen(filename, 'r');    
        set(t, 'UserData', d);    
        start(t);
    end
    
    function stopFigure(obj, event)
        //% close function handle
        d = get(obj, 'UserData');
        fclose(d.fid);
    end
    
    function updateFigure(obj, event)
        d = get(obj, 'UserData');        
        //% read new data from file
        tmp = readFile(obj);
        //% append to array in user data
        d.data = [d.data transpose(tmp)];
        //% update the plot 
        set(gcf, 'CurrentAxes', d.axes_handle);
        set(d.line_handle, 'XData', 1:length(d.data), 'YData', d.data);
        //% store the timer object user-data
        set(obj, 'UserData', d);
    end
    
    function [tmp] = readFile(obj)
        //% read binary data. file-ID is in the timer user-data
        d = get(obj, 'UserData');
        tmp = fread(d.fid);
        fprintf('Current file location : %d \n', ftell(d.fid));
        //% fprintf('End of file indicator : %d \n', feof(d.fid));
        //% reset the end-of-file indicator
        fseek(d.fid, -1, 0);
        fseek(d.fid, 1, 0);
        //% fprintf('End of file indicator : %d \n', feof(d.fid));
        set(obj, 'UserData', d); 
    end
    

    每隔约 10 毫秒将数据写入文件的 Python 代码:

    #!/anaconda/bin/python
    import numpy as np
    from time import sleep
    sleep_time = 0.01
    sigma = 5
    fobj = open('test.dat', 'wb', 0)
    for i in range(5000):
        sleep(sleep_time)
        x = int(np.random.normal(sigma))
        fobj.write('%c' % x)
    fobj.close()
    

    【讨论】:

    • 抱歉回复晚了。使用上面的python代码,可以做到:打开文本文件,每10ms连续写入数据,然后关闭文件。还是打开文件>写入数据>关闭文件并每10ms重复一次。因为我的印象是它必须使用第二种方法,因为我认为文件在关闭之前不会更新。 (因此 matlab 在文件关闭之前将无法访问新数据)另外感谢您的回答,它真的很有帮助
    • 我在使用此解决方案时遇到的另一个问题是,它似乎能够实时访问数据,尽管它没有正确绘制结果。整个绘图窗口似乎在 y 轴上随机绘制从 9 到 56->57 的线。生成的文本文件具有以下格式,例如:70 75 78 82 77 76 等。(其中每个数字都在一个新行上)因此是一个单列文本文件。但正如所解释的,它似乎并没有根据时间绘制这些值。任何帮助都会非常有帮助。谢谢。
    • python 数据生成代码实现了两种可能方法中的第一种。 python代码被打开,因此在写入磁盘之前没有缓冲('open'的第三个参数'0')。
    • 关于您的第二条评论:您是否混合了二进制读取和文本文件?我上面使用的 MATLAB 命令fread 从文件中读取二进制数据。该文件不应使用文本编辑器进行人工阅读。如果您希望 MATLAB 读取文本文件,请将 fread 替换为 fscanf
    • 甜蜜。谢谢,现在一切正常如果我现在向文本文件输出 2 组值,我将如何绘制它。我还会使用 fscanf,还是需要使用另一个读入函数,它可能可以将数据存储到数组中。 fscanf 似乎无法区分每列数据之间的差异。目前我正在使用“tmp = fscanf(d.fid, '%f', inf);”但这只是从文件开头读取数据到文件结尾,而不考虑 txt 文件格式。目前我将两组数据保存到不同的 txt 文件中并分别读取它们。但这似乎并不有效。
    【解决方案2】:

    您无法使用硬实时条件进行绘图,因此 matlab 总是会错过 10 毫秒的时隙。您必须使用选项 2 来获取所有数据。

    开始:编写一个仅读取自上次调用以来写入的新数据的函数。为此,请不要关闭文件句柄。它存储位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      相关资源
      最近更新 更多