demo/motor.rb in driving_physics-0.0.1.1 vs demo/motor.rb in driving_physics-0.0.1.2
- old
+ new
@@ -1,29 +1,55 @@
require 'driving_physics/motor'
require 'driving_physics/cli'
+require 'driving_physics/power'
-# fun idea for a different demo: keep increasing torque until idle is
-# maintained
+# next fun idea: PID controller
include DrivingPhysics
env = Environment.new
motor = Motor.new(env)
puts env
puts motor
+puts
puts "Rev it up!"
-800.upto(7000) { |rpm|
- next unless rpm % 200 == 0
- tq = motor.torque(rpm).to_f
- puts format("%s RPM: %s Nm\t%s",
- rpm.to_s.rjust(4, ' '),
- tq.round(1).to_s.rjust(5, ' '),
- '#' * (tq.to_f / 10).round)
+motor.throttle = 1.0
+[:torque, :power].each { |run|
+ puts
+ puts run.to_s.upcase + ':'
+
+ 800.upto(7000) { |rpm|
+ next unless rpm % 200 == 0
+ omega = DrivingPhysics.omega(rpm)
+ torque = motor.torque(rpm)
+ case run
+ when :torque
+ count = (torque.to_f / 10).round
+ char = 'T'
+ val = torque.round.to_s.rjust(5, ' ')
+ fmt = "%s Nm"
+ when :power
+ power = DrivingPhysics.power(torque, omega)
+ kw = power.to_f / 1000
+ count = (kw / 5).round
+ char = 'P'
+ val = kw.round(1).to_s.rjust(5, ' ')
+ fmt = "%s kW"
+ else
+ raise "unknown"
+ end
+ puts format("%s RPM: #{fmt}\t%s",
+ rpm.to_s.rjust(4, ' '),
+ val,
+ char * count)
+ }
}
puts
+puts "Now, the simulation begins..."
+puts "---"
puts "* Spin the motor up to #{motor.idle_rpm} RPM with the starter motor."
puts "* Rev it up with the throttle."
puts "* Let it die."
CLI.pause
@@ -34,16 +60,20 @@
duration = 60
status = :ignition
rpm = 0
-(duration * env.hz + 1).times { |i|
+paused = 0.0
+num_ticks = duration * env.hz + 1
+start = Timer.now
+
+num_ticks.times { |i|
# this is an input torque; alpha is determined after inertia and friction
torque = case status
when :ignition
motor.starter_torque
- when :running
+ when :running, :off_throttle, :idling
motor.torque(rpm)
else
0
end
@@ -56,34 +86,56 @@
# prevent silly oscillations due to tiny floating point errors
omega = 0 if omega < 0.00001
rpm = DrivingPhysics.rpm(omega)
+ power = DrivingPhysics.power(net_torque, omega)
+
if rpm > motor.idle_rpm and status == :ignition
status = :running
flag = true
end
if rpm > 7000 and status == :running
- status = :off
+ status = :off_throttle
+ motor.throttle = 0.0
flag = true
end
+ if rpm < 1000 and status == :off_throttle
+ status = :idling
+ motor.throttle = 0.06
+ flag = true
+ end
+
+ if status == :idling
+ if rpm < 999
+ motor.throttle += (1.0 - motor.throttle) * 0.005
+ elsif rpm > 1001
+ motor.throttle -= motor.throttle * 0.005
+ end
+ end
+
if flag or
(i < 10) or
(i < 100 and i % 10 == 0) or
(i < 1000 and i % 100 == 0) or
(i < 10_000 and i % 500 == 0) or
- i % 5000 == 0
- puts DrivingPhysics.elapsed_display(i)
- puts format("%d RPM %.1f Nm (%d Nm) Friction: %.1f Nm",
+ (i % 5000 == 0) or
+ (status == :idling and i % 100 == 0)
+ puts Timer.display(i)
+ puts format("Throttle: %.1f%%", motor.throttle * 100)
+ puts format("%d RPM %.1f Nm (%d Nm) %.1f kW Friction: %.1f Nm",
DrivingPhysics.rpm(omega),
net_torque,
torque,
+ power / 1000,
motor.spinner.rotating_friction(omega))
puts format("%d rad %.1f rad/s %.1f rad/s/s", theta, omega, alpha)
puts
- CLI.pause if flag
+ paused += CLI.pause if flag
flag = false
end
}
+
+puts Timer.summary(start, num_ticks, paused)