Class: DrivingPhysics::Disk

Inherits:
Object
  • Object
show all
Defined in:
lib/driving_physics/disk.rb

Direct Known Subclasses

Tire

Constant Summary collapse

DENSITY =

kg / L

1.0

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env) {|_self| ... } ⇒ Disk

Returns a new instance of Disk.

Yields:

  • (_self)

Yield Parameters:



111
112
113
114
115
116
117
118
119
# File 'lib/driving_physics/disk.rb', line 111

def initialize(env)
  @env = env
  @radius  = 0.35
  @width   = 0.2
  @density = DENSITY
  @base_friction  = 5.0/100_000  # constant resistance to rotation
  @omega_friction = 5.0/100_000  # scales with omega
  yield self if block_given?
end

Instance Attribute Details

#base_frictionObject

Returns the value of attribute base_friction.



109
110
111
# File 'lib/driving_physics/disk.rb', line 109

def base_friction
  @base_friction
end

#densityObject

Returns the value of attribute density.



109
110
111
# File 'lib/driving_physics/disk.rb', line 109

def density
  @density
end

#envObject (readonly)

Returns the value of attribute env.



108
109
110
# File 'lib/driving_physics/disk.rb', line 108

def env
  @env
end

#omega_frictionObject

Returns the value of attribute omega_friction.



109
110
111
# File 'lib/driving_physics/disk.rb', line 109

def omega_friction
  @omega_friction
end

#radiusObject

Returns the value of attribute radius.



109
110
111
# File 'lib/driving_physics/disk.rb', line 109

def radius
  @radius
end

#widthObject

Returns the value of attribute width.



109
110
111
# File 'lib/driving_physics/disk.rb', line 109

def width
  @width
end

Class Method Details

.alpha(torque, inertia) ⇒ Object

angular acceleration



69
70
71
# File 'lib/driving_physics/disk.rb', line 69

def self.alpha(torque, inertia)
  torque / inertia
end

.density(mass, volume_l) ⇒ Object



52
53
54
# File 'lib/driving_physics/disk.rb', line 52

def self.density(mass, volume_l)
  mass.to_f / volume_l
end

.force(axle_torque, radius) ⇒ Object

torque = force * distance



38
39
40
# File 'lib/driving_physics/disk.rb', line 38

def self.force(axle_torque, radius)
  axle_torque / radius.to_f
end

.force_vector(torque, radius) ⇒ Object

vectors only



97
98
99
100
101
102
103
104
105
106
# File 'lib/driving_physics/disk.rb', line 97

def self.force_vector(torque, radius)
  if !torque.is_a?(Vector) or torque.size != 3
    raise(ArgumentError, "torque must be a 3D vector")
  end
  if !radius.is_a?(Vector) or radius.size != 2
    raise(ArgumentError, "radius must be a 2D vector")
  end
  radius = Vector[radius[0], radius[1], 0]
  radius.cross(torque) / radius.dot(radius)
end

.mass(radius, width, density) ⇒ Object



56
57
58
# File 'lib/driving_physics/disk.rb', line 56

def self.mass(radius, width, density)
  volume_l(radius, width) * density
end

.moment_of_inertiaObject

I = 1/2 (m)(r^2) for a disk



65
66
67
# File 'lib/driving_physics/disk.rb', line 65

def self.rotational_inertia(radius, mass)
  mass * radius**2 / 2.0
end

.rotational(tangential, radius) ⇒ Object

convert acc/vel/pos to alpha/omega/theta



79
80
81
# File 'lib/driving_physics/disk.rb', line 79

def self.rotational(tangential, radius)
  tangential.to_f / radius
end

.rotational_inertia(radius, mass) ⇒ Object

I = 1/2 (m)(r^2) for a disk



61
62
63
# File 'lib/driving_physics/disk.rb', line 61

def self.rotational_inertia(radius, mass)
  mass * radius**2 / 2.0
end

.tangential(rotational, radius) ⇒ Object

convert alpha/omega/theta to acc/vel/pos



