2013年9月30日月曜日

Xtionの有効範囲

http://www.asus.com/jp/News/iidy4mD9PKJk6Zi4/

↑この記事によると、Xtionの有効範囲は
0.8m~3.5mらしい

ということは、gmappingのパラメータをこの様に書き換えたほうがよいのだろうか?

$ rosrun gmapping slam_gmapping _map_update_interval:=0.1 _maxUrange:=3.5 _linearUpdate:=0.10 _angularUpdate:=0.262 _temporalUpdate:=0.5

2013年9月26日木曜日

amclパラメーター

http://wiki.ros.org/amcl?distro=hydro

amclのパラメーターは次の3種類である

(1) 総体的なフィルタ
(2) レーザーモデル
(3) オドメトリモデル


(1) 総体的なフィルタ
min_particles ( int型、デフォルト:100 )粒子の最小許容数。

max_particles ( int型、デフォルト:5000 )粒子の最大許容数。


kld_err (double型、デフォルト:0.01 )真の分布と推定分布の間の最大誤差。

kld_z (
double型、デフォルト: 150 )
pは推定distrubition上の誤差がkld_err未満になる確率ですが、 - の上限標準正規分位点( P 1 ) 。
よくわからない


update_min_d (
double型、デフォルト: 0.2メートル)
フィルタのアップデートを実行する前に必要とされる並進運動。 

update_min_a (double型、デフォルト: π/6.0ラジアン)フィルタのアップデートを実行する前に必要とされる回転運動。

resample_interval ( int型、デフォルト: 2)リサンプリング前に必要なフィルタ更新の数。

transform_tolerance (
double型、デフォルト: 0.1秒)わからない 

recovery_alpha_slow (double型、デフォルト:0.0 (無効) )ランダムポーズを追加することによって回復するときに決定する際に使用される低速の平均体重フィルタの指数関数的な減衰率。良い値は、0.001であるかもしれません。
ランダムポーズとは?


recovery_alpha_fast (
double型、デフォルト:0.0 (無効) )ランダムポーズを追加することによって回復するときに決定する際に使用される高速の平均体重フィルタの指数関数的な減衰率。良い値は0.1であるかも。

initial_pose_x (
double型、デフォルト: 0.0メートル)初期( x)は、ガウス分布を有するフィルタ初期化するために使用されることを意味をもたらす。
どういうことに使用されるのか?


initial_pose_y (
double型、デフォルト: 0.0メートル)初期、 ( y)の意味をもたらすガウス分布とフィルター初期化するために使用。 
initial_pose_a (double型、デフォルト:0.0ラジアン)初期ポーズはガウス分布とフィルター初期化するために使用し、 (ヨー)を意味します。

initial_cov_xx (
double型、デフォルト: 0.5× 0.5メートル)初期の共分散をポーズ( X * x)は、ガウス分布とフィルター初期化するために使用。 

initial_cov_yy (double型、デフォルト: 0.5× 0.5メートル)初期、 (Y * Y )共分散をもたらすガウス分布とフィルター初期化するために使用。

initial_cov_aa (
double型、デフォルト: ( π/12 )*( π/12 )ラジアン)初期、 (ヨー*ヨー)共分散をもたらすガウス分布とフィルター初期化するために使用。

gui_publish_rate (
double型、デフォルト: -1.0 Hz)最大レート(Hz )がれるスキャンやパスが無効に-1.0 、可視化のために公開されています。

save_pose_rate (
double型、デフォルト: 0.5 Hz)最大レート(Hz )がれる格納する最後の推定変数に、パラメータサーバへのポーズと共分散〜 initial_pose_ *と〜 initial_cov_ * 。このポーズは保存されたフィルタを初期化するために、後続の実行で使用されます。無効にするには-1.0 。

use_map_topic (ブール値、デフォルト:false)trueに設定すると、 AMCLはむしろそのマップを受信するサービスコールを作るよりも、マップのトピックにサブスクライブします。


first_map_only (ブール値、デフォルト:false)trueに設定すると、 AMCLだけむしろ新しいものが受信されるたびに更新するよりも、それがサブスクライブする最初のマップを使います。



(2) レーザーモデル

