driving_physics 0.0.2.1 → 0.0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/test/disk.rb CHANGED
@@ -1,116 +1,78 @@
1
1
  require 'minitest/autorun'
2
2
  require 'driving_physics/disk'
3
+ require 'matrix'
3
4
 
4
- D = DrivingPhysics::Disk
5
+ include DrivingPhysics
5
6
 
6
- describe D do
7
+ describe Disk do
7
8
  describe "Disk.volume" do
8
9
  it "calculates the volume (m^3) of disk given radius and width" do
9
- cubic_m = D.volume(1.0, 1.0)
10
+ cubic_m = Disk.volume(1.0, 1.0)
10
11
  expect(cubic_m).must_equal Math::PI
11
12
 
12
- cubic_m = D.volume(0.35, 0.2)
13
+ cubic_m = Disk.volume(0.35, 0.2)
13
14
  expect(cubic_m).must_be_within_epsilon 0.076969
14
15
  end
15
16
  end
16
17
 
17
18
  describe "Disk.volume_l" do
18
19
  it "calculates the volume (L) of a disk given radius and width" do
19
- liters = D.volume_l(1.0, 1.0)
20
+ liters = Disk.volume_l(1.0, 1.0)
20
21
  expect(liters).must_equal Math::PI * 1000
21
22
 
22
- liters = D.volume_l(0.35, 0.2)
23
+ liters = Disk.volume_l(0.35, 0.2)
23
24
  expect(liters).must_be_within_epsilon 76.96902
24
25
  end
25
26
  end
26
27
 
27
28
  describe "Disk.density" do
28
29
  it "calculates the density (kg/L) given mass and volume" do
29
- expect(D.density(25.0, 25.0)).must_equal 1.0
30
- expect(D.density(50.0, 25.0)).must_equal 2.0
30
+ expect(Disk.density(25.0, 25.0)).must_equal 1.0
31
+ expect(Disk.density(50.0, 25.0)).must_equal 2.0
31
32
  end
32
33
  end
33
34
 
34
35
  describe "Disk.mass" do
35
36
  it "calculates the mass (kg) of a disk given radius, width, and density" do
36
- skip
37
- expect(D.mass(0.35, 0.2, D::DENSITY)).must_be_within_epsilon 25.015
37
+ expect(Disk.mass(0.35, 0.2, Disk::DENSITY)).must_be_within_epsilon 76.969
38
38
  end
39
39
  end
40
40
 
41
41
  describe "Disk.rotational_inertia" do
42
42
  it "calculates rotational inertia for a disk given radius and mass" do
43
- expect(D.rotational_inertia(0.35, 25.0)).must_be_within_epsilon 1.53125
43
+ expect(Disk.rotational_inertia(0.35, 25.0)).must_be_within_epsilon 1.53125
44
44
  end
45
45
  end
46
46
 
47
47
  describe "Disk.alpha" do
48
48
  it "calculates angular acceleration from torque and inertia" do
49
49
  scalar_torque = 1000
50
- inertia = D.rotational_inertia(0.35, 25.0)
51
- expect(D.alpha scalar_torque, inertia).must_be_within_epsilon 653.061
50
+ inertia = Disk.rotational_inertia(0.35, 25.0)
51
+ expect(Disk.alpha scalar_torque, inertia).must_be_within_epsilon 653.061
52
52
 
53
- skip # Vector
53
+ skip unless DrivingPhysics.has_vector?
54
54
  vector_torque = Vector[0, 0, 1000]
55
- vector_alpha = D.alpha vector_torque, inertia
55
+ vector_alpha = Disk.alpha vector_torque, inertia
56
56
  expect(vector_alpha).must_be_instance_of Vector
57
57
  expect(vector_alpha.size).must_equal 3
58
58
  expect(vector_alpha[2]).must_be_within_epsilon 653.06
59
59
  end
60
60
  end
61
61
 
