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:
parent
b8af44bf61
commit
21714911e8
@ -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');
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -40,6 +40,7 @@ private:
|
||||
QString matlabSwitchCode;
|
||||
QString matlabCleanupCode;
|
||||
QString matlabSaveObjectsCode;
|
||||
QString matlabExportCsvCode;
|
||||
QString matlabFunctionsCode;
|
||||
QStringList fieldTypeStrMatlab;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user