Basic mission vessel tunnel

This commit is contained in:
2023-08-29 01:01:24 +02:00
parent 5f2d358664
commit 979415cdb0
10 changed files with 569 additions and 144 deletions

View File

@@ -0,0 +1,50 @@
from enum import Enum
class ManeuverAlarmType(Enum):
ManeuverNode = 1,
SOI = 2
class Maneuver:
def __init__(self, conn, vessel):
self.vessel = vessel
self.conn = conn
def plan_next_maneuver(self, conn):
pass
class NodeManeuver(Maneuver):
alarm_type = ManeuverAlarmType.ManeuverNode
def __init__(self, conn, vessel):
super().__init__(conn, vessel)
self.mech_jeb = conn.mech_jeb
self.node_executor = self.mech_jeb.node_executor
def execute(self) -> bool:
sc = self.conn.space_center
if sc.active_vessel.name != self.vessel.name:
sc.active_vessel = self.vessel
while self.vessel.control.nodes:
self._execute_node()
return self.plan_next_maneuver()
def _execute_node(self):
self.node_executor.execute_all_nodes()
with self.conn.stream(getattr, self.node_executor, "enabled") as enabled:
enabled.rate = 1
with enabled.condition:
while enabled():
enabled.wait()
class MechJebManeuver(NodeManeuver):
def __init__(self, conn, vessel):
super().__init__(conn, vessel)
self.maneuver_planner = self.mech_jeb.maneuver_planner

View File

@@ -3,11 +3,53 @@ from krpc.services.spacecenter import SASMode
import numpy as np
from time import time, sleep
from utils import magnitude, kill_relative_velocity, correct_course
from .utils import magnitude, unitary, kill_relative_velocity, correct_course
from . import Maneuver
def unitary(vector):
return np.array(vector) / magnitude(vector)
class ApproachManeuver(Maneuver):
def __init__(self, conn, vessel_id, reference_frame):
super().__init__(conn, vessel_id)
self.reference_frame = reference_frame
def start(self):
sc = self.conn.space_center
vessel = sc.active_vessel
target = sc.target_vessel
kill_relative_velocity(self.conn, vessel, self.reference_frame)
self.conn.drawing.add_direction((0, 1, 0), self.reference_frame)
vessel.control.rcs = False
pv = vessel.position(self.reference_frame)
safety_radius = get_safety_radius(vessel) + get_safety_radius(target) + SAFETY_RADIUS_MARGIN
# if under and inside safety cylinder's circle
if pv[1] < safety_radius and pow(pv[0], 2) + pow(pv[2], 2) <= pow(safety_radius, 2):
print("We're under the target and inside the safety cylinder, getting out")
# get out of the cylinder
plane_move_vector = unitary(tuple((pv[0], pv[2]))) * (safety_radius - magnitude(tuple((pv[0], pv[2]))))
pv = vessel.position(self.reference_frame)
move_vector = np.array((plane_move_vector[0], 0, plane_move_vector[1]))
move_to_waypoint(self.conn, vessel, pv + move_vector, self.reference_frame)
print("We're outside of the safety cylinder, setting vertical distance")
pv = vessel.position(self.reference_frame)
move_to_waypoint(self.conn, vessel, (pv[0], safety_radius, pv[2]), self.reference_frame)
# should be above and outside => get inside
print("We're at the right vertical distance to the target, setting horizontal position")
move_to_waypoint(self.conn, vessel, (0, safety_radius, 0), self.reference_frame)
point_toward_direction(vessel, - np.array(vessel.position(self.reference_frame)), self.reference_frame)
return True
def get_safety_radius(vessel):
@@ -106,8 +148,6 @@ def move_to_waypoint(conn, vessel, waypoint, reference_frame):
thrust(vessel, -velocity, reference_frame)
print("Ship decelerated")
#do positition correction
sa.autopilot_mode = mj.SmartASSAutopilotMode.off
sa.update(True)
@@ -118,6 +158,7 @@ def move_to_waypoint(conn, vessel, waypoint, reference_frame):
SAFETY_RADIUS_MARGIN = 10
# DEPRECATED
def maneuver_to_approach(conn, reference_frame):
print("Handling approach")
sc = conn.space_center
@@ -158,6 +199,7 @@ def maneuver_to_approach(conn, reference_frame):
TARGET_VELOCITY = 2
# DEPRECATED
def move_with_vector(conn, vessel, vector, reference_frame):
mj = conn.mech_jeb
sa = mj.smart_ass