62
- describe "Disk.torque_vector" do
63
- it "calculates a torque in the 3rd dimension given 2D force and radius" do
64
- skip # Vector
65
- force = Vector[1000, 0]
66
- radius = Vector[0, 5]
67
- torque = D.torque_vector(force, radius)
68
- expect(torque).must_be_instance_of Vector
69
- expect(torque.size).must_equal 3
70
- expect(torque[2]).must_be_within_epsilon 5000.0
71
- end
72
- end
73
-
74
- describe "Disk.force_vector" do
75
- it "calculates a (3D) force given 3D torque and 2D radius" do
76
- skip # Vector
77
- # let's invert the Disk.torque_vector case from above:
78
- torque = Vector[0, 0, 5000]
79
- radius = Vector[0, 5]
80
- force = D.force_vector(torque, radius)
81
- expect(force).must_be_instance_of Vector
82
- expect(force.size).must_equal 3
83
- expect(force[0]).must_be_within_epsilon 1000.0
84
-
85
- # now let's rotate the radius into the x-dimension
86
- # right hand rule, positive torque means thumb into screen, clockwise
87
- # negative-x radius means positive-y force
88
- torque = Vector[0, 0, 500]
89
- radius = Vector[-5, 0]
90
- force = D.force_vector(torque, radius)
91
- expect(force).must_be_instance_of Vector
92
- expect(force.size).must_equal 3
93
- expect(force[1]).must_be_within_epsilon 100.0
94
- end
95
- end
96
-
97
62
  describe "instance methods" do
98
63
  before do
99
64
  @env = DrivingPhysics::Environment.new
100
- @disk = D.new(@env)
65
+ @disk = Disk.new(@env)
101
66
  end
102
67
 
103
68
  it "initializes" do
104
- skip
105
- expect(@disk).must_be_instance_of D
106
- expect(@disk.density).must_equal D::DENSITY # sanity check
107
- expect(@disk.mass).must_be_within_epsilon 25.01
108
-
109
- with_mass = D.new(@env) { |w|
110
- w.mass = 99.01
111
- }
69
+ expect(@disk).must_be_instance_of Disk
70
+ expect(@disk.density).must_equal Disk::DENSITY # sanity check
71
+ expect(@disk.mass).must_be_within_epsilon 76.969
72
+
73
+ with_mass = Disk.new(@env) { |w| w.mass = 99.01 }
112
74
  expect(with_mass.mass).must_equal 99.01
113
- expect(with_mass.density).wont_equal D::DENSITY
75
+ expect(with_mass.density).wont_equal Disk::DENSITY
114
76
  end
115
77
 
116
78
  it "has a string representation" do
@@ -125,8 +87,7 @@ describe D do
125
87
  end
126
88
 
127
89
  it "has inertia" do
128
- skip
129
- expect(@disk.rotational_inertia).must_be_within_epsilon 1.5321
90
+ expect(@disk.rotational_inertia).must_be_within_epsilon 4.714
130
91
  end
131
92
  end
132
93
  end
