2015年1月4日日曜日

10.ロボットビジョン(応用編その1) 

10.5 ROSとOpenCVのブリッジ: cv_bridge パッケージ
cv_bridge パッケージでROSでイメージデータをOpenCVで画像処理してみます。
カメラがKinectの時は、
$ roslaunch rbx1_vision openni_node.launch
あるいは、Webカメラの時は、
$ roslaunch rbx1_vision uvc_camera.launch device:=/dev/video0
別のターミナルウィンドウで、
$ rosrun rbx1_vision cv_bridge_demo.py
次のような画像が表示されます。

10.6 ros2opencv2.py ユーティリティ
カメラがKinectの時は、
$ roslaunch rbx1_vision openni_node.launch
あるいは、Webカメラの時は、
$ roslaunch rbx1_vision uvc_camera.launch device:=/dev/video0
別のターミナルウィンドウで、
$ roslaunch rbx1_vision ros2opencv2.launch
もう一つ別のターミナルウィンドウで、
 $ rostopic echo /roi

次のような画像が表示されます。



10.7 録画された動画の処理
video2ros.pyプログラムで、予め録画した動画を利用することができます。
以前に使った、画像処理にプログラムを実行し、
$ rosrun rbx1_vision cv_bridge_demo.py
別のターミナルウィンドウで、

$ roslaunch rbx1_vision video2ros.launch input:=`rospack find \
rbx1_vision`/videos/hide2.mp4




2015年1月2日金曜日

10. ロボットビジョン(準備編)

10章はOpenCVと連携することにより、様々な画像処理の例を紹介しています。

10.1 OpenCV, OpenNI と PCL
OpenCVオープンソースコンピュータビジョン向けライブラリで、画像処理の必要な様々な機能が用意されています。
OpenNIはオープンソースのKinect用のライブラリであり、ROSからKinectの機能を使うために必須です。
PCL(Point Cloud Library)はオープンソースの3Dポイントクラウド(点群)データ処理をまとめたライブラリであり、Kinectの3D距離データを利用する。
本書では、以下のトピックについて触れる

  • WebカメラあるいはKinect(RDB-D カメラ)をROSから利用する
  • ROS cv_bridge によりROSのイメージをOpenCVで処理する
  • 顔検出、オプティカルフロー、色追跡等のROSによる実装
  • Kinectから得られる距離情報処理

10.2 カメラの解像度に関して
処理速度との関係で、本書で扱う画像は320x240 (QVGA)であるが、場合によっては640x480 (VGA)で試してみます。

10.3 カメラドライバーのインストール
10.3.1 OpenNI用ドライバーのインストール
ROSではKinect for X360をサポートしており、以下のようにOpenNIのドライバをインストールする。
KinectはVMwareで実行されたUbuntu上では動作しないので注意が必要である。
$ sudo apt-get install ros-hydro-openni-camera

10.3.2 Webカメラ用ドライバーのインストール
ROS by ExampleではWebカメラのドライバ−にuvc_camを使っています(141ページ)
が、ソースをダウンロードしてコンパイルしなければいけないし、いろいろ面倒なので、
私はuvc_camera を使いました。
私の環境ではuvc_camera の方が安定して動いているようです。
以下のコマンドでインストールが可能です。
$ sudo apt-get install ros-hydro-uvc-camera

10.3.3 Kinect あるいは Xtion カメラのテスト
$ roslaunch rbx1_vision openni_node.launch

別のターミナルウィンドウで、
$ rosrun image_view image_view image:=/camera/rgb/image_color
こんな感じでカラー画像が表示されます。
同様に、以下のコマンドで距離画像が表示されます。
$ rosrun image_view disparity_view image:=/camera/depth/disparity

10.3.4 USB Webカメラのテスト
$ roslaunch rbx1_vision uvc_camera.launch device:=/dev/video0
あるいは
$ roslaunch rbx1_vision uvc_camera.launch device:=/dev/video1
/dev/video*  の*はお使いの環境に合わせて変えて下さい。 
また、ROS by Example では uvc_cam.launch ですが、ここでは uvc_camera.launchとします。
別のターミナルウィンドウで、以下のようにコマンドを実行すると、カラー画像が表示されるはずです。
$ rosrun image_view image_view image:=/camera/rgb/image_color

