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_FLAGS (" ENABLE" , 1 , GPSParms, enabled, 0 , AP_PARAM_FLAG_ENABLE),
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
@@ -43,6 +142,13 @@ GPS_Backend::GPS_Backend(GPS &_front, uint8_t _instance) :
43142 front{_front}
44143{
45144 _sitl = AP::sitl ();
145+
146+ #if HAL_SIM_GPS_ENABLED && AP_SIM_MAX_GPS_SENSORS > 0
147+ // default the first backend to enabled:
148+ if (_instance == 0 && !_sitl->gps [0 ].enabled .configured ()) {
149+ _sitl->gps [0 ].enabled .set (1 );
150+ }
151+ #endif
46152}
47153
48154ssize_t GPS_Backend::write_to_autopilot (const char *p, size_t size) const
@@ -78,11 +184,11 @@ ssize_t GPS::write_to_autopilot(const char *p, size_t size) const
78184 // the first will start sending back 3 satellites, the second just
79185 // stops responding when disabled. This is not necessarily a good
80186 // thing.
81- if (instance == 1 && _sitl->gps_disable [instance]) {
187+ if (instance == 1 && ! _sitl->gps [instance]. enabled ) {
82188 return -1 ;
83189 }
84190
85- const float byteloss = _sitl->gps_byteloss [instance];
191+ const float byteloss = _sitl->gps [instance]. byteloss ;
86192
87193 // shortcut if we're not doing byteloss:
88194 if (!is_positive (byteloss)) {
@@ -217,7 +323,7 @@ GPS_Backend::GPS_TOW GPS_Backend::gps_time()
217323
218324void GPS::check_backend_allocation ()
219325{
220- const Type configured_type = Type (_sitl->gps_type [instance].get ());
326+ const Type configured_type = Type (_sitl->gps [instance]. type .get ());
221327 if (allocated_type == configured_type) {
222328 return ;
223329 }
@@ -328,7 +434,7 @@ void GPS::update()
328434
329435 // Capture current position as basestation location for
330436 if (!_gps_has_basestation_position &&
331- now_ms >= _sitl->gps_lock_time [0 ]*1000UL ) {
437+ now_ms >= _sitl->gps [0 ]. lock_time *1000UL ) {
332438 _gps_basestation_data.latitude = latitude;
333439 _gps_basestation_data.longitude = longitude;
334440 _gps_basestation_data.altitude = altitude;
@@ -338,15 +444,15 @@ void GPS::update()
338444 _gps_has_basestation_position = true ;
339445 }
340446
341- const uint8_t idx = instance; // alias to avoid code churn
447+ const auto ¶ms = _sitl-> gps [ instance];
342448
343449 struct GPS_Data d {};
344450
345451 // simulate delayed lock times
346- bool have_lock = (!_sitl-> gps_disable [idx] && now_ms >= _sitl-> gps_lock_time [idx] *1000UL );
452+ bool have_lock = (params. enabled && now_ms >= params. lock_time *1000UL );
347453
348454 // 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] )) {
455+ if ((now_ms - last_write_update_ms) < (uint32_t )(1000 /params. hertz )) {
350456 // Reading runs every iteration.
351457 // Beware- physics don't update every iteration with this approach.
352458 // Currently, none of the drivers rely on quickly updated physics.
@@ -356,37 +462,37 @@ void GPS::update()
356462
357463 last_write_update_ms = now_ms;
358464
359- d.num_sats = _sitl-> gps_numsats [idx] ;
465+ d.num_sats = params. numsats ;
360466 d.latitude = latitude;
361467 d.longitude = longitude;
362468 d.yaw_deg = _sitl->state .yawDeg ;
363469 d.roll_deg = _sitl->state .rollDeg ;
364470 d.pitch_deg = _sitl->state .pitchDeg ;
365471
366472 // 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] ;
473+ d.altitude = altitude + params. noise * sinf (now_ms * 0 .0005f ) + params. alt_offset ;
368474
369475 // Add offset to c.g. velocity to get velocity at antenna and add simulated error
370- Vector3f velErrorNED = _sitl-> gps_vel_err [idx] ;
476+ Vector3f velErrorNED = params. vel_err ;
371477 d.speedN = speedN + (velErrorNED.x * rand_float ());
372478 d.speedE = speedE + (velErrorNED.y * rand_float ());
373479 d.speedD = speedD + (velErrorNED.z * rand_float ());
374480
375481 d.have_lock = have_lock;
376482
377483 // 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 ();
484+ d.horizontal_acc = params. accuracy ;
485+ d.vertical_acc = params. accuracy ;
486+ d.speed_acc = params. vel_err .get ().xy ().length ();
381487
382- if (_sitl-> gps_drift_alt [idx] > 0 ) {
488+ if (params. drift_alt > 0 ) {
383489 // 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 );
490+ d.altitude += params. drift_alt *sinf (now_ms*0 .001f *0 .02f );
385491 }
386492
387493 // correct the latitude, longitude, height and NED velocity for the offset between
388494 // the vehicle c.g. and GPS antenna
389- Vector3f posRelOffsetBF = _sitl-> gps_pos_offset [idx] ;
495+ Vector3f posRelOffsetBF = params. pos_offset ;
390496 if (!posRelOffsetBF.is_zero ()) {
391497 // get a rotation matrix following DCM conventions (body to earth)
392498 Matrix3f rotmat;
@@ -418,18 +524,18 @@ void GPS::update()
418524
419525 // get delayed data
420526 d.timestamp_ms = now_ms;
421- d = interpolate_data (d, _sitl-> gps_delay_ms [instance] );
527+ d = interpolate_data (d, params. delay_ms );
422528
423529 // Applying GPS glitch
424530 // Using first gps glitch
425- Vector3f glitch_offsets = _sitl-> gps_glitch [idx] ;
531+ Vector3f glitch_offsets = params. glitch ;
426532 d.latitude += glitch_offsets.x ;
427533 d.longitude += glitch_offsets.y ;
428534 d.altitude += glitch_offsets.z ;
429535
430- if (_sitl-> gps_jam [idx] == 1 ) {
431- simulate_jamming (d);
432- }
536+ if (params. jam == 1 ) {
537+ simulate_jamming (d);
538+ }
433539
434540 backend->publish (&d);
435541}
0 commit comments