diff --git a/Localization/en-us.cfg b/Localization/en-us.cfg
index cfea8a3ad..9361a62bf 100644
--- a/Localization/en-us.cfg
+++ b/Localization/en-us.cfg
@@ -114,16 +114,21 @@ Localization
#MechJeb_adv_Exception4 = Invalid point selected.
//Hohmann transfer
- #MechJeb_Hohm_title = two impulse (Hohmann) transfer to target
- #MechJeb_Hohm_intercept_only = no insertion burn (impact/flyby)
- #MechJeb_Hohm_simpleTransfer = coplanar maneuver
- #MechJeb_Hohm_Label1 = rendezvous time offset
-
- #MechJeb_Hohm_Exception1 = must select a target for the maneuver.
- #MechJeb_Hohm_Exception2 = target for maneuver must be in the same sphere of influence.
- #MechJeb_Hohm_Exception3 = ascending node with target doesn't exist.
- #MechJeb_Hohm_Exception4 = descending node with target doesn't exist.
- #MechJeb_Hohm_Exception5 = neither ascending nor descending node with target exists.
+ #MechJeb_Hohm_title = Hohmann Transfer
+ #MechJeb_Hohm_transfer = Transfer
+ #MechJeb_Hohm_rendezvous = Rendezvous
+ #MechJeb_Hohm_flyby = Flyby / Impact
+ #MechJeb_Hohm_intercept = Intercept
+ #MechJeb_Hohm_matchOrbit = Match orbit
+ #MechJeb_Hohm_arrivalDelay = Arrival delay
+ #MechJeb_Hohm_createArrivalNode = Create arrival node
+ #MechJeb_Hohm_simpleTransfer = Coplanar only
+
+ #MechJeb_Hohm_Exception1 = A target must be selected for this maneuver.
+ #MechJeb_Hohm_Exception2 = The target for the maneuver must be in the same sphere of influence.
+ #MechJeb_Hohm_Exception3 = No ascending node with the target exists.
+ #MechJeb_Hohm_Exception4 = No descending node with the target exists.
+ #MechJeb_Hohm_Exception5 = No ascending or descending node with the target exists.
//Change Apoapsis
#MechJeb_Ap_title = change apoapsis
diff --git a/Localization/es-es.cfg b/Localization/es-es.cfg
index 510eeac3b..0ba13e2e4 100644
--- a/Localization/es-es.cfg
+++ b/Localization/es-es.cfg
@@ -114,16 +114,21 @@ Localization
#MechJeb_adv_Exception4 = Punto no válido seleccionado.
//Hohmann transfer
- #MechJeb_Hohm_title = transferencia bi-impulsiva (Hohmann) al objetivo
- #MechJeb_Hohm_intercept_only = solo interceptar, sin captura de quema (impacto/sobrevuelo)
- #MechJeb_Hohm_simpleTransfer = transferencia coplanar simple de Hohmann
- #MechJeb_Hohm_Label1 = compensación del período objetivo fraccional
-
- #MechJeb_Hohm_Exception1 = debe seleccionar un objetivo para la transferencia bi-impulsiva.
- #MechJeb_Hohm_Exception2 = El objetivo de la transferencia bi-impulsiva debe estar en la misma esfera de influencia.
- #MechJeb_Hohm_Exception3 = el nodo ascendente con el objetivo no existe.
- #MechJeb_Hohm_Exception4 = el nodo descendente con destino no existe.
- #MechJeb_Hohm_Exception5 = No existe un nodo ascendente ni descendente con destino.
+ #MechJeb_Hohm_title = Transferencia Hohmann
+ #MechJeb_Hohm_transfer = Transferencia
+ #MechJeb_Hohm_rendezvous = Encuentro
+ #MechJeb_Hohm_flyby = Sobrevuelo / Impacto
+ #MechJeb_Hohm_intercept = Intercepción
+ #MechJeb_Hohm_matchOrbit = Igualar órbita
+ #MechJeb_Hohm_arrivalDelay = Retraso de llegada
+ #MechJeb_Hohm_createArrivalNode = Crear nodo de llegada
+ #MechJeb_Hohm_simpleTransfer = Solo coplanar
+
+ #MechJeb_Hohm_Exception1 = Debe seleccionarse un objetivo para esta maniobra.
+ #MechJeb_Hohm_Exception2 = El objetivo de la maniobra debe estar en la misma esfera de influencia.
+ #MechJeb_Hohm_Exception3 = No existe nodo ascendente con el objetivo.
+ #MechJeb_Hohm_Exception4 = No existe nodo descendente con el objetivo.
+ #MechJeb_Hohm_Exception5 = No existe nodo ascendente ni descendente con el objetivo.
//Change Apoapsis
#MechJeb_Ap_title = cambiar apoapsis
diff --git a/Localization/fr-fr.cfg b/Localization/fr-fr.cfg
index 9be4e567c..dc7209d5c 100644
--- a/Localization/fr-fr.cfg
+++ b/Localization/fr-fr.cfg
@@ -115,16 +115,21 @@ Localization
#MechJeb_adv_Exception4 = Point sélectionné invalide.
//Hohmann transfer
- #MechJeb_Hohm_title = transfert de Hohmann
- #MechJeb_Hohm_intercept_only = interception uniquement, pas de capture (impact/survol)
- #MechJeb_Hohm_simpleTransfer = simple transfert de Hohmann coplanaire
- #MechJeb_Hohm_Label1 = fraction de décalage de la période cible
-
- #MechJeb_Hohm_Exception1 = sélection d'une cible nécessaire pour l'orbite de transfert.
- #MechJeb_Hohm_Exception2 = la cible du transfert doit être dans la même sphère d'influence.
- #MechJeb_Hohm_Exception3 = le nœud ascendant avec la cible n'existe pas.
- #MechJeb_Hohm_Exception4 = le nœud descendant avec la cible n'existe pas.
- #MechJeb_Hohm_Exception5 = ni le nœud ascendant ni le nœud descendant avec la cible n'existent.
+ #MechJeb_Hohm_title = Transfert Hohmann
+ #MechJeb_Hohm_transfer = Transfert
+ #MechJeb_Hohm_rendezvous = Rendez-vous
+ #MechJeb_Hohm_flyby = Survol / Impact
+ #MechJeb_Hohm_intercept = Interception
+ #MechJeb_Hohm_matchOrbit = Calquer l'orbite
+ #MechJeb_Hohm_arrivalDelay = Délai d'arrivée
+ #MechJeb_Hohm_createArrivalNode = Créer nœud d'arrivée
+ #MechJeb_Hohm_simpleTransfer = Coplanaire uniquement
+
+ #MechJeb_Hohm_Exception1 = Une cible doit être sélectionnée pour cette manœuvre.
+ #MechJeb_Hohm_Exception2 = La cible de la manœuvre doit être dans la même sphère d'influence.
+ #MechJeb_Hohm_Exception3 = Aucun nœud ascendant avec la cible n'existe.
+ #MechJeb_Hohm_Exception4 = Aucun nœud descendant avec la cible n'existe.
+ #MechJeb_Hohm_Exception5 = Aucun nœud ascendant ou descendant avec la cible n'existe.
//Change Apoapsis
#MechJeb_Ap_title = changer apoastre
diff --git a/Localization/ru.cfg b/Localization/ru.cfg
index 4ae953d43..80a574268 100644
--- a/Localization/ru.cfg
+++ b/Localization/ru.cfg
@@ -119,16 +119,21 @@ Localization
#MechJeb_adv_Exception4 = Выбрана не правильная точка.
//Hohmann transfer
- #MechJeb_Hohm_title = би-импульсивный (Гомановский) переход к цели
- #MechJeb_Hohm_intercept_only = только захват, без зажигания захвата (столкновение/пролет мимо)
- #MechJeb_Hohm_simpleTransfer = простой копланарный Гомановский переход
- #MechJeb_Hohm_Label1 = частичное смещение целевого периода
-
- #MechJeb_Hohm_Exception1 = вы должны выбрать цель для би-импульсивного перехода.
- #MechJeb_Hohm_Exception2 = цель для би-импульсивного перехода должна быть в той же сфере тяготения.
- #MechJeb_Hohm_Exception3 = восходящий узел с целью не существует.
- #MechJeb_Hohm_Exception4 = нисходящий узел с целью не существует.
- #MechJeb_Hohm_Exception5 = ни восходящего, ни нисходящего узла с целью не существует.
+ #MechJeb_Hohm_title = Гомановский перелёт
+ #MechJeb_Hohm_transfer = Перелёт
+ #MechJeb_Hohm_rendezvous = Сближение
+ #MechJeb_Hohm_flyby = Пролёт / Столкновение
+ #MechJeb_Hohm_intercept = Перехват
+ #MechJeb_Hohm_matchOrbit = Совместить орбиту
+ #MechJeb_Hohm_arrivalDelay = Задержка прибытия
+ #MechJeb_Hohm_createArrivalNode = Создать узел прибытия
+ #MechJeb_Hohm_simpleTransfer = Только копланарный
+
+ #MechJeb_Hohm_Exception1 = Необходимо выбрать цель для этого манёвра.
+ #MechJeb_Hohm_Exception2 = Цель манёвра должна быть в той же сфере тяготения.
+ #MechJeb_Hohm_Exception3 = Восходящий узел с целью не существует.
+ #MechJeb_Hohm_Exception4 = Нисходящий узел с целью не существует.
+ #MechJeb_Hohm_Exception5 = Ни восходящего, ни нисходящего узла с целью не существует.
//Change Apoapsis
#MechJeb_Ap_title = изменить апоцентр
diff --git a/Localization/zh-cn.cfg b/Localization/zh-cn.cfg
index a322e5fc5..19bba5125 100644
--- a/Localization/zh-cn.cfg
+++ b/Localization/zh-cn.cfg
@@ -114,16 +114,21 @@ Localization
#MechJeb_adv_Exception4 = 无效的选择点。
//Hohmann transfer
- #MechJeb_Hohm_title = 双脉冲(霍曼)转移
- #MechJeb_Hohm_intercept_only = 仅转移, 无捕获制动 (将会撞击或飞掠)
- #MechJeb_Hohm_simpleTransfer = 共面转移机动
- #MechJeb_Hohm_Label1 = 交会时间偏移
-
- #MechJeb_Hohm_Exception1 = 必须为机动选择一个目标。
+ #MechJeb_Hohm_title = 霍曼转移
+ #MechJeb_Hohm_transfer = 转移
+ #MechJeb_Hohm_rendezvous = 交会
+ #MechJeb_Hohm_flyby = 飞掠 / 撞击
+ #MechJeb_Hohm_intercept = 拦截
+ #MechJeb_Hohm_matchOrbit = 匹配轨道
+ #MechJeb_Hohm_arrivalDelay = 到达延迟
+ #MechJeb_Hohm_createArrivalNode = 创建到达节点
+ #MechJeb_Hohm_simpleTransfer = 仅共面
+
+ #MechJeb_Hohm_Exception1 = 必须为此机动选择一个目标。
#MechJeb_Hohm_Exception2 = 机动目标必须在同一引力范围内。
#MechJeb_Hohm_Exception3 = 与目标的升交点不存在。
#MechJeb_Hohm_Exception4 = 与目标的降交点不存在。
- #MechJeb_Hohm_Exception5 = 与目标的降交点与升交点都不存在。
+ #MechJeb_Hohm_Exception5 = 与目标的升交点和降交点都不存在。
//Change Apoapsis
#MechJeb_Ap_title = 更改远拱点
diff --git a/MechJeb2.sln.DotSettings b/MechJeb2.sln.DotSettings
index 519df9d42..d13548001 100644
--- a/MechJeb2.sln.DotSettings
+++ b/MechJeb2.sln.DotSettings
@@ -51,6 +51,7 @@
True
True
True
+ True
True
True
True
diff --git a/MechJeb2/Maneuver/OperationTransfer.cs b/MechJeb2/Maneuver/OperationTransfer.cs
index 8a6863779..ed4c402cd 100644
--- a/MechJeb2/Maneuver/OperationTransfer.cs
+++ b/MechJeb2/Maneuver/OperationTransfer.cs
@@ -22,7 +22,7 @@ public class OperationGeneric : Operation
[UsedImplicitly]
[Persistent(pass = (int)Pass.GLOBAL)]
- public bool Rendezvous = true;
+ public bool MatchOrbit = false;
[UsedImplicitly]
[Persistent(pass = (int)Pass.GLOBAL)]
@@ -49,19 +49,41 @@ public class OperationGeneric : Operation
public override void DoParametersGUI(Orbit o, double universalTime, MechJebModuleTargetController target)
{
- Capture =
- !GUILayout.Toggle(!Capture, Localizer.Format("#MechJeb_Hohm_intercept_only")); //no capture burn (impact/flyby)
- if (Capture)
- PlanCapture = GUILayout.Toggle(PlanCapture, "Plan insertion burn");
- Coplanar = GUILayout.Toggle(Coplanar, Localizer.Format("#MechJeb_Hohm_simpleTransfer")); //coplanar maneuver
+ bool isCelestialTarget = target.Target is CelestialBody;
+
+ // two-burn capture vs single-burn intercept/flyby
GUILayout.BeginHorizontal();
- if (GUILayout.Toggle(Rendezvous, "Rendezvous"))
- Rendezvous = true;
- if (GUILayout.Toggle(!Rendezvous, "Transfer"))
- Rendezvous = false;
+ if (GUILayout.Toggle(Capture, isCelestialTarget
+ ? Localizer.Format("#MechJeb_Hohm_transfer") //Transfer
+ : Localizer.Format("#MechJeb_Hohm_rendezvous"))) //Rendezvous
+ Capture = true;
+ if (GUILayout.Toggle(!Capture, isCelestialTarget
+ ? Localizer.Format("#MechJeb_Hohm_flyby") //Flyby / Impact
+ : Localizer.Format("#MechJeb_Hohm_intercept"))) //Intercept
+ Capture = false;
GUILayout.EndHorizontal();
- if (Rendezvous)
- GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Hohm_Label1"), LagTime, "sec"); //fractional target period offset
+
+ // match the target's orbit rather than intercepting the target itself
+ if (Capture)
+ {
+ GUILayout.BeginHorizontal();
+ MatchOrbit = GUILayout.Toggle(MatchOrbit, Localizer.Format("#MechJeb_Hohm_matchOrbit")); //Match orbit
+ GUILayout.EndHorizontal();
+ }
+
+ // arrival delay offsets the intercept point (e.g. 10 seconds behind a station, or half a moon's period)
+ if (Capture && !MatchOrbit)
+ GuiUtils.SimpleTextBox(Localizer.Format("#MechJeb_Hohm_arrivalDelay"), LagTime, "sec"); //Arrival delay
+
+ // optionally create a maneuver node for the arrival burn
+ // (not offered for a direct transfer to a celestial without match orbit or arrival delay)
+ if (Capture && (!isCelestialTarget || MatchOrbit || LagTime.Val != 0))
+ PlanCapture = GUILayout.Toggle(PlanCapture, Localizer.Format("#MechJeb_Hohm_createArrivalNode")); //Create arrival node
+ else
+ PlanCapture = false;
+
+ // coplanar restricts the transfer to the parking orbit plane (user can add a mid-course correction)
+ Coplanar = GUILayout.Toggle(Coplanar, Localizer.Format("#MechJeb_Hohm_simpleTransfer")); //Coplanar only
_timeSelector.DoChooseTimeGUI();
}
@@ -75,13 +97,9 @@ protected override List MakeNodesImpl(Orbit o, double univer
new OperationException(
Localizer.Format("#MechJeb_Hohm_Exception2")); //target for bi-impulsive transfer must be in the same sphere of influence.
- if (target.Target is CelestialBody && Capture && PlanCapture)
- ErrorMessage =
- "Insertion burn to a celestial with an SOI is not supported by this maneuver. A Transfer-to-Moon maneuver needs to be written to properly support this case.";
-
Orbit targetOrbit = target.TargetOrbit;
- double lagTime = Rendezvous ? LagTime.Val : 0;
+ double lagTime = !MatchOrbit ? LagTime.Val : 0;
bool fixedTime = false;
@@ -105,7 +123,7 @@ protected override List MakeNodesImpl(Orbit o, double univer
}
(Vector3d dV1, double ut1, Vector3d dV2, double ut2) =
- OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(o, targetOrbit, universalTime, lagTime, fixedTime, Coplanar, Rendezvous,
+ OrbitalManeuverCalculator.DeltaVAndTimeForHohmannTransfer(o, targetOrbit, universalTime, lagTime, fixedTime, Coplanar, Capture && !MatchOrbit,
Capture);
if (Capture && PlanCapture)
diff --git a/MechJebLib/Maneuvers/TwoImpulseTransfer.cs b/MechJebLib/Maneuvers/TwoImpulseTransfer.cs
index 47dd27411..0df3a4b52 100644
--- a/MechJebLib/Maneuvers/TwoImpulseTransfer.cs
+++ b/MechJebLib/Maneuvers/TwoImpulseTransfer.cs
@@ -8,6 +8,7 @@
using MechJebLib.Primitives;
using MechJebLib.TwoBody;
using MechJebLib.Utils;
+using static MechJebLib.Utils.Statics;
using static System.Math;
namespace MechJebLib.Maneuvers
@@ -223,6 +224,8 @@ public static (V3 dv1, double dt1, V3 dv2, double dt2) NextManeuver(double mu, V
double lagTime = double.NaN, bool coplanar = true, bool rendezvous = true, bool capture = true,
bool fixedTime = false, bool optguard = false)
{
+ Print($"[MechJebLib] Maneuvers.NextManeuver.TwoImpulseTransfer({mu}, {r1}, {r2}, {v1}, {v2}, maxiter: {maxiter}, lagTime: {lagTime}, coplanar: {coplanar}, rendezvous: {rendezvous}, capture: {capture}, fixedTime: {fixedTime}, optguard: {optguard})");
+
double synodicPeriod = Astro.SynodicPeriod(mu, r1, v1, r2, v2);
if (fixedTime)
@@ -240,7 +243,7 @@ public static (V3 dv1, double dt1, V3 dv2, double dt2) NextManeuver(double mu, V
dtguess += synodicPeriod * 0.10;
}
- throw new MechJebLibException($"TwoImpulseTransfer.NextManeuver({mu}, {r1}, {v1}, {v2}, {r2}): too many iterations");
+ throw new MechJebLibException($"[MechJebLib] Maneuvers.NextManeuver.TwoImpulseTransfer(): too many iterations");
}
}
}