クレイジースモールシリーズ第16,17弾

クレイジースモール3D5FT,クレイジースモール6A5FT

姿勢情報出力+5方向プログラマブルキーボード

(9軸センサー搭載)クレイジースモール3D5FT 製品番号 CZSM3D5FT JAN 4580618303503

(6軸センサー搭載)クレイジースモール6A5FT 製品番号 CZSM6A5FT JAN 4580618306504

開発製造 cooyou.org
トップページ
製品ホームページ https://cooyou.org/3d
お問い合わせ先 admininfo@cooyou.org

製品比較
製品方向数非接触/接触反応速度反応距離外乱光干渉押し続けモードマウス
OneFT1接触速い--ありクリック
AirOneFT1非接触遅い/速い(自動)長い少ないありクリック
ATch1非接触/接触速い短い多いありクリック
FT4接触速い--ありクリック
AirFT4非接触遅いなしクリック
5FT5接触速い--ありフル
3D5FT,6A5FT5接触速い--ありなし(アプリで実現)

「クレイジースモール3D5FT」「クレイジースモール6A5FT」のご紹介


「クレイジースモール3D5FT」Amazonでの販売ページ

「クレイジースモール6A5FT」Amazonでの販売ページ

上下左右に加えて押し込みもできる5方向ジョイスティック搭載のUSBプログラマブルキーボードに加えて、姿勢情報のシリアル通信出力ができるデバイスです。各方向に最大3つのキーの組み合わせを登録可能。側面の3つのABCボタンに割り当てられたプリセットごとに登録できます。
姉妹品の5FTとの大きな違いは、本体の姿勢情報(回転角度,加速度)をシリアル通信で出力できる点です。
マウス機能は本体にはありませんが、シリアル通信を利用して空中マウスとして利用できる付属アプリがあります。空中マウス機能ではPC画面へ向けるだけで、向けた先にマウスカーソルが移動します。
また、姿勢情報にはロール、ピッチ、ヨーの他に、3次元CGで多用されるクォータニオンと、本体のジョイスティックボタン情報も含まれます。
※ロール、ピッチ、ヨーの代わりに3軸の加速度に変更することも設定で可能です。
本体はCOMポートとしても認識されますので、簡単に他のソフトウェアと連携が可能です。また、付属アプリでは、シリアル通信をLANのソケット通信やWebSocket 通信に変換する付属ソフトがありますので、例えば、Web GL(Three.jsを利用)を使ってブラウザ上で3次元CGを表示するWebページとも連携することができます。javascriptで簡単にJSON形式で情報を取得できます。OpenGLのpythonのサンプルもあります。Processingのサンプルもあります。
モデリングソフトのBlenderと連携するプラグインのサンプル(※experimental)もあります。Blender内の任意のオブジェクトの姿勢(角度)を、本体の姿勢と同じにすることができます。
ゲームエンジンのUnityやUnrealEngineからも付属ソフトウェアを介して連携することが簡単にできます。サンプルスクリプトがありますので、すぐに実装できると思います。
シリアル通信の方式は、姿勢情報を連続的に出力するモード(プリセットB)と、アプリ側から要求があった場合に返信するモード(プリセットC)の2種類があります。プリセットAの場合はシリアル通信は行いません。シリアル通信とキーボード出力は併用出来ます。※キーボード出力処理の間はシリアル通信は停止します。
VRやロボット制御などの研究開発分野やゲーム開発などで姿勢制御に利用できます。Open GLやDirectXなどの3次元CGプログラミングやクォータニオン,行列演算の学習用途やRaspberry PiやArduinoとの連携にも適してます。
付属ソフトやサンプルのソースコードを公開しておりますので、自由にご利用ください。
※3D5FTは9軸センサー搭載でYAWドリフトが起こりにくいです。6A5FTは地磁気センサーが無いためYAWドリフトは原理的には起こる可能性がありますが、地磁気には影響されません。
※姿勢情報には移動量、角速度、地磁気情報は含まれません。
※クォータニオンから4次元行列への変換サンプルもあります。
※ロールピッチヨーの角度単位は度ですが、利用する座標系や演算順序が異なると正しく表示されません。
※姿勢情報はクリティカルな用途や精密制御の用途には適しません。
※磁石やPC等の磁界を乱す機器の近くの場合は、正しい姿勢情報が得られない場合があります。その場合は、磁石やPCから10cm以上離すなどをしてお試しください。


仕様

インターフェースマイクロUSB USBバスパワーで動作
動作OSWindows
※標準ドライバでキーボード、COMポートとして認識
ボタン側面A,B,C (USB近くからA、中央B、離れたC)
ジョイスティックスイッチ式8方向傾斜(登録は4方向)+プッシュ
姿勢センサー3D5FT:9軸(加速度、ジャイロ、地磁気),6A5FT:6軸(加速度、ジャイロ)
プリセット A,B,Cの3つ。各ボタンで切り替え。
   それぞれキー出力モードを設定可能
   プリセットごと左右上下,押し込みにそれぞれに最大3つのキー登録