data/test/gearbox.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'minitest/autorun'
2
+ require 'driving_physics/gearbox'
3
+
4
+ include DrivingPhysics
5
+
6
+ describe Gearbox do
7
+ it "has gear ratios" do
8
+ end
9
+
10
+ it "has a final drive" do
11
+ end
12
+
13
+ it "has a neutral gear" do
14
+ end
15
+
16
+ it "has a clutch with state" do
17
+ end
18
+
19
+ it "has mass" do
20
+ end
21
+
22
+ it "has rotating mass" do
23
+ end
24
+
25
+ it "converts crank torque to axle torque" do
26
+ end
27
+
28
+ it "has losses due to inertia and friction" do
29
+ end
30
+
31
+ it "converts crank omega to axle omega (and vice versa)" do
32
+ end
33
+
34
+ it "varies torque delivery based on gear ratio and clutch" do
35
+ end
36
+ end
data/test/motor.rb ADDED
@@ -0,0 +1,236 @@
1
+ require 'minitest/autorun'
2
+ require 'driving_physics/motor'
3
+
4
+ include DrivingPhysics
5
+
6
+ describe "interpolate" do
7
+ it "validates xs and ys match in size" do
8
+ xs = [0, 5, 10, 15, 20]
9
+ ys = [10, 10, 10, 10, 5]
10
+ expect(DrivingPhysics.interpolate(1, xs: xs, ys: ys)).must_equal 10
11
+ expect { DrivingPhysics.interpolate(1, xs: xs + [10], ys: ys) }.must_raise
12
+ expect { DrivingPhysics.interpolate(1, xs: xs, ys: ys + [10]) }.must_raise
13
+ end
14
+
15
+ it "validates x is within the range of xs" do
16
+ xs = [0, 5, 10, 15, 20]
17
+ ys = [10, 10, 10, 10, 5]
18
+ expect(DrivingPhysics.interpolate(1, xs: xs, ys: ys)).must_equal 10
19
+ expect { DrivingPhysics.interpolate(-1, xs: xs, ys: ys) }.must_raise
20
+ expect { DrivingPhysics.interpolate(25, xs: xs, ys: ys) }.must_raise
21
+ end
22
+
23
+ it "validates the xs are in ascending order" do
24
+ xs = [0, 5, 10, 15, 20]
25
+ ys = [10, 10, 10, 10, 5]
26
+ expect(DrivingPhysics.interpolate(1, xs: xs, ys: ys)).must_equal 10
27
+ xs[1] = 15
28
+ expect {
29
+ DrivingPhysics.interpolate(16, xs: xs, ys: ys)
30
+ }.must_raise
31
+ end
32
+
33
+ it "performs linear interpolation to yield a y value for a valid x" do
34
+ xs = [0, 5, 10, 15, 20]
35
+ ys = [5, 5, 10, 10, 15]
36
+
37
+ expect(DrivingPhysics.interpolate(0, xs: xs, ys: ys)).must_equal 5
38
+ expect(DrivingPhysics.interpolate(1, xs: xs, ys: ys)).must_equal 5
39
+ expect(DrivingPhysics.interpolate(4, xs: xs, ys: ys)).must_equal 5
40
+ expect(DrivingPhysics.interpolate(5, xs: xs, ys: ys)).must_equal 5
41
+ expect(DrivingPhysics.interpolate(6, xs: xs, ys: ys)).must_equal 6
42
+ expect(DrivingPhysics.interpolate(7, xs: xs, ys: ys)).must_equal 7
43
+ expect(DrivingPhysics.interpolate(8, xs: xs, ys: ys)).must_equal 8
44
+ expect(DrivingPhysics.interpolate(9, xs: xs, ys: ys)).must_equal 9
45
+ expect(DrivingPhysics.interpolate(10, xs: xs, ys: ys)).must_equal 10
46
+ expect(DrivingPhysics.interpolate(11, xs: xs, ys: ys)).must_equal 10
47
+ expect(DrivingPhysics.interpolate(12, xs: xs, ys: ys)).must_equal 10
48
+ expect(DrivingPhysics.interpolate(14, xs: xs, ys: ys)).must_equal 10
49
+ expect(DrivingPhysics.interpolate(15, xs: xs, ys: ys)).must_equal 10
50
+ expect(DrivingPhysics.interpolate(16, xs: xs, ys: ys)).must_equal 11
51
+ expect(DrivingPhysics.interpolate(17, xs: xs, ys: ys)).must_equal 12
52
+ expect(DrivingPhysics.interpolate(18, xs: xs, ys: ys)).must_equal 13
53
+ expect(DrivingPhysics.interpolate(19, xs: xs, ys: ys)).must_equal 14
54
+ expect(DrivingPhysics.interpolate(20, xs: xs, ys: ys)).must_equal 15
55
+ end
56
+ end
57
+
58
+ # shorthand
59
+ def tc(rpms, torques)
60
+ TorqueCurve.new(rpms: rpms, torques: torques)
61
+ end
62
+
63
+ describe TorqueCurve do
64
+ before do
65
+ @default = TorqueCurve.new
66
+ @rpms = [500, 1000, 3500, 6000, 7000, 7100]
67
+ @torques = [ 0, 100, 300, 300, 250, 0]
68
+ @minr = [0, 1]
69
+ @mint = [0, 0]
70
+ end
71
+
72
+ it "maps rpm values to torque values" do
73
+ expect(@default.torque(3500)).must_be(:>, 100)
74
+ end
75
+
76
+ describe "initialize" do
77
+ it "accepts two arrays: rpms, and the corresponding torques" do
78
+ expect(tc(@rpms, @torques)).must_be_kind_of(TorqueCurve)
79
+ end
80
+
81
+ it "has defaults for rpms and torques" do
82
+ expect(@default).must_be_kind_of(TorqueCurve)
83
+ end
84
+
85
+ it "validates size match for rpms and torques" do
86
+ expect( tc( @minr, @mint) ).must_be_kind_of TorqueCurve
87
+ expect { tc( [0], @mint) }.must_raise
88
+ expect { tc([0,1,2], @mint) }.must_raise
89
+ expect { tc(@minr, [0]) }.must_raise
90
+ expect { tc(@minr, [0,1,0]) }.must_raise
91
+
92
+ rpms = [100, 2000, 30_000]
93
+ torques = [0, 500, 0]
94
+
95
+ expect( tc( rpms, torques) ).must_be_kind_of TorqueCurve
96
+ expect { tc( rpms, [0, 0]) }.must_raise
97
+ expect { tc([1,2], torques) }.must_raise
98
+ expect { tc([1,2,3,4], torques) }.must_raise
99
+ end
100
+
101
+
102
+ describe "rpms" do
103
+ it "validates rpms are positive" do
104
+ expect( tc( @minr, @mint) ).must_be_kind_of TorqueCurve
105
+ expect { tc([-10, 10], @mint) }.must_raise
106
+ end
107
+
108
+ it "validates rpms are in ascending order" do
109
+ expect( tc( @minr, @mint) ).must_be_kind_of TorqueCurve
110
+ expect { tc([0, 0], @mint) }.must_raise
111
+ expect( tc([99, 100], @mint) ).must_be_kind_of TorqueCurve
112
+ expect { tc([100, 99], @mint) }.must_raise
113
+ end
114
+ end
115
+
116
+ describe "torques" do
117
+ it "validates that torques start and end at zero" do
118
+ expect( tc(@minr, @mint) ).must_be_kind_of TorqueCurve
119
+ expect { tc(@minr, [1,0]) }.must_raise
120
+ expect { tc(@minr, [0,1]) }.must_raise
121
+ expect { tc(@minr, [1,1]) }.must_raise
122
+
123
+ expect( tc([1,2,3], [0,500,0]) ).must_be_kind_of TorqueCurve
124
+ expect { tc([1,2,3], [1,500,0]) }.must_raise
125
+ expect { tc([1,2,3], [0,500,1]) }.must_raise
126
+ end
127
+
128
+ it "validates that torques are positive" do
129
+ expect( tc([1,2,3], [0, 5,0]) ).must_be_kind_of TorqueCurve
130
+ expect { tc([1,2,3], [0,-5,0]) }.must_raise
131
+ end
132
+ end
133
+ end
134
+
135
+ it "finds the peak torque and corresponding RPM" do
136
+ rpm, torque = *@default.peak
137
+ expect(rpm).must_be(:>, 1000)
138
+ expect(rpm).must_be(:<, 10_000)
139
+ expect(torque).must_be(:>, 0)
140
+ expect(torque).must_be(:<, 10_000)
141
+ end
142
+
143
+ it "interpolates to find the torque for a valid RPM" do
144
+ tc = tc(@rpms, @torques)
145
+ r1 = @rpms[1]
146
+ r2 = @rpms[2]
147
+
148
+ expect(tc.torque(r1)).must_equal @torques[1]
149
+ expect(tc.torque(r2)).must_equal @torques[2]
150
+
151
+ r3 = (r1 + r2) / 2
152
+ t3 = tc.torque(r3)
153
+ t3_expect = (@torques[1] + @torques[2]) / 2.0
154
+
155
+ expect(t3).must_be :>, @torques[1]
156
+ expect(t3).must_be :<, @torques[2]
157
+ expect(t3).must_be :>=, t3_expect.floor
158
+ expect(t3).must_be :<=, t3_expect.ceil
159
+ end
160
+
161
+ it "tracks min, idle, redline, and max rpms" do
162
+ expect(@default.min).must_be :>, 0
163
+ expect(@default.min).must_be :<, 1000
164
+ expect(@default.idle).must_be :>, @default.min
165
+ expect(@default.idle).must_be :<, 3000
166
+ expect(@default.redline).must_be :>, @default.idle
167
+ expect(@default.redline).must_be :<, 20_000
168
+ expect(@default.max).must_be :>, @default.redline
169
+ expect(@default.max).must_be :<, 20_000
170
+ end
171
+ end
172
+
173
+ describe Motor do
174
+ before do
175
+ @default = Motor.new(Environment.new)
176
+ end
177
+
178
+ it "has a throttle with state" do
179
+ expect(@default.throttle).must_equal 0.0
180
+ @default.throttle = 0.5
181
+ expect(@default.throttle).must_equal 0.5
182
+ expect(@default.throttle_pct).must_equal "50.0%"
183
+
184
+ expect { @default.throttle = 1.5 }.must_raise
185
+ end
186
+
187
+ it "has mass" do
188
+ expect(@default.mass).must_be :>, 0
189
+ expect(@default.fixed_mass).must_be :>, 0
190
+ expect(@default.rotating_mass).must_be :>, 0
191
+ end
192
+
193
+ it "has a torque curve" do
194
+ expect(@default.torque_curve).must_be_kind_of TorqueCurve
195
+ end
196
+
197
+ it "has idle RPM and redline RPM" do
198
+ expect(@default.idle).must_be :>, 500
199
+ expect(@default.idle).must_be :<, 1500
200
+
201
+ expect(@default.redline).must_be :>, @default.idle
202
+ expect(@default.redline).must_be :<, 10_000
203
+ end
204
+
205
+ it "has inertia and energy" do
206
+ expect(@default.inertia).must_be :>, 0
207
+ expect(@default.energy(99)).must_be :>, 0
208
+ end
209
+
210
+ it "determines crank alpha from torque" do
211
+ expect(@default.alpha(50)).must_be :>, 0
212
+ end
213
+
214
+ it "determines torque from crank alpha" do
215
+ a = @default.alpha(50, omega: 20)
216
+ t = @default.implied_torque(a)
217
+ # frictional losses
218
+ expect(t).must_be :>, 40
219
+ expect(t).must_be :<, 50
220
+ end
221
+
222
+ it "determines torque based on torque curve, RPM and throttle" do
223
+ @default.throttle = 1.0
224
+ expect(@default.torque(1000)).must_be :>, 0
225
+ expect(@default.torque(3500)).must_be :>, @default.torque(1000)
226
+ end
227
+
228
+ it "has an engine braking effect when the throttle is closed" do
229
+ @default.throttle = 0
230
+ expect(@default.torque(3500)).must_be :<, 0
231
+ end
232
+
233
+ it "has a starter motor to get running" do
234
+ expect(@default.starter_torque).must_be :>, 0
235
+ end
236
+ end
@@ -0,0 +1,21 @@
1
+ require 'minitest/autorun'
2
+ require 'driving_physics/powertrain'
3
+
4
+ include DrivingPhysics
5
+
6
+ describe Powertrain do
7
+ it "has a motor and a gearbox" do
8
+ end
9
+
10
+ it "has mass" do
11
+ end
12
+
13
+ it "coverts rpm to axle torque" do
14
+ end
15
+
16
+ it "converts rpm to axle omega" do
17
+ end
18
+
19
+ it "determines crank rpm from axle_omega" do
20
+ end
21
+ end
data/test/scalar_force.rb CHANGED
@@ -12,8 +12,7 @@ describe ScalarForce do
12
12
  # ROT_COF's value is from observing that rotational resistance