74
75
76
# File 'lib/driving_physics/disk.rb', line 74

def self.tangential(rotational, radius)
  rotational * radius
end

.torque_vector(force, radius) ⇒ Object

vectors only



84
85
86
87
88
89
90
91
92
93
94
# File 'lib/driving_physics/disk.rb', line 84

def self.torque_vector(force, radius)
  if !force.is_a?(Vector) or force.size != 2
    raise(ArgumentError, "force must be a 2D vector")
  end
  if !radius.is_a?(Vector) or radius.size != 2
    raise(ArgumentError, "radius must be a 2D vector")
  end
  force = Vector[force[0], force[1], 0]
  radius = Vector[radius[0], radius[1], 0]
  force.cross(radius)
end

.volume(radius, width) ⇒ Object

in m^3



43
44
45
# File 'lib/driving_physics/disk.rb', line 43

def self.volume(radius, width)
  Math::PI * radius ** 2 * width
end

.volume_l(radius, width) ⇒ Object

in L



48
49
50
# File 'lib/driving_physics/disk.rb', line 48

def self.volume_l(radius, width)
  volume(radius, width) * 1000
end

Instance Method Details

#alpha(torque, omega: 0, normal_force: nil) ⇒ Object



133
134
135
136
# File 'lib/driving_physics/disk.rb', line 133

def alpha(torque, omega: 0, normal_force: nil)
  (torque - self.rotating_friction(omega, normal_force: normal_force)) /
    self.rotational_inertia
end

#force(axle_torque) ⇒ Object



166
167
168
# File 'lib/driving_physics/disk.rb', line 166

def force(axle_torque)
  self.class.force(axle_torque, @radius)
end

#implied_torque(alpha) ⇒ Object



138
139
140
# File 'lib/driving_physics/disk.rb', line 138

def implied_torque(alpha)
  alpha * self.rotational_inertia
end

#massObject



142
143
144
# File 'lib/driving_physics/disk.rb', line 142

def mass
  self.class.mass(@radius, @width, @density)
end

#mass=(val) ⇒ Object



146
147
148
149
# File 'lib/driving_physics/disk.rb', line 146

def mass=(val)
  @density = self.class.density(val, self.volume_l)
  @normal_force = nil # force update
end

#normal_forceObject



128
129
130
131
# File 'lib/driving_physics/disk.rb', line 128

def normal_force
  @normal_force ||= self.mass * @env.g
  @normal_force
end

#rotating_friction(omega, normal_force: nil) ⇒ Object

modeled as a tiny but increasing torque opposing omega also scales with normal force maybe not physically faithful but close enough



177
178
179
180
181
182
183
# File 'lib/driving_physics/disk.rb', line 177

def rotating_friction(omega, normal_force: nil)
  return omega if omega.zero?
  normal_force = self.normal_force if normal_force.nil?
  mag = omega.abs
  sign = omega / mag
  -1 * sign * normal_force * (@base_friction + mag * @omega_friction)
end

#rotational_inertiaObject Also known as: moment_of_inertia



161
162
163
# File 'lib/driving_physics/disk.rb', line 161

def rotational_inertia
  self.class.rotational_inertia(@radius, self.mass)
end

#tangential(rotational) ⇒ Object



170
171
172
# File 'lib/driving_physics/disk.rb', line 170

def tangential(rotational)
  self.class.tangential(rotational, @radius)
end

#to_sObject



121
122
123
124
125
126
# File 'lib/driving_physics/disk.rb', line 121

def to_s
  [[format("%d mm x %d mm (RxW)", @radius * 1000, @width * 1000),
    format("%.1f kg  %.2f kg/L", self.mass, @density),
   ].join(" | "),
  ].join("\n")
end

#volumeObject

in m^3



152
153
154
# File 'lib/driving_physics/disk.rb', line 152

def volume
  self.class.volume(@radius, @width)
end

#volume_lObject

in L



157
158
159
# File 'lib/driving_physics/disk.rb', line 157

def volume_l
  self.class.volume_l(@radius, @width)
end