laser_min_range (double型、デフォルト: -1.0 )最小スキャン範囲。-1.0はレーザの報告最小範囲を使用。 
laser_max_range (double型、デフォルト: -1.0 )
最大スキャン範囲。-1.0 はレーザの報告最大範囲を使用。

laser_max_beams ( int型、デフォルト:30 )フィルタの更新時に各スキャンでどのように多くの等間隔のビームが使用される。 
laser_z_hit (double型、デフォルト:0.95 )モデルのz_hit部分の混合重み。 
laser_z_short (double型、デフォルト: 0.1)モデルのz_short部分の混合重み。
laser_z_max (
double型、デフォルト:0.05 )モデルのz_max部分の混合重み。
laser_z_rand (
double型、デフォルト:0.05 )モデルのz_rand部分の混合重み。
laser_sigma_hit (
double型、デフォルト: 0.2メートル)ガウスモデルの標準偏差は、モデルのz_hit一部に使用した。
laser_lambda_short (
double型、デフォルト: 0.1)モデルのz_short部分の指数関数的な減衰パラメータ。
laser_likelihood_max_dist (
double型、デフォルト: 2.0メートル)最大距離はlikelihood_fieldモデルで使用するために、地図上に障害物インフレを行うため。 
laser_model_type (文字列、デフォルトは" likelihood_field " )どのモデルを使用すると、ビームまたはlikelihood_fieldどちらか。


(3) オドメトリモデル
「差分」と「全方位」のモデルタイプがある

odom_model_type(文字列デフォルトは"diff"
どのモデル"diff(差分)"または "omni(全方位)"のいずれかを使用する

 
odom_alpha1ダブルデフォルト0.2)
ロボットの動きの回転成分からオドメトリの自転の見積りの予想ノイズを指定します

 

odom_alpha2ダブルデフォルト0.2)
ロボットの動きの並進成分からオドメトリの自転の見積りの予想ノイズを指定します

 
odom_alpha3ダブルデフォルト0.2)
ロボットの動きの並進成分からオドメトリ翻訳上の見積りの予想されるノイズを指定します

 
odom_alpha4ダブルデフォルト0.2)
ロボットの動きの回転成分からオドメトリ翻訳見積もりの予想ノイズを指定します


odom_alpha5ダブルデフォルト0.2)
翻訳関連のノイズパラメータモデルは"全方位"である場合にのみ使用


