Nicla Sense MEをデータ入力に使う②クオータニオンのデータをBLEで受け取るセントラル

 クオータニオンの出力をするNicla Sense MEのデータを受ける、セントラルをmatlabで作ります。3Dの表示部分はposeplotを使います。

実数で送ってくる

 クオータニオンのデータ、x、y、z、wは実数です。IEEE754 単精度浮動小数点数の形式:binary32を実数に戻します。

 実数に戻す処理をテキスト処理で記述した事例です。


function  shortF = hex2numS(decimal4)  % IEE754の単精度浮動小数点数の形式:binary32
    dataBig = strcat(num2str(dec2bin( decimal4(1),8)),num2str(dec2bin( decimal4(2),8)) ...
                  ,num2str(dec2bin( decimal4(3),8)),num2str(dec2bin( decimal4(1),8)));
    sign = (-1)^str2num(dataBig(1));        % 符号
    exponentBit = dataBig(2:1:9);
    fractionBit = ("1" + dataBig(10:1:end));
    fraction = bin2dec(fractionBit)/(2^23) ;          % 仮数
    exponent = 2 ^ (bin2dec(exponentBit) -127) ;      % 指数

    shortF = sign * fraction * exponent;
end

function Q = read_IMU(f11, f12, f13, f14)
    x = hex2numS(flip(read(f11))); % little endian->big endian
    y = hex2numS(flip(read(f12)));
    z = hex2numS(flip(read(f13)));
    w = hex2numS(flip(read(f14)));
    Q = [w x y z];
end

 数値で処理をしたプログラムです。


function  binary32 = IEEE754(fourDigit)  % IEEE754の単精度浮動小数点数の形式:binary32  
    dataBigendian = uint32(bitshift(fourDigit(1), 24) + bitshift(fourDigit(2), 16) + bitshift(fourDigit(3), 8) + fourDigit(4));

    sign = power(-1, double(bitget(dataBigendian,32)));
    fraction = 1.0 + double(bitshift(uint32(bitshift(uint32(bitshift(dataBigendian,1)) , 8)), -9)) / 8388608.0;    % 仮数
    exponents = double(2^(double(double(bitshift(bitshift(dataBigendian,1), -24))-127.0)));   % 指数

    binary32 = sign * fraction * exponents;
    %fprintf(" sign %.1f fraction %.4f exponents %.4f ",sign,fraction,exponents);
end

function Q = read_IMU(f11, f12, f13, f14)
    x = IEEE754(flip(read(f11))); % little endian->big endian
    y = IEEE754(flip(read(f12)));
    z = IEEE754(flip(read(f13)));
    w = IEEE754(flip(read(f14)));
    Q = [w x y z];
end

メイン・プログラム

 クオータニオンの四つのデータを読んできます。順序は、 w、x、y、zです。

  rotators = read_IMU(f11, f12, f13, f14);

 次のquaternion関数で、a+bi+cj+dkの形式に変換します。

  quaternion(rotators) 

 plane3.stlは、Windows10に入っていたスペースシャトルの3Dデータを、Webのあったツールでstlファイル形式に変換しました。


clear scan = blelist("Timeout", 20); Nicla_address = "9313D63DDE91"; % scanで見つかったアドレスを代入 b = ble(Nicla_address); % Nicla_BHI260 ServiceUUID = "F000AA30-0451-4000-B000-000000000000"; BHI260_QuaterX_Characteristic_UUID = "F000AA5A-0451-4000-B000-000000000000"; BHI260_QuaterY_Characteristic_UUID = "F000AA5B-0451-4000-B000-000000000000"; BHI260_QuaterZ_Characteristic_UUID = "F000AA5C-0451-4000-B000-000000000000"; BHI260_QuaterW_Characteristic_UUID = "F000AA5D-0451-4000-B000-000000000000"; f11 = characteristic(b, ServiceUUID, BHI260_QuaterX_Characteristic_UUID); subscribe(f11); % Notify f12 = characteristic(b, ServiceUUID, BHI260_QuaterY_Characteristic_UUID); subscribe(f12); f13 = characteristic(b, ServiceUUID, BHI260_QuaterZ_Characteristic_UUID); subscribe(f13); f14 = characteristic(b, ServiceUUID, BHI260_QuaterW_Characteristic_UUID); subscribe(f14); stopTimer = 200; disp('start'); figure; tic; while(toc < stopTimer) rotators = read_IMU(f11, f12, f13, f14); poseplot(quaternion(rotators), MeshFileName="plane3.stl",scaleFactor=0.3); view([50 50 -10]); end unsubscribe(f11); unsubscribe(f12); unsubscribe(f13); unsubscribe(f14); clear b

 実行例です。

前へ

Nicla Sense MEをデータ入力に使う①クオータニオンのデータをBLEで出力するペリフェラル

次へ

IMU WT901からUARTでデータ取得①接続