wheel_odometry
役割
wheel_odometry は Rogidrive encoder から omni wheel odometry を計算します。全 wheel の encoder を受け取った後、差分を body 座標の \((\Delta x,\Delta y,\Delta\theta)\) に変換して積分します。
Interface
種別 |
名前 |
型 / 内容 |
|---|---|---|
subscribe |
|
Rogidrive status |
publish |
|
|
tf |
|
|
Encoder 差分
motor position \(q_i\) は、rogidrive_position_is_revolutions=true なら revolution から radian へ変換します。
false の場合は \(\phi_i=q_i\) です。前回積分値との差分は、
wrap_angle_delta=true なら、
です。omni wheel 側の角度差分は、
ここで \(s_i\) は encoder_signs[i]、\(G\) は motor_to_omni_reduction_ratio です。
Wheel constraint
wheel 位置角を \(\alpha_i\)、駆動方向角を \(\beta_i\)、中心から wheel までの距離を \(R\) とします。
body delta \(\xi=(\Delta x,\Delta y,\Delta\theta)^T\) による wheel 接地点の移動は、
です。これを駆動方向へ射影した量が wheel の接地点移動量 \(b_i\) になります。
ここで \(\rho\) は wheel_radius です。行列の 1 行は、
右辺は、
です。
最小二乗
全 wheel について、
を作り、正規方程式で解きます。
実装では 3x3 の Cramer 法で解きます。行列式が小さい場合は解けないため、その周期の odometry 更新をスキップします。
積分
body 座標の差分 \((\Delta x,\Delta y,\Delta\theta)\) は、中点 yaw で odom 座標へ回転して積分します。
速度は \(dt\) で割ります。
設定ファイル
wheel_odometry はパッケージ同梱の rogi_localization/odometry/wheel_odometry/config/wheel_odometry.yaml を使います。rogi_nav.launch.py は sample profile から選んだ初期 pose だけを追加で上書きします。
key |
sample/default 値 |
数式上の意味 |
|---|---|---|
|
|
encoder 入力 topic |
|
|
odometry publish topic |
|
|
odom message frame / TF 親 |
|
|
child frame |
|
profile 由来 |
積分初期値 \((x,y,\theta)\) |
|
|
status から使う motor 名 |
|
|
\(\rho\) |
|
|
\(R\) |
|
|
\(G\) |
|
|
\(\alpha_i\) |
|
|
\(\beta_i\) |
|
|
\(s_i\) |
|
|
\(q_i\) を revolution として扱う |
|
|
encoder 差分を \([-\pi,\pi]\) に畳む |
|
|
|
profile 側では launch.components.localization.wheel_odometry.enabled が起動可否です。sample の sim.yaml では false、real.yaml では true です。
cmd_vel_to_dcmotor_node と wheel 幾何が一致していないと、command と odometry が逆向きになります。少なくとも次の配列は同じ順序で揃えます。