driving_physics 0.0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/test/car.rb ADDED
@@ -0,0 +1,156 @@
1
+ require 'minitest/autorun'
2
+ require 'driving_physics/car'
3
+
4
+ C = DrivingPhysics::Car
5
+
6
+ describe C do
7
+ before do
8
+ @env = DrivingPhysics::Environment.new
9
+ @c = C.new(@env)
10
+ end
11
+
12
+ def get_moving
13
+ @c.controls.brake_pedal = 0.0
14
+ @c.controls.drive_pedal = 1.0
15
+ @c.add_fuel 10
16
+ 50.times { @c.tick! }
17
+ expect(@c.condition.speed).must_be :>, 0.0
18
+ end
19
+
20
+
21
+ it "initializes" do
22
+ expect(@c).must_be_instance_of C
23
+ end
24
+
25
+ it "has a string representation" do
26
+ str = @c.to_s
27
+ expect(str).must_be_instance_of String
28
+ expect(str.length).must_be(:>, 5)
29
+ end
30
+
31
+ it "adds fuel and reports overflow" do
32
+ expect(@c.condition.fuel).must_equal 0.0
33
+ @c.add_fuel 10.0
34
+ expect(@c.condition.fuel).must_equal 10.0
35
+ overflow = @c.add_fuel @c.fuel_capacity
36
+ expect(@c.condition.fuel).must_equal @c.fuel_capacity
37
+ expect(overflow).must_equal 10.0
38
+ end
39
+
40
+ it "varies drive_force based on drive_pedal and available fuel" do
41
+ expect(@c.drive_force).must_equal 0.0 # no pedal
42
+ @c.controls.drive_pedal = 1.0
43
+ expect(@c.drive_force).must_equal 0.0 # no fuel
44
+ @c.add_fuel 10
45
+
46
+ expect(@c.drive_force).must_equal @c.max_drive_force # vroom!
47
+ end
48
+
49
+ it "has a drive vector in direction of @dir" do
50
+ @c.add_fuel 10
51
+ @c.controls.drive_pedal = 1.0
52
+ dv = @c.drive_force_vector
53
+ expect(dv).must_be_instance_of Vector
54
+ dvn = dv.normalize
55
+ [0,1].each { |dim|
56
+ expect(dvn[dim]).must_be_within_epsilon @c.condition.dir[dim]
57
+ }
58
+ end
59
+
60
+ it "varies brake_force based on brake_pedal" do
61
+ expect(@c.brake_force).must_equal 0.0 # no pedal
62
+ @c.controls.brake_pedal = 1.0
63
+ expect(@c.brake_force).must_equal @c.max_brake_force
64
+ end
65
+
66
+ it "has a brake vector opposing movement or @dir" do
67
+ # hmm, no good way to go in reverse
68
+ # just test against forward movement for now
69
+ @c.controls.brake_pedal = 1.0
70
+ bv = @c.brake_force_vector
71
+ expect(bv).must_be_instance_of Vector
72
+ bvn = bv.normalize
73
+ [0,1].each { |dim|
74
+ expect(bvn[dim]).must_be_within_epsilon @c.condition.dir[dim] * -1
75
+ }
76
+
77
+ get_moving
78
+
79
+ @c.controls.drive_pedal = 0.0
80
+ @c.controls.brake_pedal = 1.0
81
+ bdir = @c.brake_force_vector.normalize
82
+ vdir = @c.condition.vel.normalize
83
+ [0,1].each { |dim|
84
+ expect(bdir[dim]).must_be_within_epsilon vdir[dim] * -1
85
+ }
86
+ end
87
+
88
+ it "tracks the mass of remaining fuel" do
89
+ expect(@c.fuel_mass).must_equal 0.0
90
+ @c.add_fuel 10
91
+ expect(@c.fuel_mass).must_be_within_epsilon 7.1
92
+ end
93
+
94
+ it "tracks total_mass including fuel and driver" do
95
+ expect(@c.total_mass).must_equal @c.mass + @c.driver_mass
96
+ @c.add_fuel 10
97
+ expect(@c.total_mass).must_equal @c.mass + @c.fuel_mass + @c.driver_mass
98
+ end
99
+
100
+ it "computes the total weight based on G" do
101
+ expect(@c.weight).must_be_within_epsilon 10535.0
102
+ end
103
+
104
+ it "computes resistance forces based on instance variables" do
105
+ air = @c.air_resistance
106
+ expect(air).must_be_kind_of Vector
107
+ expect(air.magnitude).must_equal 0.0
108
+
109
+ rot = @c.rotational_resistance
110
+ expect(rot).must_be_kind_of Vector
111
+ expect(rot.magnitude).must_equal 0.0
112
+
113
+ roll = @c.rolling_resistance
114
+ expect(roll).must_be_kind_of Vector
115
+ expect(roll.magnitude).must_be :>, 0
116
+ end
117
+
118
+ describe C::Condition do
119
+ before do
120
+ @cond = @c.condition
121
+ end
122
+
123
+ it "intializes" do
124
+ expect(@cond).must_be_kind_of C::Condition
125
+ end
126
+
127
+ it "has a string representation" do
128
+ str = @cond.to_s
129
+ expect(str).must_be_kind_of String
130
+ expect(str.length).must_be :>, 5
131
+ end
132
+
133
+ it "has a lateral direction clockwise from @dir" do
134
+ lat = @cond.lat_dir
135
+ expect(lat).must_be_kind_of Vector
136
+ expect(lat.magnitude).must_be_within_epsilon 1.0
137
+ expect(lat.independent?(@cond.dir)).must_equal true
138
+ end
139
+
140
+ it "has a movement_dir based on velocity, or @dir when stopped" do
141
+ md = @cond.movement_dir
142
+ expect(md).must_be_kind_of Vector
143
+ expect(md.magnitude).must_be_within_epsilon 1.0
144
+ expect(md).must_equal @cond.dir
145
+
146
+ get_moving
147
+ md = @cond.movement_dir
148
+ expect(md).must_be_kind_of Vector
149
+ expect(md.magnitude).must_be_within_epsilon 1.0
150
+ vd = @cond.vel.normalize
151
+ [0,1].each { |dim|
152
+ expect(md[dim]).must_be_within_epsilon vd[dim]
153
+ }
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,29 @@
1
+ require 'minitest/autorun'
2
+ require 'driving_physics'
3
+
4
+ describe DrivingPhysics do
5
+ it "displays elapsed ms in a friendly form" do
6
+ expect(DrivingPhysics.elapsed_display 12572358).must_equal "03:29:32.358"
7
+ end
8
+
9
+ it "calculates kph from m/s" do
10
+ expect(DrivingPhysics.kph 23.2).must_equal 83.52
11
+ end
12
+
13
+ describe "Scalar Physics" do
14
+ # these functions also work with vectors
15
+ it "uses F=ma to calculate acceleration given force and mass" do
16
+ expect(DrivingPhysics.acc 7000, 1000).must_equal 7.0
17
+ end
18
+
19
+ it "calculates a new velocity given acceleration" do
20
+ expect(DrivingPhysics.vel 0.0, 7.0).must_be_within_epsilon 0.007
21
+ expect(DrivingPhysics.vel 1.1, 7.1).must_be_within_epsilon 1.1071
22
+ end
23
+
24
+ it "calculates a new position given velocity" do
25
+ expect(DrivingPhysics.pos 0.0, 3.0).must_be_within_epsilon 0.003
26
+ expect(DrivingPhysics.pos 2.2, 3.5).must_be_within_epsilon 2.2035
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ require 'minitest/autorun'
2
+ require 'driving_physics/scalar_force'
3
+
4
+ include DrivingPhysics
5
+
6
+ describe ScalarForce do
7
+ # i.e. multiply this number times speed^2 to approximate drag force
8
+ it "calculates a reasonable drag constant" do
9
+ expect(ScalarForce.air_resistance 1).must_be_within_epsilon DRAG
10
+ end
11
+
12
+ # ROT_COF's value is from observing that rotational resistance
13
+ # matches air resistance at roughly 30 m/s in street cars
14
+ it "approximates a reasonable rotational resistance constant" do
15
+ expect(30 * ScalarForce.air_resistance(1)).must_be_within_epsilon ROT_COF
16
+ end
17
+
18
+ it "approximates a positive drag force" do
19
+ expect(ScalarForce.air_resistance 30).must_be_within_epsilon 383.13
20
+ end
21
+
22
+ it "approximates a positive rotational resistance force" do
23
+ expect(ScalarForce.rotational_resistance 30).must_be_within_epsilon 383.13
24
+ end
25
+
26
+ it "approximates a positive rolling resistance force" do
27
+ nf = 1000 * G
28
+ expect(ScalarForce.rolling_resistance nf).must_be_within_epsilon 98.0
29
+ end
30
+ end
data/test/tire.rb ADDED
@@ -0,0 +1,125 @@
1
+ require 'driving_physics/tire'
2
+ require 'minitest/autorun'
3
+
4
+ include DrivingPhysics
5
+
6
+ describe Tire do
7
+ TP = Tire::TemperatureProfile
8
+
9
+ describe TP do
10
+ before do
11
+ @tp = TP.new
12
+ end
13
+
14
+ it "initializes with two same-sized arrays" do
15
+ expect(@tp).must_be_kind_of TP
16
+ expect(TP.new([0,1,2,3], [0,1.0,0.7,0.4])).wont_be_nil
17
+ expect { TP.new('', '') }.must_raise ArgumentError
18
+ expect { TP.new([]) }.must_raise ArgumentError
19
+ expect { TP.new([0], []) }.must_raise ArgumentError
20
+ expect { TP.new([], [0.0]) }.must_raise ArgumentError
21
+ end
22
+
23
+ it "determines a grip number from a temp number" do
24
+ { -500 => TP::MIN_GRIP,
25
+ -100 => 0.1,
26
+ -0.0001 => 0.1,
27
+ 0.0 => 0.5
28
+ }.each { |temp, gf| expect(@tp.grip_factor(temp)).must_equal gf }
29
+ end
30
+
31
+ it "has a critical_temp above the temp for 100%" do
32
+ expect(@tp.critical_temp).must_be(:>, 90)
33
+ expect(@tp.critical_temp).must_equal 105
34
+ end
35
+
36
+ it "has a map that increases to 100% and decreases below 80%" do
37
+ expect {
38
+ TP.new([0,1,2,3,4], [0.0,0.1,0.2,0.3,0.4])
39
+ }.must_raise TP::Error
40
+
41
+ expect {
42
+ TP.new([0,1,2,3,4], [0.0, 1.0, 0.99, 0.98, 0.97])
43
+ }.must_raise TP::Error
44
+ end
45
+ end
46
+
47
+ before do
48
+ @t = Tire.new
49
+ end
50
+
51
+ it "initializes with default values without a block" do
52
+ expect(@t).must_be_kind_of Tire
53
+ end
54
+
55
+ it "accepts a block to initialize with custom values" do
56
+ t = Tire.new { |x|
57
+ x.tread_mm = 9999
58
+ x.g_factor = -0.1234
59
+ }
60
+
61
+ expect(t.tread_mm).must_equal 9999
62
+ expect(t.g_factor).must_equal(-0.1234)
63
+ end
64
+
65
+ it "knows when the tread is gone" do
66
+ expect(@t.tread_left?).must_equal true
67
+
68
+ @t.condition.tread_mm = 0.00001
69
+ expect(@t.tread_left?).must_equal true
70
+
71
+ @t.condition.tread_mm = 0.0
72
+ expect(@t.tread_left?).must_equal false
73
+ end
74
+
75
+ it "has 50% grip when down to the cords" do
76
+ expect(@t.tread_factor).must_equal 1.0
77
+
78
+ @t.condition.tread_mm = 0.0
79
+ expect(@t.tread_factor).must_be_within_epsilon 0.5
80
+ end
81
+
82
+ it "has less than 10% tread factor when the cords start to wear" do
83
+ expect(@t.tread_factor).must_equal 1.0
84
+
85
+ @t.condition.tread_mm = 5.0
86
+ expect(@t.tread_factor).must_equal 1.0
87
+
88
+ @t.condition.tread_mm = 0.0
89
+ expect(@t.tread_factor).must_be_within_epsilon 0.5
90
+
91
+ @t.condition.cords_mm = 0.9
92
+ expect(@t.tread_factor).must_be_within_epsilon 0.45
93
+ end
94
+
95
+ it "has decreasing heat cycle factor" do
96
+ expect(@t.condition.heat_cycles).must_equal 0
97
+ expect(@t.heat_cycle_factor).must_equal 1.0
98
+
99
+ @t.condition.heat_cycles = 20
100
+ expect(@t.heat_cycle_factor).must_be(:<, 1.0)
101
+ end
102
+
103
+ it "has a temp factor according to temperature profile" do
104
+ expect(@t.condition.temp_c).must_equal 25
105
+ expect(@t.temp_factor).must_equal 0.75
106
+
107
+ @t.condition.temp_c = 90
108
+ expect(@t.temp_factor).must_equal 1.0
109
+ end
110
+
111
+ it "incorporates temp, heat_cycles, and tread depth into available grip" do
112
+ @t.condition.temp_c = 60
113
+ expect(@t.temp_factor).must_be_within_epsilon 0.8
114
+
115
+ @t.condition.heat_cycles = 10
116
+ expect(@t.heat_cycle_factor).must_be_within_epsilon 0.96
117
+
118
+ @t.condition.tread_mm = 5.0
119
+ expect(@t.tread_factor).must_equal 1.0
120
+ expect(@t.max_g).must_be_within_epsilon 0.768
121
+
122
+ @t.condition.tread_mm = 0.0
123
+ expect(@t.max_g).must_be_within_epsilon 0.384
124
+ end
125
+ end
@@ -0,0 +1,90 @@
1
+ require 'minitest/autorun'
2
+ require 'driving_physics/vector_force'
3
+
4
+ include DrivingPhysics
5
+
6
+ describe VectorForce do
7
+ before do
8
+ @drive_force = Vector[7000.0, 0.0]
9
+ @v = Vector[3.0, 0]
10
+ @mass = 1000
11
+ @weight = @mass * G
12
+ end
13
+
14
+ it "generates uniformly random numbers centered on zero" do
15
+ hsh = {}
16
+ 110_000.times {
17
+ num = DrivingPhysics.random_centered_zero(5)
18
+ hsh[num] ||= 0
19
+ hsh[num] += 1
20
+ }
21
+ # note, this will fail occasionally due to chance
22
+ hsh.values.each { |count|
23
+ expect(count).must_be(:>=, 9000)
24
+ expect(count).must_be(:<=, 11000)
25
+ }
26
+ end
27
+
28
+ it "coerces magnitude=0 to magnitude=1" do
29
+ a = Array.new(999) { DrivingPhysics.random_centered_zero(0) }
30
+ expect(a.all? { |i| i == 0 }).must_equal false
31
+ end
32
+
33
+ it "generates a random unit vector" do
34
+ low_res = DrivingPhysics.random_unit_vector(2, resolution: 1)
35
+ if low_res[0] == 0.0
36
+ expect(low_res[1].abs).must_equal 1.0
37
+ elsif low_res[0].abs == 1.0
38
+ expect(low_res[1]).must_equal 0.0
39
+ elsif low_res[0].abs.round(3) == 0.707
40
+ expect(low_res[1].abs.round(3)) == 0.707
41
+ else
42
+ p low_res
43
+ raise "unexpected"
44
+ end
45
+
46
+ 9.times {
47
+ high_res = DrivingPhysics.random_unit_vector(3, resolution: 9)
48
+ expect(high_res.magnitude).must_be_within_epsilon 1.0
49
+ }
50
+ end
51
+
52
+ it "calculates air resistance as the square of velocity" do
53
+ df = VectorForce.air_resistance(@v,
54
+ frontal_area: 3,
55
+ drag_cof: 0.1,
56
+ air_density: 0.5)
57
+
58
+ # double the velocity, drag force goes up by 4
59
+ df2 = VectorForce.air_resistance(@v * 2,
60
+ frontal_area: 3,
61
+ drag_cof: 0.1,
62
+ air_density: 0.5)
63
+
64
+ expect(df2).must_equal df * 4
65
+ end
66
+
67
+ it "calculates the rolling resistance as a function of the normal force" do
68
+ rr = VectorForce.rolling_resistance(@weight, dir: @v)
69
+
70
+ # double the normal force, rolling resistance goes up by 2 (linear)
71
+ rr2 = VectorForce.rolling_resistance(@weight * 2, dir: @v)
72
+
73
+ expect(rr2).must_equal rr * 2
74
+ end
75
+
76
+ it "calculates the rotational resistance as a function of velocity" do
77
+ rr = VectorForce.rotational_resistance(@v)
78
+ rr2 = VectorForce.rotational_resistance(@v * 2)
79
+ expect(rr2).must_equal rr * 2
80
+ end
81
+
82
+ it "sums resistance forces" do
83
+ rf = VectorForce.all_resistance(@v, dir: @v, nf_mag: @weight)
84
+ # opposite direction
85
+ expect(rf.normalize).must_equal(-1 * @v.normalize)
86
+
87
+ # smaller magnitude
88
+ expect(rf.magnitude).must_be(:<, @drive_force.magnitude)
89
+ end
90
+ end
data/test/wheel.rb ADDED
@@ -0,0 +1,177 @@
1
+ require 'minitest/autorun'
2
+ require 'driving_physics/wheel'
3
+
4
+ W = DrivingPhysics::Wheel
5
+
6
+ describe W do
7
+ describe "Wheel.traction" do
8
+ it "calculates traction force from normal force and coeff of friction" do
9
+ scalar_nf = 9800 # N
10
+ cof = 1.1
11
+ scalar_t = W.traction(scalar_nf, cof)
12
+ expect(scalar_t).must_equal 10780.0
13
+
14
+ vector_nf = Vector[9800, 0]
15
+ vector_t = W.traction(vector_nf, cof)
16
+ expect(vector_t).must_equal Vector[10780.0, 0.0]
17
+ end
18
+ end
19
+
20
+ describe "Wheel.volume" do
21
+ it "calculates the volume (m^3) of disk given radius and width" do
22
+ cubic_m = W.volume(1.0, 1.0)
23
+ expect(cubic_m).must_equal Math::PI
24
+
25
+ cubic_m = W.volume(0.35, 0.2)
26
+ expect(cubic_m).must_be_within_epsilon 0.076969
27
+ end
28
+ end
29
+
30
+ describe "Wheel.volume_l" do
31
+ it "calculates the volume (L) of a disk given radius and width" do
32
+ liters = W.volume_l(1.0, 1.0)
33
+ expect(liters).must_equal Math::PI * 1000
34
+
35
+ liters = W.volume_l(0.35, 0.2)
36
+ expect(liters).must_be_within_epsilon 76.96902
37
+ end
38
+ end
39
+
40
+ describe "Wheel.density" do
41
+ it "calculates the density (kg/L) given mass and volume" do
42
+ expect(W.density(25.0, 25.0)).must_equal 1.0
43
+ expect(W.density(50.0, 25.0)).must_equal 2.0
44
+ end
45
+ end
46
+
47
+ describe "Wheel.mass" do
48
+ it "calculates the mass (kg) of a disk given radius, width, and density" do
49
+ expect(W.mass(0.35, 0.2, W::DENSITY)).must_be_within_epsilon 25.015
50
+ end
51
+ end
52
+
53
+ describe "Wheel.rotational_inertia" do
54
+ it "calculates rotational inertia for a disk given radius and mass" do
55
+ expect(W.rotational_inertia(0.35, 25.0)).must_be_within_epsilon 1.53125
56
+ end
57
+ end
58
+
59
+ describe "Wheel.alpha" do
60
+ it "calculates angular acceleration from torque and inertia" do
61
+ scalar_torque = 1000
62
+ inertia = W.rotational_inertia(0.35, 25.0)
63
+ expect(W.alpha scalar_torque, inertia).must_be_within_epsilon 653.061
64
+
65
+ vector_torque = Vector[0, 0, 1000]
66
+ vector_alpha = W.alpha vector_torque, inertia
67
+ expect(vector_alpha).must_be_instance_of Vector
68
+ expect(vector_alpha.size).must_equal 3
69
+ expect(vector_alpha[2]).must_be_within_epsilon 653.06
70
+ end
71
+ end
72
+
73
+ describe "Wheel.torque_vector" do
74
+ it "calculates a torque in the 3rd dimension given 2D force and radius" do
75
+ force = Vector[1000, 0]
76
+ radius = Vector[0, 5]
77
+ torque = W.torque_vector(force, radius)
78
+ expect(torque).must_be_instance_of Vector
79
+ expect(torque.size).must_equal 3
80
+ expect(torque[2]).must_be_within_epsilon 5000.0
81
+ end
82
+ end
83
+
84
+ describe "Wheel.force_vector" do
85
+ it "calculates a (3D) force given 3D torque and 2D radius" do
86
+ # let's invert the Wheel.torque_vector case from above:
87
+ torque = Vector[0, 0, 5000]
88
+ radius = Vector[0, 5]
89
+ force = W.force_vector(torque, radius)
90
+ expect(force).must_be_instance_of Vector
91
+ expect(force.size).must_equal 3
92
+ expect(force[0]).must_be_within_epsilon 1000.0
93
+
94
+ # now let's rotate the radius into the x-dimension
95
+ # right hand rule, positive torque means thumb into screen, clockwise
96
+ # negative-x radius means positive-y force
97
+ torque = Vector[0, 0, 500]
98
+ radius = Vector[-5, 0]
99
+ force = W.force_vector(torque, radius)
100
+ expect(force).must_be_instance_of Vector
101
+ expect(force.size).must_equal 3
102
+ expect(force[1]).must_be_within_epsilon 100.0
103
+ end
104
+ end
105
+
106
+ describe "instance methods" do
107
+ before do
108
+ @env = DrivingPhysics::Environment.new
109
+ @w = W.new(@env)
110
+ end
111
+
112
+ it "initializes" do
113
+ expect(@w).must_be_instance_of W
114
+ expect(@w.density).must_equal W::DENSITY # sanity check
115
+ expect(@w.mass).must_be_within_epsilon 25.01
116
+
117
+ with_mass = W.new(@env, mass: 99.01)
118
+ expect(with_mass.mass).must_equal 99.01
119
+ expect(with_mass.density).wont_equal W::DENSITY
120
+ end
121
+
122
+ it "has a string representation" do
123
+ str = @w.to_s
124
+ expect(str).must_be_instance_of String
125
+ expect(str.length).must_be(:>, 5)
126
+ end
127
+
128
+ it "loses radius as it wears" do
129
+ expect(@w.radius).must_equal 350.0
130
+ @w.wear!(50)
131
+ expect(@w.radius).must_equal 300.0
132
+ end
133
+
134
+ it "calculates mass from current radius" do
135
+ expect(@w.mass).must_be_within_epsilon 25.01
136
+ @w.wear!(50)
137
+ expect(@w.mass).must_be_within_epsilon 18.378
138
+ end
139
+
140
+ it "has volume" do
141
+ expect(@w.volume).must_be_within_epsilon 0.07697
142
+ expect(@w.volume_l).must_be_within_epsilon 76.96902
143
+ end
144
+
145
+ it "has inertia" do
146
+ expect(@w.rotational_inertia).must_be_within_epsilon 1.5321
147
+ end
148
+
149
+ it "has traction force based on normal force" do
150
+ scalar_nf = 9800
151
+ expect(@w.traction scalar_nf).must_equal 10780.0
152
+ expect(@w.traction scalar_nf, static: false).must_equal 6860.0
153
+
154
+ vector_nf = Vector[9800, 0]
155
+ expect(@w.traction vector_nf).must_equal Vector[10780.0, 0.0]
156
+ expect(@w.traction vector_nf, static: false).
157
+ must_equal Vector[6860.0, 0.0]
158
+ end
159
+
160
+ it "determines (e.g. thrust) force based on axle torque" do
161
+ expect(@w.force 1000).must_be_within_epsilon 2857.143
162
+ @w.wear! 50
163
+ expect(@w.force 1000).must_be_within_epsilon 3333.333
164
+ end
165
+
166
+ it "determines tractable torque" do
167
+ scalar_nf = 9800
168
+ expect(@w.tractable_torque scalar_nf).must_be_within_epsilon 3773.0
169
+ kin_tq = @w.tractable_torque scalar_nf, static: false
170
+ expect(kin_tq).must_be_within_epsilon 2401.0
171
+
172
+ # not sure about how torque vectors work, but the "math" "works":
173
+ vector_nf = Vector[9800, 0]
174
+ expect(@w.tractable_torque(vector_nf)[0]).must_be_within_epsilon 3773.0
175
+ end
176
+ end
177
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: driving_physics
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Rick Hull
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 1980-01-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: WIP
14
+ email:
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.md
20
+ - Rakefile
21
+ - VERSION
22
+ - demo/car.rb
23
+ - demo/scalar_force.rb
24
+ - demo/tire.rb
25
+ - demo/vector_force.rb
26
+ - demo/wheel.rb
27
+ - driving_physics.gemspec
28
+ - lib/driving_physics.rb
29
+ - lib/driving_physics/car.rb
30
+ - lib/driving_physics/environment.rb
31
+ - lib/driving_physics/imperial.rb
32
+ - lib/driving_physics/scalar_force.rb
33
+ - lib/driving_physics/tire.rb
34
+ - lib/driving_physics/vector_force.rb
35
+ - lib/driving_physics/wheel.rb
36
+ - test/car.rb
37
+ - test/driving_physics.rb
38
+ - test/scalar_force.rb
39
+ - test/tire.rb
40
+ - test/vector_force.rb
41
+ - test/wheel.rb
42
+ homepage: https://github.com/rickhull/driving_physics
43
+ licenses:
44
+ - LGPL-3.0
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: '2'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubygems_version: 3.2.26
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: WIP
65
+ test_files: []