13
13
  # matches air resistance at roughly 30 m/s in street cars
14
14
  it "approximates a reasonable rotational resistance constant" do
15
- expect(30 * ScalarForce.air_resistance(1)).
16
- must_be_within_epsilon(-1 * ROT_COF)
15
+ _(30 * ScalarForce.air_resistance(1)).must_be_within_epsilon(-1 * ROT_COF)
17
16
  end
18
17
 
19
18
  it "approximates a positive drag force" do
@@ -21,12 +20,10 @@ describe ScalarForce do
21
20
  end
22
21
 
23
22
  it "approximates a positive rotational resistance force" do
24
- expect(ScalarForce.rotational_resistance 30).
25
- must_be_within_epsilon(-383.13)
23
+ _(ScalarForce.rotational_resistance 30).must_be_within_epsilon(-383.13)
26
24
  end
27
25
 
28
26
  it "approximates a positive rolling resistance force" do
29
- nf = 1000 * G
30
- expect(ScalarForce.rolling_resistance nf).must_be_within_epsilon(-98.0)
27
+ _(ScalarForce.rolling_resistance(1000 * G)).must_be_within_epsilon(-98.0)
31
28
  end
32
29
  end
data/test/tire.rb CHANGED
@@ -1,128 +1,94 @@
1
1
  require 'minitest/autorun'
