前回 に続き磁気センサーからの取得値を3次元で可視化してみました。
磁気センサー値の可視化
Unityのスクリプトを書き換えて磁気センサーからの出力をそのまま(1/100倍してますが)画面上に点として表示してみました。
センサーを手で持っていろんな向きに回すことで球形っぽいものができました。
センサー値を2,000回分取得した時の結果です。
しかしよく見ると真球ではなくて多少いびつな形になってます。
Unityスプリプト
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.IO;
using System;
using UnityEngine;
public class magnetic : MonoBehaviour
{
public int Count;
public GameObject obj;
private float cpx, cpy, cpz;
private SerialPort port;
private int i;
void Start()
{
port = new SerialPort("COM11", 38400, Parity.None, 8, StopBits.One);
Debug.Log("start");
port.NewLine = "\r\n";
port.ReadBufferSize = 64;
port.ReadTimeout = 50;
port.Open();
i = 0;
}
// Update is called once per frame
void Update()
{
if (i < Count)
{
if (port.IsOpen)
{
try
{
String data = port.ReadLine();
string[] arr = data.Split(',');
if (arr.Length == 3)
{
cpx = float.Parse(arr[0]) / 100f; // 1/100倍
cpy = float.Parse(arr[1]) / 100f;
cpz = float.Parse(arr[2]) / 100f;
Instantiate(obj, new Vector3(cpx, cpy, cpz), Quaternion.identity);
Debug.Log(i.ToString() + " : " + data + "\r\n");
System.Array.Resize(ref arr, 0);
i++;
}
}
catch (TimeoutException)
{
}
}
}
}
}
実際に点を打つ命令は以下の箇所です。
点(実際は球型のオブジェクト)をセンサー値をもとにした3次元座標上に複製しています。
Instantiate(obj, new Vector3(cpx, cpy, cpz), Quaternion.identity);
今回、はまって時間をロスしたので注意点として記載しておきます。
上記スクリプトは球形オブジェクト(Sphere)以外のLightやCameraなどにアタッチしないといけません。Sphereにアタッチすると複製からも複製を作ろうとするのでソフトがハングアップします。
今回はDirectional Lightに上記スクリプトをアタッチしたので、Directional Lightのインスペクタに描画数と複製のもととなる球形オブジェクトを指定します。
考察
今はやり?のChatGPTに「磁気センサーの出力値からベクトルに置き換える方法は?」と質問した際、手順に「方向の計算」というのがあったのでさらに詳しく聞いてみたところ、一般的な手順として以下を示してくれました。
1.ベクトルの正規化
2.地磁気ベクトルの分解
3.方向の計算
1.ベクトルの正規化をすることにより形状が真球になると思われます。(今回は実施しません。)
回転数算出のめどが立ったので次回はそちらを試してみようと思います。
それにしても電源コードが接続された状態でセンサー基板をグルグル回すのはやりづらいです。
購入中のパーツが届いてくれれば、コードレス化できるのに。
ではまた。