Main Content

Inertial navigation system and GNSS/GPS simulation model

The `insSensor`

System object™ models a device that fuses measurements from an inertial navigation system (INS)
and global navigation satellite system (GNSS) such as a GPS, and outputs the fused
measurements.

To output fused INS and GNSS measurements:

Create the

`insSensor`

object and set its properties.Call the object with arguments, as if it were a function.

To learn more about how System objects work, see What Are System Objects?.

returns a System object, `INS`

= insSensor`INS`

, that models a device that outputs measurements from
an INS and GNSS.

sets properties using one or
more name-value pairs. Unspecified properties have default values. Enclose each property
name in quotes.`INS`

= insSensor(`Name,Value`

)

Unless otherwise indicated, properties are *nontunable*, which means you cannot change their
values after calling the object. Objects lock when you call them, and the
`release`

function unlocks them.

If a property is *tunable*, you can change its value at
any time.

For more information on changing property values, see System Design in MATLAB Using System Objects.

`MountingLocation`

— Location of sensor on platform (m)`[0 0 0]`

(default) | three-element real-valued vector of form [Location of the sensor on the platform, in meters, specified as a three-element
real-valued vector of the form [*x*
*y*
*z*]. The vector defines the offset of the sensor origin from the
origin of the platform.

**Tunable: **Yes

**Data Types: **`single`

| `double`

`RollAccuracy`

— Accuracy of roll measurement (deg)`0.2`

(default) | nonnegative real scalarAccuracy of the roll measurement of the sensor body, in degrees, specified as a nonnegative real scalar.

*Roll* is the rotation around the *x*-axis of
the sensor body. Roll noise is modeled as a white noise process.
`RollAccuracy`

sets the standard deviation of the roll measurement
noise.

**Tunable: **Yes

**Data Types: **`single`

| `double`

`PitchAccuracy`

— Accuracy of pitch measurement (deg)`0.2`

(default) | nonnegative real scalarAccuracy of the pitch measurement of the sensor body, in degrees, specified as a nonnegative real scalar.

*Pitch* is the rotation around the *y*-axis of
the sensor body. Pitch noise is modeled as a white noise process.
`PitchAccuracy`

defines the standard deviation of the pitch
measurement noise.

**Tunable: **Yes

**Data Types: **`single`

| `double`

`YawAccuracy`

— Accuracy of yaw measurement (deg)`1`

(default) | nonnegative real scalarAccuracy of the yaw measurement of the sensor body, in degrees, specified as a nonnegative real scalar.

*Yaw* is the rotation around the *z*-axis of
the sensor body. Yaw noise is modeled as a white noise process.
`YawAccuracy`

defines the standard deviation of the yaw measurement
noise.

**Tunable: **Yes

**Data Types: **`single`

| `double`

`PositionAccuracy`

— Accuracy of position measurement (m)`[1 1 1]`

(default) | nonnegative real scalar | three-element real-valued vectorAccuracy of the position measurement of the sensor body, in meters, specified as a
nonnegative real scalar or a three-element real-valued vector. The elements of the
vector set the accuracy of the *x*-, *y*-, and
*z*-position measurements, respectively. If you specify
`PositionAccuracy`

as a scalar value, then the object sets the
accuracy of all three positions to this value.

Position noise is modeled as a white noise process.
`PositionAccuracy`

defines the standard deviation of the position
measurement noise.

**Tunable: **Yes

**Data Types: **`single`

| `double`

`VelocityAccuracy`

— Accuracy of velocity measurement (m/s)`0.05`

(default) | nonnegative real scalarAccuracy of the velocity measurement of the sensor body, in meters per second, specified as a nonnegative real scalar.

Velocity noise is modeled as a white noise process.
`VelocityAccuracy`

defines the standard deviation of the velocity
measurement noise.

**Tunable: **Yes

**Data Types: **`single`

| `double`

`AccelerationAccuracy`

— Accuracy of acceleration measurement (m/s`0`

(default) | nonnegative real scalarAccuracy of the acceleration measurement of the sensor body, in meters per second, specified as a nonnegative real scalar.

Acceleration noise is modeled as a white noise process.
`AccelerationAccuracy`

defines the standard deviation of the
acceleration measurement noise.

**Tunable: **Yes

**Data Types: **`single`

| `double`

`AngularVelocityAccuracy`

— Accuracy of angular velocity measurement (deg/s)`0`

(default) | nonnegative real scalarAccuracy of the angular velocity measurement of the sensor body, in meters per second, specified as a nonnegative real scalar.

Angular velocity is modeled as a white noise process.
`AngularVelocityAccuracy`

defines the standard deviation of the
acceleration measurement noise.

**Tunable: **Yes

**Data Types: **`single`

| `double`

`TimeInput`

— Enable input of simulation time`false`

or `0`

(default) | `true`

or `1`

Enable input of simulation time, specified as a logical `0`

(`false`

) or `1`

(`true`

). Set this
property to `true`

to input the simulation time by using the `simTime`

argument.

**Tunable: **No

**Data Types: **`logical`

`HasGNSSFix`

— Enable GNSS fix`true`

or `1`

(default) | `false`

or `0`

Enable GNSS fix, specified as a logical `1`

(`true`

) or `0`

(`false`

). Set this
property to `false`

to simulate the loss of a GNSS receiver fix. When a
GNSS receiver fix is lost, position measurements drift at a rate specified by the
`PositionErrorFactor`

property.

**Tunable: **Yes

To enable this property, set `TimeInput`

to
`true`

.

**Data Types: **`logical`

` PositionErrorFactor`

— Position error factor without GNSS fix`[0 0 0]`

(default) | nonnegative scalar | 1-by-3 vector of scalarsPosition error factor without GNSS fix, specified as a scalar or a 1-by-3 vector of scalars.

When the `HasGNSSFix`

property is set to
`false`

, the position error grows at a quadratic rate due to constant
bias in the accelerometer. The position error for a position component
*E*(*t*) can be expressed as
*E*(*t*) =
1/2*α**t*^{2}, where
*α* is the position error factor for the corresponding component and
*t* is the time since the GNSS fix is lost. While running, the object
computes *t* based on the `simTime`

input. The
computed *E*(*t*) values for the *x*,
*y*, and *z* components are added to the
corresponding position components of the `gTruth`

input.

**Tunable: **Yes

To enable this property, set `TimeInput`

to
`true`

and `HasGNSSFix`

to
`false`

.

**Data Types: **`single`

| `double`

`RandomStream`

— Random number source`'Global stream'`

(default) | `'mt19937ar with seed'`

Random number source, specified as one of these options:

`'Global stream'`

–– Generate random numbers using the current global random number stream.`'mt19937ar with seed'`

–– Generate random numbers using the mt19937ar algorithm, with the seed specified by the`Seed`

property.

**Data Types: **`char`

| `string`

`Seed`

— Initial seed`67`

(default) | nonnegative integerInitial seed of the mt19937ar random number generator algorithm, specified as a nonnegative integer.

To enable this property, set `RandomStream`

to
`'mt19937ar with seed'`

.

**Data Types: **`single`

| `double`

| `int8`

| `int16`

| `int32`

| `int64`

| `uint8`

| `uint16`

| `uint32`

| `uint64`

models the data received from an INS sensor reading and GNSS sensor reading. The output
measurement is based on the inertial ground-truth state of the sensor body,
`measurement`

= INS(`gTruth`

)`gTruth`

.

additionally specifies the time of simulation, `measurement`

= INS(`gTruth`

,`simTime`

)`simTime`

. To enable
this syntax, set the `TimeInput`

property to `true`

.

`gTruth`

— Inertial ground-truth state of sensor bodystructure

Inertial ground-truth state of sensor body, in local Cartesian coordinates, specified as a structure containing these fields:

Field | Description |
---|---|

`'Position'` | Position, in meters, specified as a real, finite |

`'Velocity'` | Velocity ( |

`'Orientation'` | Orientation with respect to the local Cartesian coordinate system, specified as one of these options: *N*-element column vector of`quaternion` objects3-by-3-by- *N*array of rotation matrices*N*-by-3 matrix of [*x*_{roll}*y*_{pitch}*z*_{yaw}] angles in degrees
Each quaternion or rotation matrix is a frame rotation from
the local Cartesian coordinate system to the current sensor body coordinate
system. |

`'Acceleration'` | Acceleration ( |

`'AngularVelocity'` | Angular velocity ( |

The field values must be of type `double`

or
`single`

.

The `Position`

, `Velocity`

, and
`Orientation`

fields are required. The other fields are
optional.

**Example: **```
struct('Position',[0 0 0],'Velocity',[0 0
0],'Orientation',quaternion([1 0 0 0]))
```

`simTime`

— Simulation timenonnegative real scalar

Simulation time, in seconds, specified as a nonnegative real scalar.

**Data Types: **`single`

| `double`

`measurement`

— Measurement of sensor body motionstructure

Measurement of the sensor body motion, in local Cartesian coordinates, returned as a structure containing these fields:

Field | Description |
---|---|

`'Position'` | Position, in meters, specified as a real, finite |

`'Velocity'` | Velocity ( |

`'Orientation'` | Orientation with respect to the local Cartesian coordinate system, specified as one of these options: *N*-element column vector of`quaternion` objects3-by-3-by- *N*array of rotation matrices*N*-by-3 matrix of [*x*_{roll}*y*_{pitch}*z*_{yaw}] angles in degrees
Each quaternion or rotation matrix is a frame rotation from
the local Cartesian coordinate system to the current sensor body coordinate
system. |

`'Acceleration'` | Acceleration ( |

`'AngularVelocity'` | Angular velocity ( |

The returned field values are of type `double`

or
`single`

and are of the same type as the corresponding field values
in the `gTruth`

input.

To use an object function, specify the
System object as the first input argument. For
example, to release system resources of a System object named `obj`

, use
this syntax:

release(obj)

`insSensor`

`perturbations` | Perturbation defined on object |

`perturb` | Apply perturbations to object |

Create a motion structure that defines a stationary position at the local north-east-down (NED) origin. Because the platform is stationary, you need to define only a single sample. Assume the ground-truth motion is sampled for 10 seconds with a 100 Hz sample rate. Create a default `insSensor`

System object™. Preallocate variables to hold output from the `insSensor`

object.

Fs = 100; duration = 10; numSamples = Fs*duration; motion = struct( ... 'Position',zeros(1,3), ... 'Velocity',zeros(1,3), ... 'Orientation',ones(1,1,'quaternion')); INS = insSensor; positionMeasurements = zeros(numSamples,3); velocityMeasurements = zeros(numSamples,3); orientationMeasurements = zeros(numSamples,1,'quaternion');

In a loop, call `INS`

with the stationary motion structure to return the position, velocity, and orientation measurements in the local NED coordinate system. Log the position, velocity, and orientation measurements.

for i = 1:numSamples measurements = INS(motion); positionMeasurements(i,:) = measurements.Position; velocityMeasurements(i,:) = measurements.Velocity; orientationMeasurements(i) = measurements.Orientation; end

Convert the orientation from quaternions to Euler angles for visualization purposes. Plot the position, velocity, and orientation measurements over time.

orientationMeasurements = eulerd(orientationMeasurements,'ZYX','frame'); t = (0:(numSamples-1))/Fs; subplot(3,1,1) plot(t,positionMeasurements) title('Position') xlabel('Time (s)') ylabel('Position (m)') legend('North','East','Down') subplot(3,1,2) plot(t,velocityMeasurements) title('Velocity') xlabel('Time (s)') ylabel('Velocity (m/s)') legend('North','East','Down') subplot(3,1,3) plot(t,orientationMeasurements) title('Orientation') xlabel('Time (s)') ylabel('Rotation (degrees)') legend('Roll', 'Pitch', 'Yaw')

Generate INS measurements using the `insSensor`

System object™. Use `waypointTrajectory`

to generate the ground-truth path. Use `trackingScenario`

to organize the simulation and visualize the motion.

Specify the ground-truth trajectory as a figure-eight path in the North-East plane. Use a 50 Hz sample rate and 5 second duration.

Fs = 50; duration = 5; numSamples = Fs*duration; t = (0:(numSamples-1)).'/Fs; a = 2; x = a.*sqrt(2).*cos(t) ./ (sin(t).^2 + 1); y = sin(t) .* x; z = zeros(numSamples,1); waypoints = [x,y,z]; path = waypointTrajectory('Waypoints',waypoints,'TimeOfArrival',t);

Create an `insSensor`

System object to model receiving INS data. Set the `PositionAccuracy`

to `0.1`

.

`ins = insSensor('PositionAccuracy',0.1);`

Create a tracking scenario with a single platform whose motion is defined by `path`

.

```
scenario = trackingScenario('UpdateRate',Fs);
quadcopter = platform(scenario);
quadcopter.Trajectory = path;
```

Create a theater plot to visualize the ground-truth `quadcopter`

motion and the quadcopter motion measurements modeled by `insSensor`

.

tp = theaterPlot('XLimits',[-3, 3],'YLimits', [-3, 3]); quadPlotter = platformPlotter(tp, ... 'DisplayName', 'Ground-Truth Motion', ... 'Marker', 's', ... 'MarkerFaceColor','blue'); insPlotter = detectionPlotter(tp, ... 'DisplayName','INS Measurement', ... 'Marker','d', ... 'MarkerFaceColor','red');

In a loop, advance the scenario until it is complete. For each time step, get the current motion sample, model INS measurements for the motion, and then plot the result.

while advance(scenario) motion = platformPoses(scenario,'quaternion'); insMeas = ins(motion); plotPlatform(quadPlotter,motion.Position); plotDetection(insPlotter,insMeas.Position); pause(1/scenario.UpdateRate) end

Generate INS measurements using the `insSensor`

System object™. Use `waypointTrajectory`

to generate the ground-truth path.

Specify a ground-truth orientation that begins with the sensor body *x*-axis aligned with North and ends with the sensor body *x*-axis aligned with East. Specify waypoints for an arc trajectory and a time-of-arrival vector for the corresponding waypoints. Use a 100 Hz sample rate. Create a `waypointTrajectory`

System object with the waypoint constraints, and set `SamplesPerFrame`

so that the entire trajectory is output with one call.

eulerAngles = [0,0,0; ... 0,0,0; ... 90,0,0; ... 90,0,0]; orientation = quaternion(eulerAngles,'eulerd','ZYX','frame'); r = 20; waypoints = [0,0,0; ... 100,0,0; ... 100+r,r,0; ... 100+r,100+r,0]; toa = [0,10,10+(2*pi*r/4),20+(2*pi*r/4)]; Fs = 100; numSamples = floor(Fs*toa(end)); path = waypointTrajectory('Waypoints',waypoints, ... 'TimeOfArrival',toa, ... 'Orientation',orientation, ... 'SampleRate',Fs, ... 'SamplesPerFrame',numSamples);

Create an `insSensor`

System object to model receiving INS data. Set the `PositionAccuracy`

to `0.1`

.

`ins = insSensor('PositionAccuracy',0.1);`

Call the waypoint trajectory object, `path`

, to generate the ground-truth motion. Call the INS simulator, `ins`

, with the ground-truth motion to generate INS measurements.

[motion.Position,motion.Orientation,motion.Velocity] = path(); insMeas = ins(motion);

Convert the orientation returned by `ins`

to Euler angles in degrees for visualization purposes. Plot the full path and orientation over time.

orientationMeasurementEuler = eulerd(insMeas.Orientation,'ZYX','frame'); subplot(2,1,1) plot(insMeas.Position(:,1),insMeas.Position(:,2)); title('Path') xlabel('North (m)') ylabel('East (m)') subplot(2,1,2) t = (0:(numSamples-1)).'/Fs; plot(t,orientationMeasurementEuler(:,1), ... t,orientationMeasurementEuler(:,2), ... t,orientationMeasurementEuler(:,3)); title('Orientation') legend('Yaw','Pitch','Roll') xlabel('Time (s)') ylabel('Rotation (degrees)')

Generate C and C++ code using MATLAB® Coder™.

Usage notes and limitations:

See System Objects in MATLAB Code Generation (MATLAB Coder).

You have a modified version of this example. Do you want to open this example with your edits?

You clicked a link that corresponds to this MATLAB command:

Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

Select web siteYou can also select a web site from the following list:

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

- América Latina (Español)
- Canada (English)
- United States (English)

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)