Skip to content

Instantly share code, notes, and snippets.

@nateberkopec
Created July 31, 2017 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nateberkopec/9a91a29df831cab88e43e6cea78d8b88 to your computer and use it in GitHub Desktop.
Save nateberkopec/9a91a29df831cab88e43e6cea78d8b88 to your computer and use it in GitHub Desktop.
KRPC - test rocket script
require 'krpc'
CLIENT_NAME = "Flight Computer"
MISSION_NAME = "UPPER STAGE TEST"
HOST_IP = "192.168.1.13"
KRPC_CMD_WAIT = 0.01
SPOOL_TO_THRUST_PERCENT = 0.25
$client = KRPC::Client.new(name: CLIENT_NAME, host: HOST_IP).connect!
class CAPCOM
def say(msg, length = 5)
$client.ui.message(msg, length)
puts msg
end
def prompt(msg, length = 5)
say(msg, length)
gets
end
def sleep_until(&block)
until block.call
sleep(KRPC_CMD_WAIT)
end
end
def countdown(from = 3)
(from..1).each { |i| say i; sleep(1) }
end
end
class Rocket
attr_accessor :vessel, :stages, :capcom
def initialize(vessel, capcom)
self.capcom = CAPCOM.new
self.vessel = vessel
self.stages = populate_stages
end
def current_stage
stages.first
end
def stage!(stage_msg = nil)
capcom.say stage_msg
capcom.say "STAGING! STAGE #{stages.size}"
vessel.control.activate_next_stage
stages.pop
end
def launch!
control.throttle = 1
stage!("FIRST STAGE IGNITION")
end
private
def method_missing(method, *args, &block)
vessel.send(method, *args, &block)
end
def populate_stages
parts_by_stage = parts_collected_by_stage
number_of_stages = parts_by_stage.keys.size - 1 # subtract the -1 stage
engines_by_stage = engines_collected_by_stage
(1..number_of_stages).map do |i|
stage_number = i + 1
Stage.new(engines: engines_by_stage[number_of_stages - i])
end
end
def parts_collected_by_stage
vessel.parts.all.reduce({}) do |memo, x|
stage = x.stage
memo[stage] ||= []
memo[stage] << x
memo
end
end
def engines_collected_by_stage
vessel.parts.engines.reduce({}) do |memo, engine|
stage = engine.part.stage
memo[stage] ||= []
memo[stage] << engine
memo
end
end
end
class Stage
attr_accessor :engines, :number, :max_thrust, :max_fuel
def initialize(engines:)
self.engines = engines
end
def engine
engines.first
end
def engines_firing?
engines_active_stream.get
end
def has_fuel?
engines_has_fuel_stream.get
end
def spooled?
self.max_thrust ||= engine.max_thrust
self.max_fuel ||= engine.propellants.first.total_resource_capacity
thrust_stream.get > (max_thrust * SPOOL_TO_THRUST_PERCENT)
end
private
def engines_active_stream
@engines_active_stream ||= engine.active_stream
end
def engines_has_fuel_stream
@engines_has_fuel_stream ||= engine.has_fuel_stream
end
def thrust_stream
@thrust_stream ||= engine.thrust_stream
end
end
$capcom = CAPCOM.new
$capcom.prompt "PRESS ENTER WHEN YOU ARE IN THE FLIGHT SCENE AND HAVE QUICKSAVED"
$client.space_center.quickload
$rocket = Rocket.new($client.space_center.active_vessel, $capcom)
$capcom.prompt "PRESS ENTER TO LAUNCH"
$rocket.auto_pilot.target_pitch_and_heading(90, 90)
$rocket.auto_pilot.engage()
$capcom.countdown
$rocket.launch!
$capcom.sleep_until { $rocket.current_stage.engines_firing? }
$capcom.sleep_until { $rocket.current_stage.spooled? }
$rocket.stage!("THRUST SPOOL COMPLETE, DETACHING PYLON")
$capcom.say "WE HAVE LIFT-OFF OF THE #{MISSION_NAME}"
$capcom.sleep_until { !$rocket.current_stage.has_fuel? }
$rocket.stage!
$capcom.sleep_until { !$rocket.current_stage.has_fuel? }
$rocket.stage!("FAIRING DETACHING")
sleep(0.5)
$rocket.stage!("SPIN MOTORS FIRING")
sleep(1.1) # Burn time of the spin motors
$rocket.stage! # detaching for the final Baby Sergeants
sleep(0.5)
$rocket.stage! # 3x Baby Sergeants
$capcom.sleep_until { !$rocket.current_stage.has_fuel? }
$rocket.stage! # 1x Baby Sergeant
$capcom.sleep_until { !$rocket.current_stage.has_fuel? }
$rocket.stage! # Probe release and quit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment