@@ -102,17 +102,19 @@ def _smooth(self):
102102 self ._x = np .empty ((0 , 16 ), dtype = "float64" )
103103 self ._P = np .empty ((0 , * self ._ains .P .shape ), dtype = "float64" )
104104 elif n_samples == 1 :
105- self ._x = np .asarray_chkfinite (self ._x_buf )
106- self ._P = np .asarray_chkfinite (self ._P_buf )
105+ self ._x = np .asarray (self ._x_buf )
106+ self ._P = np .asarray (self ._P_buf )
107107 elif n_samples != len (self ._x ):
108- self . _x , self . _P = self . _backward_sweep (
108+ x , P = _rts_backward_sweep (
109109 self ._x_buf ,
110110 self ._dx_buf ,
111111 self ._P_buf ,
112112 self ._P_prior_buf ,
113113 self ._phi_buf ,
114114 cov_smoothing = self ._cov_smoothing ,
115115 )
116+ self ._x = np .asarray (x )
117+ self ._P = np .asarray (P )
116118
117119 @property
118120 def x (self ) -> NDArray :
@@ -239,68 +241,68 @@ def euler(self, degrees: bool = False) -> NDArray:
239241 theta = np .array ([_euler_from_quaternion (q_i ) for q_i in q ])
240242 return np .degrees (theta ) if degrees else theta
241243
242- @staticmethod
243- def _backward_sweep (
244- x : NDArray ,
245- dx : NDArray ,
246- P : NDArray ,
247- P_prior : NDArray ,
248- phi : NDArray ,
249- cov_smoothing : bool ,
250- ) -> tuple [NDArray , NDArray ]:
251- """
252- Perform a backward sweep with the RTS algorithm [1].
253244
254- Parameters
255- ----------
256- x : NDArray, shape (n_samples, 16)
257- The state vector.
258- dx : NDArray, shape (n_samples, 15) or (n_samples, 12)
259- The error state vector.
260- P : NDArray, shape (n_samples, 15, 15) or (n_samples, 12, 12)
261- The covariance matrix.
262- P_prior : NDArray, shape (n_samples, 15, 15) or (n_samples, 12, 12)
263- The a priori covariance matrix.
264- phi : NDArray, shape (n_samples, 15, 15) or (n_samples, 12, 12)
265- The state transition matrix.
266- cov_smoothing : bool
267- Whether to include the error covariance matrix in the smoothing process.
245+ def _rts_backward_sweep (
246+ x : list [NDArray ],
247+ dx : list [NDArray ],
248+ P : list [NDArray ],
249+ P_prior : list [NDArray ],
250+ phi : list [NDArray ],
251+ cov_smoothing : bool ,
252+ ) -> tuple [list [NDArray ], list [NDArray ]]:
253+ """
254+ Perform a backward sweep with the RTS algorithm [1].
268255
269- Returns
270- -------
271- x_smth : NDArray, shape (n_samples, 15) or (n_samples, 12)
272- The smoothed state vector.
273- P_smth : NDArray, shape (n_samples, 15, 15) or (n_samples, 12, 12)
274- The smoothed covariance matrix if include_cov is True, otherwise None.
256+ Parameters
257+ ----------
258+ x : NDArray, shape (n_samples, 16)
259+ The state vector.
260+ dx : NDArray, shape (n_samples, 15) or (n_samples, 12)
261+ The error state vector.
262+ P : NDArray, shape (n_samples, 15, 15) or (n_samples, 12, 12)
263+ The covariance matrix.
264+ P_prior : NDArray, shape (n_samples, 15, 15) or (n_samples, 12, 12)
265+ The a priori covariance matrix.
266+ phi : NDArray, shape (n_samples, 15, 15) or (n_samples, 12, 12)
267+ The state transition matrix.
268+ cov_smoothing : bool
269+ Whether to include the error covariance matrix in the smoothing process.
270+
271+ Returns
272+ -------
273+ x_smth : NDArray, shape (n_samples, 15) or (n_samples, 12)
274+ The smoothed state vector.
275+ P_smth : NDArray, shape (n_samples, 15, 15) or (n_samples, 12, 12)
276+ The smoothed covariance matrix if include_cov is True, otherwise None.
275277
276- References
277- ----------
278- [1] R. G. Brown and P. Y. C. Hwang, "Random signals and applied Kalman
279- filtering with MATLAB exercises", 4th ed. Wiley, pp. 208-212, 2012.
280- """
278+ References
279+ ----------
280+ [1] R. G. Brown and P. Y. C. Hwang, "Random signals and applied Kalman
281+ filtering with MATLAB exercises", 4th ed. Wiley, pp. 208-212, 2012.
282+ """
281283
282- x = np .asarray_chkfinite (x ).copy ()
283- dx = np .asarray_chkfinite (dx ).copy ()
284- P = np .asarray_chkfinite (P ).copy ()
285-
286- # Backward sweep
287- for k in range (len (x ) - 2 , - 1 , - 1 ):
288- # Smoothed error-state estimate and corresponding covariance
289- A = P [k ] @ phi [k ].T @ np .linalg .inv (P_prior [k + 1 ])
290- ddx = A @ dx [k + 1 ]
291- dx [k , : ] += ddx
292- if cov_smoothing :
293- P [k , :, : ] += A @ (P [k + 1 ] - P_prior [k + 1 ]) @ A .T
294-
295- # Reset
296- dda = ddx [6 :9 ]
297- ddq = (1.0 / np .sqrt (4.0 + dda .T @ dda )) * np .r_ [2.0 , dda ]
298- x [k , :3 ] = x [k , :3 ] + ddx [:3 ]
299- x [k , 3 :6 ] = x [k , 3 :6 ] + ddx [3 :6 ]
300- x [k , 6 :10 ] = _quaternion_product (x [k , 6 :10 ], ddq )
301- x [k , 6 :10 ] = _normalize (x [k , 6 :10 ])
302- x [k , - 3 :] = x [k , - 3 :] + ddx [- 3 :]
303- if dx . shape [ 1 ] == 15 :
304- x [k , 10 :13 ] = x [k , 10 :13 ] + ddx [9 :12 ]
305-
306- return x , P
284+ x = x . copy () # np.asarray_chkfinite(x).copy()
285+ dx = dx . copy () # np.asarray_chkfinite(dx).copy()
286+ P = P . copy () # np.asarray_chkfinite(P).copy()
287+
288+ # Backward sweep
289+ for k in range (len (x ) - 2 , - 1 , - 1 ):
290+ # Smoothed error-state estimate and corresponding covariance
291+ A = P [k ] @ phi [k ].T @ np .linalg .inv (P_prior [k + 1 ])
292+ ddx = A @ dx [k + 1 ]
293+ dx [k ] += ddx
294+ if cov_smoothing :
295+ P [k ] += A @ (P [k + 1 ] - P_prior [k + 1 ]) @ A .T
296+
297+ # Reset
298+ dda = ddx [6 :9 ]
299+ ddq = (1.0 / np .sqrt (4.0 + dda .T @ dda )) * np .r_ [2.0 , dda ]
300+ x [k ][ :3 ] = x [k ][ :3 ] + ddx [:3 ]
301+ x [k ][ 3 :6 ] = x [k ][ 3 :6 ] + ddx [3 :6 ]
302+ x [k ][ 6 :10 ] = _quaternion_product (x [k ][ 6 :10 ], ddq )
303+ x [k ][ 6 :10 ] = _normalize (x [k ][ 6 :10 ])
304+ x [k ][ - 3 :] = x [k ][ - 3 :] + ddx [- 3 :]
305+ if dx [ k ]. size == 15 :
306+ x [k ][ 10 :13 ] = x [k ][ 10 :13 ] + ddx [9 :12 ]
307+
308+ return x , P
0 commit comments