This is a project that demonstrates the use of a Kalman filter for estimating the position of a aircraft navigating through N receivers. The data is visualized using TypeScript and PlotyJs.
To get started, clone the repository:
git clone https://github.com/kyzinatra/KalmanFilter.git
cd KalmanFilter
Then install the dependencies:
npm install
To run the project, use the following command:
npm run dev
This will start the development server, and you can access the project by opening your web browser and navigating to http://localhost:5173.
The src/models
folder contains classes of physical models. So the navigation class is responsible for the join to work of the aircraft and receivers. It stores instances of all receivers and the aircraft. It also creates them and initializes the sending of signals to the receivers by the makeCheck
method. After the calculation of positions occurs in the findCoord method. We then calculate the closed solution and use it as the initial approximation for the least squares method. Than data will be displayed on the screen.
All utility classes for rendering and math calculations are located in src/models/utils
. The CoordsCalc
class computes the solutions reffered earlier. This folder also stores the implementation of the matrix and vector.
Start tracking is in src/utils/startDetection
. The detection function initializes the distribution of signals to receivers and then starts the calculation of coordinates and draws the result. It also runs the Aircraft.move()
function to move the aircraft through space.
By default, 12 receivers and a aircraft are drawn. All other files are needed for the UI and are not directly involved in the modeling. In the main part there are 3 graphs that represents the real position of the aircraft, obtained using the least squares method and using the Kalman filter.
The klaman filter is in the file src/models/utls/Filter.ts
. It is a general filter algorithm that needs to be passed a matrix before running. They are created in a file src/utls/kalmanMatrices.ts
To freely receive and process signals a Navigation
class was created, whitch stores and uses all instances of the Aircraft
and Receiver
classes. This class implements the makeCheck()
method to send a signal from the aircraft to receivers. To do this, there is a getLightDelay()
method on the aircraft, which returns the delay that is necessary for the light to go from the aircraft to the receiver. After this time is added to the current time and sent to receivers. After this moment, nowhere else possible to find out the time it took the signal to reach the receivers. In the findCord()
method (which will be discussed later) we only have the exact position of each receivers and TOA (Time of signal arrival). We need to calculate TDOA and aircraft position.
findCord()
method simply run all methods from CoordsCalc
class and return result to the main process, which print it on the screen in src/utils/detection.ts
.
The solutions presented in this section are mathematically exact, which means that they use algebraic approaches to solve the problem of hyperbolic positioning. Basically, the problem can be defined by the following system of equations which is set up by writing down equation for different stations [1]:
Where is x
, y
, z
and
The calculations starts with some equation transformation. First of all, we square the equation:
It makes no sense to show all the transformations and mathematical calculations there. You can see it here [1]. I'll show the result and move on the implementation.
To implement this to code, I created the Vector
and Matrix
classes.
Vector
class have a usual methods such as mul()
, sub()
, add()
. You can multiply Vector
by Vector
or Number
. You can see the implementation in the ./src/modules/Vector.ts
file.
Next, I created a Matrix
class for my tasks. I have 3 different methods for multiplying by a scalar, a vector and another matrix, methods have also been made to calculate the determinant in O(n^3)
and simply matrix invert by adding an identity matrix on the right. All these methods allowed me feel free to work with the formulas above and create the getClosedSolution()
method, which implements all these mathematical calculations.
These equations can be transformed into the following form and, for the sake of simplicity, we newly replace the time variables by the so-called pseudo ranges [1]
- We have to calculate the following derivatives to perform the tailor expansion
where
- Putting up the system matrix A in the point
$\vec{x_a}$ . - Calculate
$d\vec{x}$ - Calculate
$d\vec{x}$ using these formulas:
- Repeat from step 1, but replacing
$\vec{x_a}$ by the$\vec{x}$
The Kalman filter is based on its classical representation [3]. Next, we present the formulas for its implementation. First of all, you have to define the state vector. In our case, it contains the position, velocity, and acceleration at time
The second, we have to define
-
$F$ — process evolution Matrix (9x9 in our case) -
$H$ — observation model Matrix (3x9 in our case) -
$Q$ — process noise covariance Matrix (9x9 in our case) -
$R$ — observation noise covariance Matrix (3x3 in our case) -
$P$ — estimation error covariance Matrix (9x9 in our case)
Here they are in order:
After we have determined all the necessary metrics, we will describe the algorithm of the Kalman filter itself. This algorithm works iteratively and at each step receives a new estimate from the previous one.
- Predict step
- Update
- Elaboration of Methods and Algorithms for Passive Aircraft and Vehicle Detection over Time of Signal Arrival Differences
- Pseudo-range multilateration (Wikipedia)
- Kalman filter (Wikipedia)
- Kalman R.E. "New Results in Linear Filtering and Prediction Theory"
This project was created by kyzinatra and is licensed under the MIT License.