初期値は以下(左,右,上,下,押し込み順):
プリセットA*A,D,W,S,
プリセットB矢印左,右,上,下,スペース
プリセットC登録なし
設定項目*が初期値
キー出力モード(*押し続け、瞬間、連続)
連続時の時間間隔(*低速、中速、高速)
オールリセット
センサー初期設定
姿勢ゼロ点リセット
出力モード(*軸回転、加速度)
シリアル通信ボーレート115200,ストップビット1,フロー制御なし,パリティビットなし
回転角度、クォータニオン、ジョイスティック状態
付属ソフト空中マウス機能、LAN通信、WebSocket
登録キー日本語キーボードのキー
ケース 色ABS樹脂 黒
幅.奥行.高さ 重さ46x25x38mm 23g
付属品取扱説明書
*USBデータケーブルは付属しません
*付属ソフトは製品HPよりダウンロードしてください
保証期間3ヵ月
日本製

本体は主にプラスチック素材で出来ておりますので、体重をかけたり強い力で操作すると破損の恐れがあります。保証外となりますのでご注意ください。


クレイジースモール3D5FT,6A5FT取扱説明書




姿勢情報を利用する準備

取説に従って、センサーの初期設定を行ってください。次の手順です。
※センサーに影響ないように磁石やPCから最低10cmは離して行ってください。
初期設定はCボタンを押したままケーブルを挿して(電源ON)ください。その後、ボタンを離します。
次に、本体を平置きしてから、Cボタンを押して離します。このまま3秒待ちます。
※姿勢は、本体のジョイスティック面を天井方向、側面ボタンを左、USBソケットを手前に置いた状態が、平置きと考えてください。
(3D5FTの場合のみ次の操作)次に、Cボタンを押して離します。本体を8の字を描くようにあらゆる方向へ回します。これを1分間続けます。

その後、ケーブルを抜きます(電源OFF)。
※設定が適切でない場合や、電磁波や磁石等の影響がある場合、本体を動かしていなくても、いつまでも姿勢が変化し続けることがあります。(実行開始20秒程度は不安定ですが正常です。)
姿勢情報はプリセットBまたはCで利用できますので、ボタンを押さない状態でケーブルを挿して(電源ON)から、BまたはCボタンを押して離します。

シリアル通信の準備としましては、COMポート名の確認が必要ですので、本体とPCをUSBケーブルで接続してから、
Windowsのデバイスマネージャ(スタートボタンを右クリックしたメニューから起動できます)を表示して、「ポート(COMとLPT)」の表示をご確認ください。
複数のCOMポートがある場合は、ケーブルを抜き刺ししてみて、非表示・表示となったものです。
本体の動作としましては、
プリセットBで運用している場合は、プリセットBボタンで姿勢が本体内でゼロリセットされます。
プリセットCで運用している場合は、プリセットCボタンで姿勢が本体内でゼロリセットされます。
プリセットAでは姿勢情報は利用できません。

シリアル通信

プリセットBまたはCにしておく必要があります。ボーレイトは115200の固定です。
プリセットBでは、本体からPCへ送信を連続的に行います。
プリセットCでは、本体は受信状態となり、’D’という文字を受けた時だけ、PCへ1回の送信を行います。連続的に送信するには、この動作を繰り返します。
送信フォーマットは、テキストデータで、76バイト固定長です。
CZS,X軸回転,Y軸回転,Z軸回転,qx,qy,qz,qw,LRUDP,チェックディジット2桁(改行)
となります。

(例)

CZS,-001.515,-022.405, 006.895,-0.00126,-0.19469, 0.05642, 0.97923,00000,28

‘CZS’は固定の文字列
軸回転は角度(単位は度) 999.999 プラス値の場合は先頭はスペース
qx,qy,qz,qwはクォータニオン9.99999 プラス値の場合は先頭はスペース
ジョイスティック(LEFT,RIGHT,UP,DOWN,PUSH)の5つの状態(押されている1、押されていない0)00000の部分です。
先頭のCZSから最後のカンマまでのアスキーコードを数値として、全て合計し、合計値末尾の2桁を文字列にしたもの。(2桁のチェックディジット)
最後に改行\nが入ります。
※設定により軸回転出力の代わりに加速度出力に変更することが可能です。設定方法は、BおよびCボタンを押しながら電源ON後ボタンを離してから、次にAボタンを押した場合は軸回転出力(初期値)となり、Bボタンを押した場合は加速度出力となります。設定後は電源OFFします。

※キー割り当てがある場合、ジョイスティック傾斜でキー出力も別途行われますが、その間は通信が一時的に停止します。

以下の各サンプルを実行している時に、角度がずれている場合は、プリセットボタンを押すことで、ゼロ点リセットされます。安定するまで通信開始から20秒程度かかりますので、その間は平置きにしておくほうがいいです。必要に応じて複数回ゼロ点リセットを行なっても結構です。
センサーの初期設定がうまくいっていないと角度のずれは直りませんので、その場合は再度初期設定を行なってください。

