driving_physics 0.0.0.3 → 0.0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -1
- data/VERSION +1 -1
- data/demo/car.rb +153 -0
- data/demo/disk.rb +76 -0
- data/demo/gearbox.rb +47 -0
- data/demo/motor.rb +89 -0
- data/demo/powertrain.rb +40 -0
- data/demo/scalar_force.rb +3 -3
- data/demo/tire.rb +88 -0
- data/demo/vector_force.rb +3 -3
- data/lib/driving_physics/car.rb +103 -0
- data/lib/driving_physics/cli.rb +17 -0
- data/lib/driving_physics/disk.rb +184 -0
- data/lib/driving_physics/gearbox.rb +109 -0
- data/lib/driving_physics/motor.rb +99 -0
- data/lib/driving_physics/power.rb +20 -0
- data/lib/driving_physics/powertrain.rb +39 -0
- data/lib/driving_physics/tire.rb +120 -0
- data/lib/driving_physics/vector_force.rb +15 -2
- data/lib/driving_physics.rb +1 -0
- data/test/disk.rb +129 -0
- data/test/{wheel.rb → tire.rb} +59 -55
- data/test/vector_force.rb +7 -1
- metadata +17 -4
- data/demo/wheel.rb +0 -84
- data/lib/driving_physics/wheel.rb +0 -191
data/test/disk.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'driving_physics/disk'
|
3
|
+
|
4
|
+
D = DrivingPhysics::Disk
|
5
|
+
|
6
|
+
describe D do
|
7
|
+
describe "Disk.volume" do
|
8
|
+
it "calculates the volume (m^3) of disk given radius and width" do
|
9
|
+
cubic_m = D.volume(1.0, 1.0)
|
10
|
+
expect(cubic_m).must_equal Math::PI
|
11
|
+
|
12
|
+
cubic_m = D.volume(0.35, 0.2)
|
13
|
+
expect(cubic_m).must_be_within_epsilon 0.076969
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "Disk.volume_l" do
|
18
|
+
it "calculates the volume (L) of a disk given radius and width" do
|
19
|
+
liters = D.volume_l(1.0, 1.0)
|
20
|
+
expect(liters).must_equal Math::PI * 1000
|
21
|
+
|
22
|
+
liters = D.volume_l(0.35, 0.2)
|
23
|
+
expect(liters).must_be_within_epsilon 76.96902
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "Disk.density" do
|
28
|
+
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
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "Disk.mass" do
|
35
|
+
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
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "Disk.rotational_inertia" do
|
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
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "Disk.alpha" do
|
48
|
+
it "calculates angular acceleration from torque and inertia" do
|
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
|
52
|
+
|
53
|
+
vector_torque = Vector[0, 0, 1000]
|
54
|
+
vector_alpha = D.alpha vector_torque, inertia
|
55
|
+
expect(vector_alpha).must_be_instance_of Vector
|
56
|
+
expect(vector_alpha.size).must_equal 3
|
57
|
+
expect(vector_alpha[2]).must_be_within_epsilon 653.06
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "Disk.torque_vector" do
|
62
|
+
it "calculates a torque in the 3rd dimension given 2D force and radius" do
|
63
|
+
force = Vector[1000, 0]
|
64
|
+
radius = Vector[0, 5]
|
65
|
+
torque = D.torque_vector(force, radius)
|
66
|
+
expect(torque).must_be_instance_of Vector
|
67
|
+
expect(torque.size).must_equal 3
|
68
|
+
expect(torque[2]).must_be_within_epsilon 5000.0
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "Disk.force_vector" do
|
73
|
+
it "calculates a (3D) force given 3D torque and 2D radius" do
|
74
|
+
# let's invert the Disk.torque_vector case from above:
|
75
|
+
torque = Vector[0, 0, 5000]
|
76
|
+
radius = Vector[0, 5]
|
77
|
+
force = D.force_vector(torque, radius)
|
78
|
+
expect(force).must_be_instance_of Vector
|
79
|
+
expect(force.size).must_equal 3
|
80
|
+
expect(force[0]).must_be_within_epsilon 1000.0
|
81
|
+
|
82
|
+
# now let's rotate the radius into the x-dimension
|
83
|
+
# right hand rule, positive torque means thumb into screen, clockwise
|
84
|
+
# negative-x radius means positive-y force
|
85
|
+
torque = Vector[0, 0, 500]
|
86
|
+
radius = Vector[-5, 0]
|
87
|
+
force = D.force_vector(torque, radius)
|
88
|
+
expect(force).must_be_instance_of Vector
|
89
|
+
expect(force.size).must_equal 3
|
90
|
+
expect(force[1]).must_be_within_epsilon 100.0
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "instance methods" do
|
95
|
+
before do
|
96
|
+
@env = DrivingPhysics::Environment.new
|
97
|
+
@disk = D.new(@env)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "initializes" do
|
101
|
+
skip
|
102
|
+
expect(@disk).must_be_instance_of D
|
103
|
+
expect(@disk.density).must_equal D::DENSITY # sanity check
|
104
|
+
expect(@disk.mass).must_be_within_epsilon 25.01
|
105
|
+
|
106
|
+
with_mass = D.new(@env) { |w|
|
107
|
+
w.mass = 99.01
|
108
|
+
}
|
109
|
+
expect(with_mass.mass).must_equal 99.01
|
110
|
+
expect(with_mass.density).wont_equal D::DENSITY
|
111
|
+
end
|
112
|
+
|
113
|
+
it "has a string representation" do
|
114
|
+
str = @disk.to_s
|
115
|
+
expect(str).must_be_instance_of String
|
116
|
+
expect(str.length).must_be(:>, 5)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "has volume" do
|
120
|
+
expect(@disk.volume).must_be_within_epsilon 0.07697
|
121
|
+
expect(@disk.volume_l).must_be_within_epsilon 76.96902
|
122
|
+
end
|
123
|
+
|
124
|
+
it "has inertia" do
|
125
|
+
skip
|
126
|
+
expect(@disk.rotational_inertia).must_be_within_epsilon 1.5321
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/test/{wheel.rb → tire.rb}
RENAMED
@@ -1,92 +1,92 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
|
-
require 'driving_physics/
|
2
|
+
require 'driving_physics/tire'
|
3
3
|
|
4
|
-
|
4
|
+
T = DrivingPhysics::Tire
|
5
5
|
|
6
|
-
describe
|
7
|
-
describe "
|
6
|
+
describe T do
|
7
|
+
describe "Tire.traction" do
|
8
8
|
it "calculates traction force from normal force and coeff of friction" do
|
9
9
|
scalar_nf = 9800 # N
|
10
10
|
cof = 1.1
|
11
|
-
scalar_t =
|
11
|
+
scalar_t = T.traction(scalar_nf, cof)
|
12
12
|
expect(scalar_t).must_equal 10780.0
|
13
13
|
|
14
14
|
vector_nf = Vector[9800, 0]
|
15
|
-
vector_t =
|
15
|
+
vector_t = T.traction(vector_nf, cof)
|
16
16
|
expect(vector_t).must_equal Vector[10780.0, 0.0]
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
describe "
|
20
|
+
describe "Tire.volume" do
|
21
21
|
it "calculates the volume (m^3) of disk given radius and width" do
|
22
|
-
cubic_m =
|
22
|
+
cubic_m = T.volume(1.0, 1.0)
|
23
23
|
expect(cubic_m).must_equal Math::PI
|
24
24
|
|
25
|
-
cubic_m =
|
25
|
+
cubic_m = T.volume(0.35, 0.2)
|
26
26
|
expect(cubic_m).must_be_within_epsilon 0.076969
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
describe "
|
30
|
+
describe "Tire.volume_l" do
|
31
31
|
it "calculates the volume (L) of a disk given radius and width" do
|
32
|
-
liters =
|
32
|
+
liters = T.volume_l(1.0, 1.0)
|
33
33
|
expect(liters).must_equal Math::PI * 1000
|
34
34
|
|
35
|
-
liters =
|
35
|
+
liters = T.volume_l(0.35, 0.2)
|
36
36
|
expect(liters).must_be_within_epsilon 76.96902
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
describe "
|
40
|
+
describe "Tire.density" do
|
41
41
|
it "calculates the density (kg/L) given mass and volume" do
|
42
|
-
expect(
|
43
|
-
expect(
|
42
|
+
expect(T.density(25.0, 25.0)).must_equal 1.0
|
43
|
+
expect(T.density(50.0, 25.0)).must_equal 2.0
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
describe "
|
47
|
+
describe "Tire.mass" do
|
48
48
|
it "calculates the mass (kg) of a disk given radius, width, and density" do
|
49
|
-
expect(
|
49
|
+
expect(T.mass(0.35, 0.2, T::DENSITY)).must_be_within_epsilon 25.015
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
describe "
|
53
|
+
describe "Tire.rotational_inertia" do
|
54
54
|
it "calculates rotational inertia for a disk given radius and mass" do
|
55
|
-
expect(
|
55
|
+
expect(T.rotational_inertia(0.35, 25.0)).must_be_within_epsilon 1.53125
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
describe "
|
59
|
+
describe "Tire.alpha" do
|
60
60
|
it "calculates angular acceleration from torque and inertia" do
|
61
61
|
scalar_torque = 1000
|
62
|
-
inertia =
|
63
|
-
expect(
|
62
|
+
inertia = T.rotational_inertia(0.35, 25.0)
|
63
|
+
expect(T.alpha scalar_torque, inertia).must_be_within_epsilon 653.061
|
64
64
|
|
65
65
|
vector_torque = Vector[0, 0, 1000]
|
66
|
-
vector_alpha =
|
66
|
+
vector_alpha = T.alpha vector_torque, inertia
|
67
67
|
expect(vector_alpha).must_be_instance_of Vector
|
68
68
|
expect(vector_alpha.size).must_equal 3
|
69
69
|
expect(vector_alpha[2]).must_be_within_epsilon 653.06
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
describe "
|
73
|
+
describe "Tire.torque_vector" do
|
74
74
|
it "calculates a torque in the 3rd dimension given 2D force and radius" do
|
75
75
|
force = Vector[1000, 0]
|
76
76
|
radius = Vector[0, 5]
|
77
|
-
torque =
|
77
|
+
torque = T.torque_vector(force, radius)
|
78
78
|
expect(torque).must_be_instance_of Vector
|
79
79
|
expect(torque.size).must_equal 3
|
80
80
|
expect(torque[2]).must_be_within_epsilon 5000.0
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
describe "
|
84
|
+
describe "Tire.force_vector" do
|
85
85
|
it "calculates a (3D) force given 3D torque and 2D radius" do
|
86
|
-
# let's invert the
|
86
|
+
# let's invert the Tire.torque_vector case from above:
|
87
87
|
torque = Vector[0, 0, 5000]
|
88
88
|
radius = Vector[0, 5]
|
89
|
-
force =
|
89
|
+
force = T.force_vector(torque, radius)
|
90
90
|
expect(force).must_be_instance_of Vector
|
91
91
|
expect(force.size).must_equal 3
|
92
92
|
expect(force[0]).must_be_within_epsilon 1000.0
|
@@ -96,7 +96,7 @@ describe W do
|
|
96
96
|
# negative-x radius means positive-y force
|
97
97
|
torque = Vector[0, 0, 500]
|
98
98
|
radius = Vector[-5, 0]
|
99
|
-
force =
|
99
|
+
force = T.force_vector(torque, radius)
|
100
100
|
expect(force).must_be_instance_of Vector
|
101
101
|
expect(force.size).must_equal 3
|
102
102
|
expect(force[1]).must_be_within_epsilon 100.0
|
@@ -106,72 +106,76 @@ describe W do
|
|
106
106
|
describe "instance methods" do
|
107
107
|
before do
|
108
108
|
@env = DrivingPhysics::Environment.new
|
109
|
-
@
|
109
|
+
@tire = T.new(@env)
|
110
110
|
end
|
111
111
|
|
112
112
|
it "initializes" do
|
113
|
-
expect(@
|
114
|
-
expect(@
|
115
|
-
expect(@
|
113
|
+
expect(@tire).must_be_instance_of T
|
114
|
+
expect(@tire.density).must_equal T::DENSITY # sanity check
|
115
|
+
expect(@tire.mass).must_be_within_epsilon 25.01
|
116
116
|
|
117
|
-
with_mass =
|
117
|
+
with_mass = T.new(@env) { |w|
|
118
|
+
w.mass = 99.01
|
119
|
+
}
|
118
120
|
expect(with_mass.mass).must_equal 99.01
|
119
|
-
expect(with_mass.density).wont_equal
|
121
|
+
expect(with_mass.density).wont_equal T::DENSITY
|
120
122
|
end
|
121
123
|
|
122
124
|
it "has a string representation" do
|
123
|
-
str = @
|
125
|
+
str = @tire.to_s
|
124
126
|
expect(str).must_be_instance_of String
|
125
127
|
expect(str.length).must_be(:>, 5)
|
126
128
|
end
|
127
129
|
|
128
130
|
it "loses radius as it wears" do
|
129
|
-
|
130
|
-
|
131
|
-
|
131
|
+
old_r = @tire.radius
|
132
|
+
wear_amt = 50/1000r
|
133
|
+
@tire.wear! wear_amt
|
134
|
+
expect(@tire.radius).must_equal old_r - wear_amt
|
132
135
|
end
|
133
136
|
|
134
137
|
it "calculates mass from current radius" do
|
135
|
-
expect(@
|
136
|
-
@
|
137
|
-
expect(@
|
138
|
+
expect(@tire.mass).must_be_within_epsilon 25.01
|
139
|
+
@tire.wear!(50/1000r)
|
140
|
+
expect(@tire.mass).must_be_within_epsilon 18.378
|
138
141
|
end
|
139
142
|
|
140
143
|
it "has volume" do
|
141
|
-
expect(@
|
142
|
-
expect(@
|
144
|
+
expect(@tire.volume).must_be_within_epsilon 0.07697
|
145
|
+
expect(@tire.volume_l).must_be_within_epsilon 76.96902
|
143
146
|
end
|
144
147
|
|
145
148
|
it "has inertia" do
|
146
|
-
expect(@
|
149
|
+
expect(@tire.rotational_inertia).must_be_within_epsilon 1.5321
|
147
150
|
end
|
148
151
|
|
149
152
|
it "has traction force based on normal force" do
|
150
153
|
scalar_nf = 9800
|
151
|
-
expect(@
|
152
|
-
expect(@
|
154
|
+
expect(@tire.traction scalar_nf).must_equal 10780.0
|
155
|
+
expect(@tire.traction scalar_nf, static: false).must_equal 6860.0
|
153
156
|
|
154
157
|
vector_nf = Vector[9800, 0]
|
155
|
-
expect(@
|
156
|
-
expect(@
|
158
|
+
expect(@tire.traction vector_nf).must_equal Vector[10780.0, 0.0]
|
159
|
+
expect(@tire.traction vector_nf, static: false).
|
157
160
|
must_equal Vector[6860.0, 0.0]
|
158
161
|
end
|
159
162
|
|
160
163
|
it "determines (e.g. thrust) force based on axle torque" do
|
161
|
-
expect(@
|
162
|
-
@
|
163
|
-
expect(@
|
164
|
+
expect(@tire.force 1000).must_be_within_epsilon 2857.143
|
165
|
+
@tire.wear! 50/1000r
|
166
|
+
expect(@tire.force 1000).must_be_within_epsilon 3333.333
|
164
167
|
end
|
165
168
|
|
166
169
|
it "determines tractable torque" do
|
167
170
|
scalar_nf = 9800
|
168
|
-
expect(@
|
169
|
-
kin_tq = @
|
171
|
+
expect(@tire.tractable_torque scalar_nf).must_be_within_epsilon 3773.0
|
172
|
+
kin_tq = @tire.tractable_torque scalar_nf, static: false
|
170
173
|
expect(kin_tq).must_be_within_epsilon 2401.0
|
171
174
|
|
172
175
|
# not sure about how torque vectors work, but the "math" "works":
|
173
176
|
vector_nf = Vector[9800, 0]
|
174
|
-
expect(@
|
177
|
+
expect(@tire.tractable_torque(vector_nf)[0]).
|
178
|
+
must_be_within_epsilon 3773.0
|
175
179
|
end
|
176
180
|
end
|
177
181
|
end
|
data/test/vector_force.rb
CHANGED
@@ -74,9 +74,15 @@ describe VectorForce do
|
|
74
74
|
end
|
75
75
|
|
76
76
|
it "calculates the rotational resistance as a function of velocity" do
|
77
|
+
rr = VectorForce.rotational_resistance(@v, rot_const: 0)
|
78
|
+
rr2 = VectorForce.rotational_resistance(@v * 2, rot_const: 0)
|
79
|
+
expect(rr2).must_equal rr * 2
|
80
|
+
|
81
|
+
# now with rot_const != 0, the relationship is skewed
|
77
82
|
rr = VectorForce.rotational_resistance(@v)
|
78
83
|
rr2 = VectorForce.rotational_resistance(@v * 2)
|
79
|
-
expect(rr2).
|
84
|
+
expect(rr2).wont_equal rr * 2 # because of rot_const
|
85
|
+
expect(rr2.magnitude).must_be(:<, (rr * 2).magnitude)
|
80
86
|
end
|
81
87
|
|
82
88
|
it "sums resistance forces" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: driving_physics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Hull
|
@@ -19,20 +19,33 @@ files:
|
|
19
19
|
- README.md
|
20
20
|
- Rakefile
|
21
21
|
- VERSION
|
22
|
+
- demo/car.rb
|
23
|
+
- demo/disk.rb
|
24
|
+
- demo/gearbox.rb
|
25
|
+
- demo/motor.rb
|
26
|
+
- demo/powertrain.rb
|
22
27
|
- demo/scalar_force.rb
|
28
|
+
- demo/tire.rb
|
23
29
|
- demo/vector_force.rb
|
24
|
-
- demo/wheel.rb
|
25
30
|
- driving_physics.gemspec
|
26
31
|
- lib/driving_physics.rb
|
32
|
+
- lib/driving_physics/car.rb
|
33
|
+
- lib/driving_physics/cli.rb
|
34
|
+
- lib/driving_physics/disk.rb
|
27
35
|
- lib/driving_physics/environment.rb
|
36
|
+
- lib/driving_physics/gearbox.rb
|
28
37
|
- lib/driving_physics/imperial.rb
|
38
|
+
- lib/driving_physics/motor.rb
|
39
|
+
- lib/driving_physics/power.rb
|
40
|
+
- lib/driving_physics/powertrain.rb
|
29
41
|
- lib/driving_physics/scalar_force.rb
|
42
|
+
- lib/driving_physics/tire.rb
|
30
43
|
- lib/driving_physics/vector_force.rb
|
31
|
-
-
|
44
|
+
- test/disk.rb
|
32
45
|
- test/driving_physics.rb
|
33
46
|
- test/scalar_force.rb
|
47
|
+
- test/tire.rb
|
34
48
|
- test/vector_force.rb
|
35
|
-
- test/wheel.rb
|
36
49
|
homepage: https://github.com/rickhull/driving_physics
|
37
50
|
licenses:
|
38
51
|
- LGPL-3.0
|
data/demo/wheel.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'driving_physics/wheel'
|
2
|
-
|
3
|
-
include DrivingPhysics
|
4
|
-
|
5
|
-
env = Environment.new
|
6
|
-
wheel = Wheel.new(env, mass: 25.0)
|
7
|
-
|
8
|
-
puts env
|
9
|
-
puts wheel
|
10
|
-
|
11
|
-
# 1000 kg car
|
12
|
-
# 4 tires
|
13
|
-
# 250 kg per tire plus tire mass
|
14
|
-
|
15
|
-
supported_mass = 1000 # kg
|
16
|
-
total_mass = supported_mass + 4 * wheel.mass
|
17
|
-
corner_mass = Rational(total_mass) / 4
|
18
|
-
normal_force = corner_mass * env.g
|
19
|
-
axle_torque = 1000 # N*m
|
20
|
-
friction_loss = 0.05 # 5% friction / hysteresis loss
|
21
|
-
|
22
|
-
puts [format("Corner mass: %d kg", corner_mass),
|
23
|
-
format("Normal force: %.1f N", normal_force),
|
24
|
-
format("Axle torque: %d Nm", axle_torque),
|
25
|
-
].join("\n")
|
26
|
-
puts
|
27
|
-
|
28
|
-
traction = wheel.traction(normal_force)
|
29
|
-
drive_force = wheel.force(axle_torque)
|
30
|
-
inertial_loss = wheel.inertial_loss(axle_torque, supported_mass)
|
31
|
-
friction_loss *= axle_torque # 5% of the axle torque
|
32
|
-
|
33
|
-
# drive force = (axle torque - inertia - friction) limited by traction
|
34
|
-
|
35
|
-
net_axle_torque = axle_torque - inertial_loss - friction_loss
|
36
|
-
net_drive_force = wheel.force(net_axle_torque)
|
37
|
-
net_drive_force = traction if net_drive_force > traction # traction limited
|
38
|
-
|
39
|
-
acc = DrivingPhysics.acc(net_drive_force, supported_mass) # translational
|
40
|
-
|
41
|
-
puts [format("Traction: %.1f N", traction),
|
42
|
-
format("Drive force: %.1f N", drive_force),
|
43
|
-
format("Inertial loss: %.1f Nm", inertial_loss),
|
44
|
-
format("Friction loss: %.1f Nm", friction_loss),
|
45
|
-
format("Net Axle Torque: %.1f Nm", net_axle_torque),
|
46
|
-
format("Net Drive Force: %.1f N", net_drive_force),
|
47
|
-
format("Acceleration: %.1f m/s/s", acc),
|
48
|
-
format("Alpha: %.2f r/s/s", acc / wheel.radius_m),
|
49
|
-
].join("\n")
|
50
|
-
puts
|
51
|
-
|
52
|
-
duration = 100 # sec
|
53
|
-
|
54
|
-
dist = 0.0 # meters
|
55
|
-
speed = 0.0 # meters/s
|
56
|
-
|
57
|
-
theta = 0.0 # radians
|
58
|
-
omega = 0.0 # radians/s
|
59
|
-
|
60
|
-
(duration * env.hz).times { |i|
|
61
|
-
# accumulate frictional losses with speed (omega)
|
62
|
-
omega_loss_cof = [wheel.omega_friction * omega, 1.0].min
|
63
|
-
slowed_acc = acc - acc * omega_loss_cof
|
64
|
-
|
65
|
-
# translational kinematics
|
66
|
-
speed += slowed_acc * env.tick
|
67
|
-
dist += speed * env.tick
|
68
|
-
|
69
|
-
# rotational kinematics
|
70
|
-
alpha = slowed_acc / wheel.radius_m
|
71
|
-
omega += alpha * env.tick
|
72
|
-
theta += omega * env.tick
|
73
|
-
|
74
|
-
if i < 10 or
|
75
|
-
(i < 10_000 and i%1000 == 0) or
|
76
|
-
(i % 10_000 == 0)
|
77
|
-
puts DrivingPhysics.elapsed_display(i)
|
78
|
-
puts format("Wheel: %.1f r %.2f r/s %.3f r/s^2", theta, omega, alpha)
|
79
|
-
puts format(" Car: %.1f m %.2f m/s %.3f m/s^2", dist, speed, slowed_acc)
|
80
|
-
puts format("Omega Frictional Loss: %.1f%%", omega_loss_cof * 100)
|
81
|
-
puts "Press [enter]"
|
82
|
-
gets
|
83
|
-
end
|
84
|
-
}
|