1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +01:00

Convert log files to structure of array instead of array of struct from Kenz

This commit is contained in:
James Cotton 2012-01-01 13:14:18 -06:00
parent b8af44bf61
commit 21714911e8
3 changed files with 110 additions and 39 deletions

View File

@ -1,39 +1,54 @@
function [] = OPLogConvert(logfile)
function [] = OPLogConvert(varargin)
%% Define indices and arrays of structures to hold data
% THIS FILE IS AUTOMATICALLY GENERATED.
$(ALLOCATIONCODE)
outputType='mat'; %Default output is a .mat file
if nargin==0
%%
if (exist('uigetfile'))
[FileName, PathName]=uigetfile;
[FileName, PathName]=uigetfile('*.opl');
logfile=fullfile(PathName, FileName);
else
error('Your technical computing program does not support file choosers. Please input the file name in the argument. ')
end
elseif nargin>0
logfile=varargin{1};
if nargin>1
outputType=varargin{2};
end
end
if ~strcmpi(outputType,'mat') && ~strcmpi(outputType,'csv')
error('Incorrect file format specified. Second argument must be ''mat'' or ''csv''.');
end
$(ALLOCATIONCODE)
fid = fopen(logfile);
correctMsgByte=hex2dec('20');
correctSyncByte=hex2dec('3C');
% Parse log file, entry by entry
while (1)
%% Read logging header
timestamp = fread(fid, 1, 'uint32');
timestamp = fread(fid, 1, '*uint32');
if (feof(fid)); break; end
datasize = fread(fid, 1, 'int64');
datasize = fread(fid, 1, '*int64');
%% Read message header
% get sync field (0x3C, 1 byte)
sync = fread(fid, 1, 'uint8');
if sync ~= hex2dec('3C')
if sync ~= correctSyncByte
disp ('Wrong sync byte');
return
end
% get msg type (quint8 1 byte ) should be 0x20, ignore the rest?
msgType = fread(fid, 1, 'uint8');
if msgType ~= hex2dec('20')
if msgType ~= correctMsgByte
disp ('Wrong msgType');
return
end
@ -42,12 +57,15 @@ while (1)
% get obj id (quint32 4 bytes)
objID = fread(fid, 1, 'uint32');
if (isempty(objID)) %End of file
break;
end
%% Read object
switch objID
$(SWITCHCODE)
otherwise
disp(['Unknown object ID: 0x' dec2hex(objID)]);
disp(['Unknown object ID: 0x' dec2hex(objID)]);
msgBytesLeft = datasize - 1 - 1 - 2 - 4;
fread(fid, msgBytesLeft, 'uint8');
end
@ -60,13 +78,52 @@ fclose(fid);
% Trim output structs
$(CLEANUPCODE)
matfile = strrep(logfile,'opl','mat');
save(matfile $(SAVEOBJECTSCODE));
if strcmpi(outputType,'mat')
matfile = strrep(logfile,'opl','mat');
save(matfile $(SAVEOBJECTSCODE));
else
$(EXPORTCSVCODE);
end
%% Object reading functions
$(FUNCTIONSCODE)
% This function prunes the excess pre-allocated space
function [structOut]=PruneStructOfArrays(structIn, lastIndex)
fieldNames = fieldnames(structIn);
for i=1:length(fieldNames)
structOut.(fieldNames{i})=structIn.(fieldNames{i})(1:lastIndex);
end
function OPLog2csv(structIn, structName, logfile)
%Get each field name from the structure
fieldNames = fieldnames(structIn);
%Create a text string with the field names
headerOut=sprintf('%s,',fieldNames{:});
headerOut=headerOut(1:end-1); %Trim off last `,` and `\t`
%Assign the structure arrays to a matrix.
matOut=zeros(max(size(structIn.(fieldNames{1}))), length(fieldNames));
if isempty(structIn.(fieldNames{1}));
matOut=[];
else
for i=1:length(fieldNames)
matOut(:,i)=structIn.(fieldNames{i});
end
end
% Create filename by replacing opl by csv
[path, name] = fileparts(logfile);
csvDirName=[name '_csv'];
[dummyA, dummyB]=mkdir(fullfile(path, csvDirName)); %Dummy outputs so the program doens't throw warnings about "Directory already exists"
csvfile=fullfile(path, csvDirName , [name '.csv']);
%Write to csv.
dlmwrite(csvfile, headerOut, '');
dlmwrite(csvfile, matOut, '-append');

View File

