FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
RigidBodyTerms.h
1#pragma once
2
27namespace rigid_body
28{
30enum class MunkMoment
31{
32 Included,
33 Omitted
34};
35
37inline void Skew(const double a[3], double S[3][3])
38{
39 S[0][0] = 0.0;
40 S[0][1] = -a[2];
41 S[0][2] = a[1];
42 S[1][0] = a[2];
43 S[1][1] = 0.0;
44 S[1][2] = -a[0];
45 S[2][0] = -a[1];
46 S[2][1] = a[0];
47 S[2][2] = 0.0;
48}
49
51inline void Cross(const double a[3], const double b[3], double axb[3])
52{
53 axb[0] = a[1] * b[2] - a[2] * b[1];
54 axb[1] = a[2] * b[0] - a[0] * b[2];
55 axb[2] = a[0] * b[1] - a[1] * b[0];
56}
57
60inline void Momenta(const double rigid[6], const double added[6], const double vel[3], const double waterVel[3],
61 const double omega[3], double momentum[3], double angularMomentum[3], double addedMomentum[3])
62{
63 for (int i = 0; i < 3; i++) {
64 addedMomentum[i] = added[i] * (vel[i] - waterVel[i]);
65 momentum[i] = rigid[i] * vel[i] + addedMomentum[i];
66 angularMomentum[i] = (rigid[i + 3] + added[i + 3]) * omega[i];
67 }
68}
69
72inline void OmegaTermsWrench(const double rigid[6], const double added[6], const double vel[3], const double waterVel[3],
73 const double omega[3], MunkMoment munk, double wrench[6])
74{
75 double momentum[3];
76 double angularMomentum[3];
77 double addedMomentum[3];
78 Momenta(rigid, added, vel, waterVel, omega, momentum, angularMomentum, addedMomentum);
79
80 double omegaCrossMomentum[3];
81 double omegaCrossAngularMomentum[3];
82 double omegaCrossWaterVel[3];
83 Cross(omega, momentum, omegaCrossMomentum);
84 Cross(omega, angularMomentum, omegaCrossAngularMomentum);
85 Cross(omega, waterVel, omegaCrossWaterVel);
86
87 double munkMoment[3] = {0.0, 0.0, 0.0};
88 if (munk == MunkMoment::Included) {
89 const double relVel[3] = {vel[0] - waterVel[0], vel[1] - waterVel[1], vel[2] - waterVel[2]};
90 Cross(relVel, addedMomentum, munkMoment);
91 }
92
93 for (int i = 0; i < 3; i++) {
94 wrench[i] = -omegaCrossMomentum[i] - added[i] * omegaCrossWaterVel[i];
95 wrench[i + 3] = -omegaCrossAngularMomentum[i] - munkMoment[i];
96 }
97}
98
105inline void AddOmegaTermsJacobian(const double rigid[6], const double added[6], const double vel[3], const double waterVel[3],
106 const double omega[3], MunkMoment munk, double dWrench[6][6])
107{
108 double momentum[3];
109 double angularMomentum[3];
110 double addedMomentum[3];
111 Momenta(rigid, added, vel, waterVel, omega, momentum, angularMomentum, addedMomentum);
112 const double relVel[3] = {vel[0] - waterVel[0], vel[1] - waterVel[1], vel[2] - waterVel[2]};
113
114 double skewOmega[3][3];
115 double skewMomentum[3][3];
116 double skewAngularMomentum[3][3];
117 double skewWaterVel[3][3];
118 double skewAddedMomentum[3][3];
119 double skewRelVel[3][3];
120 Skew(omega, skewOmega);
121 Skew(momentum, skewMomentum);
122 Skew(angularMomentum, skewAngularMomentum);
123 Skew(waterVel, skewWaterVel);
124 Skew(addedMomentum, skewAddedMomentum);
125 Skew(relVel, skewRelVel);
126
127 for (int i = 0; i < 3; i++) {
128 for (int j = 0; j < 3; j++) {
129 dWrench[i][j] += -skewOmega[i][j] * (rigid[j] + added[j]);
130 dWrench[i][j + 3] += skewMomentum[i][j] + added[i] * skewWaterVel[i][j];
131 dWrench[i + 3][j + 3] += skewAngularMomentum[i][j] - skewOmega[i][j] * (rigid[j + 3] + added[j + 3]);
132 if (munk == MunkMoment::Included)
133 dWrench[i + 3][j] += skewAddedMomentum[i][j] - skewRelVel[i][j] * added[j];
134 }
135 }
136}
137} // namespace rigid_body