pythonのシリアル通信サンプル

本体とシリアル通信を行うサンプルです。言語はpython3系で、pyserialライブラリが使われてます。
25行程度の簡単なプログラムですのでpythonを知らなくても、ほぼ理解できると思います。
実行するには、pythonとpyserialのインストールだけ少し手間かと思いますが、ここでは解説しません。pythonは3系を使ってます。
リンクを右クリックで保存ssv.py
実行方法は、本体をプリセットCにしておき、COMポートの名前を指定して、


python ssv.py COMNAME
です。例えば、COM19でCOMポートが認識されている場合では、

python ssv.py COM19
と実行すると、'D'という文字をアプリ側から送信して返信をダンプします。それを繰り返します。
実用的なアプリにするには、チェックディジットを計算して合致しているか確認すべきです。


pythonのOpenGLサンプル

シリアル通信を行なってOpenGLでオブジェクトの姿勢を本体とリアルタイムで一致させるサンプルです。言語はpython3系で、PyOpenGL,pyserial,glfwライブラリが使われてます。
リンクを右クリックで保存3dtest.py

実行方法は、COMポートの名前を指定して、


python 3dtest.py COMNAME [0 or 1]
です。最後の数字は0か省略であればプリセットCでの通信を行い、1の場合はプリセットBでの通信を行うという意味です。本体のほうもこのプリセット設定に合わせておく必要があります。
例えば、COM19でCOMポートが認識されている場合で、プリセットCの時は、

python 3dtest.py COM19
のように実行します。
サンプルではメイン関数で主な処理がされていて

##### rotate matrix from quaternion #########
m=[ 1, 0, 0, 0, 0, 1, 0, 0,0, 0, 1, 0, 0, 0, 0, 1]
compose(q[0],q[1],q[2],q[3],m)
glMultMatrixf(m)
#####################################
の部分で、通信によって取得したクォータニオンqをcompose関数によって4次元行列mに変換を行い
glMultMatrixf関数で回転を適用してます。
ここで、composeはサンプルファイル内で定義されている関数です。

また、クォータニオンからロールピッチヨーの回転に変換してから、適用するには上記はコメントアウトして、下記部分のコメントを外すと同様の動作となります。

##### rotate degree from quaternion ########
#deg=[0,0,0]
#Quaternion2EulerDeg(q[0],q[1],q[2],q[3],deg)
#glRotatef(deg[2], 0.0, 0.0, 1.0)
#glRotatef(deg[1], 0.0, 1.0, 0.0)
#glRotatef(deg[0], 1.0, 0.0, 0.0)
####################################
Quaternion2EulerDegはサンプルファイル内で定義されている関数です。クォータニオンからロールピッチヨーの角度に変換してます。

また、同じように取得したロールピッチヨーの値を使用する場合は、上記はコメントアウトして、下記部分のコメントを外すと同様の動作となります。

##### rotate degree ##########################
#glRotatef(d[2], 0.0, 0.0, 1.0)
#glRotatef(d[1], 0.0, 1.0, 0.0)
#glRotatef(d[0], 1.0, 0.0, 0.0)
##########################################
ジョイスティックの状態は、btn[5]の配列にそれぞれ0(押されてない)、1(押されている)がはいります。LEFT,RIGHT,UP,DOWN,PUSHの方向順で5つ格納されてます。
通信内容を表示するには、

#print(line)
のコメントを外します。コマンドプロンプトに表示されるようになります。
プリセットBとCの違いは、Cの場合だけ

com.write(b'D')
が実行されます。サンプル側から本体へ'D'という1文字を毎回送信します。
プリセットBの場合は無条件でデータが送られてくるのに対して、プリセットCでは必要な場合のみ返信されます。


Processingのサンプル

シリアル通信を行なってオブジェクトの姿勢を本体とリアルタイムで一致させるサンプルです。言語はProcessingが使われてます。
Processingはver3.3の環境で動作確認されてます。本体はプリセットCで動作します。
リンクを右クリックで保存procg.pde
実行前に、COMポートの名前をソースコードのファイルの先頭付近の以下の部分を修正してください。

String comname="COM19";



DXライブラリのサンプル

DXライブラリとはDirectXを使いやすくしたフリーのライブラリです。DxLibとも呼ばれます。
サンプルではDXライブラリを使用して、シリアル通信を行なってモデルの姿勢を本体とリアルタイムで一致させてます。
本体はプリセットCで動作します。
リンクを右クリックで保存czsm3d5ftdxlib100.zip(実行ファイル)
リンクを右クリックで保存3dtest.mv1(モデルファイル)
リンクを右クリックで保存Sample.cpp(変更部分のソースコード)

DXライブラリの公式サイトからダウンロードできる3DのサンプルソースにはSample.cppというファイルが含まれますが、
それの内容を入れ替えていただければ、ビルドできます。
VS2019にて確認しました。

