1

Labview にバイナリで保存された非常に多数のファイルがあります。各列はタイムスタンプ クラスターであり、その後にシングルのベクトルが続きます。

各データファイルをMatlab r2013aに読み込みます

fid = fopen(filename);
data = fread(fid,[N M],'*single',0,'b');
fclose(fid);

ここで、入力配列 N、M のサイズを事前に計算します。データがどのように見えるかを知っているので、data(1:5,:)そこにタイムスタンプ データが隠されていることがわかりましたが、次のようになりますM = 1

[0 -842938.0625 -1.19209289550781e-07 0 4.48415508583941e-42]

最初の要素は常に 0 で、2 番目の要素は一定のステップ サイズで単調に減少します。3 番目の要素は双安定のように見え、2 つの非常に小さな値の間を行ったり来たりします。4 番目の要素は常に 0 で、5 番目の要素も一定です。

Labview が日付をエンコードする方法と関係があると思いますが、私の google-fu はそれを理解するのに役立ちませんでした。

これをより一般的な質問にするために、次のようにします。

Labview はタイムスタンプ クラスターをバイナリ ファイルに保存するときにどのようにエンコードしますか? また、それを読み込んで、Matlab などの別のプログラミング言語で意味のある数値に変換するにはどうすればよいですか?

編集: 後世のために、これが私の最終的なコードです(上記のコードに追加されています):

datedata = data(5:-1:1,:);
data(1:5,:) = [];

dms   = typecast(reshape(datedata(2:3,:),[],1),'uint64');
dsecs = typecast(reshape(datedata(4:5,:),[],1), 'int64');

timestamp = datenum(1904,1,1) + (double(dsecs) + double(dms)*2^-64)/(3600*24);

@Floris が Mathworks から投稿したコードでは、型キャストを直接 double にしていますが、それを試してみるとガベージが発生しました。正しい日付を取得するには、まず整数に変換してから倍精度に変換する必要がありました。私のボトルネックはfreadライン上にあるため (外部ディスクから読み取るのに 0.3 秒)、余分な型キャストのステップは、物事の壮大な計画ではごくわずかです。

追加の列 4.5e-42 は、整数値 3200 に変換されます。これは、後続のシングルのベクトルの値の数です。

4

2 に答える 2

2

これは完全な答えではありませんが、役立つはずです(自宅でLabviewもMatlabも利用できないため、今は確認できません)。

同様の質問について説明している記事がhttp://www.mathworks.com/matlabcentral/newsreader/view_thread/292060にあります。私がそこから抽出したいくつかの有用な情報:

  1. タイムスタンプは double (single ではありません)
  2. 物事を理解するために、バイトの順序を反転する必要があります (リトルエンディアンとビッグエンディアン)

有用なコメントがあります:

LabView の時間規則は 1904 年 1 月 1 日からのミリ秒単位であることに注意してください。ここに 1 つのアプローチがあります (エラーが含まれている可能性がありますが、正しい方向を示します)。

次のコード スニペットも示します。

%% Read in date information
[ fid, msg ] = fopen(FileName, 'r') ;
NColumns = 60 ; % Number of data columns - probably different for your
dataset!
[a, count] = fread(fid, [ NColumns Inf], '*single') ; % Force data to
be read into Matlab workspace as singles
a = a' ; % Convert to data in columns not rows
% The last two columns of a are the timestamp
b = fliplr(a(:, end-1:end)) ; % Must swap the order of the columns
d = typecast(reshape(b',[],1), 'double') ; % Now we can can convert to
double
time_local = datenum(1904, 1, 1) + d/(24*3600) ; % Convert from
seconds to matlab time format
fclose(fid) ;

私には信じられそうに見えます。うまくいくかどうか教えてください - そうでない場合は、午前中にデバッグを手伝うことができるかもしれません...

于 2013-07-03T02:40:42.230 に答える