Free Electron
RigParticleMountSystem.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __tire_RigParticleMountSystem_h__
8 #define __tire_RigParticleMountSystem_h__
9 
10 #include "solve/solve.h"
11 
12 namespace fe
13 {
14 namespace ext
15 {
16 
17 /// @brief Tire to Rig Connection
19  virtual public Stepper,
20  public Initialize<RigParticleMountSystem>
21 {
22  public:
23  struct Mount
24  {
25  WeakRecord m_r_parent;
26  WeakRecord m_r_p0;
27  WeakRecord m_r_p1;
28  WeakRecord m_r_p2;
29  WeakRecord m_r_tire;
30  t_moa_xform m_inv_R;
31 
32  WeakRecord m_r_rig;
33  WeakRecord m_r_floor;
34  };
36  {
37  }
38  void initialize(void)
39  {
40  }
41 virtual void compile(const t_note_id &a_note_id)
42  {
43  sp<Scope> spScope = m_rg_dataset->scope();
44 
45  if(!spScope.isValid()) { return; }
46 
47  enforce<AsTire,AsTireLive>(m_rg_dataset);
48 
49  m_asRig.bind(spScope);
50  m_asPoint.bind(spScope);
51  m_asTireLive.bind(spScope);
52  m_asMount.bind(spScope);
53  m_asSurface.bind(spScope);
54 
55  AsTire asTire(spScope);
56 
57  RecordDictionary<AsRig> rd_rigs(m_rg_dataset);
58  RecordDictionary<AsTire> rd_tires(m_rg_dataset);
59 
60  std::vector<Record> mounts;
61  m_asMount.filter(mounts, m_rg_dataset);
62 
63  for(unsigned int i_mount = 0; i_mount < mounts.size(); i_mount++)
64  {
65  Record &r_mount = mounts[i_mount];
66  Mount mount;
67  mount.m_r_parent = r_mount;
68  mount.m_r_p0 = m_asMount.p0(r_mount);
69  mount.m_r_p1 = m_asMount.p1(r_mount);
70  mount.m_r_p2 = m_asMount.p2(r_mount);
71  mount.m_r_tire = rd_tires[m_asMount.tire(r_mount)];
72  mount.m_r_rig = rd_rigs[m_asMount.rig(r_mount)];
73  if( mount.m_r_p0.isValid() &&
74  mount.m_r_p1.isValid() &&
75  mount.m_r_p2.isValid() &&
76  mount.m_r_tire.isValid() &&
77  mount.m_r_rig.isValid() &&
78  m_asPoint.check(mount.m_r_p0) &&
79  m_asPoint.check(mount.m_r_p1) &&
80  m_asPoint.check(mount.m_r_p2) &&
81  m_asRig.check(mount.m_r_rig) &&
82  m_asTireLive.check(mount.m_r_tire))
83  {
84 
85  if(m_asRig.floor(mount.m_r_rig).isValid())
86  {
87  if(m_asSurface.check(m_asRig.floor(mount.m_r_rig)))
88  {
89  mount.m_r_floor = m_asRig.floor(mount.m_r_rig);
90  }
91  }
92 
93  t_moa_xform frame;
94  t_moa_xform relative;
95  setIdentity(relative);
96 
97  bool frame_made = makeFrame(frame,
98  m_asPoint.location(mount.m_r_p0),
99  m_asPoint.location(mount.m_r_p1),
100  m_asPoint.location(mount.m_r_p2),
101  relative);
102 
103  invert(mount.m_inv_R, frame);
104 
105  translate(relative, m_asMount.location(r_mount));
106  rotate(relative, m_asMount.inclination(r_mount),
107  e_xAxis);
108 
109  // useful to test for pitch relates bugs/bias
110  rotate(relative, m_asRig.pitch(mount.m_r_rig), e_yAxis);
111 
112  mount.m_inv_R = relative * mount.m_inv_R;
113 
114  m_mounts.push_back(mount);
115  }
116  }
117 
118  }
119  void step(t_moa_real a_dt)
120  {
121  for(unsigned int i_mount = 0; i_mount < m_mounts.size(); i_mount++)
122  {
123  WeakRecord &r_p0 = m_mounts[i_mount].m_r_p0;
124  WeakRecord &r_p1 = m_mounts[i_mount].m_r_p1;
125  WeakRecord &r_p2 = m_mounts[i_mount].m_r_p2;
126  WeakRecord &r_tire = m_mounts[i_mount].m_r_tire;
127  WeakRecord &r_mount = m_mounts[i_mount].m_r_parent;
128  WeakRecord &r_rig = m_mounts[i_mount].m_r_rig;
129 
130  t_moa_xform frame;
131  t_moa_xform relative;
132  setIdentity(relative);
133  bool frame_made = makeFrame(frame,
134  m_asPoint.location(r_p0),
135  m_asPoint.location(r_p1),
136  m_asPoint.location(r_p2),
137  m_mounts[i_mount].m_inv_R);
138 
139  if(m_mounts[i_mount].m_r_floor.isValid())
140  {
141  t_moa_real alpha = m_asRig.alpha(r_rig)*pi/180.0;
142 
143  m_asSurface.velocity(m_mounts[i_mount].m_r_floor)[0] =
144  m_asRig.velocity(r_rig);
145  m_asSurface.velocity(m_mounts[i_mount].m_r_floor)[1] = 0.0;
146 
147  m_asTireLive.transform(r_tire) = frame;
148 
149  if(determinant(m_asTireLive.transform(r_tire)) == 0.0)
150  { continue; }
151 
152  t_moa_xform incl_xform;
153  setIdentity(incl_xform);
154 
155  if(m_asRig.incline_floor(r_rig))
156  {
157  rotate(incl_xform, m_asRig.inclination(r_rig),
158  e_xAxis);
159  }
160  else
161  {
162  rotate(m_asTireLive.transform(r_tire),
163  m_asRig.inclination(r_rig), e_xAxis);
164  }
165 
166  rotate(incl_xform, alpha, e_zAxis);
167  //translate(incl_xform, t_moa_v3(0.0,0.0,-0.22));
168  m_asSurface.transform(m_mounts[i_mount].m_r_floor)
169  = incl_xform;
170 
171  invert(m_asMount.transform_inv(r_mount),
172  m_asTireLive.transform(r_tire));
173 
174  m_asTireLive.velocity(r_tire) =
175  rotateVector<3, t_moa_real> (
176  m_asMount.transform_inv(r_mount),
177  m_asPoint.velocity(r_p0));
178 
179  t_moa_v3 angular_velocity = t_moa_v3(0,
180  m_asRig.kappa(r_rig),0);
181  if(m_asRig.free_wheel(r_rig))
182  {
183  angular_velocity[1]
184  += (m_asRig.velocity(r_rig)*cos(alpha))
185  / m_asTireLive.radius(r_tire);
186  }
187  m_asTireLive.angular_velocity(r_tire) = angular_velocity;
188  }
189  else
190  {
191 
192  // rig is essentially being used as a rolling road here
193  t_moa_real alpha = m_asRig.alpha(r_rig)*pi/180.0;
194  t_moa_v3 rig_vel(0,0,0);
195  rig_vel[0] = m_asRig.velocity(r_rig) * cos(alpha);
196  rig_vel[1] = m_asRig.velocity(r_rig) * sin(alpha);
197  rig_vel[2] = 0.0;
198 
199  m_asTireLive.transform(r_tire) = frame;
200 
201  if(determinant(m_asTireLive.transform(r_tire)) == 0.0)
202  {
203  continue;
204  }
205 
206  rotate(m_asTireLive.transform(r_tire),
207  m_asRig.inclination(r_rig), e_xAxis);
208  invert(m_asMount.transform_inv(r_mount),
209  m_asTireLive.transform(r_tire));
210 
211  rig_vel = rotateVector<3, t_moa_real>(
212  m_asMount.transform_inv(r_mount),rig_vel);
213 
214  t_moa_v3 tire_space_p0_v =
215  rotateVector<3, t_moa_real> (
216  m_asMount.transform_inv(r_mount),
217  m_asPoint.velocity(r_p0));
218 
219  t_moa_v3 vel = tire_space_p0_v + rig_vel;
220 
221  m_asTireLive.velocity(r_tire) = vel;
222 
223  t_moa_v3 angular_velocity = t_moa_v3(0,
224  m_asRig.kappa(r_rig),0);
225  if(m_asRig.free_wheel(r_rig))
226  {
227  angular_velocity[1]
228  += (m_asRig.velocity(r_rig)*cos(alpha))
229  / m_asTireLive.radius(r_tire);
230  }
231  m_asTireLive.angular_velocity(r_tire) = angular_velocity;
232  }
233  }
234  accumulate();
235  }
236  void accumulate(void)
237  {
238  for(unsigned int i_mount = 0; i_mount < m_mounts.size(); i_mount++)
239  {
240  WeakRecord &r_p0 = m_mounts[i_mount].m_r_p0;
241  WeakRecord &r_p1 = m_mounts[i_mount].m_r_p1;
242  WeakRecord &r_p2 = m_mounts[i_mount].m_r_p2;
243  WeakRecord &r_tire = m_mounts[i_mount].m_r_tire;
244 
245  t_moa_xform tire_xform = m_asTireLive.transform(r_tire);
246 
247  t_moa_v3 rig_space_F = rotateVector<3, t_moa_real>
248  (tire_xform, m_asTireLive.force(r_tire));
249  t_moa_v3 rig_space_M = rotateVector<3, t_moa_real>
250  (tire_xform, m_asTireLive.moment(r_tire));
251 
252  t_moa_v3 rig_space_P = tire_xform.translation();
253 
254  applyFMToPoints(rig_space_F, rig_space_M, rig_space_P,
255  m_asPoint, r_p0, r_p1, r_p2);
256  }
257  }
258 
259  std::vector<Mount> m_mounts;
260  AsForcePoint m_asPoint;
261  AsTireLive m_asTireLive;
262  AsRigParticlesMount m_asMount;
263  AsRigLive m_asRig;
264  AsSurface m_asSurface;
265 };
266 
267 } /* namespace ext */
268 } /* namespace fe */
269 
270 #endif /* __tire_RigParticleMountSystem_h__ */
271 
virtual void compile(const t_note_id &a_note_id)
Compile internal structure for dataset.
Definition: RigParticleMountSystem.h:41
Tire Test Rig Live.
Definition: tireAS.h:206
Tire.
Definition: tireAS.h:36
Tire to Rig Connection.
Definition: RigParticleMountSystem.h:18
void step(t_moa_real a_dt)
Move system forward in time by a timestep.
Definition: RigParticleMountSystem.h:119
kernel
Definition: namespace.dox:3
force application point
Definition: shapeAS.h:42
Matrix< 4, 4, T > & invert(Matrix< 4, 4, T > &a_inverted, const Matrix< 4, 4, T > &a_matrix)
4x4 full matrix inversion
Definition: Matrix.h:1033
Time Stepping System.
Definition: Stepper.h:15
Per-class participation in the Initialized <> mechanism.
Definition: Initialized.h:117
Run Time Single Contact Tire Model.
Definition: tireAS.h:49
Reference to an instance of a Layout.
Definition: RecordSB.h:35
Non-persistent reference to an instance of a Layout.
Definition: WeakRecordSB.h:17