モデルファイルは(作業フォルダから読み取られますので、)実行ファイルと同じフォルダに配置してください。
モデルファイルはBlenderで作成してFBX形式に出力したものを、DXライブラリのツールでmv1形式に変換したものです。
実行ファイルは解凍すると、exeファイルになりますので、以下のように引数にCOM名を指定して実行できます。
姿勢はプリセットCボタンを押したときにゼロリセットされます。CGモデルと姿勢が一致するまで何度か操作を行ってみてください。
※円錐の先が天井方向、直方体が奥の方向となっている状態が角度0とします。本体は手前にUSB側、ジョイスティック面を天井方向とします。
ESCキーでウインドウを閉じて終了します。

czsm3d5ft.exe COM19



クォータニオンを利用するには行列に変換してから利用します。WinMain関数内の以下で設定されてます。

////////quaternion to matrix/////////
MATRIX   matrix;
compose(-param[3], -param[4], param[5], param[6], (float*)matrix.m);
MV1SetRotationMatrix(mh, matrix);
//////////////////////////////////////
ここで、composeはSample.cpp内で実装されている関数です。
ロールピッチヨーを利用するには、上記をコメントアウトして以下のコメントを外します

////////degree ///////////////////////
//mrot.x = deg2rad(-param[0]);
//mrot.y = deg2rad(-param[1]);
//mrot.z = deg2rad(param[2]);
//MV1SetRotationXYZ(mh, mrot);
/// //////////////////////////////////



付属ソフトウェア

付属ソフトウェア実行ファイル、ソースファイル
(※シリアル通信からシリアル通信への転送アプリは'Arduino Unoを利用したロボット制御'で後述)
リンクを右クリックで保存czsm3dexe110.zip(実行ファイル)
リンクを右クリックで保存czsm3dsrc110.zip(ソースファイル。VS2019プロジェクト)
実行ファイルのzipを解凍するとczsm3d.exeとなりますので、それをダブルクリックすると実行できます。
実行を許可するかどうかの表示がでたら許可してください。
ソースからのビルドはVS2019(Communityエディションで可)で、NuGetでopenssl-vc140-static-32_64 ver1.1.1.1というパッケージを追加するとビルドできます。

付属ソフトウェアを利用した空中マウス


付属ソフトを利用した空中マウスの利用方法について解説します。

付属ソフトを起動して、[設定・実行]メニューから[設定]を表示します。

設定画面で、"COM名称"を入力します。
空中マウスの"プリセットB"または"プリセットC"を選択します。本体のプリセット設定に合わせます。
"軸回転"を選択します。本体の設定も軸回転出力(初期値)にしておきます。
"マウス機能有効"をチェックします。
"画面からの位置"を入力します。画面の横幅に対して、本体までの距離が長い場合は、1.0以上の数値、短い場合は1.0未満の数値にするといいです。画面の横幅の実サイズに対して何倍の距離かを設定します。
"LAN通信サーバー機能有効"のチェックは、使用しない場合は未チェックにしてください。
[OK]ボタンで設定を保存します。
次に[設定・実行]メニューから[実行]を行います。
本体を画面中央に向けた状態で、本体のプリセットボタンBまたはCを押すと、画面中央にマウスカーソルが移動します。20秒ほどで安定しますので、安定するまで何度かプリセットボタンを押して結構です。
本体の向きを変えると、カーソル位置が移動します。
ジョイスティックを左に倒すと、左クリック。右に倒すと、右クリック。押し込むと、中クリックです。
上下に倒すと上下スクロールです。
カーソルのブレをなくすには、付属ソフトウェアの設定画面で空中マウスの"平均化レベル"の数値を変更してください。
大きい数値ほど値が平均化されてスムーズになりますが、動きの連動が遅くなります。
最小の1が最も敏感な動きとなります。
スクロール速度を変更するには、付属ソフトウェアの設定画面で空中マウスの"スクロール速度"の数値を変更してください。数値が大きいほどスクロールも大きくなります。
終了するには、プリセットボタンをAにしてシリアル通信を無効にするか、またはケーブルを抜いてください。
その後、付属ソフトウェアのウィンドウを閉じてください。

付属ソフトウェアを利用したLAN通信

他アプリで、シリアル通信ではなく、LANソケット通信で姿勢情報を得たい場合があります。
付属ソフトウェアを利用することにより、本体とのシリアル通信は付属ソフトウェア内で行い、
他アプリからはLANソケット通信で情報の受け渡しを行うことが可能です。
データのフォーマットはシリアル通信のデータから、CZSのヘッダとチェックディジットと改行を抜いたものです。
X軸回転,Y軸回転,Z軸回転,qx,qy,qz,qw,LRUDP
となります。テキストデータで、72バイトの固定長です。
※軸回転出力の代わりに加速度出力に変更することができます。本体および付属ソフトの設定変更が必要です。クォータニオン出力は設定に関わらず出力します。

