driving_physics 0.0.0.3 → 0.0.1.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.
- 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
|
-
}
|