2
2
  require 'driving_physics/tire'
3
+ require 'driving_physics/vector_force'
3
4
 
4
- T = DrivingPhysics::Tire
5
+ include DrivingPhysics
5
6
 
6
- describe T do
7
+ describe Tire do
7
8
  describe "Tire.traction" do
8
9
  it "calculates traction force from normal force and coeff of friction" do
9
10
  scalar_nf = 9800 # N
10
11
  cof = 1.1
11
- scalar_t = T.traction(scalar_nf, cof)
12
+ scalar_t = Tire.traction(scalar_nf, cof)
12
13
  expect(scalar_t).must_equal 10780.0
13
14
 
14
- skip # Vector
15
+ skip unless DrivingPhysics.has_vector?
15
16
  vector_nf = Vector[9800, 0]
16
- vector_t = T.traction(vector_nf, cof)
17
+ vector_t = Tire.traction(vector_nf, cof)
17
18
  expect(vector_t).must_equal Vector[10780.0, 0.0]
18
19
  end
19
20
  end
20
21
 
21
22
  describe "Tire.volume" do
22
23
  it "calculates the volume (m^3) of disk given radius and width" do
23
- cubic_m = T.volume(1.0, 1.0)
24
+ cubic_m = Tire.volume(1.0, 1.0)
24
25
  expect(cubic_m).must_equal Math::PI