(例)

  -1.515, -22.405,   6.895,-0.00126,-0.19469, 0.05642, 0.97923,0,0,0,0,0

内容の詳細はシリアル通信のフォーマット解説を参照してください。
小数の表記で、桁埋めのために先頭に挿入されていた0が省略されてます。

付属ソフトを起動して、[設定・実行]メニューから[設定]を表示します。
設定画面でポート番号を入力して、"LAN通信サーバー機能有効"のチェックを行います。
"WebSocketサーバーにする"のチェックは未チェックにします。
[OK]ボタンで設定を保存します。
次に、[設定・実行]メニューから[実行]を行います。
これでLAN通信が実行されます。
本体はプリセットCで行なってください。
本体は軸回転出力で行なってください。
付属ソフトウェアの設定画面でLAN通信の"平均化レベル"の数値は、適切な値に変更してください。
大きい数値ほど値が平均化されますが、値の遅延が大きくなります。
最小の1が最も遅延が小さいですが、値のばらつきが大きいです。

python版のシリアル通信-WebSocket変換

シリアル通信をWebSocket通信に変換するpython3スクリプトがあります。WebSocketサーバとして動作します。Windows以外のOSでも使用できます。
本体はプリセットCで行なってください。
リンクを右クリックで保存3dcom2websocket.py

python 3dcom2websocket.py COM名 [WebSocketポート(デフォルト8096)]
raspberry pi3での実行例

python3 3dcom2websocket.py /dev/ttyACM0
raspberry pi3では本機をUSBに挿すと/dev/ttyACM0で認識されました。
WebSocketのフォーマットはWindows版の付属ソフトと同じで互換があります。
Raspberry Pi OSでは20021年時点ではpython2系が入っているようなので、sudo apt-get install python3 python3-pipなどを行ってpython3環境を作成しました。
sudo pip3 install pyserial asyncio websocketsでインポートするライブラリをインストールしておきます。
デスクトップ環境は不要なので、コンソール版のRaspberry Pi OS Liteで行いました。マイクロSDカードにOSイメージをコピーするときにwpa_supplicant.conf(以下のようにwifiの設定を記載)と空のsshファイルをbootドライブ下に作成しておき、上記の3dcom2websocket.pyもコピーしておきます。

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP
network={
 ssid="(ここにWiFiのSSID名)"
 psk="(ここにWiFiのパスワード)"
}
そうすると、sshでIPアドレスの代わりにraspberrypi.localで接続ができました。sshのログイン初期パスワードはraspberryです。
/etc/rc.localの最終exit行の上に/usr/bin/python3 /boot/3dcom2websocket.py /dev/ttyACM0 &と記載しておくと起動時に自動実行されます。
実行時にシリアル通信やソケット通信が切れても、再接続待ちに自動的になるスクリプトとなってます。

pythonのLAN通信のサンプル

リンクを右クリックで保存3dsock.py
LAN通信をダンプするだけのアプリです。12行しかありません。プリセットCで動作します。

host="127.0.0.1"
port=8096
の部分を付属ソフトのホストのIPアドレスとポート番号に合わせて書き換えてください。127.0.0.1とはlocalhostのことです。
付属ソフトを実行してから、サンプルを実行します。

python 3dsock.py
として実行します。

付属ソフトウェアを利用したWebSocket通信

Web GLなどを利用して、ブラウザ上でCGを表示したい場合、WebSocketで姿勢情報を得ることができると便利です。
付属ソフトウェアを利用することで、WebSocket通信が可能になります。
データのフォーマットはLAN通信のフォーマットと似てますが、JSON形式にしたものです。
{"d":[X軸回転,Y軸回転,Z軸回転],"q":[qx,qy,qz,qw],"b":[L,R,U,D,P]}
となります。テキストデータで86バイトの固定長です。
dは回転角度(単位は度)※設定により、軸回転の代わりに加速度を出力することも可能です。
qはクォータニオン
bはジョイスティック状態5方向
となります。
(例)
{"d":[ -1.515, -22.405, 6.895],"q":[-0.00126,-0.19469, 0.05642, 0.97923],"b":[0,0,0,0,0]}

最後のジョイスティックの情報が5つに分割されて記述されます。
javascriptでJSON文字列をオブジェクト化するには、obj = JSON.parse(JSON文字列);のようにします。
これにより、obj.dとすれば、角度の小数の配列で扱えます。同様にクォータニオンはobj.qで、ジョイスティック状態はobj.bで整数の配列です。

WebGL(Three.js)のサンプル