10.4 OpenCV の Ubuntu Linuxへのインストール
以降の章で使うOpenCVライブラリを次にようにインストールしておいてください。
$ sudo apt-get install ros-hydro-opencv2 ros-hydro-vision-opencv

2014年12月22日月曜日

8.2 ArbotiX シミュレータでmove_baseノードをテストする

8.2 ArbotiX シミュレータによる move_base のテスト

まだ地図が出来ていないので~/catkin_ws/src/rbx1/rbx1_nav/maps/blank_map.pgmという何も無い環境(真っ黒な地図)でロボットを動かす。
地図の指定は以下のように~/catkin_ws/src/rbx1/rbx1_nav/maps/blank_map.yamlファイルで行う。
ノードを実行可能にすることを忘れないように:
mage: blank_map.pgm
resolution: 0.01
origin: [-2.5, -2.5, 0]
occupied_thresh: 0.65
free_thresh: 0.196 # Taken from the Willow Garage map in the turtlebot_navigation package
negate: 0
move_baseノードはfake_move_base_blank_map.launchで起動する
<launch>
<!-- Run the map server with a blank map -->
<node name="map_server" pkg="map_server" type="map_server" args="$(find rbx1_nav)/maps/blank_map.yaml"/>
<!-- Launch move_base and load all navigation parameters -->
<include file="$(find rbx1_nav)/launch/fake_move_base.launch" />
<!-- Run a static transform between /odom and /map -->
<node pkg="tf" type="static_transform_publisher" name="odom_map_broadcaster" args="0 0 0 0 0 0 /odom /map 100" />
</launch>
始めに、map_serverノードをblank_map.yamlを引数として起動する
次に、以下で説明する fake_move_base.launch を読み込む。fake_move_base.launch ではmove_baseノード
を起動する。
最後に、ここではブランク地図を使い、シミュレータ内のロボットはセンサを持たないので距離データを使えないので、
代わりにオドメトリが完全なものとして、マップ上の自己位置を更新する。

fake_move_base.launchは次のような内容です
<launch>
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<rosparam file="$(find rbx1_nav)/config/fake/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find rbx1_nav)/config/fake/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find rbx1_nav)/config/fake/local_costmap_params.yaml" command="load" />
<rosparam file="$(find rbx1_nav)/config/fake/global_costmap_params.yaml" command="load" />
<rosparam file="$(find rbx1_nav)/config/fake/base_local_planner_params.yaml" command="load" />
</node>
</launch>
パラメータファイルに関しては8.1.2を見てください。

起動は以下のようにします。
始めに、ArbotiXシミュレータを起動します。
$roslaunch rbx1_bringup fake_turtlebot.launch
ここで、KOBUKIを使いたいときには
$roslaunch rbx1_bringup fake_turtlebot2.launch
とします。
次に、move_baseノードをブランク地図で起動します。
$roslaunch rbx1_nav fake_move_base_blank_map.launch
さらに、可視化のためにRvizを起動します。
$rosrun rviz rviz -d `rospack find rbx1_nav`/nav.rviz
最後に、コマンドラインからmove_baseアクションを送ることでロボットが指定された位置・姿勢に向けて移動します。
以下の例は、ロボットをX軸方向に1mだけ移動させます。
※以下のコマンドをコピペする時に、継続行を示す”バックスラッシュ”は不要です。
$rostopic pub /move_base_simple/goal geometry_msgs/PoseStamped \'{ header: { frame_id: "map" }, pose: { position: { x: 1.0, y: 0, z: 0 }, orientation: { x: 0, y: 0, z: 0, w: 1 } } }'
こちらを使って下さい。
$rostopic pub /move_base_simple/goal geometry_msgs/PoseStamped '{ header: { frame_id: "map" }, pose: { position: { x: 1.0, y: 0, z: 0 }, orientation: { x: 0, y: 0, z: 0, w: 1 } } }'
次のコマンドでは、グローバル座標系で初期位置・姿勢に戻ります。
$rostopic pub /move_base_simple/goal geometry_msgs/PoseStamped '{ header: { frame_id: "map" }, pose: { position: { x: 0, y: 0, z: 0 }, orientation: { x: 0, y: 0, z: 0, w: 1 } } }'