25
26
 
26
- cubic_m = T.volume(0.35, 0.2)
27
+ cubic_m = Tire.volume(0.35, 0.2)
27
28
  expect(cubic_m).must_be_within_epsilon 0.076969
28
29
  end
29
30
  end
30
31
 
31
32
  describe "Tire.volume_l" do
32
33
  it "calculates the volume (L) of a disk given radius and width" do
33
- liters = T.volume_l(1.0, 1.0)
34
+ liters = Tire.volume_l(1.0, 1.0)
34
35
  expect(liters).must_equal Math::PI * 1000
35
36
 
36
- liters = T.volume_l(0.35, 0.2)
37
+ liters = Tire.volume_l(0.35, 0.2)
37
38
  expect(liters).must_be_within_epsilon 76.96902
38
39
  end
39
40
  end
40
41
 
41
42
  describe "Tire.density" do
42
43
  it "calculates the density (kg/L) given mass and volume" do
43
- expect(T.density(25.0, 25.0)).must_equal 1.0
44
- expect(T.density(50.0, 25.0)).must_equal 2.0
44
+ expect(Tire.density(25.0, 25.0)).must_equal 1.0
45
+ expect(Tire.density(50.0, 25.0)).must_equal 2.0
45
46
  end
46
47
  end
47
48
 
48
49
  describe "Tire.mass" do
49
50
  it "calculates the mass (kg) of a disk given radius, width, and density" do
50
- expect(T.mass(0.35, 0.2, T::DENSITY)).must_be_within_epsilon 25.015
51
+ expect(Tire.mass(0.35, 0.2, Tire::DENSITY)).must_be_within_epsilon 25.015
51
52
  end
52
53
  end
53
54
 
54
55
  describe "Tire.rotational_inertia" do
55
56
  it "calculates rotational inertia for a disk given radius and mass" do
56
- expect(T.rotational_inertia(0.35, 25.0)).must_be_within_epsilon 1.53125
57
+ expect(Tire.rotational_inertia(0.35, 25.0)).must_be_within_epsilon 1.53125
57
58
  end
58
59
  end
59
60
 
60
61
  describe "Tire.alpha" do
61
62
  it "calculates angular acceleration from torque and inertia" do
62
63
  scalar_torque = 1000
63
- inertia = T.rotational_inertia(0.35, 25.0)
64
- expect(T.alpha scalar_torque, inertia).must_be_within_epsilon 653.061
64
+ inertia = Tire.rotational_inertia(0.35, 25.0)
65
+ expect(Tire.alpha scalar_torque, inertia).must_be_within_epsilon 653.061
65
66
 