Three.jsというjavascriptの3次元CGを扱うライブラリを利用して、Web GLで描画するブラウザ上で動作するアプリで、オブジェクトの姿勢を本体とリアルタイムで一致させるサンプルです。姿勢情報の各値も表示されます。
まず、準備としまして、サンプルの以下のURLを環境に合わせて変更してください。
また、Three.jsはCDNを利用してネット経由で参照しますので、ネット環境がない場合は動作しません。
※必要に応じてThree.jsをダウンロードしてローカル環境で動作させるなど、工夫してください。
リンクを右クリックで保存three.html
付属ソフトウェアの設定画面で"LAN通信サーバー機能有効"および"WebSocketサーバーにする"をチェックして、"ポート番号"を入力して、設定後、[設定・実行]メニューから[実行]しておきます。
本体のプリセットはCにしておきます。
ブラウザのアドレス欄にthree.htmlファイルをドラッグアンドドロップすると表示されます。

付属ソフトウェアである接続先のIPアドレスとポート番号を入力します。127.0.0.1はlocalhostの意味です。
付属ソフトウェアのポート番号の設定に合わせてください。
画面にstart,stopボタンがありますので、startボタンを押してください。
専用ソフトウェアで接続エラーのログ表示となった場合は、設定を見直してください。
再度stopボタンを押して、付属ソフトウェアを再度実行してから、startボタンを押すと、再度接続します。
※LAN環境で別々のPCで通信を行うと通信エラーになる場合があります。ブラウザのセキュリティ設定で以下のように許可するとエラーが無くなります。
 Firefoxの場合はアドレス欄にabout:configとして設定を表示して、network.websocket.allowInsecureFromHTTPSをtrueに変更します。
 Chromeの場合は、アドレス欄の鍵マークをクリックしてサイトの設定を表示して、”安全でないコンテンツ”を許可します。
 上記の設定で、例えば、cooyou.orgサーバー上のthree.htmlを表示して、192.168.0.150のようなIPアドレス指定で、ローカルエリアPCの付属ソフトウェアと通信が可能です。
 (2021年時点での確認)

付属ソフトウェアの設定画面でLAN通信の"平均化レベル"の数値は、適切な値に変更してください。
大きい数値ほど値が平均化されますが、値の遅延が大きくなります。
最小の1が最も遅延が小さいですが、値のばらつきが大きいです。
クォータニオンで以下のように姿勢が設定されます。

box.quaternion.set(obj.q[0],obj.q[1],obj.q[2],obj.q[3]);
ロールピッチヨーで設定するには、上記をコメントアウトして、以下のコメントを削除します。

//box.rotation.set(deg2rad(obj.d[0]),deg2rad(obj.d[1]),deg2rad(obj.d[2]));
ここで、初期設定で、回転の演算順を次のように設定してます。

box.rotation.order = "XYZ";


Blenderのサンプル(experimental)

フリーの3DモデリングソフトのBlenderのプラグインです。Blender2.92.0にて動作確認されてます。
LAN通信は行いませんので、付属ソフトウェアは必要ありませんがpythonのpyserialライブラリが必要です。
Blenderにpyserialライブラリを追加しておく必要があります。
インストール方法はpyserialのgithubからzipをダウンロードして、
解凍したら(下図左)のようにserialというフォルダをBlenderのscripts/modulesにコピー(下図右)します。

リンクを右クリックで保存3dtest.blend(Blenderのモデルサンプル)

リンクを右クリックで保存czsm3d5ftblenderplugin.py(プラグイン)
現在アクティブなオブジェクトの姿勢を任意のタイミングでシリアル通信を行って、本体の姿勢と一致させるプラグインです。CZSM3D5FTというプラグイン名です。
本体のプリセットはCにしてください。
プラグインをインストールする前に、コードの編集が必要です。

comname='COM19'
という部分を、環境に合わせてCOM名を変更してください。
その後、Blenderにインストールしてから有効化してください。[編集]メニューから[プリファレンス]を選択します。

アドオンの[インストール]ボタンを押して、czsm3d5ftblenderplugin.pyファイルを選択してから、

チェックをして有効化します。

プラグインを削除するには、検索窓にCZSMと記載すると検索されるので、左側の三角をクリックして、以下の画面で削除ボタンを押します。

プラグインのショートカットキーは'D'キーです。プラグインのこの部分で定義されてます。

kmi = km.keymap_items.new(CZSM3D5FT.bl_idname, 'D', 'PRESS', ctrl=False, shift=False)
Blender上で任意のオブジェクトにフォーカスがある状態で、キーボードのDキーを押すと、シリアル通信で1バイトの'D'が本体へ送信されて、姿勢情報が返信されます。
現在アクティブなオブジェクトの姿勢が設定されます。
Dキーは本体のジョイスティック操作で送出しても結構です。プリセットCにはデフォルトではキー割り当てがないので、Dキーを登録すると同様に動作します。
小文字のdでいいので、キー設定の詳細は取説を参照いただきたいですが C,P,1 060 の登録設定でジョイスティック押し込みでdが出力されます。

通信はキーを押された時にしか行われないため、リアルタイムでの姿勢変更はできません。
プリセットボタンCを押して、Dキーを打ち、ゼロ点合わせを、何度か行うと初期角度が安定します。円錐がZ軸方向へ立っていて、直方体がY軸方向へ向いているのが初期角度です。

obj=bpy.context.view_layer.objects.active
が現在アクティブなオブジェクトを取得するコードです。
姿勢はクォータニオンで設定してます。

###Quaternion###
obj.rotation_mode='QUATERNION'
obj.rotation_quaternion=(qw,qx,qy,qz)
################
ロールピッチヨーの角度で設定するには、上記をコメントアウトして、以下のコメントを削除してください。編集後にプラグインは削除してから、再インストールして、有効化してください。

###Euler###
#obj.rotation_mode='XZY'
#obj.rotation_euler = (math.radians(d[0]), math.radians(-d[2]),math.radians(d[1]))
###########


Unityでの利用

ゲームエンジンのUnityではTCPソケット通信がサポートされているため、付属ソフトウェアを仲介して姿勢情報をリアルタイムに扱うことが可能です。

準備としましては、付属ソフトウェアの"LAN通信サーバー機能を有効"にチェックをして、"WebSocketサーバーにする"は未チェックにします。プリセットCで利用します。
Unityでは、オブジェクトに以下の部分のIPアドレスとポート番号を、環境に合わせて編集してから、
C#スクリプトを制御したいオブジェクトにアタッチしておきます。
リンクを右クリックで保存sample.cs

tcp = new TcpClient("127.0.0.1", 8096);
付属ソフトウェアを実行してから、Unityを再生すると姿勢がリアルタイムで反映されます。
プリセットCボタンを何度か押して、ゼロ点リセットを行ってください。20秒程度で安定します。
Unityの座標系はX軸方向が右で、Y軸方向が上で、Z軸方向が奥です。

サンプルでは以下の部分でクォータニオンを利用してます。

this.transform.rotation = new Quaternion(-q[0],-q[1],q[2],q[3]);
ジョイスティック状態はサンプルではbtn[5]の配列変数で利用できますし、キー登録をしておくと、キー出力も利用できます。
動きをスムーズにする場合は、付属ソフトの"平均化レベル"を大きくできますが、動きの遅延も大きくなります。


Unreal Engineでの利用

ゲームエンジンのUnreal EngineではWinsockが動くため、付属ソフトウェアを仲介して姿勢情報をリアルタイムに扱うことが可能です。
UE4.26.2にて、テンプレートカテゴリはゲーム用で、C++用のBlankのプロジェクトでスターターコンテンツなしで作成しました。
動作はWindows上で開発環境上での実行、およびWindows64bit用のパッケージ化での実行にて確認しました。
準備としましては、付属ソフトウェアの"LAN通信サーバー機能を有効"にチェックをして、"WebSocketサーバーにする"は未チェックにします。プリセットCで利用します。
UEでは以下のようにC++クラスをアクタを親クラスとして追加します。
VS2019でのコード編集手順を示します。
リンクを右クリックで保存CzsmActor.h
リンクを右クリックで保存CzsmActor.cpp
まず、アクタのヘッダファイルの先頭にWinSock2.hのinclude文を追加します。
次に、sock変数をprivateとして追加します。

private:
	SOCKET sock;
次に、BeginPlay()の行の下にEndPlay関数を追加します。

virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
次に、アクタの.cppファイルのほうの実装ですが、BeginPlay関数でWinSockの初期化と接続、EndPlay関数でWinSockの終了処理、
Tick関数で、姿勢情報の受信とアクタの回転処理を行ってます。
サンプルファイルの内容をコピペしていただければそのまま使えると思います。
アクタの.cppファイルの以下の部分のIPアドレスとポート番号を、環境に合わせて編集してから、レベルエディタでコンパイルボタンを押してコンパイルします。

sock_add.sin_port = htons(8096);
sock_add.sin_addr.s_addr = inet_addr("127.0.0.1");
作成したC++クラスのアクタをレベルエディタのカメラの前方に配置します。コンポーネント追加ボタンからキューブを追加して、サイズとマテリアルを適当に調整します。
カメラに映るようにアクタの位置を調整します。回転は0にしておきます。

付属ソフトウェアを実行してから、UEを再生すると姿勢がリアルタイムで反映されます。
プリセットCボタンを何度か押して、ゼロ点リセットを行ってください。20秒程度で安定します。

サンプルでは以下の部分でクォータニオンを利用してます。

FQuat fq(q[2], -q[0], -q[1], q[3]);
this->SetActorRelativeRotation(fq);
ジョイスティック状態はサンプルではbtn[5]の配列変数で利用できますし、キー登録をしておくと、キー出力も利用できます。
動きをスムーズにする場合は、付属ソフトの"平均化レベル"を大きくできますが、動きの遅延も大きくなります。


Arduino Unoを利用したロボット制御


