ALMotion 関節の動きメモ(NAO)

##始めに
Sunaさんの記事を見ていて、自分はNAOを扱っているのに、記事にしないのもなんかアレなので、作ることにしました。
~~追記(2015/06/22):記事の書き途中ですが、先にアップしておきます。役に立つ人がいるかもしれないので。~~

>参考記事
>ALMotion 関節の動きメモ
>http://qiita.com/Suna/items/9ab7f805c2a2d2b1efef

##確認方法
###確認環境
MacBook Pro (Retina, 13-inch, Late 2013)
コレグラフ2.1.3(バーチャルロボット　NAO H21(V32))
追記(2015/06/24):バーチャルロボット　NAO H21(V32)だと、手首がないことが発覚しました。後日NAO H25(V50)で追加します。


###基本姿勢
ポーズライブラリのStandinitを利用しています。


##確認方法
Sunaさんと同じく、PythonからChoregrapheのバーチャルロボットに接続して、関節を動かしてみます。

```py
#naoqiからALProxyをインポートします。
>>> from naoqi import ALProxy
#ALProxyを使い、バーチャルロボットと接続します。
#実機でやるときは実機と繋ぎます。
#class ALProxy(name, ip, port)
>>> m = ALProxy("ALMotion", "localhost", 9559)
[I] 3343 qimessaging.session: Session listener created on tcp://0.0.0.0:0
[I] 3343 qimessaging.transportserver: TransportServer will listen on: tcp://192.168.205.16:50370
[I] 3343 qimessaging.transportserver: TransportServer will listen on: tcp://25.144.112.20:50370
[I] 3343 qimessaging.transportserver: TransportServer will listen on: tcp://127.0.0.1:50370
```


#####Tips:ALProxy
コレグラフ内の適当なボックスのpythonスクリプトを見てください。
例えば、[Animated Say Text]のボックス([Animated Say]の中にある)ですが、上の方のALProxyのところを見ると、

```py
def __init__(self):
        GeneratedClass.__init__(self, False)
        self.animSpeech = ALProxy('ALAnimatedSpeech')
```
となっており、ipとportが載っていません。NAOやPepperの中に入れて動かすアプリケーションを作る際は、ipとportを載せる必要はありません。NAOが2体いる場合にある一方にアプリケーションを入れて、もう一体を動かすなどしたいときに、ipとportを利用するそうです。(今回のように、pythonのみでバーチャルロボットと接続する際にも利用します。)



この状態から確認したい関節のコマンドを入力します。
ちなみに、NAOは以下の関節が存在します。
![スクリーンショット 2015-06-19 18.26.14.png](https://qiita-image-store.s3.amazonaws.com/0/35860/891e1bd9-82f4-f46c-9152-4905a7cc4de2.png)

>NAO - Actuator & Sensor list
>http://doc.aldebaran.com/2-1/family/nao_dcm/actuator_sensor_names.html#actuator-sensor-list-nao


##確認

setAnglesは以下のように利用します。

```py
#void ALMotionProxy::setAngles(names,angles,fractionMaxSpeed)
m.setAngles(["HeadYaw", "HeadPitch"], [0.0, 0.0], 0.1)
```

>SetAngle
>http://doc.aldebaran.com/2-1/naoqi/motion/control-joint-api.html?highlight=setangles#ALMotionProxy::setAngles__AL::ALValueCR.AL::ALValueCR.floatCR

###頭

```py
#void ALMotionProxy::setAngles(names,angles,fractionMaxSpeed)
m.setAngles(["HeadYaw", "HeadPitch"], [0.0, 0.0], 0.1)
```

####HeadPitch

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![headPitch_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/a8b3790a-e3ee-cfde-c5d6-43cc1a55860a.png "headPitch_10.png")|![headPitch00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/aa3cae44-60fb-c442-b6c9-634813b96a33.png "headPitch00.png")|![headPitch10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/389d0227-f4c3-308b-92ef-f71347260b7c.png "headPitch10.png")|

####HeadYaw

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![headyaw_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/a5665718-7b63-9767-8a95-cbecd5542a4b.png "headyaw_10.png")|![headyaw00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/086d070a-c97e-060d-3874-47f8f54d5013.png "headyaw00.png")|![headyaw10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/7f5e9584-2380-feed-5c3e-d1b417c41dec.png "headyaw10.png")|

###肩

```py
#void ALMotionProxy::setAngles(names,angles,fractionMaxSpeed)
m.setAngles(["LShoulderPitch", "LShoulderRoll"], [0.0, 0.0], 0.1)
```

####LShoulderPitch

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LShoulderPitch_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/d98b2bb5-e0cb-0888-7829-a2306922d042.png "LShoulderPitch_10.png")|![LShoulderPitch00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/37ead740-4b6e-4712-f530-e77bfe92a370.png "LShoulderPitch00.png")|![LShoulderPitch10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/7937ba23-b1c8-114a-d5d0-032e6e0d94a8.png "LShoulderPitch10.png")|