View File

@@ -1,6 +1,42 @@
from time import sleep
from utils import kill_relative_velocity, correct_course, magnitude
from .utils import kill_relative_velocity, correct_course, magnitude
from . import Maneuver
class DockingManeuver(Maneuver):
def __init__(self, conn, vessel_id, docking_part, reference_frame):
super().__init__(conn, vessel_id)
self.docking_part = docking_part
self.reference_frame = reference_frame
def start(self):
vessel = self.conn.space_center.active_vessel
self.conn.drawing.add_direction((0, 1, 0), self.reference_frame)
self.conn.drawing.add_direction((1, 0, 0), self.reference_frame)
vessel.parts.controlling = self.docking_part
kill_relative_velocity(self.conn, vessel, self.reference_frame)
set_attitude_and_roll(self.conn, vessel, self.reference_frame)
align_horizontally(self.conn, vessel, self.reference_frame)
print("Starting docking procedure")
vessel.control.set_action_group(0, True)
rcs_push(vessel, {"y": 1}, .5)
vessel.control.rcs = True
try:
while vessel.position(self.reference_frame)[1] > 0:
print(vessel.position(self.reference_frame)[1])
correct_course(self.conn, vessel, (0, 0, 0), self.reference_frame)
sleep(1)
except ValueError as e:
vessel = self.conn.space_center.active_vessel
finally:
vessel.control.rcs = False
return True
def set_attitude_and_roll(conn, vessel, reference_frame):
@@ -127,30 +163,3 @@ def align_horizontally(conn, vessel, reference_frame):
kill_rcs_velocity(vessel, reference_frame)
print("Vertical alignment done!")
def dock_ship(conn, vessel, docking_part, reference_frame):
conn.drawing.add_direction((0, 1, 0), reference_frame)
conn.drawing.add_direction((1, 0, 0), reference_frame)
vessel.parts.controlling = docking_part
kill_relative_velocity(conn, vessel, reference_frame)
set_attitude_and_roll(conn, vessel, reference_frame)
align_horizontally(conn, vessel, reference_frame)
print("Starting docking procedure")
vessel.control.set_action_group(0, True)
rcs_push(vessel, {"y": 1}, .5)
vessel.control.rcs = True
try:
while vessel.position(reference_frame)[1] > 0:
print(vessel.position(reference_frame)[1])
correct_course(conn, vessel, (0, 0, 0), reference_frame)
sleep(1)
except ValueError as e:
vessel = conn.space_center.active_vessel
finally:
vessel.control.rcs = False

View File

