Looking for a bit of help/direction with the last piece to this script I'm working on. I'm attempting to use kRPC to automatically create maneuver nodes based on my current vessel's planetary target. I believe I have it almost complete, except for calculating the final position of the maneuver node based off the ejection angle. Here is what I have so far in python:
# used for vector math for finding ejection angle
def cross(u,v):
return (
u[1]*v[2] - u[2]*v[1],
u[2]*v[0] - u[0]*v[2],
u[0]*v[1] - u[1]*v[0])
# used for vector math for finding ejection angle
def dot(u,v):
return u[0]*v[0]+u[1]*v[1]+u[2]*v[2]
# calculate transfer window
def planetary_transfer(target_planet):
sas = vessel.control.sas
mu = conn.space_center.CelestialBody(int(str((conn.space_center.bodies['Sun']))[42:-1])).gravitational_parameter # gravitational constant of kerbol
r = conn.space_center.CelestialBody(int(str((conn.space_center.bodies[target_planet]))[42:-1])).orbit.semi_major_axis # semi-major axis of the target planet
k = conn.space_center.CelestialBody(int(str(vessel.orbit.body)[42:-1])).orbit.semi_major_axis # semi-major axis of the current planet
a = (k + r) / 2. # a = (r1 + r2)/2
t = (2. * math.pi * math.sqrt(a**3 / mu)) / 2. # Kepler's Third Law (2*PI*sqrt((a^3)/GM)) divide by 2
phase_angle = 180 - math.sqrt(mu / r) * t / r * 180 / math.pi # optimal angle between current planet and target planet
soi = conn.space_center.CelestialBody(int(str(vessel.orbit.body)[42:-1])).sphere_of_influence # SOI of current planet
d = vessel.orbit.radius # radius of vessel from center of mass
v = math.sqrt(mu / (soi + k)) * (math.sqrt((2. * r) / (soi + k + r)) - 1.) # change in velocity needed for the Hohmann transfer
kmu = conn.space_center.CelestialBody(int(str(vessel.orbit.body)[42:-1])).gravitational_parameter # gravitational constant of current planet
ejection_velocity = math.sqrt((d * (soi * v**2 - 2. * kmu) + 2. * soi * kmu) / (d * soi)) # velocity required to escape current planet SOI
ejection_angle = 180 - math.degrees(math.acos(math.sqrt(kmu**2 / (kmu - ejection_velocity**2 * d)**2))) # angle to start ejection burn
dtt = distance_to_target() #distance from origin planet to target
ct = conn.space_center.CelestialBody(int(str((conn.space_center.bodies[target_planet]))[42:-1])).orbit.radius #current target's distance from kerbol
co = conn.space_center.CelestialBody(int(str(vessel.orbit.body)[42:-1])).orbit.radius #origin planet's distance from kerbol
current_angle = 180 - (math.degrees(math.cos((ct**2 + co**2 - dtt**2)/(2*ct*co)))) #current phase angle between origin and target planet
ut = conn.add_stream(getattr, conn.space_center, 'ut') #universal time
cop = conn.space_center.CelestialBody(int(str(vessel.orbit.body)[42:-1])).orbit.period #origin planet's orbital period
top = conn.space_center.CelestialBody(int(str((conn.space_center.bodies[target_planet]))[42:-1])).orbit.period #target planet's orbital period
cdc = cop/360 #how many seconds origin planet takes to move 1 degree
tdc = cdc/top * 360 #how many degrees does target move in relation to origin
angle_dif = current_angle - phase_angle
time_to_phase_angle = ((angle_dif/tdc)/360) * cop #how many seconds until angle equals phase angle
delta_v = (ejection_velocity - math.sqrt(kmu/d)) #delta_v required for burn to reach ejection velocity
time_to_ejection_angle = 0 #TODO - figure out current angle in relation to origin planet's prograde movement
# these vectors are all in orbital_reference_frame
prograde = (0,1,0)
retrograde = (0,-1,0)
radial_out = (-1,0,0)
radial_in = (1,0,0)
normal = (0,0,1)
antinormal = (0,0,-1)
reference_frame = conn.space_center.CelestialBody(int(str(vessel.orbit.body)[42:-1])).orbital_reference_frame
# TODO - figure out final node position and place it in relation to ejection angle
# requires current node position compared to orbital reference frame prograde position
# use vector math to calculate the current angle
# calculate burn time (using Tsiolkovsky rocket equation: https://en.wikipedia.org/wiki/Tsiolkovsky_rocket_equation)
F = vessel.available_thrust
Isp = vessel.specific_impulse * 9.82
m0 = vessel.mass
m1 = m0 / math.exp(delta_v/Isp)
flow_rate = F / Isp
burn_time = (m0 - m1) / flow_rate
node = vessel.control.add_node(ut() + time_to_phase_angle + time_to_ejection_angle, prograde=delta_v, radial=0) # create maneuver node
ap = vessel.auto_pilot
ap.engage()
ap.reference_frame = node.reference_frame
ap.target_direction = (0, 1, 0)
ap.wait()
burn_ut = ut() + time_to_phase_angle + time_to_ejection_angle - (burn_time/2.)
lead_time = 10
conn.space_center.warp_to(burn_ut - lead_time)
time_to_node = node.time_to
while time_to_node - (burn_time/2.) > 0:
pass
time.sleep(burn_time - 0.0)
vessel.control.throttle = 0.05
remaining_burn = conn.add_stream(node.remaining_burn_vector, node.reference_frame)
while remaining_burn()[1] > 3.0:
pass
vessel.control.throttle = 0.0
node.remove()
if sas is True:
vessel.control.sas = True
ap.disengage()