ã«ã«ãã³ãã£ã«ã¿ãè§£æçã«èšç®ãã§ããã«ãé¢ãããå¿çšã®ç¯å²ã極ããŠåºãç¶æ æšå®ææ³ã§ããããããããããã»ã©ã·ã³ãã«ã§äœ¿ãããªãã«æè¡è ã®å·®ãåºããã®ã¯ç¡ããšæãã
ã«ã«ãã³ãã£ã«ã¿ã®äœ¿ãããªãåãåãããã®ã¯äžèšã®3ç¹ã®èŠçŽ ã«éçŽãããã
- ç¶æ æ¹çšåŒã®ã¢ããªã³ã°
- 芳枬æ¹çšåŒã®ã¢ããªã³ã°
- äºåååžã®èšå®
- 座æšç³»ã®åãæ¹
ã§ãããã«ã«ãã³ãã£ã«ã¿ã§ã¯ç¶æ æ¹çšåŒã«ãã£ãŠèšç®ãããç¶æ éãšèŠ³æž¬æ¹çšåŒã«ãã£ãŠèšç®ãããç¶æ éãã«ã«ãã³ã²ã€ã³ã䜿ã£ãŠäžæã«æ··ãåãããŠæšå®ãè¡ããããã§æ··ãåããããšã¯ãåæ¹çšåŒã«ãã£ãŠèšç®ãããç¶æ ã®äžç¢ºå®æ§ãå å³ããŠæçµçãªæšå®å€ãå®ãããšããããšã§ãããçŽæçã«ã¯ç¶æ æ¹çšåŒã®äºæž¬ãšèŠ³æž¬æ¹çšåŒã®è£æ£ã®èšã£ãŠããããšãããã¿ããšã¯äžèŽããªãããšããããšãèµ·ãããããããã®å åç¹ãå®ããããšããã®ãã«ã«ãã³ã²ã€ã³ã§ãããšèããŠããã
ã«ã«ãã³ã²ã€ã³ã¯äºåååžãšç¶æ æ¹çšåŒãšèŠ³æž¬æ¹çšåŒãå®ããã°ãããšã¯ããŒã¿ã«ãã£ãŠèªåã§å®ãŸãããã®èšç®ãè§£æçã§ããããšãèŠäºã§ããããªã³ã©ã€ã³ã®ãªã¢ã«ã¿ã€ã æšå®ã®äž»åœ¹ãšããŠçŸåšãåèšãç¶ããŠããã
ä»åã¯ããã®äžã§ãããªã¢ã«ã¿ã€ã æšå®ãã«äœ¿ãããšãèæ ®ãããç¶æ æ¹çšåŒããšã芳枬æ¹çšåŒãã®ã¢ããªã³ã°ã«çç®ããããšæãã
å ·äœçã«ã¯ã芳枬ããÎtã ãéå»ã®ã»ã³ãµå€ã«åºã¥ããå Žåã«ããã®å€ããªã¢ã«ã¿ã€ã ã«çŸåšã®ç¶æ æšå®ã«ã©ã®ããã«çšããã®ãã顿ã«ããã
ä»åã¯ããã芳枬é å»¶ãšåŒã¶ããšã«ããããã®ãããªããšãã¯æ¬¡ã®ãããªã±ãŒã¹ã§çãããã
- ã»ã³ãµå€ã®ååŸãããã«ã«ãã³ãã£ã«ã¿ãå®è¡ããããã»ã¹ã«å¯Ÿããéä¿¡é å»¶
- ã»ã³ãµå€ã®ååŸãããç¶æ éã®èšç®ã¢ã«ãŽãªãºã ã«æéãèŠããïŒe.g.ã«ã¡ã©ã§ã®äœçœ®æšå®ïŒ
èŠããã« Event Time ãš Process Time ãç¡èŠã§ããªãã»ã©ãããŠãããšããããšã§ããããã®ãããªæå»ã®ãºã¬ãã«ã«ãã³ãã£ã«ã¿åŽã«åžåããŠãããã®ãä»åã®åé¡ã§ãããä»åã¯ç°¡åã®ãããé å»¶ã®æå»ã¯ã¢ã«ãŽãªãºã ã®å€ã§åãã£ãŠãããã®ãšãããããã¯ãã«ã¡ã©ã®ç»çŽ ããŒã¿ããç§»åéãç®åºããããšããè¡æã®çããŒã¿ããäœçœ®æ å ±ãç®åºããããšããæ³å®ãããããŒã¿ã®çºçæå»ïŒEvent TimeïŒãšèšç®ãããŠäœçœ®ã®æ å ±ã«ãªãæå»ïŒProcess TimeïŒãç°ãªãããšãæ³å®ããããã¢ã«ãŽãªãºã ã®èšç®æéãèŠç©ãã£ãŠåååºåã§ããããšãæ³å®ãããæèšã®æ£ããã劥åœã§ããã°ã䜿ããªãããã¯ãã·ã ãããšããæŠç¥ã§ããã
ã¡ãªã¿ã«èŠ³æž¬é å»¶æéèªäœãç¶æ æ¹çšåŒã«åã蟌ãããšãããããšæãã°ã§ããããã ããã»ã©æ å ±ãããã£ãŠããªãéãå¯èŠ³æž¬æ§ãæªãããã ãã§ãããäºåååžåŽã«ã¯å¡ãã®é 延床åã¯çãèŸŒãæ¹ãè¯ããé å»¶æéãåãã£ãŠããèšå®ãšããã®ã¯ãã€ãŸããšããã芳枬é å»¶æéãç¶æ æ¹çšåŒã«åã蟌ãã§ããããäºåååžã§äžç¢ºå®æ§ãã»ãŒç¡ããšèšå®ããŠããã«ç䟡ã§ããïŒããããããªãã°èšç®éãæžãåãç¶æ æ¹çšåŒã«åã蟌ãŸãªãæ¹ãè¯ãïŒã
ã¡ãªã¿ã«ã«ã¡ã©ã§ãGNSSã§ãäœçœ®ã®æ å ±ãåæå»å·®ååãã°é床ãåºããé床ãåºããªãã°ã芳枬ãã§ããŠããªãåºéã§çéçŽç·éåãä»®å®ããããšã§ã芳枬é å»¶ãè£æ£ããŠããã«ã«ãã³ãã£ã«ã¿ã«æž¡ãããšãã§ãããã ãã©ã倧æµã®å Žåã芳枬ã®åšæãããç¶æ æ¹çšåŒã§ã®äºæž¬ã®åšæã®æ¹ãéããäºæž¬ã®åšæåŽã®æ å ±ãæå¹æŽ»çšããŠèŠ³æž¬é å»¶ãè£æ£ã§ããæ¹ããçéçŽç·éåã®ä»®å®ããç·©ããªãæåŸ ãããã
ä»åã¯è»äž¡ã®éåã顿ãšããããŸããè»äž¡ã®ç¶æ ãšã¯äœãããå®çŸ©ããªããã°ãªããªããä»åã¯ä»¥äžã®4ã€ã®éã§è»äž¡ã®ç¶æ ã衚çŸããã
-
$p_x, p_y$ ïŒè»äž¡ã®äœçœ®ïŒã©ãã«ãããïŒ -
$\psi$ ïŒæ¹äœè§ãã€ãŸãè»äž¡ãã©ã£ã¡ãåããŠããã -
$v$ ïŒé床ãã€ãŸãã©ããããã®éãã§é²ãã§ããã
ããã¯ãè»äž¡ã空ããèŠäžããããšãã«ãã©ãã«ããŠãã©ã£ã¡ãåããŠããŠãã©ããããã®éãã§åããŠããããã衚ããŠãããæ¹äœè§ãšé床ãåããã°ã次ã®ç¬éã«ã©ã®æ¹åã«ã©ãã ãé²ãããåããããšããããã ã
次ã«å ¥åãã€ãŸããé転è ãäœãããŠãããããå®çŸ©ããã
-
$f$ ïŒé§ååïŒã¢ã¯ã»ã«ãèžãåïŒ -
$\delta$ ïŒã¹ãã¢è§ïŒãã³ãã«ãã©ãã ãåã£ãŠãããïŒ
éåã¢ãã«ã¯ Kinematic Bicycle Model ãæ¡çšãããããã¯ãè»äž¡ãèªè»¢è»ã®ããã«å茪ãšåŸèŒªã®2茪ã§ã¢ãã«åããããšããç°¡ç¥åã§ããã4茪è»ã§ããå·Šå³ã®ã¿ã€ã€ããŸãšããŠèããã°2茪ãšããŠè¿äŒŒã§ããã
ãã®åŒãäœãèšã£ãŠããããäžã€ãã€èŠãŠãããã
äœçœ®ã®æŽæ°
æ¹äœè§ã®æŽæ°
éåºŠã®æŽæ°
ãããã³ãŒãã«ãããšæ¬¡ã®ããã«ãªãã
import numpy as np
def bicycle_dynamics(x, u, L, m, c, dt):
"""è»äž¡ã®ç¶æ
ã1ã¹ãããé²ãã"""
px, py, psi, v = x
f, delta = u
# äœçœ®ïŒä»ã®éåºŠãšæ¹åã§é²ã
px_next = px + dt * v * np.cos(psi)
py_next = py + dt * v * np.sin(psi)
# æ¹äœè§ïŒã¹ãã¢è§ã«å¿ããŠæ²ãã
psi_next = psi + dt * v / L * np.tan(delta)
# é床ïŒé§ååã§å éãæµæã§æžé
v_next = v + dt * (f / m - c * v)
return np.array([px_next, py_next, psi_next, v_next])ã«ã«ãã³ãã£ã«ã¿ã¯æ¬æ¥ãç·åœ¢ã·ã¹ãã çšã®ææ³ã§ããããããäžã®ç¶æ
æ¹çšåŒã¯
ã€ã³ãã¢ã³ãšã¯äœãïŒ ãããéãå°ãå€ãããšããçµæãã©ãã ãå€ããããã衚ãè¡åã§ãããããšãã°ãæ¹äœè§ã1床å€ããããæ¬¡ã®Xäœçœ®ã¯ã©ãã ãå€ãããïŒããšããæåºŠãå šãŠã®çµã¿åããã«ã€ããŠäžŠã¹ããã®ã ã
ç¶æ
ã«é¢ããã€ã³ãã¢ã³
ããšãã°
def compute_jacobians(x, u, L, m, c, dt):
"""ã€ã³ãã¢ã³ F ãš G ãèšç®ãã"""
psi, v = x[2], x[3]
delta = u[1]
F = np.array([
[1.0, 0.0, -dt * v * np.sin(psi), dt * np.cos(psi)],
[0.0, 1.0, dt * v * np.cos(psi), dt * np.sin(psi)],
[0.0, 0.0, 1.0, dt / L * np.tan(delta)],
[0.0, 0.0, 0.0, 1.0 - dt * c],
])
return F芳枬ãšããŠã¯GNSSã«ããäœçœ®èŠ³æž¬ãèãããGNSSã¯ç©ºããããã®è»ã¯ããã«ããããšäœçœ®
ãã®
ããã¯çŸå®çãªä»®å®ã ãããïŒ æè¿ã®GNSSã¯æ¡ä»¶ãè¯ããã°ã»ã³ãã¡ãŒãã«çŽã®ç²ŸåºŠãåºããäžæ¹ããã€ãŒã«ãªãã¡ããªïŒè»èŒªã®å転ããæšå®ããé床ïŒã¯ã¿ã€ã€ã®ã¹ãªããã空転ã§å€§ããçããã ãããGNSSãä¿¡é ŒããŠããªãã¡ããªã¯è£å©çã«äœ¿ãããšããæŠç¥ã¯æ¡ä»¶ã«ãã£ãŠã¯çŸå®çã§ãããïŒãããã芳枬é å»¶ã®åœ±é¿ãèŠãäŸé¡ã ããããŸãå€ãã«èŠãŠã±ããå®éã¯ãã«ããç«ã¡äžŠã¶ãã³ããã¿ã³ãšãã ãšãã«ããã¹ã§å³ããã£ãããããã©ïŒ
ã«ã«ãã³ãã£ã«ã¿ã¯ãäºæž¬ããšãæŽæ°ãã®2ã¹ããããç¹°ãè¿ãã
ãŸããç¶æ æ¹çšåŒã䜿ã£ãŠã次ã®ç¶æ ã¯ãããªãã ããããšäºæž¬ããã
åæã«ãäºæž¬ã®äžç¢ºå®æ§ïŒå ±åæ£ïŒãæŽæ°ããã
ãã®åŒã¯ãäžç¢ºå®æ§ãã©ãäŒæããããã衚ããŠãããäºæž¬ã ããããŠãããšãäžç¢ºå®æ§ã¯ã©ãã©ã倧ãããªã£ãŠããã ã¢ãã«ãå®ç§ã§ã¯ãªããããäºæž¬ãéããã»ã©ãæ¬åœã¯ã©ãã«ãããåãããªããªããã®ã ã
芳枬ãåŸãããããäºæž¬ãšèŠ³æž¬ãæ··ãåãããŠæšå®ãæ¹åããã
ãã®ã«ã«ãã³ã²ã€ã³
ããšã話ã§èšãã°ã倩æ°äºå ±ãšå®éã®æ°æž©ãæ··ãåããããããªãã®ã ã倩æ°äºå ±ïŒäºæž¬ïŒããææ¥ã¯20床ããšèšã£ãŠããŠãå®éã«æž©åºŠèšïŒèŠ³æž¬ïŒãèŠãã22床ã ã£ããã§ã枩床èšãããŸãä¿¡é Œã§ããªããšããããããã¶ã21床ãããã ããããšæšå®ãããæž©åºŠèšããããæ£ç¢ºãªã芳枬ãä¿¡ããŠ22床ã«è¿ãå€ããæž©åºŠèšãæªãããã°å€©æ°äºå ±ãä¿¡ããŠ20床ã«è¿ãå€ãæ¡çšããããã®ãã©ããããä¿¡ãããããèªåã§æ±ºããŠãããã®ãã«ã«ãã³ãã£ã«ã¿ã ã
def ekf_predict(mu, P, u, Q, L, m, c, dt):
"""EKFã®äºæž¬ã¹ããã"""
mu_pred = bicycle_dynamics(mu, u, L, m, c, dt)
F = compute_jacobians(mu, u, L, m, c, dt)
P_pred = F @ P @ F.T + Q # äžç¢ºå®æ§ãå¢ãã
return mu_pred, P_pred
def ekf_update(mu, P, z, R):
"""EKFã®æŽæ°ã¹ããã"""
H = np.array([[1, 0, 0, 0], [0, 1, 0, 0]])
y = z - H @ mu # ã€ãããŒã·ã§ã³ïŒäºæž¬ãšèŠ³æž¬ã®å·®ïŒ
S = H @ P @ H.T + R
K = P @ H.T @ np.linalg.inv(S) # ã«ã«ãã³ã²ã€ã³
mu_upd = mu + K @ y # ç¶æ
ãä¿®æ£
P_upd = (np.eye(4) - K @ H) @ P # äžç¢ºå®æ§ãæžã
return mu_upd, P_updããã§éèŠãªã®ã¯ã芳枬
ããŠããããããæ¬é¡ã§ãããGNSSã®èŠ³æž¬ã«ã¯é
å»¶ããããæå»
ããã§
ããã¯äœãæå³ãããïŒ ä»æå ã«å±ãããäœçœ®æ å ±ãã¯ãå®ã¯0.5ç§åã®äœçœ®ãªã®ã ã è»ãæé36kmïŒç§é10mïŒã§èµ°ã£ãŠãããã0.5ç§ã§5mé²ããã€ãŸããä»ããã«ããããšæã£ãŠäœ¿ã£ãŠããäœçœ®æ å ±ã¯ãå®ã¯5måŸãã®äœçœ®ãããããªãã
äžçªåçŽãªã¢ãããŒãã¯ãé å»¶ãç¡èŠããŠãå°çãã芳枬ãçŸåšã®ç¶æ ã®èŠ³æž¬ãšããŠæ±ãããšã ã
ãããå³ã§èããŠã¿ãããè»ãåã«åãã£ãŠèµ°ã£ãŠãããšããã
-
æå»
$k-d$ ïŒè»ã¯äœçœ®Aã«ãããGNSSããã®äœçœ®ã芳枬ããã -
æå»
$k-d$ ãã$k$ ãŸã§ïŒè»ã¯åã«é²ã¿ç¶ãããã«ã«ãã³ãã£ã«ã¿ã¯äºæž¬ãç¹°ãè¿ãããè»ã¯ä»ãäœçœ®Bã«ããã ããããšæšå®ããã -
æå»
$k$ ïŒGNSSã®èŠ³æž¬ãå±ãããäœçœ®ã¯Aã ããšèšã£ãŠããã - Naiveã¢ãããŒãïŒããããä»Bã«ãããšæã£ããã©ãGNSSã¯Aã ãšèšã£ãŠãããGNSSãä¿¡é Œãããããšãæšå®äœçœ®ãAã®æ¹ã«åŒãæ»ãã
ããã¯æããã«ééã£ãŠããã GNSSãèšã£ãŠãããAãã¯0.5ç§åã®äœçœ®ã§ãã£ãŠãä»ã®äœçœ®ã§ã¯ãªããGNSSãä¿¡é Œããã°ããã»ã©ïŒ$R$ ãå°ããã»ã©ïŒããã®ãéå»ãžã®åŒãæ»ããã匷ããªãã
ããšã話ã§èšãã°ãå人ãããä»ã©ãã«ããïŒããšèãããŠãLINEã®äœçœ®æ å ±ãéã£ãããå®ã¯ããã¯5ååã®äœçœ®ã§ãä»ã¯ããé§ ã«çããŠããã®ã«ãå人ã¯ããŸã ãã®ã«ãã§ã«ããã®ãããšæã蟌ããããªãã®ã ãå人ãããªãã®èšèã100%ä¿¡ããã¿ã€ããªãããã«ãã§ããåããŠããªãããšç¢ºä¿¡ããŠããŸãã
def naive_filter_loop(mu, P, u_all, z_all, has_gnss, Q, R, L, m, c, dt):
"""Naiveãã£ã«ã¿ïŒé
å»¶ãç¡èŠããïŒééã£ãã¢ãããŒãïŒ"""
mu_history = [mu]
for k in range(len(u_all)):
# äºæž¬
mu, P = ekf_predict(mu, P, u_all[k], Q, L, m, c, dt)
# æŽæ°ïŒé
å»¶ãç¡èŠããŠãå°çãã芳枬ããä»ã®äœçœ®ããšããŠæ±ãïŒ
if has_gnss[k]:
mu, P = ekf_update(mu, P, z_all[k], R) # ãããééãïŒ
mu_history.append(mu)
return np.array(mu_history)æ£ç¢ºãªæ å ±ãééã£ãæå»ã«äœ¿ã£ãŠããã®ãåé¡ã®æ¬è³ªã§ãããç®èãªããšã«ãè¯ãã»ã³ãµã䜿ãã»ã©æšå®ãçããGNSSã®ç²ŸåºŠãé«ãããä¿¡é Œãããã§ãæå»ãééã£ãŠããããçµæçã«å€§ããå€ãããšããæªåŸªç°ã ã
芳枬é å»¶ãé©åã«æ±ãææ³ãšããŠãä»åã¯2ã€ã®ææ³ãå®è£ ããã
- å±¥æŽåäŒæïŒReplayïŒ: 芳枬ãå°çããããéå»ã®ç¶æ ã«é¡ã£ãп޿°ããçŸåšãŸã§åèšç®ãã
- 確ççã¯ããŒãã³ã°ïŒStochastic CloningïŒ: éå»ã®ç¶æ ã®ã³ããŒïŒã¯ããŒã³ïŒãä¿æããã¯ãã¹å ±åæ£ã远跡ãã
æãçŽæ¥çãªã¢ãããŒãã¯ãã¿ã€ã ãã·ã³ã«ä¹ã£ãŠéå»ã«æ»ããããã§èŠ³æž¬ãåæ ãããŠããããŸãçŸåšã«æ»ã£ãŠãããšãããã®ã ã
å ·äœçã«ã¯ã
- æå»
$k$ ã«èŠ³æž¬$z_k$ ãå°çãããã¯æå»$k-d$ ã®èŠ³æž¬ã ãšåãã£ãŠããã - ä¿åããŠãããæå»
$k-d$ ã®ç¶æ æšå®å€ãåãåºãã - ãã®ç¶æ ã«å¯ŸããŠèŠ³æž¬æŽæ°ãè¡ãã
- ä¿åããŠãããå
¥å
$u_{k-d}, u_{k-d+1}, ..., u_{k-1}$ ã䜿ã£ãŠãæå»$k$ ãŸã§äºæž¬ãåèšç®ããã
ãã®æŽæ°ãããéå»ã®ç¶æ ãããçŸåšãŸã§åäŒæããã
ãã®æ¹æ³ãæ£ããçç±ã¯ãèŠ³æž¬ãæ£ããæå»ã®ç¶æ
ã«å¯ŸããŠé©çšããŠããããã ãGNSSããæå»
å€äŒã¿ã®æ¥èšãæžããŠããŠã3æ¥åã®åºæ¥äºã®èšæ¶ãééã£ãŠããããšã倿ãããã3æ¥åã®ããŒãžãæžãçŽããŠããã以éã®ããŒãžãæŽåæ§ãåãããã«æžãçŽããããªãã®ã ã垳尻åããããã£ãããšããã§ããã
def replay_filter_loop(mu, P, u_all, z_all, has_gnss, delay_steps, Q, R, L, m, c, dt):
"""Replayãã£ã«ã¿ïŒå±¥æŽãé¡ã£ãŠåèšç®ãã"""
mu_history = [mu]
P_history = [P]
for k in range(len(u_all)):
# éåžžã®äºæž¬
mu, P = ekf_predict(mu, P, u_all[k], Q, L, m, c, dt)
mu_history.append(mu)
P_history.append(P)
# GNSS芳枬ãå°çããããéå»ã«é¡ã£ãп޿°
if has_gnss[k] and k >= delay_steps:
obs_step = k - delay_steps
# éå»ã®ç¶æ
ãåãåºããŠæŽæ°
mu_past = mu_history[obs_step]
P_past = P_history[obs_step]
mu_upd, P_upd = ekf_update(mu_past, P_past, z_all[k], R)
# æŽæ°ããéå»ããçŸåšãŸã§åäŒæ
for i in range(delay_steps):
mu_upd, P_upd = ekf_predict(mu_upd, P_upd, u_all[obs_step + i], Q, L, m, c, dt)
# çŸåšã®ç¶æ
ãæŽæ°
mu = mu_upd
P = P_upd
mu_history[-1] = mu
P_history[-1] = P
return np.array(mu_history)å©ç¹ïŒçè«çã«æ£ãããåäŒæã®åã¹ãããã§ææ°ã®ç¶æ ã䜿ã£ãŠç·åœ¢åãçŽãã®ã§ãéç·åœ¢æ§ãæ£ç¢ºã«åæ ã§ããã
æ¬ ç¹ïŒèšç®ã³ã¹ããé«ããé
å»¶ã
Replay ã®èšç®ã³ã¹ããé¿ãããããéå»ã®ç¶æ ã®ã³ããŒïŒã¯ããŒã³ïŒãä¿æããçŸåšã®ç¶æ ãšã®çžé¢ã远跡ãããšããææ³ãããã
ã¢ã€ãã¢ã¯ããã ãGNSSã芳枬ãè¡ãæå»ã«ããã®æç¹ã®ç¶æ æšå®å€ããã¯ããŒã³ããšããŠä¿åããŠããããã®åŸãçŸåšã®ç¶æ ã¯äºæž¬ã§é²ãã§ããããã¯ããŒã³ã¯åãããªãããã ããçŸåšã®ç¶æ ãšã¯ããŒã³ã®çžé¢ïŒã¯ãã¹å ±åæ£ïŒã¯è¿œè·¡ãç¶ããã
ãªãçžé¢ãéèŠãïŒ çŸåšã®ç¶æ ã¯éå»ã®ç¶æ ããäºæž¬ã§èšç®ãããŠãããããäž¡è ã¯ç¡é¢ä¿ã§ã¯ãªãããéå»ã®ç¶æ ãå®ã¯å°ããããŠããããšåãã£ãããããããçŸåšã®ç¶æ ãããã«å¿ããŠãããŠããã¯ãããšæšè«ã§ããããã®ãé£åããŠããã床åãããã¯ãã¹å ±åæ£ã ã
芳枬æå»ã«ã¯ããŒã³ãäœæãããšãæ¡åŒµç¶æ ãã¯ãã«ã¯æ¬¡ã®ããã«ãªãã
å ±åæ£è¡åãæ¡åŒµãããã
ããã§
äºæž¬ã¹ãããã§ã¯ãçŸåšã®ç¶æ ã ããæŽæ°ããããã¯ããŒã³ã¯éå»ã®ç¶æ ãªã®ã§åããªãããããã¯ãã¹å ±åæ£ã¯æŽæ°ããå¿ èŠãããã
ãã®åŒã¯ãç¶æ
é·ç§»ã§çŸåšã®ç¶æ
ãå€ãããšãã¯ããŒã³ãšã®çžé¢ãããã«å¿ããŠå€åãããããšã衚ããŠãããã€ã³ãã¢ã³
芳枬ãå°çããããã¯ããŒã³ã«å¯ŸããŠæŽæ°ãè¡ãããããŠãã¯ãã¹å ±åæ£ãéããŠçŸåšã®ç¶æ ãæŽæ°ããã
çŽæçã«èšãã°ããéå»ã®ç¶æ ãããã ããããŠãããªããçŸåšã®ç¶æ ãããã ããããŠããã¯ãããšããæšè«ããã¯ãã¹å ±åæ£ã䜿ã£ãŠè¡ã£ãŠããã®ã ã
ééãæ¹ã䌌ãŠãããšèããŠããã®ã§ãããåéšã«å±ãåã¯ã次ã®è©Šéšã§äœç¹åãããããã€ãäºæž¬ããŠãã詊éšã«èšããè¯ãå§¿å¢ã ã**1幎åã«åãã詊éšã®çµæã¯äºæ³ããã10ç¹é«ãã£ããšããã**ãªãã»ã©ãäºæ³ã¯æ§ãããªããã§ããã**æŽã«å幎åã®è©Šéšã®äºæ³ã¯80ç¹ã§ãã£ãã**ããŠãä»åã¯æ°ããªè©Šéšã«æãããšããŠããã**ä»åã®è©Šéšã®äºæ³ã¯85ç¹ã ãããã§ãååã®è©Šéšã®ç¹æ°ã®çµæãä»åŸããã88ç¹ã ã£ããšããã£ãã**ãŸãçµæã®æ¹ãé«ããä»åŸãããæ å ±ã¯å幎åã®æ å ±ã§ããããåŸåããããŠäºæž¬ãããäžæ¯ãããç¹ãåããã ãããšããããšã«ç¢ºä¿¡ãæãŠããã§ã¯ãªããïŒã€ãŸãä»åã®è©Šéšã®äºæ³ã¯85ç¹ã ãšããŠããããéå»ã®è©ŠéšãåŒãç¶ãäžæ¯ãããçµæãåŸãããŠããããšã芳枬ããããšã«ãããä»åã®çµæã94ç¹ãããã«æŽæ°ããŠãããããã ã
10幎åŸã芪ã®èº«é·ã®æ£ç¢ºãªå€ãåãã£ãïŒèŠ³æž¬ãå°çïŒããã®ãšãããå ã®èº«é·ãæã£ãŠãããã5cmé«ãã£ãããšåããã°ãããããåŒã®èº«é·ããçžé¢ã®åã ãé«ããããããªãããšæšè«ã§ããããããã¯ãã¹å ±åæ£ã䜿ã£ãæŽæ°ã ã
def cloning_filter_loop(mu, P, u_all, z_all, has_gnss, should_clone, delay_steps, Q, R, L, m, c, dt):
"""確ççã¯ããŒãã³ã°ïŒã¯ãã¹å
±åæ£ã远跡ãã"""
mu_history = [mu]
# ã¯ããŒã³ã®ç¶æ
mu_clone = mu.copy()
P_clone = P.copy()
P_cross = P.copy() # åæã¯åãç¶æ
ãªã®ã§ P_cross = P
clone_valid = False
for k in range(len(u_all)):
# ã¯ããŒã³ãäœæããã¿ã€ãã³ã°ïŒGNSS芳枬㮠delay_steps åïŒ
if should_clone[k]:
mu_clone = mu.copy()
P_clone = P.copy()
P_cross = P.copy()
clone_valid = True
# äºæž¬ïŒçŸåšã®ç¶æ
ãæŽæ°
F = compute_jacobians(mu, u_all[k], L, m, c, dt)
mu, P = ekf_predict(mu, P, u_all[k], Q, L, m, c, dt)
# ã¯ãã¹å
±åæ£ã®äŒæïŒããããã¢ïŒïŒ
P_cross = F @ P_cross
# GNSS芳枬ãå°çããããã¯ããŒã³ã䜿ã£ãп޿°
if has_gnss[k] and clone_valid:
H = np.array([[1, 0, 0, 0], [0, 1, 0, 0]])
y = z_all[k] - H @ mu_clone # ã¯ããŒã³ïŒéå»ã®ç¶æ
ïŒãšã®å·®
S = H @ P_clone @ H.T + R
S_inv = np.linalg.inv(S)
# ã¯ãã¹å
±åæ£ã䜿ã£ãŠçŸåšã®ç¶æ
ãæŽæ°
K_current = P_cross @ H.T @ S_inv
mu = mu + K_current @ y
P = P - K_current @ S @ K_current.T
clone_valid = False
mu_history.append(mu)
return np.array(mu_history)å©ç¹ïŒèšç®ã³ã¹ããäœããå±¥æŽã®åèšç®ãäžèŠã§ãè¡åæŒç®ã®ã¿ã§æžãããªã¢ã«ã¿ã€ã åŠçã«åããŠããã
æ¬ ç¹ïŒã¯ããŒã³äœææã®ç·åœ¢åã䜿ãç¶ããããã匷ãéç·åœ¢æ§ãããå Žåã«è¿äŒŒèª€å·®ãèç©ããå¯èœæ§ãããããã ããä»åã®å®éšã§ã¯å®çšäžåé¡ãªãã¬ãã«ã ã£ãã
以äžã®æ¡ä»¶ã§3ææ³ãæ¯èŒããã
| ãã©ã¡ãŒã¿ | å€ |
|---|---|
| ã·ãã¥ã¬ãŒã·ã§ã³æé | 30ç§ |
| ãªãã¡ããªæŽæ°ã¬ãŒã | 500 Hz |
| GNSSæŽæ°ã¬ãŒã | 1 Hz |
| GNSSé å»¶ | 0.5ç§ïŒ250ã¹ãããïŒ |
| GNSSãã€ãº | Ï = 0.001 mïŒã»ãŒçå€ïŒ |
| èŠ³æž¬å ±åæ£ R | Ï = 0.01 mïŒGNSSãä¿¡é ŒïŒ |
çŸå®ã®ã·ã¹ãã ã§ã¯ãã«ã«ãã³ãã£ã«ã¿ã䜿ãã¢ãã«ãã©ã¡ãŒã¿ã¯çå€ãšäžèŽããªããä»åã¯ä»¥äžã®èª€å·®ãèšå®ããã
| ãã©ã¡ãŒã¿ | çå€ | æšå®ã«äœ¿ãå€ | 誀差 |
|---|---|---|---|
| ãã€ãŒã«ããŒã¹$L$ | 2.5 m | 2.3 m | -8% |
| è»äž¡è³ªé$m$ | 1500 kg | 1400 kg | -7% |
| æµæä¿æ°$c$ | 0.1 | 0.2 | +100% |
ããã¯äœãæå³ãããïŒ ã«ã«ãã³ãã£ã«ã¿ã¯ãééã£ãã¢ãã«ãã§äºæž¬ããŠãããšããããšã ã
ããšãã°ããã€ãŒã«ããŒã¹ãå®éããçããšæã£ãŠããããããåãã¹ãã¢è§ãªããã£ãšæ²ããã¯ãããšäºæž¬ããã質éãå®éãã軜ããšæã£ãŠããããããåãé§ååãªããã£ãšå éããã¯ãããšäºæž¬ãããæµæä¿æ°ã2åã ãšæã£ãŠããããããé床ã¯ãã£ãšèœã¡ãã¯ãããšäºæž¬ããã
ãã®ãããªã¢ãã«èª€å·®ãããç¶æ³ããã芳枬ã«ããè£æ£ãéèŠã«ãªããäºæž¬ã ãã«é Œããšãã¢ãã«ã®ééãããã®ãŸãŸæšå®èª€å·®ã«ãªããã ãããããGNSSã®ãããªå€éšèŠ³æž¬ã§å®æçã«è£æ£ããããšãå¿ èŠãªã®ã ã
ãã€ã³ãã¯GNSSã®ãã€ãºãéåžžã«å°ãããšããèšå®ã ãããã¯ãGNSSãä¿¡é Œããããšããããšãæå³ãããä¿¡é Œã§ããã»ã³ãµã®æ å ±ãæ£ãã䜿ãããã©ããããé å»¶è£æ£ã®äŸ¡å€ã瀺ãããšã«ãªãã
è»éã¯åè»éäžãèè¡ãããã¿ãŒã³ãšãããã¹ãã¢è§ã¯æ£åŒŠæ³¢ã§æ»ããã«å€åãããæåããªããå·Šå³ã«å€§ããèè¡ããåããæš¡æ¬ããŠãããé床ãåºãŠããç¶æ ã§ã®æåã¯ãé å»¶ã®åœ±é¿ã倧ããåºãããæ¡ä»¶ã ã
é»ç·ãçã®è»è·¡ãç·ç·ãNaiveïŒé å»¶ç¡èŠïŒãéç·ãCloningãèµ€ç Žç·ãReplayã§ãããããŒã³ã¿ã®ç¹ã¯GNSS芳枬ç¹ã瀺ãã
Naiveã§ã¯è»è·¡ãçå€ãã倧ãããããŠããã®ãäžç®çç¶ã ãç·ã®ç·ãé»ã®ç·ããã¯ã¿åºããŠããŸãã§è»ãèè¡ããããŠããããã«èŠãããããã¯GNSS芳枬ã®ãã³ã«ã0.5ç§åã®äœçœ®ãã«åŒãæ»ãããŠããããã ãäžæ¹ãCloningãšReplayã¯ã»ãŒçå€ã«è¿œåŸããŠãããé»ç·ã«ãŽã£ããéãªã£ãŠããã
äžããé ã«Xäœçœ®ãYäœçœ®ãæ¹äœè§ãé床ãé§ååãã¹ãã¢è§ã瀺ããæšªè»žïŒæéïŒã¯å šãŠã®ããããã§æããŠããã
Naiveã§ã¯ãGNSS芳枬ã®ãã³ã«æšå®äœçœ®ããžã£ã³ãããŠããã®ãåãããç¹ã«Xäœçœ®ãšYäœçœ®ã®ã°ã©ãã§ãç·ç·ãã®ã¶ã®ã¶ã«ãªã£ãŠãããããã¯æ£ç¢ºãªèŠ³æž¬ãééã£ãæå»ã«äœ¿ã£ãŠããããã ã1ç§ããšã«ãéå»ã«åŒãæ»ããããâãäºæž¬ã§é²ããâããŸãåŒãæ»ãããããç¹°ãè¿ããŠããã
CloningãšReplayã¯ãã®ãžã£ã³ãããªããæ»ããã«çå€ã远跡ããŠãããé å»¶è£æ£ãå¹ããŠãã蚌æ ã ã
ãŸãNaiveãé å»¶è£æ£ãéåºŠã®æšå®ã¯å®åžžçãªãã€ã¢ã¹ãåºãŠããã®ãããããæµæãè»äž¡è³ªéã®ã¢ãã«å誀差ãçŸããŠãããšèããŠãããããã§ãäœçœ®ã®æ¬¡å ã§ã¯GNSSã®æéé å»¶ãç¹ã蟌ãã æšå®ããããšã§ãäºæž¬ã®ããªãããè£æ£ã§ããŠããããšãçŽ æŽãããçµæã§ããã
| ææš | NaiveïŒé å»¶ç¡èŠïŒ | Cloning | Replay |
|---|---|---|---|
| RMSE äœçœ® [m] | 1.44 | 0.32 | 0.34 |
| RMSE æ¹äœ [deg] | 4.64 | 1.06 | 1.16 |
| èšç®æé [s] | 0.23 | 0.27 | 0.37 |
â»èšç®æéã¯JITã³ã³ãã€ã«æžã¿ã®ç¶æ
ã§èšæž¬ïŒåäžå
¥å圢ç¶ã§ã®ãŠã©ãŒã ã¢ããåŸïŒãäž¡ææ³ãšã lax.scanã䜿çšããæé©åå®è£
ã§ã®æ¯èŒã
æ°åã§èŠããšå·®ã¯æŽç¶ãšããŠãããNaiveã®äœçœ®RMSEã¯çŽ1.4mã§ãé å»¶è£æ£ææ³ïŒçŽ0.34mïŒã®çŽ4åã§ãããæ¹äœè§ãåæ§ã§ãNaiveã¯çŽ5床ãããŠããã®ã«å¯Ÿããé å»¶è£æ£ææ³ã¯1床çšåºŠã«åãŸã£ãŠããã
ãªããé å»¶è£æ£ææ³ã§ãçŽ30cmã®RMSEãæ®ã£ãŠããã®ã¯ãã¢ãã«ãã©ã¡ãŒã¿ã®èª€å·®ã®åœ±é¿ã§ãããGNSSã¯1ç§ã«1åããæ¥ãªãã®ã§ããã®éã¯ã¢ãã«ã§äºæž¬ãããããªããã¢ãã«ãééã£ãŠããã°ããã®åã ã誀差ãèç©ãããããã¯é å»¶è£æ£ãšã¯å¥ã®åé¡ã§ãããã¢ãã«ã®ç²ŸåºŠåäžãããã»ã¹ãã€ãºã®ãã¥ãŒãã³ã°ã§æ¹åã§ããäœå°ãããã
Naiveææ³ãããã»ã©æªãçµæã«ãªãçç±ã¯ãGNSSãä¿¡é ŒããŠããããã ãç®èã«èããããããããªããããããæ¬è³ªã§ããã
ã«ã«ãã³ã²ã€ã³ã®åŒãæãåºããŠã»ããã
ãšãããããã®ãä¿¡é ŒããŠãã芳枬ããæå»ãééããŠãããé床ã10m/sã®å Žåã0.5ç§ã®é å»¶ã§5mãã®å·®ãçãããGNSSãã5måŸãã«ããããšèšã£ãŠããã®ãä¿¡ããŠãæšå®äœçœ®ã5måŸãã«åŒãæ»ããã§ãå®éã«ã¯è»ã¯é²ãã§ããããããŸãäºæž¬ã§é²ãããããŠãŸãåŒãæ»ãããã
è¯ãã»ã³ãµãééã£ãäœ¿ãæ¹ã§äœ¿ããšãæªãã»ã³ãµã䜿ãããæªãçµæã«ãªããšããæèšã ã
| ææ³ | èšç®æé | éåºŠæ¯ |
|---|---|---|
| Cloning | 0.27s | 1.4x é«é |
| Replay | 0.37s | 1.0x |
Cloningã¯Replayã®çŽ1.4åé«éã§ãããäž¡ææ³ãšã lax.scanãçšããæé©åå®è£
ã§ã®æ¯èŒã ã
ãªããã®å·®ãçããã®ãïŒReplayã¯åGNSSå°çæã«250ã¹ãããåã®åèšç®ãå¿
èŠã ã30ç§éã§30åã®GNSS芳枬ããããããåèš
äžæ¹ãCloningã¯ã¯ãã¹å
±åæ£ã®äŒæ
ãªã¢ã«ã¿ã€ã åŠçã§ã¯ããã®å·®ã¯æ±ºå®çã ã500Hzã§åãã·ã¹ãã ã§ã¯ã1ã¹ãããããã2ms以å ã«åŠçãçµããå¿ èŠããããReplayã ãšãã®å¶çŽãæºãããªãå¯èœæ§ãããããCloningãªãäœè£ãããã
CloningãšReplayã®äœçœ®RMSEã¯ã»ãŒåãïŒ0.34mïŒã§ãããäž¡ææ³ã®å·®ã¯1cmæªæºã§ãå®çšäžç¡èŠã§ããã¬ãã«ã ã
ä»åã¯ã¢ãã«ãã©ã¡ãŒã¿ã«å€§ããªèª€å·®ïŒç¹ã«æµæä¿æ°ã+100%ïŒããããããé å»¶è£æ£ææ³ã§ãçŽ30cmã®RMSEãæ®ã£ãŠãããããã¯ã¢ãã«èª€å·®ã®åœ±é¿ã§ãããé å»¶è£æ£èªäœã¯æ£ããæ©èœããŠããã
ãªãCloningã®è¿äŒŒãããŸãæ©èœããŠããã®ãïŒ ã¯ãã¹å
±åæ£ã®äŒæ
ãã ãã以äžã®ç¶æ³ã§ã¯Replayãæå©ã«ãªãå¯èœæ§ãããã
- é å»¶ãéåžžã«å€§ããïŒ1ç§ä»¥äžïŒïŒç·åœ¢è¿äŒŒã®èª€å·®ãèç©ãã
- 匷ãéç·åœ¢æ§ïŒæ¥æåãé«éèµ°è¡ïŒïŒã€ã³ãã¢ã³ã倧ããå€åãã
- ãªãã©ã€ã³åŠçã§æé«ç²ŸåºŠãå¿ èŠïŒèšç®æéã«äœè£ããã
芳枬é å»¶ã®ããã«ã«ãã³ãã£ã«ã¿ã«ã€ããŠã3ã€ã®ã¢ãããŒããæ¯èŒããã
| ææ³ | é å»¶è£æ£ | 粟床 | èšç®ã³ã¹ã | æšå¥šã±ãŒã¹ |
|---|---|---|---|---|
| Naive | ãªã | â | â | é å»¶ããªãå Žåã®ã¿ |
| 確ççã¯ããŒãã³ã° | ãã | â | â | ãªã¢ã«ã¿ã€ã åŠç |
| å±¥æŽåäŒæ | ãã | â | â³ | ãªãã©ã€ã³åŠçãé«ç²ŸåºŠèŠæ± |
- é å»¶è£æ£ã¯å¿ é ïŒGNSSãä¿¡é Œããèšå®ã§ã¯ãé å»¶ãç¡èŠãããšç²ŸåºŠãçŽ4åæªåãããè¯ãã»ã³ãµãééã£ãäœ¿ãæ¹ã§äœ¿ãã®ã¯ãæªãã»ã³ãµã䜿ãããæªãã
- å€ãã®å Žåãã¯ããŒãã³ã°ã§ååïŒReplayãšã®ç²ŸåºŠå·®ã¯çŽ1.5cmã§ãèšç®æéã¯çŽ1.4åé«éããªã¢ã«ã¿ã€ã åŠçã«ã¯æé©ãªéžæã ã
- ã¢ãã«èª€å·®ã®åœ±é¿ïŒé å»¶è£æ£ãããŠãæ®ã誀差ïŒä»åã¯çŽ30cmïŒã¯ã¢ãã«ãã©ã¡ãŒã¿ã®èª€å·®ã«èµ·å ãããã¢ãã«ã®ç²ŸåºŠåäžã¯å¥éåãçµãã¹ã課é¡ã ã
-
å®è£
äžã®ãã€ã³ãïŒã¯ãã¹å
±åæ£ã®äŒæ
$P_{\text{cross}}^{+} = F \cdot P_{\text{cross}}$ ããã¢ãããã远跡ããããšã§ãéå»ã®èŠ³æž¬ã®æ å ±ãçŸåšã®ç¶æ ã«æ£ããåæ ã§ããã -
æ°å€å®å®æ§ïŒå
±åæ£è¡åã®æŽæ°ã«ã¯Joseph圢åŒ
$(I-KH)P(I-KH)^T + KRK^T$ ã䜿ãããšã§ãæ°å€çãªå®å®æ§ã確ä¿ã§ãããåçŽãª$P - KSK^T$ ã ãšäžžãèª€å·®ã§æ£å®å€æ§ã厩ããããšãããã
芳枬é å»¶ã¯ãç¡èŠããã°ãããåé¡ã§ã¯ãªããç¹ã«GNSSã®ãããªä¿¡é Œã§ããã»ã³ãµã®æ å ±ãæ£ããæŽ»çšããããã«ã¯ãé å»¶è£æ£ã¯å¿ é ã§ããã確ççã¯ããŒãã³ã°ã¯ãèšç®ã³ã¹ããšç²ŸåºŠã®ãã©ã³ã¹ã«åªããŠããããªã¢ã«ã¿ã€ã åŠçã«ãããå®çšçãªéžæè¢ãšãªãã
- Bar-Shalom, Y., Li, X. R., & Kirubarajan, T. (2004). Estimation with Applications to Tracking and Navigation. Wiley.
- Julier, S. J., & Uhlmann, J. K. (2004). Unscented filtering and nonlinear estimation. Proceedings of the IEEE, 92(3), 401-422.
- Roumeliotis, S. I., & Burdick, J. W. (2002). Stochastic cloning: A generalized framework for processing relative state measurements. ICRA 2002.

