Free Electron
TireContactSystem.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_TireContactSystem_h__
8 #define __tire_TireContactSystem_h__
9 
10 #include "solve/solve.h"
11 
12 namespace fe
13 {
14 namespace ext
15 {
16 
17 /// MOA apply contact to tire (incl/pitch/radius)
19  virtual public Stepper,
20  public Initialize<TireContactSystem>
21 {
22  public:
23  TireContactSystem(void)
24  {
25  }
26  void initialize(void) {}
27 virtual void compile(const t_note_id &a_note_id)
28  {
29  rg_all = m_rg_dataset;
30  m_asContact.bind(rg_all->scope());
31  m_asTireLive.bind(rg_all->scope());
32 
33  enforce<AsContact,AsContactLive>(m_rg_dataset);
34 
35  for(RecordGroup::iterator i_rg = rg_all->begin();
36  i_rg != rg_all->end(); i_rg++)
37  {
38  sp<RecordArray> spRA = *i_rg;
39 
40  if(!m_asContact.check(spRA)) { continue; }
41  if(!m_asTireLive.check(spRA)) { continue; }
42 
43  for(unsigned int i_r = 0; i_r < spRA->length(); i_r++)
44  {
45  setIdentity(m_asTireLive.patch(spRA->getRecord(i_r)));
46  m_tires.push_back(spRA->getRecord(i_r));
47  }
48  }
49  }
50  void step(t_moa_real a_dt)
51  {
52  if(!rg_all->scope().isValid()) { return; }
53 
54  for(unsigned int i_tire = 0; i_tire < m_tires.size(); i_tire++)
55  {
56  Record &r_tire = m_tires[i_tire];
57 
58  if(determinant(m_asTireLive.transform(r_tire)) == 0.0)
59  { continue; }
60  SpatialTransform inv_tire_transform;
61  invert(inv_tire_transform, m_asTireLive.transform(r_tire));
62 
63  t_moa_v3 contact_point_tire = transformVector<3,t_moa_real>
64  (inv_tire_transform, m_asContact.contact(r_tire));
65 
66 
67  t_moa_real sign_based_tire_frame = 0.0;
68  if(contact_point_tire[2] > 0.0)
69  {
70  sign_based_tire_frame = -magnitude(contact_point_tire);
71  }
72  else
73  {
74  sign_based_tire_frame = magnitude(contact_point_tire);
75  }
76 
77  m_asTireLive.contact_radius(r_tire) = sign_based_tire_frame;
78 
79  // ground_N_tire -- normal in tire space
80  SpatialVector ground_N_tire =
81  rotateVector<3, t_moa_real>
82  (inv_tire_transform, m_asContact.normal(r_tire));
83 
84  t_moa_real over_under = dot(ground_N_tire, contact_point_tire);
85  if(over_under < 0.0)
86  {
87  m_asTireLive.contact_radius(r_tire) =
88  magnitude(contact_point_tire);
89  }
90  else
91  {
92  m_asTireLive.contact_radius(r_tire) =
93  -magnitude(contact_point_tire);
94  }
95 
96  SpatialVector result;
97 
98  // result -- rotation vector for tilting away from upright
99 
100 #if 0
101  t_moa_real side = dot(ground_N_tire, SpatialVector(0,0,1));
102  if(side < 0)
103  {
104  m_asTireLive.pitch(r_tire) = pi;
105  }
106  else
107  {
108  m_asTireLive.pitch(r_tire) = 0.0;
109  }
110 #endif
111 
112  cross3(result,ground_N_tire,SpatialVector(0,0,1));
113 
114  t_moa_real m = result[0];
115 
116  // protect the asin() from floating point slightly out
117  if(m > 1.0) { m = 1.0; }
118  if(m < -1.0) { m = -1.0; }
119 
120  m_asTireLive.inclination(r_tire) = asin(m);
121 
122 #if 0
123  m = result[1];
124 
125  // protect the asin() from floating point slightly out
126  if(m > 1.0) { m = 1.0; }
127  if(m < -1.0) { m = -1.0; }
128 
129  if(side < 0)
130  {
131  m_asTireLive.pitch(r_tire) -= asin(m);
132  }
133  else
134  {
135  m_asTireLive.pitch(r_tire) += asin(m);
136  }
137 #endif
138 
139  // make a patch frame
140  t_moa_xform xform;
141  setIdentity(xform);
142 
143  // Z is N
144  xform.up() = ground_N_tire;
145 
146  // side is 0,1,0 (TODO:degenerate/laying on side)
147  xform.left() = SpatialVector(0,1,0);
148 
149  // cross for X
150  cross3(xform.direction(), xform.left(), xform.up());
151  normalize(xform.direction());
152 
153  // orthonormalize Y
154  cross3(xform.left(), xform.up(), xform.direction());
155  normalize(xform.left()); // should not be necessary
156 
157  m_asTireLive.patch(r_tire) = xform;
158  }
159  }
160  private:
161  sp<RecordGroup> rg_all;
162  AsTireLive m_asTireLive;
163  AsContactLive m_asContact;
164  std::vector<Record> m_tires;
165 };
166 
167 } /* namespace ext */
168 } /* namespace fe */
169 
170 #endif /* __tire_TireContactSystem_h__ */
171 
kernel
Definition: namespace.dox:3
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
void step(t_moa_real a_dt)
Move system forward in time by a timestep.
Definition: TireContactSystem.h:50
Time Stepping System.
Definition: Stepper.h:15
Per-class participation in the Initialized <> mechanism.
Definition: Initialized.h:117
virtual void compile(const t_note_id &a_note_id)
Compile internal structure for dataset.
Definition: TireContactSystem.h:27
Run Time Single Contact Tire Model.
Definition: tireAS.h:49
STL style iterator.
Definition: RecordGroup.h:124
Reference to an instance of a Layout.
Definition: RecordSB.h:35
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
MOA apply contact to tire (incl/pitch/radius)
Definition: TireContactSystem.h:18