ロボットの軌跡が直線経路ではなく遠回りしているように思えます。
これは、経路上に障害物が無いので経路探索プログラムが一番スムーズだと思える経路を計算したからです。
pdist_scale (0.4) 
gdist_scale (0.8) 
最大速度 (max_vel_x)
このパラメータを変えると経路が変わります。
このコマンドでパラメータを変えることができます。

$rosrun rqt_reconfigure rqt_reconfigure

8.2.1 RViz上で目的地をクリックして移動させる
「2D Nav Goal」メニューをクリックし、マウスでゴールの位置と姿勢を指定する。


クォータニオンについて
一般的にロボットの姿勢を表すにはオイラー角であるRoll, Pitch, Yawを使いました。

2014年12月21日日曜日

8.1.2 経路探索のパラメータの設定

move_base ノードでは以下の4つのパラメータファイルが必要です。

(1) base_local_planner_params.yaml

controller_frequency: 3.0
  経路のプランニングを行う周期。普通のノートPCで3〜5回/秒程度に設定する。
max_vel_x: 0.3
  ロボットの最高並進速度(メートル毎秒)。室内だと0.3〜0.5程度
min_vel_x: 0.05:
  ロボットの最低並進速度(メートル毎秒)
max_rotational_vel: 1.0
  ロボットの最高回転速度(ラジアン毎秒)
min_in_place_vel_theta: 0.5
  ロボットの最低回転速度(ラジアン毎秒)
escape_vel: -0.1
  ロボットが回避するときの速度(メートル毎秒)。負の値は後退
acc_lim_x: 2.5
  x座標方向への加速度の最大値
acc_lim_y: 0.0
  y座標方向への加速度の最大値。0の場合は非ホロノミック台車の場合で真横には動けない
acc_lim_theta: 3.2
  回転の加速度の最大値
holonomic_robot: false
  全方位移動台車を使っていない場合は常に false
yaw_goal_tolerance: 0.1
  目的の姿勢との許容誤差(ラジアン)。この値が小さいとゴール付近で振動してしまう。  
xy_goal_tolerance: 0.1
  目的の位置との許容誤差(メートル)。地図の解像度よりも小さい値にしないこと。
pdist_scale: 0.8
  グローバルパスにどれだけ正確に沿って移動するか。gdist_scaleより大きな値にすると、よりグローバルパスに沿って動く。
gdist_scale: 0.4
  ゴールを目指すか、グローバルパスに沿うか、を決める。  
occdist_scale: 0.1
  障害物を回避する程度を決める。
sim_time: 1.0
  どれくらい先を考慮するか
dwa: true
  Dynamic Window Approach を使うか否か

(2) costmap_common_params.yaml

robot_radius: 0.165
  円形ロボットの場合、ロボットの半径(メートル)。
  円形で無いロボットの場合はfootprintパラメータを使う。
  0.165はTurtlebotのサイズ
footprint: [[x0, y0], [x1, y1], [x2, y2], [x3, y3], etc]
  ロボットの形状
inflation_radius: 0.3
  ロボットが障害物にぶつからないようにするための膨張パラメータ

(3) global_costmap_params.yaml

global_frame: /map
  global cost map のフレーム名称
robot_base_fame: /base_footprint
  TurtleBot用には /base_footprint を使う。
update_frequency: 1.0
  global mapを更新する頻度
publish_frequency: 0
  static globalマップは通常連続して配信する必要な無い
static_map: true
  global map は静的
rolling_window: false
  global map はロボットが動いても変更されないのでfalseにする
transform_tolerance: 1.0
  ネットワークの遅延に対処するための待ち時間(秒)

(4) local_costmap_params.yaml

global_frame: /odom
  local cost mapにおけるオドメトリのフレーム
robot_base_fame: /base_footprint
  /base_link あるいは /base_footprintを設定
  TurtleBot の場合は /base_footprint.
update_frequency: 3.0
  local map の更新頻度
publish_frequency: 1.0
  local map の配信頻度  
static_map: false
  local map は更新されるので、静的では無い。
rolling_window: true
  local map は更新される。
width: 6.0
  rolling map x座標方向
height: 6.0
  rolling map y座標方向
Resolution: 0.01
  rolling mapの解像度
transform_tolerance: 1.0
  ネットワークの遅延に対処するための待ち時間(秒)