####LShoulderRoll

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LShoulderRoll_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/60dbc6e0-fc3f-5f29-1e49-4465e82e7590.png "LShoulderRoll_10.png")|![LShoulderRoll00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/0e4aeac3-fec0-26b2-6566-353f62f2479d.png "LShoulderRoll00.png")|![LShoulderRoll10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/01958661-df57-4c7a-82f0-d7e337ec594c.png "LShoulderRoll10.png")|

###肘

```py
#void ALMotionProxy::setAngles(names,angles,fractionMaxSpeed)
m.setAngles(["LElbowYaw", "LElbowRoll"], [0.0, 0.0], 0.1)
```

####LElbowRoll

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LElbowRoll_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/54642887-e8bd-86bc-ff4c-d5cb0cf61ad0.png "LElbowRoll_10.png")|![LElbowRoll00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/db0f14d7-333b-cbce-884a-cfd6f1e4c7a0.png "LElbowRoll00.png")|![LElbowRoll10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/176dd8dc-9947-f85a-a7fe-79b823fb2fa0.png "LElbowRoll10.png")|

####LElbowYaw

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LElbowYaw_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/6cceb4a1-e497-b97d-d2e6-a7f177851f56.png "LElbowYaw_10.png")|![LElbowYaw00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/af9f4454-b1a9-96c7-ad2d-55faa44bcae4.png "LElbowYaw00.png")|![LElbowYaw10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/5936cb4f-8cc1-81bd-8be9-3a0497b44fd4.png "LElbowYaw10.png")|




###手首

```py
#void ALMotionProxy::setAngles(names,angles,fractionMaxSpeed)
m.setAngles("LWristYaw", 0.0, 0.1)
```

####LWristYaw
~~エラーが起きる~~
旧式のNAOだと手首がそもそも存在しないため、エラーが起きていました。
新型のNAOを用いて検証した結果、動くことが確認できました。
H25V50で行ったものです。

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LWristYaw_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/882eb759-20a0-d539-ef4f-c998ea506ac0.png "LWristYaw_10.png")|![LWristYaw00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/5d010a1c-af88-6cd5-6791-6f15c928a844.png "LWristYaw00.png")|![LWristYaw10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/b44537ee-ce92-d371-af99-6037acf53143.png "LWristYaw10.png")|


###手

```py
#void ALMotionProxy::setAngles(names,angles,fractionMaxSpeed)
m.setAngles("LHand", 0.0, 0.1)

#上記のものだとエラーが起きるため以下の関数を使って、手の開閉を行います。
#void ALMotionProxy::openHand(handName)
#void ALMotionProxy::closeHand(handName)
m.openHand("LHand")
m.closeHand("LHand")
```

####LHand
~~エラーが起きる~~
~~Open or Closeのため~~

|open|init|close|
|:--:|:--:|:--:|
|![LHandOpen.png](https://qiita-image-store.s3.amazonaws.com/0/35860/9f53ffba-fe5c-9c2c-4f85-d1cf020dfe43.png "LHandOpen.png")|![LHandInit2.png](https://qiita-image-store.s3.amazonaws.com/0/35860/e441b412-29e0-27b1-50b6-d571e1e1c6b2.png "LHandInit2.png")|![LHandClose.png](https://qiita-image-store.s3.amazonaws.com/0/35860/a42ab52d-1600-ad71-8627-f3eede1c99c3.png "LHandClose.png")|



###腰

```py
#void ALMotionProxy::setAngles(names,angles,fractionMaxSpeed)
m.setAngles(["LHipYawPitch", "LHipPitch", "LHipRoll"], [0.0, 0.0, 0.0], 0.1)
```

####LHipPitch

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LHipPitch_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/b79e83e2-e0c7-2a02-be66-7d9c89a49c3f.png "LHipPitch_10.png")|![LHipPitch00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/b59755b9-907e-272a-a9c7-9d6d53623e4b.png "LHipPitch00.png")|![LHipPitch10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/2635ad1a-fbd7-5dbf-130c-cc6c5e0d5755.png "LHipPitch10.png")|