odom_frame_id(文字列デフォルトは"odom"
どのフレームオドメトリに使用する


base_frame_id(文字列デフォルトは"base_link"
どのフレームロボットベースに使用する


global_frame_id(文字列デフォルトは"map"
座標系の名前はローカライゼーションシステムによって発行される












 
 

2013年9月24日火曜日

gmappingしながらnavigation

この動画では、gmappingしながらnavigationスタックを利用している



やり方は、
$ roslaunch openni_launch openni.launch
 新しい端末を開いて
$ rosrun depthimage_to_laserscan depthimage_to_laserscan image:=/camera/depth/image
 新しい端末を開いて
$ rosrun rviz rviz
 新しい端末を開いて
$ rosrun ROSARIA RosAria
 新しい端末を開いて
$ rosrun tf static_transform_publisher 0.150 0.0 0.270 0.0 0.0 0.0 /base_link /camera_link 100
 新しい端末を開いて
$ rosrun ROSARIA rob_teleop
 新しい端末を開いて
$ rosrun gmapping slam_gmapping 
このとき、mapフレームとodomフレームがtfで変換できているので、
amclを使わなくてもmove_base.launchができる

$ roslaunch mypack move_base.launch

そして、ROSARIAの場合、cmd_velトピックは/RosAria/cmd_velなので、
$ rosrun topic_tools relay cmd_vel RosAria/cmd_vel 
 
あとは、rvizを開いて2dnavgoalでゴールを指定する
なお、地図化されていない部分をゴールとして指定したら、移動車は回転する。
自己位置を推定するためだろうか?
 
地図のマッチングを行いながら移動するため、挙動がつっかえたりする。
つまり、移動車がスムーズに動きにくい。 

2013年9月21日土曜日

navigationのゴールを直接送る

rviz上でゴールを指定するのも便利だけど、やっぱ自分でゴールをパブリッシュ出来た方が良いので、やってみる

http://wiki.ros.org/navigation/Tutorials/SendingSimpleGoals

2013年9月19日木曜日

gmappingをいかに改善していくか?

gmapping machingで画像検索して
自分のぶつかってる問題と関係ありそうな症状を見つけてみた。

いろいろ記事を読んでみて、わかったことは3つ

  • KInectを使っていたとしても、デフォルトの値でもあまり問題は生じない
    • それよりも、オドメトリかロボットの操縦方法に異常があるのではという指摘
    • 異常なオドメトリに関しての対処は書いてないが、ロボットの操縦についてはヒントがかかれている
    • 既知のコーナー(おそらくマッピングが既になされている)を常にカメラの視野に入れておくこと
  • それでもパラメーターを変更してマップの精度を上げたければ、以下の三つであると
    • linearUpdate
      • 減らしたほうがよい
    • angularUpdate 
      • 上と同様、減らしたほうがよい
    • particles  
      • 増やしたほうがよい(100がちょうど良い)
  • 更新速度とパーティクルを増やすと上手く行くらしい。あとは運。 


それから、もしかすると赤外線の長さも、短くした方がいいかも
おそらく、距離が長いと、それだけ誤差が大きくなるから

2013年9月16日月曜日

gmapping色々やってみてしらべてわかったこと

Kinectをつかってgmappingしているページ
http://www.hessmer.org/blog/2011/04/10/2d-slam-with-ros-and-kinect/

この動画によると・・・


とてもゆっくり動かしている
LaserScanを使い、 マッチングするまで待ってから、動かしている
僕は今まで、何にも考えずぐるぐる動かしていた
だから地図がちゃんとつくれなかった
パラメーターは、おそらく、そんなに関係ないと思う

この動画みたいにして動かさないと、ちゃんとした地図が作れない

あと、推測だけど、カメラを置く位置を正確に測ってtfしないと、地図がズレる
もしかしたら、カメラの位置は、中心位置からあまり動かさない方がいいのかもしれない

gmappingのパラメータ

https://sites.google.com/site/slamnavigation/
あてずっぽうにパラメータをいじくるよりも、このサイトを参考にしてやってみたほうが上手くいきそう
このサイトのパラメータはこんな感じ

$ rosrun gmapping slam_gmapping _map_update_interval:=2.0 _maxUrange:=6.0 _sigma:=0.05 _kernelSize:=1 _lstep:=0.05 _astep:=0.05 _iterations:=5 _lsigma=0.075 _ogain:=3.0 _lskip:=0 _srr:=0.01 _srt:=0.02 _str:=0.01 _stt:=0.02 _linearUpdate:=0.25 _angularUpdate:=0.262 _temporalUpdate:=-1.0 _resampleThreshold:=0.5 _particles:=300 _xmin:=-50.0 _ymin:=-50.0 _xmax:=50.0 _ymax:=50.0 _delta:=0.05 _llsamplerange:=0.01 _llsamplestep:=0.01 _lasamplerange:=0.005 _lasamplestep:=0.005


パラメータの解釈
  • _map_update_interval:=2.0 
    • mapの更新間の時間は2.0s
  • _maxUrange:=6.0 
    • レーザーが届く最大範囲は6m
  • _sigma:=0.05
    • デフォルトの値
  • _kernelSize:=1
    • デフォルトの値
  • _lstep:=0.05 
    • デフォルトの値
  • _astep:=0.05 
    • デフォルトの値
  • _iterations:=5 
    • デフォルトの値
  • _lsigma=0.075 
    • デフォルトの値
  • _ogain:=3.0 
    • デフォルトの値
  • _lskip:=0 
    • デフォルトの値
  • _srr:=0.01 
    • 0.01m以内のズレを誤差とする
  • _srt:=0.02 
    •  0.02m以内のズレを誤差とする
  • _str:=0.01
    • 0.01m以内のズレを誤差とする
  • _stt:=0.02 
    • 0.02m以内のズレを誤差とする
  • _linearUpdate:=0.25
    • 0.25m平行移動したらスキャンの更新
  • _angularUpdate:=0.262 
    • 0.262回転したらスキャンの更新
  • _temporalUpdate:=-1.0 
    • デフォルトの値
    • 時間毎のスキャン更新は無し
  • _resampleThreshold:=0.5 
    • デフォルトの値
  • _particles:=300 
    • パーティクルはデフォルトの10倍
  • _xmin:=-50.0 
  • _ymin:=-50.0 
  • _xmax:=50.0 
  • _ymax:=50.0 
    • 初期マップの大きさ
  • _delta:=0.05 
    • デフォルトの値
  • _llsamplerange:=0.01 
    • デフォルトの値
  • _llsamplestep:=0.01
    • デフォルトの値
  • _lasamplerange:=0.005 
    • デフォルトの値
  • _lasamplestep:=0.005
    • デフォルトの値 

2013年9月14日土曜日

gmappingのパラメータ(昨日の続き)

gmappingについて
自己位置が不用意に動くというのは、おそらく、センサから得たデータとマッチングしているためではないか
つまり、gmappingはマッチングを優先させてしまっているのではないか
だから、自己位置がズレてしまうのではないか



それが原因だとすると、対処としては…

(1) 自己位置を優先させてマッチングさせる→できるかどうか不明
(2) マッチングの回数(頻度)を減らす→ブレを減らすため
(3) あんまり正確にマッチングさせない(?)→アバウトにすることで、自己位置を動かないようにする

とりあえず、gmappingのパラメータを洗うところから
http://wiki.ros.org/gmapping#Parameters

関係ありそうなのは、
  • ~map_update_interval (float, default: 5.0)  
  • ~transform_publish_period (float, default: 0.05)
かなあ
次点で、
  • ~throttle_scans (int, default: 1)
  • ~maxUrange (float, default: 80.0)
  • ~sigma (float, default: 0.05)  

以下、google翻訳を使って調べてみた
  • ~inverted_laser (string, default: "false"
    •  反転レーザー(?)。反転させるかどうかみたいな?
  • ~throttle_scans (int, default: 1) 
    •  どれだけスキャンデータをスキップ(無視)するか
    • この数値を増やせば、その分だけスキップする
    • たとえば、数値を3に設定すると、3回に1回データを取る
  • ~map_update_interval (float, default: 5.0)  
    • 更新頻度に関わるパラメータ
    • 数値を減らすと、更新頻度が短くなり、負荷が大きくなる
    • 更新頻度が短くなれば、それだけ地図が正確になるのだろうか?
  • ~maxUrange (float, default: 80.0) 
    • レーザーの最大範囲
    • この数値を下げたら、マップとして認識する範囲が短くなる
    • デフォルトでは、80(m?)以上はマップとして認識しない
  • ~sigma (float, default: 0.05)  
    • 欲張り法における数値(?)
    • 数値を大きくすると、新しいマッチングが追加されなくなる(つまり、数値以下であれば、同じマッチングだと認識する)
    • 実験して確かめてみるしかなさそう
  • ~kernelSize (int, default: 1) 
    • マッチングを見る範囲の大きさみたいな?
    • マッチングの範囲が小さければ、マッチングは合う可能性が高いが、マッチングの範囲が広ければ、マッチングが合わなくなる可能性が高い
    • しかし程度が分からないので、実験して調べてみる
  • ~lstep (float, default: 0.05)
    • 平行移動におけるズレ
    • よくわからない
  • ~astep (float, default: 0.05)
    • 回転におけるズレ
  • ~iterations (int, default: 5)  
    • スキャンマッチャーの対応の回数
    • マッチングを何回繰り返すか?
    • つまり、マッチング回数が多ければ正確になるが、処理は重くなる
  •  ~lsigma (float, default: 0.075) 
    • 尤度計算に使用されるビームのシグマ
    • ビームを足し合わせるってこと?
    • そもそもビームってなに?
  • ~ogain (float, default: 3.0) 
    • 尤度の評価中に再サンプリングの効果を平滑化するため、使用するゲイン。
    • ゲイン??? 
    • よくわからない
  • ~lskip (int, default: 0) 
    • 各スキャンでスキップするビームの数。
    • だからビームとは? 
  • ~srr (float, default: 0.1) 
    •  オドメトリ(ρ/ρ)の誤差
  • ~srt (float, default: 0.2)
    • 回転動作におけるオドメトリ(ρ/θ)の誤差
  • ~str (float, default: 0.1)
    • 回転オドメトリ(θ/ρ)の誤差
  • ~stt (float, default: 0.2)
    • 回転動作における回転オドメトリ(θ/θ)の誤差 
  • ~linearUpdate (float, default: 1.0) 
    • ロボットが引数分だけ動いたら、スキャンを更新する
    • つまり、デフォルトでは1m動いたらスキャンを更新する
    • 小さくした方が良いように思われる
  • ~angularUpdate (float, default: 0.5) 
    • ロボットが引数分だけ回転したら、スキャンを更新する
    • 小さくした方が良いように思われる
  • ~temporalUpdate (float, default: -1.0) 
    • 時間毎のスキャンの更新
    • デフォルトでは、時間毎の更新はオフになっている
  • ~resampleThreshold (float, default: 0.5)
    • ネフベースのリサンプリングのしきい値
    • ネフベースとは?
  • ~particles (int, default: 30) 
    • フィルター中の粒子の数
    • パーティクルを増やすと正確になる 
  • ~xmin (float, default: -100.0)
    • 初期マップサイズ
  • ~ymin (float, default: -100.0)
    • 初期マップサイズ 
  • ~xmax (float, default: 100.0)
    • 初期マップサイズ
  • ~ymax (float, default: 100.0)
    • 初期マップサイズ 
  • ~delta (float, default: 0.05) 
    • マップの解像度
  • ~llsamplerange (float, default: 0.01) 
    • 尤度のための翻訳サンプリングの範囲
  • ~llsamplestep (float, default: 0.01) 
    • 尤度のための翻訳サンプリングの範囲
  • ~lasamplerange (float, default: 0.005)  
    • 尤度のための角度サンプリングの範囲
  • ~lasamplestep (float, default: 0.005)
    • 尤度のための角度サンプリングの範囲
  • ~transform_publish_period (float, default: 0.05) 
    • tfパブリッシュの間をどれだけとるか(秒)
  • ~occ_thresh (float, default: 0.25) 
    • 障害物のある確率
    • 高ければマップが更新されない(?)
  • ~maxRange (float
    • センサの最大範囲




2013年9月13日金曜日

gmappingの地図がちゃんとしていない(途中)

gmappingが上手くできない…
直線コースがうまく地図にできない…まっすぐができない

症状:
gmapping中に直線コースをたどるとき、rviz上で、自己位置tfが戻ってしまう。つまり、まっすぐの距離が縮んでしまい、尺の合わない地図が生成されてしまう。
この状態だと、costmapしたときに、地図上の障害物と実際の障害物が不一致になるため、思ったとおりの動きをしない。

原因は何だろう
考えられる原因としては、

(1) エンコーダーの問題(ちゃんと距離を取れていない)
(2) tfの問題(/odomと/base_linkの変換が上手くいっていない)
(3) gmappingのパラメーターがおかしい

(1)について
エンコーダーの数値は、移動車をまっすぐ進めたらそれだけ増えるので、おかしいとは思えない…

(2)について
 /odomと/base_linkの変換はRosAriaというノードによって行われている。
おかしいとしたらこの変換なんだけどなあ…

→rvizでtfを可視化して確かめてみた。すると、tfだけなら位置のズレはまったく起こっていない
ちゃんと進んだ分だけrviz上のtfも動く。つまり、実測値とコンピューター上の値との齟齬はない

では、gmappingのやり方がおかしい。

ところで自分は、/odom -> /base_link -> camera_linkという変換をしている
しかし、 このページでは、間にfootprintをかませている。
つまり、/odom -> /base_footprint -> /base_link -> camera_link
でやっている。
これを直すか?
または、 (3)について、パラメーターがおかしいのか。

この様にやっている人もいる
$ rosrun gmapping slam_gmapping _xmin:=-5.0 _ymin:=-5.0 _xmax:=5.0 _ymax:=5.0 _maxUrange:=59.0 _maxRange:=63.0 _map_update_interval:=5.0 _linearUpdate:=0.2 _angularUpdate:=0.15 _particles:=50 _delta:=0.02

パラメーターの扱いはまだよくわかっていない…
このページをみて勉強しよう

そもそも
なぜマップを正確に取りたいかというと、move_baseを使いたいから
しかし、用意されたマップを用いるならば、こんな作業はおそらく必要ない。
正確なマップを使ってみるのも手段ではある…