@@ -43,60 +43,16 @@ using namespace systems;
43
43
// / \brief Private Hydrodynamics data class.
44
44
class gz ::sim::systems::HydrodynamicsPrivateData
45
45
{
46
- // / \brief Values to set via Plugin Parameters.
47
- // / Plugin Parameter: Added mass in surge, X_\dot{u} .
48
- public: double paramXdotU ;
46
+ // / \brief Contains the quadratic stability derivatives like $X_{uv}$,
47
+ // / Y_{vv}, Y_{wv} etc .
48
+ public: double stabilityQuadraticDerivative[ 216 ] ;
49
49
50
- // / \brief Plugin Parameter: Added mass in sway, Y_\dot{v}.
51
- public: double paramYdotV;
50
+ // / \brief Contains the quadratic stability derivatives like $X_{u|u|},
51
+ // / Y_{v|v|}, Y_{w|v|}$ etc.
52
+ public: double stabilityQuadraticAbsDerivative[216 ];
52
53
53
- // / \brief Plugin Parameter: Added mass in heave, Z_\dot{w}.
54
- public: double paramZdotW;
55
-
56
- // / \brief Plugin Parameter: Added mass in roll, K_\dot{p}.
57
- public: double paramKdotP;
58
-
59
- // / \brief Plugin Parameter: Added mass in pitch, M_\dot{q}.
60
- public: double paramMdotQ;
61
-
62
- // / \brief Plugin Parameter: Added mass in yaw, N_\dot{r}.
63
- public: double paramNdotR;
64
-
65
- // / \brief Plugin Parameter: Linear drag in surge.
66
- public: double paramXu;
67
-
68
- // / \brief Plugin Parameter: Quadratic drag in surge.
69
- public: double paramXuu;
70
-
71
- // / \brief Plugin Parameter: Linear drag in sway.
72
- public: double paramYv;
73
-
74
- // / \brief Plugin Parameter: Quadratic drag in sway.
75
- public: double paramYvv;
76
-
77
- // / \brief Plugin Parameter: Linear drag in heave.
78
- public: double paramZw;
79
-
80
- // / \brief Plugin Parameter: Quadratic drag in heave.
81
- public: double paramZww;
82
-
83
- // / \brief Plugin Parameter: Linear drag in roll.
84
- public: double paramKp;
85
-
86
- // / \brief Plugin Parameter: Quadratic drag in roll.
87
- public: double paramKpp;
88
-
89
- // / \brief Plugin Parameter: Linear drag in pitch.
90
- public: double paramMq;
91
-
92
- // / \brief Plugin Parameter: Quadratic drag in pitch.
93
- public: double paramMqq;
94
-
95
- // / \brief Plugin Parameter: Linear drag in yaw.
96
- public: double paramNr;
97
-
98
- // / \brief Plugin Parameter: Quadratic drag in yaw.
99
- public: double paramNrr;
54
+ // / \brief Contains the linear stability derivatives like $X_u, Y_v,$ etc.
55
+ public: double stabilityLinearTerms[36 ] = {0 };
100
56
101
57
// / \brief Water density [kg/m^3].
102
58
public: double waterDensity;
@@ -122,7 +78,9 @@ class gz::sim::systems::HydrodynamicsPrivateData
122
78
// / \brief Previous state.
123
79
public: Eigen::VectorXd prevState;
124
80
125
- // / \brief Link entity
81
+ public: Eigen::VectorXd prevStateDot;
82
+
83
+ // / Link entity
126
84
public: Entity linkEntity;
127
85
128
86
// / \brief Ocean current callback
@@ -212,25 +170,56 @@ void Hydrodynamics::Configure(
212
170
gz::sim::EventManager &/* _eventMgr*/
213
171
)
214
172
{
215
- this ->dataPtr ->waterDensity = SdfParamDouble (_sdf, " water_density" , 998 );
216
- this ->dataPtr ->paramXdotU = SdfParamDouble (_sdf, " xDotU" , 5 );
217
- this ->dataPtr ->paramYdotV = SdfParamDouble (_sdf, " yDotV" , 5 );
218
- this ->dataPtr ->paramZdotW = SdfParamDouble (_sdf, " zDotW" , 0.1 );
219
- this ->dataPtr ->paramKdotP = SdfParamDouble (_sdf, " kDotP" , 0.1 );
220
- this ->dataPtr ->paramMdotQ = SdfParamDouble (_sdf, " mDotQ" , 0.1 );
221
- this ->dataPtr ->paramNdotR = SdfParamDouble (_sdf, " nDotR" , 1 );
222
- this ->dataPtr ->paramXu = SdfParamDouble (_sdf, " xU" , 20 );
223
- this ->dataPtr ->paramXuu = SdfParamDouble (_sdf, " xUU" , 0 );
224
- this ->dataPtr ->paramYv = SdfParamDouble (_sdf, " yV" , 20 );
225
- this ->dataPtr ->paramYvv = SdfParamDouble (_sdf, " yVV" , 0 );
226
- this ->dataPtr ->paramZw = SdfParamDouble (_sdf, " zW" , 20 );
227
- this ->dataPtr ->paramZww = SdfParamDouble (_sdf, " zWW" , 0 );
228
- this ->dataPtr ->paramKp = SdfParamDouble (_sdf, " kP" , 20 );
229
- this ->dataPtr ->paramKpp = SdfParamDouble (_sdf, " kPP" , 0 );
230
- this ->dataPtr ->paramMq = SdfParamDouble (_sdf, " mQ" , 20 );
231
- this ->dataPtr ->paramMqq = SdfParamDouble (_sdf, " mQQ" , 0 );
232
- this ->dataPtr ->paramNr = SdfParamDouble (_sdf, " nR" , 20 );
233
- this ->dataPtr ->paramNrr = SdfParamDouble (_sdf, " nRR" , 0 );
173
+ if (_sdf->HasElement (" waterDensity" ))
174
+ {
175
+ ignwarn <<
176
+ " <waterDensity> parameter is deprecated and will be removed Ignition G.\n "
177
+ << " \t Please update your SDF to use <water_density> instead." ;
178
+ }
179
+
180
+ this ->dataPtr ->waterDensity = SdfParamDouble (_sdf, " waterDensity" ,
181
+ SdfParamDouble (_sdf, " water_density" , 998 )
182
+ );
183
+ // Load stability derivatives
184
+ // Use SNAME 1950 convention to load the coeffecients.
185
+ const auto snameConventionVel = " UVWPQR" ;
186
+ const auto snameConventionMoment = " xyzkmn" ;
187
+ for (auto i = 0 ; i < 6 ; i++)
188
+ {
189
+ for (auto j = 0 ; j < 6 ; j++)
190
+ {
191
+ std::string prefix = {snameConventionMoment[i]};
192
+ prefix += snameConventionVel[j];
193
+ this ->dataPtr ->stabilityLinearTerms [i*6 + j] =
194
+ SdfParamDouble (_sdf, prefix, 0 );
195
+ for (auto k = 0 ; k < 6 ; k++)
196
+ {
197
+ this ->dataPtr ->stabilityQuadraticDerivative [i*36 + j*6 + k] =
198
+ SdfParamDouble (
199
+ _sdf,
200
+ prefix + snameConventionVel[k],
201
+ 0 );
202
+ this ->dataPtr ->stabilityQuadraticAbsDerivative [i*36 + j*6 + k] =
203
+ SdfParamDouble (
204
+ _sdf,
205
+ prefix + " abs" + snameConventionVel[k],
206
+ 0 );
207
+ }
208
+ }
209
+ }
210
+
211
+ // Added mass according to Fossen's equations (p 37)
212
+ this ->dataPtr ->Ma = Eigen::MatrixXd::Zero (6 , 6 );
213
+ for (auto i = 0 ; i < 6 ; i++)
214
+ {
215
+ for (auto j = 0 ; j < 6 ; j++)
216
+ {
217
+ std::string prefix = {snameConventionMoment[i]};
218
+ prefix += " Dot" ;
219
+ prefix += snameConventionVel[j];
220
+ this ->dataPtr ->Ma (i, j) = SdfParamDouble (_sdf, prefix, 0 );
221
+ }
222
+ }
234
223
235
224
_sdf->Get <bool >(" disable_coriolis" , this ->dataPtr ->disableCoriolis , false );
236
225
_sdf->Get <bool >(" disable_added_mass" , this ->dataPtr ->disableAddedMass , false );
@@ -276,17 +265,6 @@ void Hydrodynamics::Configure(
276
265
AddWorldPose (this ->dataPtr ->linkEntity , _ecm);
277
266
AddAngularVelocityComponent (this ->dataPtr ->linkEntity , _ecm);
278
267
AddWorldLinearVelocity (this ->dataPtr ->linkEntity , _ecm);
279
-
280
-
281
- // Added mass according to Fossen's equations (p 37)
282
- this ->dataPtr ->Ma = Eigen::MatrixXd::Zero (6 , 6 );
283
-
284
- this ->dataPtr ->Ma (0 , 0 ) = this ->dataPtr ->paramXdotU ;
285
- this ->dataPtr ->Ma (1 , 1 ) = this ->dataPtr ->paramYdotV ;
286
- this ->dataPtr ->Ma (2 , 2 ) = this ->dataPtr ->paramZdotW ;
287
- this ->dataPtr ->Ma (3 , 3 ) = this ->dataPtr ->paramKdotP ;
288
- this ->dataPtr ->Ma (4 , 4 ) = this ->dataPtr ->paramMdotQ ;
289
- this ->dataPtr ->Ma (5 , 5 ) = this ->dataPtr ->paramNdotR ;
290
268
}
291
269
292
270
// ///////////////////////////////////////////////
@@ -330,7 +308,7 @@ void Hydrodynamics::PreUpdate(
330
308
// Transform state to local frame
331
309
auto pose = baseLink.WorldPose (_ecm);
332
310
// Since we are transforming angular and linear velocity we only care about
333
- // rotation
311
+ // rotation. Also this is where we apply the effects of current to the link
334
312
auto localLinearVelocity = pose->Rot ().Inverse () *
335
313
(linearVelocity->Data () - currentVector);
336
314
auto localRotationalVelocity = pose->Rot ().Inverse () * *rotationalVelocity;
@@ -343,7 +321,6 @@ void Hydrodynamics::PreUpdate(
343
321
state (4 ) = localRotationalVelocity.Y ();
344
322
state (5 ) = localRotationalVelocity.Z ();
345
323
346
- // TODO(anyone) Make this configurable
347
324
auto dt = static_cast <double >(_info.dt .count ())/1e9 ;
348
325
stateDot = (state - this ->dataPtr ->prevState )/dt;
349
326
@@ -355,40 +332,50 @@ void Hydrodynamics::PreUpdate(
355
332
356
333
// Coriolis and Centripetal forces for under water vehicles (Fossen P. 37)
357
334
// Note: this is significantly different from VRX because we need to account
358
- // for the under water vehicle's additional DOF
359
- Cmat (0 , 4 ) = - this ->dataPtr ->paramZdotW * state (2 );
360
- Cmat (0 , 5 ) = - this ->dataPtr ->paramYdotV * state (1 );
361
- Cmat (1 , 3 ) = this ->dataPtr ->paramZdotW * state (2 );
362
- Cmat (1 , 5 ) = - this ->dataPtr ->paramXdotU * state (0 );
363
- Cmat (2 , 3 ) = - this ->dataPtr ->paramYdotV * state (1 );
364
- Cmat (2 , 4 ) = this ->dataPtr ->paramXdotU * state (0 );
365
- Cmat (3 , 1 ) = - this ->dataPtr ->paramZdotW * state (2 );
366
- Cmat (3 , 2 ) = this ->dataPtr ->paramYdotV * state (1 );
367
- Cmat (3 , 4 ) = - this ->dataPtr ->paramNdotR * state (5 );
368
- Cmat (3 , 5 ) = this ->dataPtr ->paramMdotQ * state (4 );
369
- Cmat (4 , 0 ) = this ->dataPtr ->paramZdotW * state (2 );
370
- Cmat (4 , 2 ) = - this ->dataPtr ->paramXdotU * state (0 );
371
- Cmat (4 , 3 ) = this ->dataPtr ->paramNdotR * state (5 );
372
- Cmat (4 , 5 ) = - this ->dataPtr ->paramKdotP * state (3 );
373
- Cmat (5 , 0 ) = this ->dataPtr ->paramZdotW * state (2 );
374
- Cmat (5 , 1 ) = this ->dataPtr ->paramXdotU * state (0 );
375
- Cmat (5 , 3 ) = - this ->dataPtr ->paramMdotQ * state (4 );
376
- Cmat (5 , 4 ) = this ->dataPtr ->paramKdotP * state (3 );
335
+ // for the under water vehicle's additional DOF. We are just considering
336
+ // diagonal terms here. Have yet to add the cross terms here. Also note, since
337
+ // $M_a(0,0) = \dot X_u $ , $M_a(1,1) = \dot Y_v $ and so forth, we simply
338
+ // load the stability derivatives from $M_a$.
339
+ Cmat (0 , 4 ) = - this ->dataPtr ->Ma (2 , 2 ) * state (2 );
340
+ Cmat (0 , 5 ) = - this ->dataPtr ->Ma (1 , 1 ) * state (1 );
341
+ Cmat (1 , 3 ) = this ->dataPtr ->Ma (2 , 2 ) * state (2 );
342
+ Cmat (1 , 5 ) = - this ->dataPtr ->Ma (0 , 0 ) * state (0 );
343
+ Cmat (2 , 3 ) = - this ->dataPtr ->Ma (1 , 1 ) * state (1 );
344
+ Cmat (2 , 4 ) = this ->dataPtr ->Ma (0 , 0 ) * state (0 );
345
+ Cmat (3 , 1 ) = - this ->dataPtr ->Ma (2 , 2 ) * state (2 );
346
+ Cmat (3 , 2 ) = this ->dataPtr ->Ma (1 , 1 ) * state (1 );
347
+ Cmat (3 , 4 ) = - this ->dataPtr ->Ma (5 , 5 ) * state (5 );
348
+ Cmat (3 , 5 ) = this ->dataPtr ->Ma (4 , 4 ) * state (4 );
349
+ Cmat (4 , 0 ) = this ->dataPtr ->Ma (2 , 2 ) * state (2 );
350
+ Cmat (4 , 2 ) = - this ->dataPtr ->Ma (0 , 0 ) * state (0 );
351
+ Cmat (4 , 3 ) = this ->dataPtr ->Ma (5 , 5 ) * state (5 );
352
+ Cmat (4 , 5 ) = - this ->dataPtr ->Ma (3 , 3 ) * state (3 );
353
+ Cmat (5 , 0 ) = this ->dataPtr ->Ma (2 , 2 ) * state (2 );
354
+ Cmat (5 , 1 ) = this ->dataPtr ->Ma (0 , 0 ) * state (0 );
355
+ Cmat (5 , 3 ) = - this ->dataPtr ->Ma (4 , 4 ) * state (4 );
356
+ Cmat (5 , 4 ) = this ->dataPtr ->Ma (3 , 3 ) * state (3 );
377
357
const Eigen::VectorXd kCmatVec = - Cmat * state;
378
358
379
- // Damping forces (Fossen P. 43)
380
- Dmat (1 , 1 )
381
- = - this ->dataPtr ->paramYv - this ->dataPtr ->paramYvv * abs (state (1 ));
382
- Dmat (0 , 0 )
383
- = - this ->dataPtr ->paramXu - this ->dataPtr ->paramXuu * abs (state (0 ));
384
- Dmat (2 , 2 )
385
- = - this ->dataPtr ->paramZw - this ->dataPtr ->paramZww * abs (state (2 ));
386
- Dmat (3 , 3 )
387
- = - this ->dataPtr ->paramKp - this ->dataPtr ->paramKpp * abs (state (3 ));
388
- Dmat (4 , 4 )
389
- = - this ->dataPtr ->paramMq - this ->dataPtr ->paramMqq * abs (state (4 ));
390
- Dmat (5 , 5 )
391
- = - this ->dataPtr ->paramNr - this ->dataPtr ->paramNrr * abs (state (5 ));
359
+ // Damping forces
360
+ for (int i = 0 ; i < 6 ; i++)
361
+ {
362
+ for (int j = 0 ; j < 6 ; j++)
363
+ {
364
+ auto coeff = - this ->dataPtr ->stabilityLinearTerms [i * 6 + j];
365
+ for (int k = 0 ; k < 6 ; k++)
366
+ {
367
+ auto index = i * 36 + j * 6 + k;
368
+ auto absCoeff =
369
+ this ->dataPtr ->stabilityQuadraticAbsDerivative [index ] * abs (state (k));
370
+ coeff -= absCoeff;
371
+ auto velCoeff =
372
+ this ->dataPtr ->stabilityQuadraticDerivative [index ] * state (k);
373
+ coeff -= velCoeff;
374
+ }
375
+
376
+ Dmat (i, j) = coeff;
377
+ }
378
+ }
392
379
393
380
const Eigen::VectorXd kDvec = Dmat * state;
394
381
@@ -403,10 +390,10 @@ void Hydrodynamics::PreUpdate(
403
390
kTotalWrench += kCmatVec ;
404
391
}
405
392
406
- gz:: math::Vector3d
407
- totalForce ( -kTotalWrench (0 ), -kTotalWrench (1 ), -kTotalWrench (2 ));
408
- gz:: math::Vector3d
409
- totalTorque ( -kTotalWrench (3 ), -kTotalWrench (4 ), -kTotalWrench (5 ));
393
+ math::Vector3d totalForce (
394
+ -kTotalWrench (0 ), -kTotalWrench (1 ), -kTotalWrench (2 ));
395
+ math::Vector3d totalTorque (
396
+ -kTotalWrench (3 ), -kTotalWrench (4 ), -kTotalWrench (5 ));
410
397
411
398
baseLink.AddWorldWrench (
412
399
_ecm,
0 commit comments