@@ -1,103 +1,87 @@
import numpy as np
from utils import execute_node, magnitude
from .utils import magnitude
from maneuver_scheduler import ManeuverScheduler
from . import MechJebManeuver
def align_orbit_planes(conn):
print("Aligning planes")
mj = conn.mech_jeb
mp = mj.maneuver_planner
oi = mp.operation_inclination
oi.time_selector.time_reference = mj.TimeReference.eq_nearest_ad
nodes = oi.make_nodes()
class RendezvousManeuver(MechJebManeuver):
def start(self):
self.plan_next_maneuver()
# kac = conn.kerbal_alarm_clock
# kac.create_alarm(
# kac.AlarmType.maneuver,
# "{}'s Orbital transfer".format(v.name),
# nodes[0].ut
# )
def plan_next_maneuver(self):
sc = self.conn.space_center
vessel = sc.active_vessel
target = sc.target_vessel
execute_node(conn)
if vessel.orbit.distance_at_closest_approach(target.orbit) > 1000:
if vessel.orbit.relative_inclination(target.orbit) > 0.0001:
AlignOrbitPlaneWithTarget(self.conn, vessel).prepare_maneuver()
print("Planes aligned!")
elif vessel.orbit.distance_at_closest_approach(target.orbit) > 10000:
InterceptTargetOrbit(self.conn, vessel).prepare_maneuver()
else:
TuneClosestApproach(self.conn, vessel).prepare_maneuver()
return False
elif vessel.orbit.distance_at_closest_approach(target.orbit) <= 1000 < magnitude(
np.array(vessel.position(vessel.reference_frame)) - np.array(target.position(vessel.reference_frame))):
MatchVelocityWithTarget(self.conn, vessel).prepare_maneuver()
return False
else:
return True
def intercepting_target_orbit(conn):
print("Intercepting target orbit")
sc = conn.space_center
v = sc.active_vessel
mj = conn.mech_jeb
mp = mj.maneuver_planner
ot = mp.operation_transfer
ot.time_selector.time_reference = mj.TimeReference.computed
nodes = ot.make_nodes()
nodes[0].ut = nodes[0].ut + 0.1
class AlignOrbitPlaneWithTarget(RendezvousManeuver):
name = "Align orbit plane with target's"
# kac = conn.kerbal_alarm_clock
# kac.create_alarm(
# kac.AlarmType.maneuver,
# "{}'s Orbital transfer".format(v.name),
# nodes[0].ut
# )
def prepare_maneuver(self):
oi = self.maneuver_planner.operation_inclination
oi.time_selector.time_reference = self.mech_jeb.TimeReference.eq_nearest_ad
nodes = oi.make_nodes()
execute_node(conn)
node = nodes[0]
print("Target orbit intercepted!")
ManeuverScheduler.book_timeslot_for_node(self.vessel, node, self)
def tune_closest_approach(conn):
print("Tuning closest approach")
sc = conn.space_center
v = sc.active_vessel
mj = conn.mech_jeb
mp = mj.maneuver_planner
occ = mp.operation_course_correction
nodes = occ.make_nodes()
class InterceptTargetOrbit(RendezvousManeuver):
name = "Intercept target's orbit"
# kac = conn.kerbal_alarm_clock
# kac.create_alarm(
# kac.AlarmType.maneuver,
# "{}'s Orbital transfer".format(v.name),
# nodes[0].ut
# )
def prepare_maneuver(self):
ot = self.maneuver_planner.operation_transfer
ot.time_selector.time_reference = self.mech_jeb.TimeReference.computed
nodes = ot.make_nodes()
execute_node(conn)
node = nodes[0]
node.ut = node.ut + 1
print("Closest approach tuned!")
ManeuverScheduler.book_timeslot_for_node(self.vessel, node, self)
def match_velocities(conn):
print("Matching velocities")
sc = conn.space_center
v = sc.active_vessel
mj = conn.mech_jeb
mp = mj.maneuver_planner
okrv = mp.operation_kill_rel_vel
nodes = okrv.make_nodes()
class TuneClosestApproach(RendezvousManeuver):
name = "Tune closest approach with target"
# kac = conn.kerbal_alarm_clock
# kac.create_alarm(
# kac.AlarmType.maneuver,
# "{}'s Orbital transfer".format(v.name),
# nodes[0].ut
# )
def prepare_maneuver(self):
occ = self.maneuver_planner.operation_course_correction
nodes = occ.make_nodes()
execute_node(conn)
node = nodes[0]
print("Velocities matched!")
ManeuverScheduler.book_timeslot_for_node(self.vessel, node, self)
def maneuver_to_rendezvous(conn, vessel, target):
if vessel.orbit.distance_at_closest_approach(target.orbit) > 1000:
if vessel.orbit.relative_inclination(target.orbit) > 0.0001:
align_orbit_planes(conn)
class MatchVelocityWithTarget(RendezvousManeuver):
name = "Math velocity with target's"
duration = 10 * 60
if vessel.orbit.distance_at_closest_approach(target.orbit) > 10000:
intercepting_target_orbit(conn)
def prepare_maneuver(self):
okrv = self.maneuver_planner.operation_kill_rel_vel
nodes = okrv.make_nodes()
tune_closest_approach(conn)
node = nodes[0]
if vessel.orbit.distance_at_closest_approach(target.orbit) <= 1000 < magnitude(
np.array(vessel.position(vessel.reference_frame)) - np.array(target.position(vessel.reference_frame))):
match_velocities(conn)
ManeuverScheduler.book_timeslot_for_node(self.vessel, node, self, duration=self.duration)

View File

@@ -3,21 +3,18 @@ from time import time, sleep
import numpy as np
def execute_node(conn):
ne = conn.mech_jeb.node_executor
ne.execute_all_nodes()
with conn.stream(getattr, ne, "enabled") as enabled:
enabled.rate = 1
with enabled.condition:
while enabled():
enabled.wait()
def magnitude(vector):
return np.linalg.norm(vector)
def node_thrust_time(vessel, node):
return (node.delta_v * vessel.mass) / vessel.available_thrust
def unitary(vector):
return np.array(vector) / magnitude(vector)
THROTTLE = .1