@@ -98,7 +98,7 @@ static constexpr const int8_t inclination_table[13][37] = \
98
98
{ 71 , 71 , 72 , 73 , 75 , 77 , 78 , 80 , 81 , 81 , 80 , 79 , 77 , 76 , 74 , 73 , 73 , 73 , 73 , 73 , 73 , 74 , 74 , 75 , 76 , 77 , 78 , 78 , 78 , 78 , 77 , 75 , 73 , 72 , 71 , 71 , 71 }, // NOLINT
99
99
};
100
100
101
- // strength data in centi-Tesla
101
+ // strength data in centi gauss
102
102
static constexpr const int8_t strength_table[13 ][37 ] = \
103
103
{
104
104
{ 62 , 60 , 58 , 56 , 54 , 52 , 49 , 46 , 43 , 41 , 38 , 36 , 34 , 32 , 31 , 31 , 30 , 30 , 30 , 31 , 33 , 35 , 38 , 42 , 46 , 51 , 55 , 59 , 62 , 64 , 66 , 67 , 67 , 66 , 65 , 64 , 62 }, // NOLINT
@@ -134,6 +134,12 @@ class gz::sim::systems::MagnetometerPrivate
134
134
// / True if the rendering component is initialized
135
135
public: bool initialized = false ;
136
136
137
+ // / \brief True if the magnetic field is reported in gauss rather than tesla.
138
+ public: bool useUnitsGauss = true ;
139
+
140
+ // / \brief True if the magnetic field earth frame is NED rather than ENU.
141
+ public: bool useEarthFrameNED = true ;
142
+
137
143
// / \brief Create sensor
138
144
// / \param[in] _ecm Immutable reference to ECM.
139
145
// / \param[in] _entity Entity of the IMU
@@ -226,7 +232,7 @@ class gz::sim::systems::MagnetometerPrivate
226
232
return get_table_data (lat, lon, inclination_table);
227
233
}
228
234
229
- // return magnetic field strength in centi-Tesla
235
+ // return magnetic field strength in centi-Gauss
230
236
float get_mag_strength (float lat, float lon)
231
237
{
232
238
return get_table_data (lat, lon, strength_table);
@@ -242,6 +248,29 @@ Magnetometer::Magnetometer() : System(), dataPtr(
242
248
// ////////////////////////////////////////////////
243
249
Magnetometer::~Magnetometer () = default ;
244
250
251
+ // ////////////////////////////////////////////////
252
+ void Magnetometer::Configure (const Entity &/* _entity*/ ,
253
+ const std::shared_ptr<const sdf::Element> &_sdf,
254
+ EntityComponentManager &/* _ecm*/ ,
255
+ EventManager &/* _eventMgr*/ )
256
+ {
257
+ if (_sdf->HasElement (" use_units_gauss" ))
258
+ {
259
+ this ->dataPtr ->useUnitsGauss = _sdf->Get <bool >(" use_units_gauss" );
260
+ }
261
+ gzdbg << " Magnetometer: using param [use_units_gauss: "
262
+ << this ->dataPtr ->useUnitsGauss << " ]."
263
+ << std::endl;
264
+
265
+ if (_sdf->HasElement (" use_earth_frame_ned" ))
266
+ {
267
+ this ->dataPtr ->useEarthFrameNED = _sdf->Get <bool >(" use_earth_frame_ned" );
268
+ }
269
+ gzdbg << " Magnetometer: using param [use_earth_frame_ned: "
270
+ << this ->dataPtr ->useEarthFrameNED << " ]."
271
+ << std::endl;
272
+ }
273
+
245
274
// ////////////////////////////////////////////////
246
275
void Magnetometer::PreUpdate (const UpdateInfo &/* _info*/ ,
247
276
EntityComponentManager &_ecm)
@@ -446,16 +475,32 @@ void MagnetometerPrivate::Update(
446
475
get_mag_inclination (
447
476
lat_rad * 180 / GZ_PI, lon_rad * 180 / GZ_PI) * GZ_PI / 180 ;
448
477
449
- // Magnetic strength (10^5xnanoTesla )
478
+ // Magnetic strength in gauss (10^5 nano tesla = 10^-2 centi gauss )
450
479
float strength_ga =
451
480
0 .01f *
452
481
get_mag_strength (lat_rad * 180 / GZ_PI, lon_rad * 180 / GZ_PI);
453
482
454
- // Magnetic filed components are calculated by http://geomag.nrcan.gc.ca/mag_fld/comp-en.php
455
- float H = strength_ga * cosf (inclination_rad);
456
- float Z = tanf (inclination_rad) * H;
457
- float X = H * cosf (declination_rad);
458
- float Y = H * sinf (declination_rad);
483
+ // Magnetic intensity measured in telsa
484
+ float strength_tesla = 1.0E-4 * strength_ga;
485
+
486
+ // Magnetic field components are calculated in world NED frame using:
487
+ // http://geomag.nrcan.gc.ca/mag_fld/comp-en.php
488
+ float H = cosf (inclination_rad);
489
+ H *= this ->useUnitsGauss ? strength_ga : strength_tesla;
490
+ float Z_ned = tanf (inclination_rad) * H;
491
+ float X_ned = H * cosf (declination_rad);
492
+ float Y_ned = H * sinf (declination_rad);
493
+
494
+ float X = X_ned;
495
+ float Y = Y_ned;
496
+ float Z = Z_ned;
497
+ if (!this ->useEarthFrameNED )
498
+ {
499
+ // Use ENU convention for earth frame.
500
+ X = Y_ned;
501
+ Y = X_ned;
502
+ Z = -1.0 * Z_ned;
503
+ }
459
504
460
505
math::Vector3d magnetic_field_I (X, Y, Z);
461
506
it->second ->SetWorldMagneticField (magnetic_field_I);
@@ -494,6 +539,7 @@ void MagnetometerPrivate::RemoveMagnetometerEntities(
494
539
}
495
540
496
541
GZ_ADD_PLUGIN (Magnetometer, System,
542
+ Magnetometer::ISystemConfigure,
497
543
Magnetometer::ISystemPreUpdate,
498
544
Magnetometer::ISystemPostUpdate
499
545
)
0 commit comments