Marine systems simulation
CInternalCable.h
1
10
11#ifndef CInternalCable_H
12#define CInternalCable_H
13
14// Includes
15#include <string>
16#include <SimObject.h>
17#include "ICurrentVel.h"
18#include "sfh/timers/StopWatch.h"
19#include "cable/subroutines/CCableElDynStiff.h"
20#include "sfh/constants.h"
21#include "sfh/math/math.h"
22#include "sfh/linalg.h"
23#include "sfh/math/array.h"
24
25
26#define ATTACH_SPHERE
27
28
31{
32 int iNumElements;
33 double dDensity;
34 double dNumericalDamping;
35 double dDiameter;
36 double dE;
37 double dDampingRatio;
38 double dFluidRho;
39 double dMaxStep;
40 double dMaxTension;
41 double dMaxAcceleration;
42 double dStepSafetyFactor;
43 double dMeanTension0;
44 double dEAdaptationPeriod;
45 std::string sMaterialName;
46 int iCableFaces;
47 std::string sCableName;
48 double dDrawScale;
49
52 {
53 Reset();
54 }
56 void Reset()
57 {
58 iNumElements = 2;
59 dDensity = 1100;
60 dNumericalDamping = 1;
61 dDiameter = 0.01;
62 dE = 1e9;
63 dDampingRatio = 1;
64 dFluidRho = 1025;
65 dMaxStep = 1e-10;
66 dMaxTension = 1e10;
67 dMaxAcceleration = 1e10;
68 dStepSafetyFactor = 50;
69 dMeanTension0 = 0;
70 dEAdaptationPeriod = 0;
71 sMaterialName = "Trawl/SteelWire";
72 iCableFaces = 5;
73 sCableName = "";
74 dDrawScale = 1;
75 }
77 double CalcEA()
78 {
79 return sfh::pi * 0.25 * dDiameter * dDiameter* dE;
80 }
81};
82
85{
86 double dDeltaTheta;
87 double* adTheta;
88 double* adSinTheta;
89 double* adCosTheta;
90 double dTextureScale;
91 double* adCirclePos;
92 double* adFacePosNormal;
93 double* adTextureCoordU;
94 double* adTextureCoordV;
95 int iNumRenderEdges;
96 double dDrawDiam;
97 int* aiIndex;
98 int iSizeIndexBuffer;
99
104 SCableRenderSpec(int iNumFaces, int iNumElements, double dDrawDiameter)
105 {
106 dDrawDiam = dDrawDiameter;
107 iNumRenderEdges = iNumFaces + 1;
108 iSizeIndexBuffer = iNumElements * iNumRenderEdges * 2;
109 dTextureScale = 5 * (sfh::pi * dDrawDiam);
110 aiIndex = new int [iSizeIndexBuffer];
111 dDeltaTheta = 2 * sfh::pi / iNumFaces;
112 adTheta = new double [iNumRenderEdges];
113 adSinTheta = new double [iNumRenderEdges];
114 adCosTheta = new double [iNumRenderEdges];
115 adCirclePos = new double [ (iNumElements + 1) * (iNumRenderEdges) * 3 ];
116 adFacePosNormal = new double [ (iNumElements + 1) * (iNumRenderEdges) * 3 ];
117 adTextureCoordU = new double [ iNumRenderEdges ];
118 adTextureCoordV = new double [ iNumElements + 1 ];
119 adTextureCoordV[0] = 0;
120 for (unsigned short i = 0; i < iNumRenderEdges; i++)
121 {
122 adTheta[i] = i * dDeltaTheta;
123 adSinTheta[i] = sin(adTheta[i]);
124 adCosTheta[i] = cos(adTheta[i]);
125 adTextureCoordU[i] = adTheta[i] * (sfh::pi * dDrawDiam) / dTextureScale;
126 }
127 int i = 0;
128 for (int iElement = 0; iElement < iNumElements; iElement++)
129 {
130 for (int iEdge = 0; iEdge < iNumRenderEdges; iEdge++)
131 {
132 aiIndex[i++] = iElement * iNumRenderEdges + iEdge;
133 aiIndex[i++] = (iElement + 1) * iNumRenderEdges + iEdge;
134 }
135 }
136
137 }
138
141 {
142 delete [] adTheta;
143 delete [] adSinTheta;
144 delete [] adCosTheta;
145 delete [] adCirclePos;
146 delete [] adFacePosNormal;
147 delete [] adTextureCoordU;
148 delete [] adTextureCoordV;
149 }
150
157 void Update(int iElement, const double* adElPosA, const double* adElPosB, const double* adDirection, double dL0 )
158 {
159 // Creating a vector not parallel to the direction of the element.
160 sfh::math::FindNotParallel( adDirection, 3, adNotParallel );
161
162 // Creating two vectors normal to each other and the direction of the element.
163 sfh::linalg::Cross(adDirection, adNotParallel, adNormal1);
164 sfh::linalg::Cross(adDirection, adNormal1, adNormal2);
165 sfh::math::Normalize3(adNormal1);
166 sfh::math::Normalize3(adNormal2);
167 sfh::math::ArrayMultiply(adNormal1, dDrawDiam/2.0, 3);
168 sfh::math::ArrayMultiply(adNormal2, dDrawDiam/2.0, 3);
169 adTextureCoordV[iElement + 1] = adTextureCoordV[iElement] + dL0 / dTextureScale * 3;
170
171 for (unsigned short iFace = 0; iFace < iNumRenderEdges; iFace++)
172 {
173 for(unsigned short iInd = 0; iInd < 3; iInd++)
174 {
175 if(iElement == 0)
176 {
177 adFacePosNormal[iElement * ((iNumRenderEdges) * 3) + 3 * iFace + iInd] = adSinTheta[iFace]*adNormal1[iInd] + adCosTheta[iFace]*adNormal2[iInd];
178 adCirclePos[iElement * ((iNumRenderEdges) * 3) + 3 * iFace + iInd] = adElPosA[iInd] + adFacePosNormal[iElement * ((iNumRenderEdges)* 3) + 3 * iFace + iInd];
179 }
180 adFacePosNormal[(iElement + 1) * ((iNumRenderEdges) * 3) + 3 * iFace + iInd] = adSinTheta[iFace]*adNormal1[iInd] + adCosTheta[iFace]*adNormal2[iInd];
181 adCirclePos[(iElement + 1) * ((iNumRenderEdges) * 3) + 3 * iFace + iInd] = adElPosB[iInd] + adFacePosNormal[(iElement + 1) * ((iNumRenderEdges) * 3) + 3 * iFace + iInd];
182 }
183 }
184 }
185
186private:
187 // Varaiables to avoid excessive allocations
188 double adNotParallel[3];
189 double adNormal1[3];
190 double adNormal2[3];
191};
192
193//Class definition
195{
196public:
198 CInternalCable(ISimObjectCreator* pCreator, const SCableSpec& CableSpec);
199
202
203 // Member functions
204 virtual void FinalSetup(const double dT, const double *const adX, ISimObjectCreator* const pCreator);
205
207 virtual void OdeFcn(const double* const adPosA,
208 const double* const adVelA,
209 const double* const adPosB,
210 const double* const adVelB,
211 const double* const adX,
212 double* const adXDot,
213 double dT);
214
216 virtual bool InitializeStates( const double* const adPosA,
217 const double* const adVelA,
218 const double* const adPosB,
219 const double* const adVelB,
220 double* const adX );
221
223 void UpdateCable(double dNewLength, double dT);
224
227 double* const adEndForceA,
228 double* const adEndForceB,
229 double* const pdEndInertiaA,
230 double* const pdEndInertiaB,
231 const double* const adPosA,
232 const double* const adVelA,
233 const double* const adPosB,
234 const double* const adVelB,
235 const double* const adX,
236 double dT);
237
239 double GetLength();
240
241#ifdef FH_VISUALIZATION
243 void RenderInit(Ogre::Root* pOgreRoot);
244
246 void RenderUpdate( const double* const adX, const double* adPosA, const double* adPosB);
247#endif
248
249 unsigned long m_iNumElements;
250 unsigned long m_iNumNodes;
251protected:
252 // Deletes all node forces.
253 void ResetAllNodeForces();
254
255 // Adds the forces from each cable element to the array of node forces.
256 void AddAllElementForces(const double* const adPosA,
257 const double* const adVelA,
258 const double* const adPosB,
259 const double* const adVelB,
260 const double* const adX,
261 double dT);
262
263 // Calculates the derivatives of the states of the cable.
264 void CalcDerivatives(const double* const adX,
265 double* const adXDot);
266
267 // Adds the forces from one element to the array of node forces.
268 virtual void AddElementForce(int iCableElement,
269 const double adPosA[3],
270 const double adVelA[3],
271 const double adPosB[3],
272 const double adVelB[3],
273 double adForceA[3],
274 double adForceB[3],
275 double dT);
276
279
280 unsigned long* m_aIStatePos;
281 unsigned long* m_aIStateVel;
282
283 // Member variables
285 double m_dEA;
286 sfh::timers::StopWatch m_StopWatch;
287
289 double* m_adInertiaA;
290 double* m_adInertiaB;
291 double** m_aadForceA;
292 double** m_aadForceB;
293
294 ICurrentVel** m_ppCurrentVel;
295 double m_adElVelWater[3];
296 double m_adElMeanPos[3];
297 double m_adElMeanVel[3];
298
299# ifdef FH_VISUALIZATION
300 SCableRenderSpec* m_pRenderSpec;
301 Ogre::Root* m_pOgreRoot;
302 Ogre::SceneManager* m_pSceneMgr;
303 Ogre::Entity* m_pRenderElement;
304 Ogre::SceneNode* m_pRenderNode;
305 Ogre::ManualObject* m_pCableRenderObj;
306 double m_dDrawDiam;
307# ifdef ATTACH_SPHERE
308 Ogre::Entity* m_aRenderSphere[2];
309 Ogre::SceneNode* m_aRenderNodeSphere[2];
310# endif
311# endif
312};
313
314
315#endif
Definition: CCableElDynStiff.h:33
Definition: CInternalCable.h:195
void UpdateCable(double dNewLength, double dT)
Updates the cable for the next step.
unsigned long * m_aIStateVel
An array of indices to the node velocity states.
Definition: CInternalCable.h:281
CInternalCable(ISimObjectCreator *pCreator, const SCableSpec &CableSpec)
The constructor sets the pointer to the output object and the parser object.
void UpdateInertia()
Updates the inertia of the cable according to the changing length.
~CInternalCable()
The destructor deletes dynamically allocated memory.
unsigned long m_iNumNodes
The number of nodes of the cable.
Definition: CInternalCable.h:250
double m_dEA
The stiffness of the cable.
Definition: CInternalCable.h:285
SCableSpec m_CableSpec
The cable specification.
Definition: CInternalCable.h:284
double ** m_aadForceA
The force on the A nodes.
Definition: CInternalCable.h:291
CCableElDynStiff ** m_apCableElements
An array holding the cable elements.
Definition: CInternalCable.h:288
virtual bool InitializeStates(const double *const adPosA, const double *const adVelA, const double *const adPosB, const double *const adVelB, double *const adX)
Method for setting initial conditions when the input is known, which may be implemented in the indivi...
double GetLength()
Calculates the length of the cable.
double * m_adInertiaB
The inertia of the B nodes.
Definition: CInternalCable.h:290
void AddEndForcesAndInertia(double *const adEndForceA, double *const adEndForceB, double *const pdEndInertiaA, double *const pdEndInertiaB, const double *const adPosA, const double *const adVelA, const double *const adPosB, const double *const adVelB, const double *const adX, double dT)
Adds the end forces and inertia to the supplied data structures.
double * m_adInertiaA
The inertia of the A nodes.
Definition: CInternalCable.h:289
virtual void OdeFcn(const double *const adPosA, const double *const adVelA, const double *const adPosB, const double *const adVelB, const double *const adX, double *const adXDot, double dT)
Calculates the state derivatives and the end forces.
double ** m_aadForceB
The force on the B nodes.
Definition: CInternalCable.h:292
unsigned long * m_aIStatePos
An array of indices to the node position states.
Definition: CInternalCable.h:280
unsigned long m_iNumElements
The number of elements to divide the cable into.
Definition: CInternalCable.h:249
Definition: ICurrentVel.h:12
Contains some specifications and methods used for rendering cables.
Definition: CInternalCable.h:85
SCableRenderSpec(int iNumFaces, int iNumElements, double dDrawDiameter)
Definition: CInternalCable.h:104
~SCableRenderSpec()
The destructor frees allocated memory.
Definition: CInternalCable.h:140
void Update(int iElement, const double *adElPosA, const double *adElPosB, const double *adDirection, double dL0)
Definition: CInternalCable.h:157
Contains some specifications used for simulating cables.
Definition: CInternalCable.h:31
void Reset()
Resets the specification to the defaults.
Definition: CInternalCable.h:56
double CalcEA()
Calculates the stiffness of the cable.
Definition: CInternalCable.h:77
SCableSpec()
The constructor sets some default values.
Definition: CInternalCable.h:51