Skip to content

Commit 4cce4e9

Browse files
committed
SITL: add ability to simulate more than 2 GPSs
1 parent 9f9a444 commit 4cce4e9

File tree

6 files changed

+211
-226
lines changed

6 files changed

+211
-226
lines changed

libraries/SITL/SIM_GPS.cpp

Lines changed: 120 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,105 @@
3030

3131
#include <GCS_MAVLink/GCS.h>
3232

33+
namespace SITL {
34+
// user settable parameters for airspeed sensors
35+
const AP_Param::GroupInfo SIM::GPSParms::var_info[] = {
36+
// @Param: DISABLE
37+
// @DisplayName: GPS disable
38+
// @Description: Disables GPS
39+
// @Values: 0:Enable, 1:GPS Disabled
40+
// @User: Advanced
41+
AP_GROUPINFO("DISABLE", 1, GPSParms, disable, 0),
42+
// @Param: LAG_MS
43+
// @DisplayName: GPS Lag
44+
// @Description: GPS lag
45+
// @Units: ms
46+
// @User: Advanced
47+
AP_GROUPINFO("LAG_MS", 2, GPSParms, delay_ms, 100),
48+
// @Param: TYPE
49+
// @DisplayName: GPS type
50+
// @Description: Sets the type of simulation used for GPS
51+
// @Values: 0:None, 1:UBlox, 5:NMEA, 6:SBP, 7:File, 8:Nova, 9:SBP2, 11:Trimble, 19:MSP
52+
// @User: Advanced
53+
AP_GROUPINFO("TYPE", 3, GPSParms, type, GPS::Type::UBLOX),
54+
// @Param: BYTELOS
55+
// @DisplayName: GPS Byteloss
56+
// @Description: Percent of bytes lost from GPS
57+
// @Units: %
58+
// @User: Advanced
59+
AP_GROUPINFO("BYTELOS", 4, GPSParms, byteloss, 0),
60+
// @Param: NUMSATS
61+
// @DisplayName: GPS Num Satellites
62+
// @Description: Number of satellites GPS has in view
63+
AP_GROUPINFO("NUMSATS", 5, GPSParms, numsats, 10),
64+
// @Param: GLITCH
65+
// @DisplayName: GPS Glitch
66+
// @Description: Glitch offsets of simulated GPS sensor
67+
// @Vector3Parameter: 1
68+
// @User: Advanced
69+
AP_GROUPINFO("GLITCH", 6, GPSParms, glitch, 0),
70+
// @Param: HZ
71+
// @DisplayName: GPS Hz
72+
// @Description: GPS Update rate
73+
// @Units: Hz
74+
AP_GROUPINFO("HZ", 7, GPSParms, hertz, 5),
75+
// @Param: DRFTALT
76+
// @DisplayName: GPS Altitude Drift
77+
// @Description: GPS altitude drift error
78+
// @Units: m
79+
// @User: Advanced
80+
AP_GROUPINFO("DRFTALT", 8, GPSParms, drift_alt, 0),
81+
// @Param: POS
82+
// @DisplayName: GPS Position
83+
// @Description: GPS antenna phase center position relative to the body frame origin
84+
// @Units: m
85+
// @Vector3Parameter: 1
86+
AP_GROUPINFO("POS", 9, GPSParms, pos_offset, 0),
87+
// @Param: NOISE
88+
// @DisplayName: GPS Noise
89+
// @Description: Amplitude of the GPS1 altitude error
90+
// @Units: m
91+
// @User: Advanced
92+
AP_GROUPINFO("NOISE", 10, GPSParms, noise, 0),
93+
// @Param: LCKTIME
94+
// @DisplayName: GPS Lock Time
95+
// @Description: Delay in seconds before GPS1 acquires lock
96+
// @Units: s
97+
// @User: Advanced
98+
AP_GROUPINFO("LCKTIME", 11, GPSParms, lock_time, 0),
99+
// @Param: ALT_OFS
100+
// @DisplayName: GPS Altitude Offset
101+
// @Description: GPS Altitude Error
102+
// @Units: m
103+
AP_GROUPINFO("ALT_OFS", 12, GPSParms, alt_offset, 0),
104+
// @Param: HDG
105+
// @DisplayName: GPS Heading
106+
// @Description: Enable GPS1 output of NMEA heading HDT sentence or UBLOX_RELPOSNED
107+
// @Values: 0:Disabled, 1:Enabled
108+
// @User: Advanced
109+
AP_GROUPINFO("HDG", 13, GPSParms, hdg_enabled, SIM::GPS_HEADING_NONE),
110+
// @Param: ACC
111+
// @DisplayName: GPS Accuracy
112+
// @Description: GPS Accuracy
113+
// @User: Advanced
114+
AP_GROUPINFO("ACC", 14, GPSParms, accuracy, 0.3),
115+
// @Param: VERR
116+
// @DisplayName: GPS Velocity Error
117+
// @Description: GPS Velocity Error Offsets in NED
118+
// @Vector3Parameter: 1
119+
// @User: Advanced
120+
AP_GROUPINFO("VERR", 15, GPSParms, vel_err, 0),
121+
// @Param: JAM
122+
// @DisplayName: GPS jamming enable
123+
// @Description: Enable simulated GPS jamming
124+
// @User: Advanced
125+
// @Values: 0:Disabled, 1:Enabled
126+
AP_GROUPINFO("JAM", 16, GPSParms, jam, 0),
127+
128+
AP_GROUPEND
129+
};
130+
}
131+
33132
// the number of GPS leap seconds - copied from AP_GPS.h
34133
#define GPS_LEAPSECONDS_MILLIS 18000ULL
35134

