PLEN:bit:モーションエディタ

PLEN:bit、自分でモーションを作るのはなかなか大変です。何かいいエディターがあればいいのですが…。

APPRICATION FOR PLEN SERIES
https://plen.jp/wp/plen2/#application

ありました!PLEN2用のアプリケーションとして、モーションエディターが公式に用意されていました。

PLEN2 と PLEN:bit、サーボの数は違いますが、基本的なモーション情報は同じ形式になっていると思います。なので、ツールからモーションのデータが取得できれば、データを活用することが可能だと思います。


(2019/07/01追記)
PLEN Project公式さんから、PLEN:bit と同じ体形の PLEN2 mini 用モーションエディタの情報を教えてもらえました!
→ PLEN:bit:PLEN2 mini 用モーションエディタ

扱うファイルフォーマットは同じなので、以下の説明についてはそのまま使えます。


試してみます!


ブラウザで起動します。操作方法はカンタン。どんなポーズを何秒間するかを、順番に登録していくだけです。

アイコンにマウスオーバすれば、説明が出ます。


ファイル読み込み / ファイル保存 / 新規モーション作成 / モーションプロパティ表示
PLEN2とファイル同期(使えません)/ モーション再生 / 前モーション / 次モーション


ポーズの左右入れ替え / 左側の状態を右側にコピー /右側の状態を左側にコピー
素立ちに戻す / カメラを最初の位置に戻す


時間設定。右側の開いている場所をクリックするとモーション追加。ドラッグ&ドロップでモーション順序の入れ替えが可能です。

プロパティで表示される画面です。Slot は、PLENと同期したときのスロット番号だと思います。なので今回は何でも良さそう。
Nameは、モーションの名前です。ファイル保存の時のファイルネームにも使用されます。初期値は「Empty」です。

コードプロパティ部分でループ設定ができるようですが、単純に「ループする」という情報が書き出されるだけです。その情報を見てどうするかは、モーション再生の実装側でがんばるしかない。


動きの確認もできます。


PLEN:bit とサーボ構成が同じPLEN mini のモーションデータが公開されていたので、読み込んでみます。

plen-Motion/motion-plen2-mini/
https://github.com/plenprojectcompany/plen-Motion/tree/master/motion-plen2-mini

PLEN2とPLEN:bitではサーボの数が違うのですが、各サーボはこんな風に対応してます。


モーションを作成してセーブすると、JSONファイルが保存されます。

{
	"slot": 44,
	"name": "TestMotion",
	"codes": [],
	"frames": [
	{
		"transition_time_ms": 500,
		"outputs": [
		{
			"device": "right_shoulder_pitch",
			"value": 0
		},
		{
			"device": "right_shoulder_roll",
			"value": 0
		},
		{
			"device": "right_elbow_roll",
			"value": 0
		},
		{
			"device": "right_thigh_yaw",
			"value": 0
		},
		{
			"device": "right_thigh_roll",
			"value": 0
		},
		{
			"device": "right_thigh_pitch",
			"value": 0
		},
		{
			"device": "right_knee_pitch",
			"value": 0
		},
		{
			"device": "right_foot_pitch",
			"value": 0
		},
		{
			"device": "right_foot_roll",
			"value": 0
		},
		{
			"device": "left_shoulder_pitch",
			"value": 0
		},
		{
			"device": "left_shoulder_roll",
			"value": 0
		},
		{
			"device": "left_elbow_roll",
			"value": 0
		},
		{
			"device": "left_thigh_yaw",
			"value": 0
		},
		{
			"device": "left_thigh_roll",
			"value": 0
		},
		{
			"device": "left_thigh_pitch",
			"value": 0
		},
		{
			"device": "left_knee_pitch",
			"value": 0
		},
		{
			"device": "left_foot_pitch",
			"value": 0
		},
		{
			"device": "left_foot_roll",
			"value": 0
		}
		]
	},

(…… 以下、モーションデータが続く)

outputs に、各サーボの角度、transition_time_ms に、そのモーションに掛ける時間が入ってます。

outputs の device がサーボ位置の指定ですね。PLEN:bit のサーボ番号との対応はこうなります。

right_shoulder_pitch:4
right_shoulder_roll:6
right_elbow_roll:対応なし
right_thigh_yaw:5
right_thigh_roll:対応なし
right_thigh_pitch:対応なし
right_knee_pitch:対応なし
right_foot_pitch:対応なし
right_foot_roll:7
left_shoulder_pitch:0
left_shoulder_roll:2
left_elbow_roll:対応なし
left_thigh_yaw:1
left_thigh_roll:対応なし
left_thigh_pitch:対応なし
left_knee_pitch:対応なし
left_foot_pitch:対応なし
left_foot_roll:3

この情報を、MakeCode PLEN:bit 拡張のsetAngle関数に渡すと、モーションを実行してくれます。

export function setAngle(angle: number[], msec: number)

angleで [サーボ0の角度, サーボ1の角度, … サーボ7の角度] を渡し、msec で transition_time_ms の値を渡します。

手作業で角度を書いていくのは大変なので、JSON ファイルから JavaScript ファイルに変換する Python スクリプトを書きました。

使い方はこうです。

python makeMotionScript.py {対象モーションファイル}.json

「{対象モーションファイル}.motionScript」のファイル名で、MakeCode用の JavaScriptファイルが生成されます。

let motionData: number[] = []
motionData = [0,0,0,0,0,0,0,0]
plenbit.setAngle(motionData, 500)
motionData = [909,0,0,0,-904,0,-8,0]
plenbit.setAngle(motionData, 500)
motionData = [909,0,-767,0,-904,0,791,0]
plenbit.setAngle(motionData, 500)
motionData = [15,0,-767,0,44,0,791,0]
plenbit.setAngle(motionData, 500)
motionData = [0,0,0,0,0,0,0,0]
plenbit.setAngle(motionData, 500)

マウスの手作業でモーションを設定していたので、本来0のつもりのところにも、微妙な値が入っちゃってますねw

これを、MakeCode のJavaScript画面で、適当な場所にコピー&ペースト。

ちなみにブロックに切り替えるとこんな感じです。配列設定があるので、かなり縦長。

(2019/07/04追記)

よく考えたら、

motionData = [0,0,0,0,0,0,0,0]
plenbit.setAngle(motionData, 500)

っていったん代入しなくても、

plenbit.setAngle([0,0,0,0,0,0,0,0], 500)

って直接引数に配列指定してしまえばいいですね…。

ブロックに切り替えるとこうなります。

ほぼ、JavaScript そのまんまになっちゃいますね。

ということで、上記Pythonスクリプトも、こちらの出力になるように書き直しておきました。


それでは、実行!

モーションエディタで設定した通りに動きましたー!

ループ情報などのコードプロパティ部分(codes)には対応してません。自分でJavaScriptのループ処理を書いた方が早いと思うので…。


それでは、どんどんモーション作っていきましょう!