動機
ROSのパッケージにある、ar_track_alvarの準備ができたので、つぎは実際にトピックを拾って、マーカーの姿勢をとれるかやってみる。
環境
- Ubuntu 16.04 LTS
- ROS Kinetic Kame
- 今回使用したのUSBカメラ(Logicool C270 UVC対応)1台
参考にした情報
ARマーカーの姿勢情報の取得
ar_pose_markerのデータ取得
ar_pose_markerトピックをsubscribeするノードを作成する。
特に書いてなかったがこれまで「camera_eval」と名前をつけたパッケージで、カメラ接続の検証などをしていたため、そのパッケージ内のscriptsに、以下のようにコードをつくる。
シンプルに、subscriberとcallbackだけ。
import rospy
from ar_track_alvar_msgs.msg import AlvarMarkers
class ARPoseSubscriber(object):
def __init__(self):
self.sub = rospy.Subscriber("/ar_pose_marker", AlvarMarkers, self.callback_alvmarker)
def callback_alvmarker(self, markers):
for m in markers.markers:
marker_id = m.id
if marker_id == 4:
marker_pose = m.pose.pose
pos = marker_pose.position
ori = marker_pose.orientation
rospy.loginfo("marker[%d] position (x,y,z) = (%3.3f: %3.3f: %3.3f), orientation (x,y,z,w) = (%3.3f: %3.3f: %3.3f: %3.3f)"
% (marker_id, pos.x, pos.y, pos.z, ori.x, ori.y, ori.z, ori.w))
return
if __name__ == '__main__':
rospy.init_node('ar_pose_subscriber')
ARPoseSubscriber()
rospy.spin()
ここでは、3x3の九つマーカーが印刷されたものを使っているので、センターにあるmarker_id==4のものだけ、loginfoに出力するようにしている。
$ chmod 755 ar_pose_subscriber.py
として、実行可能にしておく。
つぎに、launchファイルに下のように追加する。
<node name="ar_pose_subscriber" pkg="camera_eval" type="ar_pose_subscriber.py"/>
パッケージ名は、先ほどのコードが置いてある自作のパッケージ名として、実行可能にしたpythonファイルを指定する。
別の端末を立ち上げて、
rqt_console
とすれば、出力したloginfoがどんどん発行されて流れて行くのが見れる。
ひとまず、位置・姿勢の情報がとれた。厳密な値の比較をしていないが、カメラからマーカーを離すとzの値が増加するし、カメラに対してマーカーを右に動かすとプラスに、左に動かすとマイナスに値が変化する様子が見れた。
tfトピックのデータ取得(失敗?)
それでは次に、/tfトピックでもできるかやってみよう。
(2018/4/12追記)
/ar_pose_markerの土岐と同様に、/tfのメッセージの型も分かったので、
import rospy
import tf
import tf2_ros
from tf2_msgs.msg import TFMessage
class TfSubscriber(object):
def __init__(self):
self.sub = rospy.Subscriber('/ar_track_alvar/tf', TFMessage, self.callback_tf)
def callback_tf(self, markers):
for m in markers.transforms:
marker_pose = m.transform
tra = marker_pose.translation
rot = marker_pose.rotation
rospy.loginfo("position (x,y,z) = (%3.3f: %3.3f: %3.3f), orientation (x,y,z,w) = (%3.3f: %3.3f: %3.3f: %3.3f)"
% (tra.x, tra.y, tra.z, rot.x, rot.y, rot.z, rot.w))
if __name__ == '__main__':
rospy.init_node('tf_subscriber')
TfSubscriber()
rospy.spin()
としてみたのだが、rqt_consoleでloginfoに出てこなかった。launchしたときに特にエラー表示もないし、rqt_graphで見てもノードが立ってたり、/tfを受け取れている様子なんだけどね。
空飛ぶロボットのつくりかた ROStfのお勉強
うごくものづくりのために 座標変換パッケージ "tf"の使い方
MyEnigma 世界で一番簡単なtfの使い方
の情報を見てみると、topicのsubscribeではなくて、tfのlistenerを使う感じ?
tf(モジュール名とトピック名が同じだから、/tfってしないと分かりづらいな)のことをもっと勉強しよう。