@ -54,6 +54,7 @@ bool UAVObjectGeneratorMatlab::generate(UAVObjectParser* parser,QString template
matlabCodeTemplate.replace( QString("$(CLEANUPCODE)"), matlabCleanupCode);
matlabCodeTemplate.replace( QString("$(SAVEOBJECTSCODE)"), matlabSaveObjectsCode);
matlabCodeTemplate.replace( QString("$(FUNCTIONSCODE)"), matlabFunctionsCode);
matlabCodeTemplate.replace( QString("$(EXPORTCSVCODE)"), matlabExportCsvCode);
bool res = writeFile( matlabOutputPath.absolutePath() + "/OPLogConvert.m", matlabCodeTemplate );
if (!res) {
@ -78,7 +79,7 @@ bool UAVObjectGeneratorMatlab::process_object(ObjectInfo* info)
QString objectTableName(objectName);
QString tableIdxName(objectName.toLower() + "Idx");
QString functionName("Read" + info->name + "Object");
QString functionCall(functionName + "(fid, timestamp)");
QString functionCall(functionName + "(fid, timestamp, ");
QString objectID(QString().setNum(info->id));
QString isSingleInst = boolTo01String( info->isSingleInst );
@ -87,7 +88,7 @@ bool UAVObjectGeneratorMatlab::process_object(ObjectInfo* info)
// Generate allocation code (will replace the $(ALLOCATIONCODE) tag) //
//===================================================================//
// matlabSwitchCode.append("\t\tcase " + objectID + "\n");
matlabAllocationCode.append("\n\t" + tableIdxName + " = 1;\n");
matlabAllocationCode.append("\n\t" + tableIdxName + " = 0;\n");
QString type;
QString allocfields;
if (0){
@ -97,7 +98,7 @@ bool UAVObjectGeneratorMatlab::process_object(ObjectInfo* info)
type = fieldTypeStrMatlab[info->fields[n]->type];
// Append field
if ( info->fields[n]->numElements > 1 )
allocfields.append("\t" + objectTableName + "(1)." + info->fields[n]->name + " = zeros(1," + QString::number(info->fields[n]->numElements, 10) + ");\n");
allocfields.append("\t" + objectTableName + "(1)." + info->fields[n]->name + " = zeros(" + QString::number(info->fields[n]->numElements, 10) + ",1);\n");
else
allocfields.append("\t" + objectTableName + "(1)." + info->fields[n]->name + " = 0;\n");
}
@ -112,52 +113,64 @@ bool UAVObjectGeneratorMatlab::process_object(ObjectInfo* info)
type = fieldTypeStrMatlab[info->fields[n]->type];
// Append field
if ( info->fields[n]->numElements > 1 )
allocfields.append(",...\n\t\t '" + info->fields[n]->name + "', zeros(1," + QString::number(info->fields[n]->numElements, 10) + ")");
allocfields.append(",...\n\t\t '" + info->fields[n]->name + "', zeros(" + QString::number(info->fields[n]->numElements, 10) + ",1)");
else
allocfields.append(",...\n\t\t '" + info->fields[n]->name + "', 0");
}
allocfields.append(");\n");
}
}
matlabAllocationCode.append(allocfields);
matlabAllocationCode.append("\t" + objectTableName.toUpper() + "_OBJID=" + objectID + ";\n");
matlabAllocationCode.append("\t" + objectTableName.toUpper() + "_OBJID=" + objectID + ";\n");
//=============================================================//
//==============================================================//
// Generate 'Switch:' code (will replace the $(SWITCHCODE) tag) //
//=============================================================//
//==============================================================//
matlabSwitchCode.append("\t\tcase " + objectTableName.toUpper() + "_OBJID\n");
matlabSwitchCode.append("\t\t\t" + objectTableName + "(" + tableIdxName +") = " + functionCall + ";\n");
matlabSwitchCode.append("\t\t\t" + tableIdxName + " = " + tableIdxName +" + 1;\n");
matlabSwitchCode.append("\t\t\tif " + tableIdxName + " > length(" + objectTableName +")\n");
matlabSwitchCode.append("\t\t\t\t" + objectTableName + "(" + tableIdxName + "*2+1) = " + objectTableName +"(end);\n");
matlabSwitchCode.append("\t\t\t\t" + objectTableName +"(end)=[];\n");
// matlabSwitchCode.append("\t\t\t" + objectTableName + "(" + tableIdxName +") = " + functionCall + ";\n");
matlabSwitchCode.append("\t\t\t" + tableIdxName + " = " + tableIdxName +" + 1;\n");
matlabSwitchCode.append("\t\t\t" + objectTableName + "= " + functionCall + objectTableName + ", " + tableIdxName + ");\n");
matlabSwitchCode.append("\t\t\tif " + tableIdxName + " >= length(" + objectTableName +") %Check to see if pre-allocated memory is exhausted\n");
matlabSwitchCode.append("\t\t\t\tFieldNames= fieldnames(" + objectTableName +");\n");
matlabSwitchCode.append("\t\t\t\tfor i=1:length(FieldNames) %Grow structure\n");
matlabSwitchCode.append("\t\t\t\t\t" + objectTableName + ".(FieldNames{i})(:," + tableIdxName + "*2+1) = 0;\n");
matlabSwitchCode.append("\t\t\t\tend;\n");
matlabSwitchCode.append("\t\t\tend\n");
//=============================================================//
//============================================================//
// Generate 'Cleanup:' code (will replace the $(CLEANUP) tag) //
//=============================================================//
matlabCleanupCode.append(objectTableName + "(" + tableIdxName +":end) = [];\n");
//============================================================//
matlabCleanupCode.append(objectTableName + "=PruneStructOfArrays(" + objectTableName + "," + tableIdxName +"); %#ok<NASGU>\n" );
//=============================================================================//
// Generate objects saving code code (will replace the $(SAVEOBJECTSCODE) tag) //
//=============================================================================//
//========================================================================//
// Generate objects saving code (will replace the $(SAVEOBJECTSCODE) tag) //
//========================================================================//
matlabSaveObjectsCode.append(",'"+objectTableName+"'");
matlabFunctionsCode.append("%%\n% " + objectName + " read function\n");
//==========================================================================//
// Generate objects csv export code (will replace the $(EXPORTCSVCODE) tag) //
//==========================================================================//
matlabExportCsvCode.append("\tOPLog2csv(" + objectTableName + ", '"+objectTableName+"', logfile);\n");
// OPLog2csv(ActuatorCommand, 'ActuatorCommand', logfile)
//=================================================================//
// Generate functions code (will replace the $(FUNCTIONSCODE) tag) //
//=================================================================//
//Generate function description comment
matlabFunctionsCode.append("function [" + objectName + "] = " + functionCall + "\n");
matlabFunctionsCode.append("\t" + objectName + ".timestamp = timestamp;\n");
//Generate function description comment
matlabFunctionsCode.append("%%\n% " + objectName + " read function\n");
matlabFunctionsCode.append("function [" + objectName + "] = " + functionCall + objectTableName + ", " + tableIdxName + ")" + "\n");
matlabFunctionsCode.append("\t" + objectName + ".timestamp(" + tableIdxName + ")= timestamp;\n");
matlabFunctionsCode.append("\tif " + isSingleInst + "\n");
matlabFunctionsCode.append("\t\theaderSize = 8;\n");
matlabFunctionsCode.append("\telse\n");
matlabFunctionsCode.append("\t\t" + objectName + ".instanceID = fread(fid, 1, 'uint16');\n");
matlabFunctionsCode.append("\t\t" + objectName + ".instanceID(" + tableIdxName + ") = (fread(fid, 1, 'uint16'));\n");
matlabFunctionsCode.append("\t\theaderSize = 10;\n");
matlabFunctionsCode.append("\tend\n\n");
@ -169,14 +182,14 @@ bool UAVObjectGeneratorMatlab::process_object(ObjectInfo* info)
type = fieldTypeStrMatlab[info->fields[n]->type];
// Append field
if ( info->fields[n]->numElements > 1 )
funcfields.append("\t" + objectName + "." + info->fields[n]->name + " = double(fread(fid, " + QString::number(info->fields[n]->numElements, 10) + ", '" + type + "'));\n");
funcfields.append("\t" + objectName + "." + info->fields[n]->name + "(:," + tableIdxName + ") = double(fread(fid, " + QString::number(info->fields[n]->numElements, 10) + ", '" + type + "'));\n");
else
funcfields.append("\t" + objectName + "." + info->fields[n]->name + " = double(fread(fid, 1, '" + type + "'));\n");
funcfields.append("\t" + objectName + "." + info->fields[n]->name + "(" + tableIdxName + ") = double(fread(fid, 1, '" + type + "'));\n");
}
matlabFunctionsCode.append(funcfields);
matlabFunctionsCode.append("\t% read CRC\n");
matlabFunctionsCode.append("\tfread(fid, 1, 'uint8');\n");
matlabFunctionsCode.append("\tfread(fid, 1, '*uint8');\n");
matlabFunctionsCode.append("\n\n");

View File

@ -40,6 +40,7 @@ private:
QString matlabSwitchCode;
QString matlabCleanupCode;
QString matlabSaveObjectsCode;
QString matlabExportCsvCode;
QString matlabFunctionsCode;
QStringList fieldTypeStrMatlab;