ここでは下記クレイジースモール3D5FT,6A5FT専用のシリアル通信の専用転送アプリを利用してロボットアームを制御する例を紹介します。
リンクを右クリックで保存(クレイジースモール専用シリアル転送ソフト実行ファイル)czsmcom2comexe100.zip
リンクを右クリックで保存(クレイジースモール専用シリアル転送ソフトVisualStudio2019用ソース一式)czsmcom2comsrc100.zip
ハードウェアで用意する主なものはPC、ロボットアーム、Arduino Uno(互換機)、外部電源(デバッグ用のUSBシリアル変換ケーブルを3つ利用)、ブレッドボードです。
ロボットアーム(TS90Aサーボモーター5個付き)はここでは中華製個人輸入で送料込み2500円くらいのものを使いました。安いですね。
サーボモーターを動かすにはArduinoから電源を取ると不安定なので、外部電源にします。
ここでは、5個のうち3個のモーターだけを使うことにします。
外部電源の取り方はいろいろあると思いますが、5Vでサーボモーター1個につき1Aとれるといいようですが、
とりあえず1Aまでなくても一応動くので、ここでは、ブレッドボードに簡単に挿せるデバッグ用のUSBシリアル変換ケーブルを3つ使って5VとGND線だけ拝借してモーター用電源に利用しました。
電源として利用するだけなので、USBシリアル変換としては利用しないのですが、開発時には、Arduino Unoのデバッグで利用しました。

ソフトウェアシリアルライブラリを使うと、PCからは追加COMポートとして利用できるようになります。
標準のUSBのほうは通信用のCOMとして利用するため、デバッグ用出力には使えなかったためです。
Auduino Unoは以下のスケッチを書き込んでおきます。
リンクを右クリックで保存arduinoczsm3d.ino
Servoライブラリを使用してます。

TS90Aのサーボモーターは3本の線があり、茶色線はGND(他の全部のGNDとも接続しておきます。)、赤色線は5V(これは各デバッグ用のUSBシリアル変換ケーブルの5Vと接続)、オレンジ線(制御用の線なので、任意のArduino Unoのピンに接続)
ちなにみにServoライブラリを使うと、PWM用のピン以外でも使えるようになるらしいです。

さて、転送用ソフトのほうは起動して、設定を行います(設定・実行メニューから設定)。クレイジースモール本体の受信COM名称に記載して、Arduino Unoを転送先COM名称に記載します。
プリセットはCを選択して、軸回転を選択します。
転送先ボーレートは今回はArduino用スケッチで38400固定にしてあるので38400にします。(受信用は115200固定となってます。)
平均化レベルは1にします。
クレイジースモール本体のほうは起動してプリセットCにします。
Arduino Unoとロボットアームを起動すると自動的に初期位置に動きます。
通信待ちになりますから、転送ソフトを実行します。(設定・実行メニューから実行)
ロボットアームと本体の姿勢が連動しますので、本体Cボタンで本体角度のゼロ点設定を行うと見た目の角度が一致します。
台の横回転(Yaw)と、アームの縦回転(Pitch)と、アームの爪の開閉(Roll)が連動します。
サーボモーターの角度最小値と最大値は以下のようになってます。

#define SVMIN (544+200)
#define SVMAX (2400-200)
180度を動かすのに、本来は544と2400らしいのですが、あまり角度を大きく変化させたくなかったのでオフセットで+-200としてます。
実際に角度を設定している部分は以下です。

void loop(){
  float param[7];
  char btn[5];
  char buf[77];

  //only mode C
  Serial.write('D');

  if(ReadSerial(buf)) {
     if(splitword(buf,param,btn)){
	    //softSerial.print(buf);
	    servo2.write(getNumber(param[1]));
	    delay(10);
	    servo3.write(getNumber(-param[0]));
	    delay(10);
	    //servo4.write(getNumber(0));
	    //servo5.write(getNumber(0));
	    servo6.write(getNumber(param[2]));
	    delay(10);

     }
  }
}
Serial.write('D');でPCへ1文字'D'を送信すると、転送ソフトがクレイジースモールへ送り、姿勢情報がPCへ返り、それがArduinoへ転送されます。
プリセットBで運用する場合は、この書き込みは不要です。
姿勢情報のフォーマットは"シリアル通信"で解説がありますので、そちらをご参照ください。
ReadSerialで受信が成功すると、splitword関数が真となります。param配列(角度とクォータニオン)とbtn配列(ジョイスティックボタン状態)に情報が入ります。
それをservo2,3,4にwriteすれば角度が変わります。getNumberとは角度をサーボ用の数値にマッピングしているだけです。
servo4,5は今回は未使用です。クォータニオンとジョイスティックボタン情報は今回は未使用です。
また、サーボモーターと制御ピンの設定はservo2.attach(2,SVMIN,SVMAX);のように指定されてますので変更できます。
通信速度はSerial.begin(38400);のように指定されてますので変更できます。
Arduino Unoの通信バッファが64バイトでして、1回の姿勢情報のバイト数より小さいので、転送ソフトではそれを考慮して32バイトで分割して3回送信してます。
ReadSerial(buf)関数を呼ぶと、姿勢情報1回が受け取れるようにしてます。




Crazy Small 3D5FT,6A5FT