66
- skip # Vector
67
+ skip unless DrivingPhysics.has_vector?
67
68
  vector_torque = Vector[0, 0, 1000]
68
- vector_alpha = T.alpha vector_torque, inertia
69
+ vector_alpha = Tire.alpha vector_torque, inertia
69
70
  expect(vector_alpha).must_be_instance_of Vector
70
71
  expect(vector_alpha.size).must_equal 3
71
72
  expect(vector_alpha[2]).must_be_within_epsilon 653.06
72
73
  end
73
74
  end
74
75
 
75
- describe "Tire.torque_vector" do
76
- it "calculates a torque in the 3rd dimension given 2D force and radius" do
77
- skip # Vector
78
- force = Vector[1000, 0]
79
- radius = Vector[0, 5]
80
- torque = T.torque_vector(force, radius)
81
- expect(torque).must_be_instance_of Vector
82
- expect(torque.size).must_equal 3
83
- expect(torque[2]).must_be_within_epsilon 5000.0
84
- end
85
- end
86
-
87
- describe "Tire.force_vector" do
88
- it "calculates a (3D) force given 3D torque and 2D radius" do
89
- # let's invert the Tire.torque_vector case from above:
90
- skip # Vector
91
- torque = Vector[0, 0, 5000]
92
- radius = Vector[0, 5]
93
- force = T.force_vector(torque, radius)
94
- expect(force).must_be_instance_of Vector
95
- expect(force.size).must_equal 3
96
- expect(force[0]).must_be_within_epsilon 1000.0
97
-
98
- # now let's rotate the radius into the x-dimension
99
- # right hand rule, positive torque means thumb into screen, clockwise
100
- # negative-x radius means positive-y force
101
- torque = Vector[0, 0, 500]
102
- radius = Vector[-5, 0]
103
- force = T.force_vector(torque, radius)
104
- expect(force).must_be_instance_of Vector
105
- expect(force.size).must_equal 3
106
- expect(force[1]).must_be_within_epsilon 100.0
107
- end
108
- end
109
-
110
76
  describe "instance methods" do
111
77
  before do
112
78
  @env = DrivingPhysics::Environment.new
113
- @tire = T.new(@env)
79
+ @tire = Tire.new(@env)
114
80
  end
115
81
 
116
82
  it "initializes" do
117
- expect(@tire).must_be_instance_of T
118
- expect(@tire.density).must_equal T::DENSITY # sanity check
83
+ expect(@tire).must_be_instance_of Tire
84
+ expect(@tire.density).must_equal Tire::DENSITY # sanity check
119
85
  expect(@tire.mass).must_be_within_epsilon 25.01
120
86
 
121
- with_mass = T.new(@env) { |w|
87
+ with_mass = Tire.new(@env) { |w|
122
88
  w.mass = 99.01
123
89
  }
124
90
  expect(with_mass.mass).must_equal 99.01
125
- expect(with_mass.density).wont_equal T::DENSITY
91
+ expect(with_mass.density).wont_equal Tire::DENSITY
126
92
  end
127
93
 
128
94
  it "has a string representation" do
@@ -158,7 +124,7 @@ describe T do
158
124
  expect(@tire.traction scalar_nf).must_equal 10780.0
159
125
  expect(@tire.traction scalar_nf, static: false).must_equal 6860.0
160
126
 
161
- skip # Vector
127
+ skip unless DrivingPhysics.has_vector?
162
128
  vector_nf = Vector[9800, 0]
163
129
  expect(@tire.traction vector_nf).must_equal Vector[10780.0, 0.0]
164
130
  expect(@tire.traction vector_nf, static: false).
@@ -178,7 +144,7 @@ describe T do
178
144
  expect(kin_tq).must_be_within_epsilon 2401.0
179
145
 
180
146
  # not sure about how torque vectors work, but the "math" "works":
181
- skip # Vector
147
+ skip unless DrivingPhysics.has_vector?
182
148
  vector_nf = Vector[9800, 0]
183
149
  expect(@tire.tractable_torque(vector_nf)[0]).
184
150
  must_be_within_epsilon 3773.0