Optimally Converting a CAN message in Matlab
7 次查看(过去 30 天)
显示 更早的评论
Hi,
I am working on converting a CAN logger file that is several hours long. The tools provided by the CAN logger manufacturer can't handle data files this big. So I have just buckled down and done it in Matlab. Basically, because the Vehicle Networking Toolbox reads a dbc file for you which saved me a lot of time.
The problem is that the script runs really slow... after running the profiler on it, it appears that a significant amount of time is used doing the operations to convert the logger data into an engineering number. This includes functions like bin2dec, dec2bin, fliplr.
I start with a line from a logger file such as this:
' 0.000595 1 33 Rx D 8 00 96 17 32 00 00 64 09';
The last 8 numbers are the 8 bytes of the CAN message. I read this into an array called "bytes". This works pretty quickly.
bytes = [0 96 17 32 0 0 64 9]
I then process "bytes" array to get what I call "bitstrm". Just 1's and 0's that I can select and process.
%Convert bytes directly to a bitstream
bitstrm = fliplr(dec2bin(typecast(uint8(bytes),'uint64'),64));
Then I run the data through the attached function, "calc_sig_value" that converts it to engineering units. (Would have pasted below but couldn't get code button to work). The function is more or less carrying out this operation.
"engineering value" = calc_sig_value(bitstream,CAN_Message_ID,Signal_index,database_structure)
where database_structure is the output of applying canDatabase() from the vehicle network toolbox to a Vector *.DBC file
My question is this: Based on the process I have detailed so far, am I doing operations to convert this message in an inefficient way that can be easily improved by rearranging the order I call MATLAB functions in? I feel like I am doing a lot of fliplrs, and dec2bin, bin2dec, etc. and probably not in the optimal order. This process does give the correct values, it is just slow.
Let me know if something is unclear... I expect I have left out something major that I am doing. Also, I can't really provide my dbc file, unless I were to sanitize it. Let me know if that really helps with optimizing.
0 个评论
采纳的回答
Walter Roberson
2016-2-3
It is an error to use dec2bin on a uint64 whose value might exceed 2^53-1 . dec2bin() will convert its input to double and convert that.
To avoid that, do not group into uint64. You can dec2bin() the doubles directly. But be careful, because when you group them with typecast to uint64, the byte order effectively flips around, with the first byte in the list becoming the least significant byte. If that is something you want to preserve then
bitstrm = reshape(fliplr(dec2bin(bytes,8)).',1,[]);
and note that the fliplr() is doing something fairly different here (reversing by byte, not the whole stream)
You can avoid a function call overhead by using a temporary variable
t = dec2bin(bytes,8);
bitstrm = reshape(t(:,end:-1:1).',1,[]);
I would have expected that someone would have put together some mex code to do this conversion, but I do not see it at the moment.
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!