@@ -78,11 +177,11 @@ ssize_t GPS::write_to_autopilot(const char *p, size_t size) const
78177
// the first will start sending back 3 satellites, the second just
79178
// stops responding when disabled. This is not necessarily a good
80179
// thing.
81-
if (instance == 1 && _sitl->gps_disable[instance]) {
180+
if (instance == 1 && _sitl->gps[instance].disable) {
82181
return -1;
83182
}
84183

85-
const float byteloss = _sitl->gps_byteloss[instance];
184+
const float byteloss = _sitl->gps[instance].byteloss;
86185

87186
// shortcut if we're not doing byteloss:
88187
if (!is_positive(byteloss)) {
@@ -217,7 +316,7 @@ GPS_Backend::GPS_TOW GPS_Backend::gps_time()
217316

218317
void GPS::check_backend_allocation()
219318
{
220-
const Type configured_type = Type(_sitl->gps_type[instance].get());
319+
const Type configured_type = Type(_sitl->gps[instance].type.get());
221320
if (allocated_type == configured_type) {
222321
return;
223322
}
@@ -328,7 +427,7 @@ void GPS::update()
328427

329428
//Capture current position as basestation location for
330429
if (!_gps_has_basestation_position &&
331-
now_ms >= _sitl->gps_lock_time[0]*1000UL) {
430+
now_ms >= _sitl->gps[0].lock_time*1000UL) {
332431
_gps_basestation_data.latitude = latitude;
333432
_gps_basestation_data.longitude = longitude;
334433
_gps_basestation_data.altitude = altitude;
@@ -338,15 +437,15 @@ void GPS::update()
338437
_gps_has_basestation_position = true;
339438
}
340439

341-
const uint8_t idx = instance; // alias to avoid code churn
440+
const auto &params = _sitl->gps[instance];
342441

343442
struct GPS_Data d {};
344443

345444
// simulate delayed lock times
346-
bool have_lock = (!_sitl->gps_disable[idx] && now_ms >= _sitl->gps_lock_time[idx]*1000UL);
445+
bool have_lock = (!params.disable && now_ms >= params.lock_time*1000UL);
347446

348447
// Only let physics run and GPS write at configured GPS rate (default 5Hz).
349-
if ((now_ms - last_write_update_ms) < (uint32_t)(1000/_sitl->gps_hertz[instance])) {
448+
if ((now_ms - last_write_update_ms) < (uint32_t)(1000/params.hertz)) {
350449
// Reading runs every iteration.
351450
// Beware- physics don't update every iteration with this approach.
352451
// Currently, none of the drivers rely on quickly updated physics.
@@ -356,37 +455,37 @@ void GPS::update()
356455

357456
last_write_update_ms = now_ms;
358457

359-
d.num_sats = _sitl->gps_numsats[idx];
458+
d.num_sats = params.numsats;
360459
d.latitude = latitude;
361460
d.longitude = longitude;
362461
d.yaw_deg = _sitl->state.yawDeg;
363462
d.roll_deg = _sitl->state.rollDeg;
364463
d.pitch_deg = _sitl->state.pitchDeg;
365464

366465
// add an altitude error controlled by a slow sine wave
367-
d.altitude = altitude + _sitl->gps_noise[idx] * sinf(now_ms * 0.0005f) + _sitl->gps_alt_offset[idx];
466+
d.altitude = altitude + params.noise * sinf(now_ms * 0.0005f) + params.alt_offset;
368467

369468
// Add offset to c.g. velocity to get velocity at antenna and add simulated error
370-
Vector3f velErrorNED = _sitl->gps_vel_err[idx];
469+
Vector3f velErrorNED = params.vel_err;
371470
d.speedN = speedN + (velErrorNED.x * rand_float());
372471
d.speedE = speedE + (velErrorNED.y * rand_float());
373472
d.speedD = speedD + (velErrorNED.z * rand_float());
374473

375474
d.have_lock = have_lock;
376475

377476
// fill in accuracies
378-
d.horizontal_acc = _sitl->gps_accuracy[idx];
379-
d.vertical_acc = _sitl->gps_accuracy[idx];
380-
d.speed_acc = _sitl->gps_vel_err[instance].get().xy().length();
477+
d.horizontal_acc = params.accuracy;
478+
d.vertical_acc = params.accuracy;
479+
d.speed_acc = params.vel_err.get().xy().length();
381480

382-
if (_sitl->gps_drift_alt[idx] > 0) {
481+
if (params.drift_alt > 0) {
383482
// add slow altitude drift controlled by a slow sine wave
384-
d.altitude += _sitl->gps_drift_alt[idx]*sinf(now_ms*0.001f*0.02f);
483+
d.altitude += params.drift_alt*sinf(now_ms*0.001f*0.02f);
385484
}
386485

387486
// correct the latitude, longitude, height and NED velocity for the offset between
388487
// the vehicle c.g. and GPS antenna
389-
Vector3f posRelOffsetBF = _sitl->gps_pos_offset[idx];
488+
Vector3f posRelOffsetBF = params.pos_offset;
390489
if (!posRelOffsetBF.is_zero()) {
391490
// get a rotation matrix following DCM conventions (body to earth)
392491
Matrix3f rotmat;
@@ -418,18 +517,18 @@ void GPS::update()
418517

419518
// get delayed data
420519
d.timestamp_ms = now_ms;
421-
d = interpolate_data(d, _sitl->gps_delay_ms[instance]);
520+
d = interpolate_data(d, params.delay_ms);
422521

423522
// Applying GPS glitch
424523
// Using first gps glitch
425-
Vector3f glitch_offsets = _sitl->gps_glitch[idx];
524+
Vector3f glitch_offsets = params.glitch;
426525
d.latitude += glitch_offsets.x;
427526
d.longitude += glitch_offsets.y;
428527
d.altitude += glitch_offsets.z;
429528

430-
if (_sitl->gps_jam[idx] == 1) {
431-
simulate_jamming(d);
432-
}
529+
if (params.jam == 1) {
530+
simulate_jamming(d);
531+
}
433532

434533
backend->publish(&d);
435534
}

libraries/SITL/SIM_GPS_NMEA.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ void GPS_NMEA::publish(const GPS_Data *d)
9999
ground_track_deg,
100100
dstring);
101101

102-
if (_sitl->gps_hdg_enabled[instance] == SITL::SIM::GPS_HEADING_HDT) {
102+
if (_sitl->gps[instance].hdg_enabled == SITL::SIM::GPS_HEADING_HDT) {
103103
nmea_printf("$GPHDT,%.2f,T", d->yaw_deg);
104104
}
105-
else if (_sitl->gps_hdg_enabled[instance] == SITL::SIM::GPS_HEADING_THS) {
105+
else if (_sitl->gps[instance].hdg_enabled == SITL::SIM::GPS_HEADING_THS) {
106106
nmea_printf("$GPTHS,%.2f,%c,T", d->yaw_deg, d->have_lock ? 'A' : 'V');
107-
} else if (_sitl->gps_hdg_enabled[instance] == SITL::SIM::GPS_HEADING_KSXT) {
107+
} else if (_sitl->gps[instance].hdg_enabled == SITL::SIM::GPS_HEADING_KSXT) {
108108
// Unicore support
109109
// $KSXT,20211016083433.00,116.31296102,39.95817066,49.4911,223.57,-11.32,330.19,0.024,,1,3,28,27,,,,-0.012,0.021,0.020,,*2D
110110
nmea_printf("$KSXT,%04u%02u%02u%02u%02u%02u.%02u,%.8f,%.8f,%.4f,%.2f,%.2f,%.2f,%.2f,%.3f,%u,%u,%u,%u,,,,%.3f,%.3f,%.3f,,",

libraries/SITL/SIM_GPS_UBLOX.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ void GPS_UBlox::publish(const GPS_Data *d)
267267
pvt.headVeh = 0;
268268
memset(pvt.reserved2, '\0', ARRAY_SIZE(pvt.reserved2));
269269

270-
if (_sitl->gps_hdg_enabled[instance] > SITL::SIM::GPS_HEADING_NONE) {
270+
#if 0
271+
if (_sitl->gps[instance].hdg_enabled > SITL::SIM::GPS_HEADING_NONE) {
271272
const Vector3f ant1_pos = _sitl->gps_pos_offset[instance^1].get();
272273
const Vector3f ant2_pos = _sitl->gps_pos_offset[instance].get();
273274
Vector3f rel_antenna_pos = ant2_pos - ant1_pos;
@@ -289,14 +290,15 @@ void GPS_UBlox::publish(const GPS_Data *d)
289290
relposned.relPosHeading = degrees(Vector2f(rel_antenna_pos.x, rel_antenna_pos.y).angle()) * 1.0e5;
290291
relposned.flags = gnssFixOK | diffSoln | carrSolnFixed | isMoving | relPosValid | relPosHeadingValid;
291292
}
293+
#endif
292294

293295
send_ubx(MSG_POSLLH, (uint8_t*)&pos, sizeof(pos));
294296
send_ubx(MSG_STATUS, (uint8_t*)&status, sizeof(status));
295297
send_ubx(MSG_VELNED, (uint8_t*)&velned, sizeof(velned));
296298
send_ubx(MSG_SOL, (uint8_t*)&sol, sizeof(sol));
297299
send_ubx(MSG_DOP, (uint8_t*)&dop, sizeof(dop));
298300
send_ubx(MSG_PVT, (uint8_t*)&pvt, sizeof(pvt));
299-
if (_sitl->gps_hdg_enabled[instance] > SITL::SIM::GPS_HEADING_NONE) {
301+
if (_sitl->gps[instance].hdg_enabled > SITL::SIM::GPS_HEADING_NONE) {
300302
send_ubx(MSG_RELPOSNED, (uint8_t*)&relposned, sizeof(relposned));
301303
}
302304

libraries/SITL/SIM_config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <AP_HAL/AP_HAL_Boards.h>
44
#include <GCS_MAVLink/GCS_config.h>
55

6+
#define AP_SIM_MAX_GPS_SENSORS 4
7+
68
#ifndef HAL_SIM_ADSB_ENABLED
79
#define HAL_SIM_ADSB_ENABLED (CONFIG_HAL_BOARD == HAL_BOARD_SITL)
810
#endif

0 commit comments

Comments
 (0)