####LHipRoll

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LHipRoll_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/8a3609a2-1aea-4bb5-b56d-81404bee9837.png "LHipRoll_10.png")|![LHipRoll00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/74fcec3e-11cd-31a8-db55-58787c868418.png "LHipRoll00.png")|![LHipRoll10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/a964fd38-a94f-1593-bafa-c724479009aa.png "LHipRoll10.png")|

####LHipYawPitch

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LHipYawPitch_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/d334f046-d4e1-6aeb-61fd-1d9cf0c638eb.png "LHipYawPitch_10.png")|![LHipYawPitch00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/a0715f4a-9bef-7bde-3408-4a720bc84073.png "LHipYawPitch00.png")|![LHipYawPitch10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/98f21f4c-fbd9-79df-f286-0553cbc1ca0a.png "LHipYawPitch10.png")|

###脚

```py
#void ALMotionProxy::setAngles(names,angles,fractionMaxSpeed)
m.setAngles(["LKneePitch", "LAnklePitch","LAnkleRoll"], [0.0, 0.0, 0.0], 0.1)
```

####LKneePitch

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LKneePitch_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/fcc1612f-cbe5-ffc0-6f7f-8ba64d266c9c.png "LKneePitch_10.png")|![LKneePitch00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/ed6261a0-1eee-58c5-7415-cfeaca0ddcfd.png "LKneePitch00.png")|![LKneePitch10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/0440c76c-d6c7-206a-1a5a-6300d1902063.png "LKneePitch10.png")|

####LAnklePitch

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LAnklePitch_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/43a43213-662f-823b-a440-dc71e08fa90f.png "LAnklePitch_10.png")|![LAnklePitch00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/81264822-9b54-ceda-1a66-cbdf150e0a2d.png "LAnklePitch00.png")|![LAnklePitch10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/55b82c8f-f83c-18b6-1548-c620aa022bbe.png "LAnklePitch10.png")|

####LAnkleRoll

|-1.0|0.0|1.0|
|:--:|:--:|:--:|
|![LAnkleRoll_10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/e8f88315-20f4-db05-9335-e3015cd238ee.png "LAnkleRoll_10.png")|![LAnkleRoll00.png](https://qiita-image-store.s3.amazonaws.com/0/35860/7480473a-45aa-814c-25d3-cfbd294bf24e.png "LAnkleRoll00.png")|![LAnkleRoll10.png](https://qiita-image-store.s3.amazonaws.com/0/35860/c62438ce-209e-1685-ba50-6109b6de96eb.png "LAnkleRoll10.png")|

##感想
~~LHand, LWristYawはsetAnglesだとダメみたい？~~
~~何かやり方あったら教えて下さい。~~
~~また、すこし調べてみます。~~
追記(2015/06/24):原因がわかりました。バーチャルロボットのバージョンのせいでした。とりあえず、LWristYawは後日追加します。
LHandはopen,closeなので、うまくいかないのかもしれません。また調べてみます。

###感想
実際にバーチャルロボットを動かしてみて、表を作ったりしたことで、適当な値をボコスカ入れるのはダメだということがわかった。

今回はバーチャルロボットで[-1.0,0.0,1.0]という値を強制的に入れて動かしたが、実機では絶対うまく行かない。というか、危ない。なので、今後もし実機で検証するなり、動かして見るなりする際にはドキュメントの"JOINTS"の項目によく目を通してから行おうと思う。



##参考URL

>NAO - Actuator & Sensor list
>http://doc.aldebaran.com/2-1/family/nao_dcm/actuator_sensor_names.html#actuator-sensor-list-nao

>JOINTS
>http://doc.aldebaran.com/2-1/family/robots/joints_robot.html#robot-joints-v4-head-joints