# Seamless Indoor-Outdoor Localization Through Transition Detection
## 4 Positioning Engines
### Outdoor Positioning Engine  
The GNSS fix position (\(lat,lon\)) and the confidence interval \(\sigma\) of the position are received from the Android LocationManager API every 1 s. The AI-IMU returns the estimated moved distance and rotated angle in a 0.25 s interval. The extended Kalman filter (EKF) was used to estimate the position using those measurements in the outdoor environment. The rotational speed \(\omega\) (\(rad/s\)), direction angle \(\theta\) (\(rad\)), movement speed \(v\) (\(m/s\)), x position \(p_{x}\) (\(m\)), and y position \(p_{y}\) (\(m\)) were used as state variables, as shown below:  
\[X= \begin{bmatrix}\omega&\theta&v&p_{x}&p_{y}\end{bmatrix} ^{T} \tag{23}\]  
The initial position \(p_{x}\), \(p_{y}\) is either handed over from the indoor/transition positioning engine or decided from the initial GNSS fix position. The state-transition function \(\Phi\) and its Jacobian matrix \(A\) from the state at time \(t\) to time \(t+dt\) was modeled as below:  
\[X[t+dt|t]=\Phi(X[t])= \begin{bmatrix}\omega[t]\\ \omega[t]dt+\theta[t]\\ v[t]\\ \cos(\theta[t])v[t]dt+p_{x}[t]\\ \sin(\theta[t])v[t]dt+p_{y}[t]\end{bmatrix}  \tag{24}\]  
\[A[t]= \begin{bmatrix}1&0&0&0&0\\ dt&1&0&0&0\\ 0&0&1&0&0\\ 0&-\sin(\theta[t])v[t]dt&\cos(\theta[t])dt&1&0\\ 0&\cos(\theta[t])v[t]dt&\sin(\theta[t])dt&0&1\end{bmatrix}  \tag{25}\]  
The prediction noise covariance matrix \(Q\) was designed as below:  
\[Q= \begin{bmatrix}1\times 10^{-2}&0&0&0&0\\ 0&1\times 10^{-2}&0&1\times 10^{-2}&1\times 10^{-2}\\ 0&0&4\times 10^{-1}&0&0\\ 0&1\times 10^{-2}&0&1\times 10^{-1}&1\times 10^{-2}\\ 0&1\times 10^{-2}&0&1\times 10^{-2}&1\times 10^{-1}\end{bmatrix}  \tag{26}\]  
The AI-IMU measurement gives the angular displacement in direction angle \(d\theta_{ai-imu}\) (\(rad\)) and moved distance \(dp_{ai-imu}\) (\(m\)) for time interval \(dt_{ai-imu}\) (\(s\)), while the GNSS measurement gives latitude \(p_{lat}\) (\(rad\)), longitude \(p_{lon}\) (\(rad\)), and accuracy \(\sigma\) (\(m\)). The \(\sigma\) value, obtained from the Android LocationManager API, represents the range within where there is 68% probability that the true position will be found. The measured states (\(z_{ai-imu}\), \(z_{gnss}\)) at time \(t\) were derived as below:  
\[z_{ai-imu}[t]= \begin{bmatrix}\omega^{ai-imu}[t]\\ v^{ai-imu}[t]\end{bmatrix} =\frac{1}{dt^{ai-imu}[t]} \begin{bmatrix}d\theta^{ ai-imu}[t]\\ ||dp^{ai-imu}[t]||\end{bmatrix}  \tag{27}\]\[z_{gnss}[t]= \begin{bmatrix}\theta sns[t]\\ p_{x}^{snss}[t]\\ p_{y}^{snss}[t]\end{bmatrix} = \begin{bmatrix}u(\tan^{-1}(\frac{dp_{gnss}^{trans}[t]}{dp _{x}^{snss}[t]}))\\ p_{x}^{gnss}[t]\\ p_{y}^{snss}[t]\end{bmatrix} , \tag{28}\]  
where \(u\) is a phase unwrapping function, and \(\dot{p}_{gnss}\) is an estimated speed from the differentiated GNSS position in the time domain. The measurement noise covariance matrices \(R_{ai-imu}\) and \(R_{gnss}\) for the AI-IMU and GNSS were designed as below:  
\[R^{ai-imu}= \begin{bmatrix}1\times 10^{-2}&0\\ 0&1\times 10^{-1}\end{bmatrix}  \tag{29}\]  
\[R^{gnss}[t]= \begin{bmatrix}\frac{\pi}{3}&0&0\\ 0&\frac{1}{2}\sigma[t]^{2}\times 10^{-1}&0\\ 0&0&\frac{1}{2}\sigma[t]^{2}\times 10^{-1}\end{bmatrix} c[t] \tag{30}\]  
\[c[t]= \begin{cases}\frac{1000}{1+e^{\frac{d\pi}{3}\pi[3]}}+1,&\text{if }v[t]\leq 10^{-4}\\ \min(e^{\frac{3\pi[3]}{2\sigma[t]}[-\frac{|v[t]|}{2\sigma[t]}}(\frac{1000}{1+ e^{\frac{d\pi}{20}}}+1),10^{4}),\text{otherwise}\end{cases}  \tag{31}\]  
where \(\sigma\) is the accuracy obtained from the android location request, and \(c[t]\) is a weight function of the predicted speed(\(v[t]\)), the estimated speed from GNSS fix positions (\(v_{gnss}[t]\)), and the estimated moved distance from the transition region (\(d[t]\)), designed to increase the measurement error covariance when the position is close to the transition area or the displacement of the position from the GNSS measurement is too large compared to the estimated movement speed.