Faster/better conversion than using swapbytes typecast on udp byte datastream?

I am data-streaming from a netFT device using udp port. The data comes odered in chuncks of 36-bytes in a dubble array.
It is then converted to useful forcevalues using a swapbytes- typecast conversion between uint8 and int32. However this conversion is to slow for the live data stream and results in a slow buildup in the buffer. (which is solved with a dynamic buffer data collection). The swapbytes call is apprently the call that takes the longest time.
Is thera a way to do a faster/better conversion?
I can change the encoding for the data coming from the udp, but this changes the encoding to early in the conversion (the uint8 encoding rather than the int32 encoding?) and i dont know what changes in the conversion to do to accommodate the change? And would it even be faster?
If there is no alternative would it be faster to do the conversion in larger chuncks? It is now called with a for-loop with splitup data from a reading of aproxmatly 36000-bytes.
u = udpport('byte', 'IPV4');
% [some code to start data stream]
data = read(u, 36);
%u.ByteOrder="big-endian"
%u.ByteOrder="little-endian"
%% Exampel data
data =[0 5 187 8 1 136 61 48 0 0 0 0 1 67 58 246 255 127 176 76 10 231 55 137 255 240 253 91 255 229 79 46 255 240 59 110];
fx = double(swapbytes(typecast(uint8(data(13:16)), 'int32')))/1000000; %too slow, is there a faster way

 Accepted Answer

Try this:
%% Exampel data
data =[0 5 187 8 1 136 61 48 0 0 0 0 1 67 58 246 255 127 176 76 10 231 55 137 255 240 253 91 255 229 79 46 255 240 59 110];
fx = double(swapbytes(typecast(uint8(data(13:16)), 'int32')))/1000000
fx = 21.1832
polyval(data(13:16),256)/1000000
ans = 21.1832
%or (this syntax migh be apted to be optimized by JIT, EE)
(data(16)+256*(data(15)+256*(data(14)+256*data(13))))/1000000
ans = 21.1832

6 Comments

Super, that seems to be about 3 times as fast. Would not had figured that out, smart use of polyval for the bytevalue scaling. However I seem to get a overflow issue in on another axis fy (data(17:20)) on some values with this method so will have to figure that out. (force values above +15 (negativ seems fine))
If you post your answer in the answerblock i can accept the answer if you like.
This was by far the fastest way but has also the overflow issues.
(data(16)+256*(data(15)+256*(data(14)+256*data(13))))/1000000 0.025 s
fxP = polyval(data(13:16),256)/1000000; 2.891 s
fx = double(swapbytes(typecast(uint8(data(13:16)), 'int32')))/1000000 5.954 s
Time is scaled by a live data collection run
"overflow issue in on another axis fy (data(17:20)) on some values with this method"
Can you provide example? Probably the first byte should be interpreted as signed?
The issue is when the first two bytes switch between 0 to 255. In the end it should be a signed int32, how do you change the first byte to a signed one? I tried with some typecast on the first byte but didnt seem to work. Very grateful for the help so far.
offset=[20.5376145665714 4287.33172423386 182.674551254429 4293.93191662815 4293.18155802271 4293.92427340814];
fx=[-20.5278905665714
4274.41518743343
-20.4875565665714
-20.5142975665714
-20.4923575665714
4274.38868343343
4274.34425143343
4274.37630543343
-20.5027935665714
4274.36378243343
-20.5036935665714
4274.33137143343
4274.40336943343]+offset(1)
DataX=[0 0 37 252;
255 255 199 98;
0 0 195 138;
0 0 91 21;
0 0 176 201;
255 255 95 218;
255 254 178 74;
255 255 47 128;
0 0 136 5;
255 254 254 149;
0 0 132 129;
255 254 127 250;
255 255 153 56];
fy=[7.47539876614064
-4287.29615723386
7.31717076614132
7.42155976614140
7.46915576614083
7.58695976614126
7.58782776614135
-4287.27964423386
7.39467276614141
-4287.29164423386
7.56807976614073
-4287.30481823386
7.49322576614122
7.51997376614145
7.57563476614087
-4287.25314423386]+offset(2)
Datay=[255 253 142 83;
0 0 138 239;
255 251 36 63;
255 252 188 4;
255 253 117 240;
255 255 66 28;
255 255 69 128;
0 0 203 112;
255 252 82 253;
0 0 156 144;
255 254 248 92;
0 0 105 26;
255 253 211 246;
255 254 60 114;
255 255 21 223;
0 1 50 244];
for i=1:13
fxR=(DataX(i,4)+256*(DataX(i,3)+256*(DataX(i,2)+256*DataX(i,1))))/1000000
fyR=(Datay(i,4)+256*(Datay(i,3)+256*(Datay(i,2)+256*Datay(i,1))))/1000000
end
Solved the overflow issue by going back to typecast, but switching the datainput order, eliminating swapbytes. A bit slower than the more optimized solotion (about 50 times slower) but much faster than the swapbytes method. So it will do for now. Thanks for the help.
fxCast=double(typecast(uint8(data(16:-1:13)),'int32'))/1000000;
Overfow fix, using simple comparison
fxR = (DataX(i,4)+256*(DataX(i,3)+256*(DataX(i,2)+256*DataX(i,1))))/1000000;
if fxR > 2.147483647000000e3 % double(intmax('int32'))/1e6
fxR = fxR-4.294967296000000e3; % -double(intmax('uint32'))/1e6
end

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2023b

Asked:

on 1 Feb 2024

Edited:

on 2 Feb 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!