Skip to content

Commit 27e7ecd

Browse files
Fix #759 (Request: possibility to only set roll / pitch / heading - not all at once)
1 parent b4f3a7f commit 27e7ecd

File tree

7 files changed

+204
-18
lines changed

7 files changed

+204
-18
lines changed

GameData/RemoteTech/Localization/en-us.cfg

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,18 @@ Localization
293293
#RT_AttitudeFragment_RadialMinus_desc = Orient to Anti-radial.
294294
#RT_AttitudeFragment_NormalMinus = NRM\n-
295295
#RT_AttitudeFragment_NormalMinus_desc = Orient to Anti-normal.
296-
#RT_AttitudeFragment_PIT = PIT:
296+
#RT_AttitudeFragment_PIT = PIT
297297
#RT_AttitudeFragment_PIT_desc = Sets pitch.
298-
#RT_AttitudeFragment_HDG = HDG:
298+
#RT_AttitudeFragment_HDG = HDG
299299
#RT_AttitudeFragment_HDG_desc = Sets heading.
300-
#RT_AttitudeFragment_RLL = RLL:
300+
#RT_AttitudeFragment_RLL = RLL
301301
#RT_AttitudeFragment_RLL_desc = Sets roll.
302+
#RT_AttitudeFragment_IgnorePit = IGN\nPIT
303+
#RT_AttitudeFragment_IgnorePit_desc = Ignore pitch control.
304+
#RT_AttitudeFragment_IgnoreHdr = IGN\nHDR
305+
#RT_AttitudeFragment_IgnoreHdr_desc = Ignore heading control.
306+
#RT_AttitudeFragment_IgnoreRll = IGN\nRLL
307+
#RT_AttitudeFragment_IgnoreRll_desc = Ignore roll control.
302308
#RT_AttitudeFragment_Throttle = Throttle:
303309
#RT_AttitudeFragment_BURN = BURN
304310
#RT_AttitudeFragment_BURN_desc = Example: 125, 125s, 5m20s, 1d6h20m10s, 123m/s.

GameData/RemoteTech/Localization/zh-cn.cfg

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,18 @@ Localization
292292
#RT_AttitudeFragment_RadialMinus_desc = 朝向径向向下.
293293
#RT_AttitudeFragment_NormalMinus = 反法向
294294
#RT_AttitudeFragment_NormalMinus_desc = 朝向反法线方向.
295-
#RT_AttitudeFragment_PIT = PIT:
295+
#RT_AttitudeFragment_PIT = PIT
296296
#RT_AttitudeFragment_PIT_desc = 设定俯仰角.
297-
#RT_AttitudeFragment_HDG = HDG:
297+
#RT_AttitudeFragment_HDG = HDG
298298
#RT_AttitudeFragment_HDG_desc = 设定偏航角.
299-
#RT_AttitudeFragment_RLL = RLL:
299+
#RT_AttitudeFragment_RLL = RLL
300300
#RT_AttitudeFragment_RLL_desc = 设定滚转角.
301+
#RT_AttitudeFragment_IgnorePit = IGN\nPIT
302+
#RT_AttitudeFragment_IgnorePit_desc = Ignore pitch control.
303+
#RT_AttitudeFragment_IgnoreHdr = IGN\nHDR
304+
#RT_AttitudeFragment_IgnoreHdr_desc = Ignore heading control.
305+
#RT_AttitudeFragment_IgnoreRll = IGN\nRLL
306+
#RT_AttitudeFragment_IgnoreRll_desc = Ignore roll control.
301307
#RT_AttitudeFragment_Throttle = 节流阀:
302308
#RT_AttitudeFragment_BURN = 点火
303309
#RT_AttitudeFragment_BURN_desc = 例如: 125, 125s, 5m20s, 1d6h20m10s, 123m/s.

src/RemoteTech/FlightComputer/Commands/AbstractCommand.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ public static ICommand LoadCommand(ConfigNode n, FlightComputer fc)
129129
case "HibernationCommand": { command = new HibernationCommand(); break; }
130130
case "AxisGroupCommand": { command = new AxisGroupCommand(); break; }
131131
case "PIDCommand": { command = new PIDCommand(); break; }
132+
case "FlightControlCommand": { command = new FlightControlCommand(); break; }
132133
}
133134

134135
if (command != null)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System;
2+
3+
namespace RemoteTech.FlightComputer.Commands
4+
{
5+
public class FlightControlCommand : AbstractCommand
6+
{
7+
[Persistent] public bool ignorePitchOutput;
8+
[Persistent] public bool ignoreHeadingOutput;
9+
[Persistent] public bool ignoreRollOutput;
10+
11+
private bool mAbort;
12+
private string stringReady = "";
13+
14+
public override string ShortName
15+
{
16+
get
17+
{
18+
return "Pitch, Heading and Roll controls";
19+
}
20+
}
21+
22+
public override string Description
23+
{
24+
get
25+
{
26+
return ShortName + ":" + Environment.NewLine + stringReady + base.Description;
27+
}
28+
}
29+
30+
public static FlightControlCommand WithPHR(bool ignore_pitch, bool ignore_heading, bool ignore_roll)
31+
{
32+
return new FlightControlCommand()
33+
{
34+
ignorePitchOutput = ignore_pitch,
35+
ignoreHeadingOutput = ignore_heading,
36+
ignoreRollOutput = ignore_roll,
37+
TimeStamp = RTUtil.GameTime,
38+
};
39+
}
40+
41+
public override bool Pop(FlightComputer fc)
42+
{
43+
if (fc != null)
44+
{
45+
//remove active command if existing
46+
var activeCommand = FlightControlCommand.findActiveControlCmd(fc);
47+
if(activeCommand != null && activeCommand.CmdGuid != this.CmdGuid)
48+
{
49+
activeCommand.Abort();
50+
}
51+
52+
//build custom string
53+
var list = new string[3];
54+
var count = 0;
55+
if (ignorePitchOutput) { list[count++] = "Pitch ignored"; }
56+
if (ignoreHeadingOutput) { list[count++] = "Heading ignored"; }
57+
if (ignoreRollOutput) { list[count++] = "Roll ignored"; }
58+
59+
for(int i=0; i<count;i++)
60+
{
61+
stringReady += list[i];
62+
if (i < count -1) { stringReady += ", "; }
63+
}
64+
if (stringReady.Length > 0) { stringReady += Environment.NewLine; }
65+
66+
return true;
67+
}
68+
return false;
69+
}
70+
71+
public override bool Execute(FlightComputer fc, FlightCtrlState ctrlState)
72+
{
73+
SteeringHelper.FlightOutputControlMask = 0; //blank off
74+
75+
if (mAbort || (!ignorePitchOutput && !ignoreHeadingOutput && !ignoreRollOutput)) { return true; }
76+
77+
if (ignorePitchOutput) { SteeringHelper.FlightOutputControlMask |= SteeringHelper.FlightControlOutput.IgnorePitch; }
78+
if (ignoreHeadingOutput) { SteeringHelper.FlightOutputControlMask |= SteeringHelper.FlightControlOutput.IgnoreHeading; }
79+
if (ignoreRollOutput) { SteeringHelper.FlightOutputControlMask |= SteeringHelper.FlightControlOutput.IgnoreRoll; }
80+
81+
return false;
82+
}
83+
84+
public static FlightControlCommand findActiveControlCmd(FlightComputer fc)
85+
{
86+
var cmdItr = fc.ActiveCommands.GetEnumerator();
87+
while (cmdItr.MoveNext())
88+
{
89+
if (cmdItr.Current is FlightControlCommand)
90+
{
91+
return cmdItr.Current as FlightControlCommand;
92+
}
93+
}
94+
95+
return null;
96+
}
97+
98+
public override void Abort() { mAbort = true; }
99+
}
100+
}

src/RemoteTech/FlightComputer/FlightCore.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ public static void HoldAttitude(FlightCtrlState fs, FlightComputer f, ReferenceF
123123
/// <summary>
124124
/// Single entry point of all Flight Computer orientation holding, including maneuver node.
125125
/// </summary>
126-
public static void HoldOrientation(FlightCtrlState fs, FlightComputer f, Quaternion target, bool ignoreRoll = false)
126+
public static void HoldOrientation(FlightCtrlState fs, FlightComputer f, Quaternion target, bool ignoreRoll = false, bool ignorePitch = false, bool ignoreHeading = false)
127127
{
128128
f.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, false);
129-
SteeringHelper.SteerShipToward(target, fs, f, ignoreRoll);
129+
SteeringHelper.SteerShipToward(target, fs, f, ignoreRoll, ignorePitch, ignoreHeading);
130130
}
131131

132132
/// <summary>
@@ -176,9 +176,23 @@ public static double GetTotalThrust(Vessel v)
176176

177177
public static class SteeringHelper
178178
{
179+
public enum FlightControlOutput
180+
{
181+
IgnorePitch = 1,
182+
IgnoreHeading = 2,
183+
IgnoreRoll = 4,
184+
}
185+
179186
private const double outputDeadband = 0.001;
180187
private const float driveLimit = 1.0f;
181188

189+
private static FlightControlOutput outputControlMask = 0;
190+
public static FlightControlOutput FlightOutputControlMask
191+
{
192+
get { return outputControlMask; }
193+
set { outputControlMask = value; }
194+
}
195+
182196
/* MechJeb2 torque variables */
183197
private static Vector6 torqueReactionWheel = new Vector6();
184198
private static Vector6 torqueGimbal = new Vector6();
@@ -206,7 +220,7 @@ public static Vector3d TorqueReactionSpeed
206220
/// <param name="c">The FlightCtrlState for the current vessel.</param>
207221
/// <param name="fc">The flight computer carrying out the slew</param>
208222
/// <param name="ignoreRoll">[optional] to ignore the roll</param>
209-
public static void SteerShipToward(Quaternion target, FlightCtrlState c, FlightComputer fc, bool ignoreRoll)
223+
public static void SteerShipToward(Quaternion target, FlightCtrlState c, FlightComputer fc, bool ignoreRoll, bool ignorePitch, bool ignoreHeading)
210224
{
211225
var actuation = fc.PIDController.GetActuation(target);
212226

@@ -216,9 +230,9 @@ public static void SteerShipToward(Quaternion target, FlightCtrlState c, FlightC
216230
actuation.z = Math.Abs(actuation.z) >= outputDeadband ? actuation.z : 0.0;
217231

218232
// update the flight controls
219-
c.pitch = Mathf.Clamp((float) actuation.x, -driveLimit, driveLimit);
220-
c.roll = !ignoreRoll ? Mathf.Clamp((float) actuation.y, -driveLimit, driveLimit) : 0.0f;
221-
c.yaw = Mathf.Clamp((float) actuation.z, -driveLimit, driveLimit);
233+
c.pitch = (ignorePitch || (FlightOutputControlMask & FlightControlOutput.IgnorePitch) == FlightControlOutput.IgnorePitch) ? 0.0f : Mathf.Clamp((float) actuation.x, -driveLimit, driveLimit);
234+
c.roll = (ignoreRoll || (FlightOutputControlMask & FlightControlOutput.IgnoreRoll) == FlightControlOutput.IgnoreRoll) ? 0.0f : Mathf.Clamp((float) actuation.y, -driveLimit, driveLimit);
235+
c.yaw = (ignoreHeading || (FlightOutputControlMask & FlightControlOutput.IgnoreHeading) == FlightControlOutput.IgnoreHeading) ? 0.0f : Mathf.Clamp((float) actuation.z, -driveLimit, driveLimit);
222236
}
223237

224238
/// <summary>

src/RemoteTech/RemoteTech.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120
<Compile Include="FlightComputer\Commands\CancelCommand.cs" />
121121
<Compile Include="FlightComputer\Commands\DriveCommand.cs" />
122122
<Compile Include="FlightComputer\Commands\HibernationCommand.cs" />
123+
<Compile Include="FlightComputer\Commands\FlightControlCommand.cs" />
123124
<Compile Include="FlightComputer\Commands\ManeuverCommand.cs" />
124125
<Compile Include="FlightComputer\Commands\PartActionCommand.cs" />
125126
<Compile Include="FlightComputer\Commands\PIDCommand.cs" />

src/RemoteTech/UI/AttitudeFragment.cs

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using RemoteTech.FlightComputer.Commands;
44
using UnityEngine;
55
using KSP.Localization;
6+
using static RemoteTech.FlightComputer.SteeringHelper;
7+
using RemoteTech.FlightComputer;
68

79
namespace RemoteTech.UI
810
{
@@ -82,14 +84,13 @@ private double DeltaV
8284
}
8385
}
8486

85-
private FlightAttitude Attitude { get { return mAttitude; } }
86-
8787
private FlightComputer.FlightComputer mFlightComputer;
8888
private Action mOnClickQueue;
8989

9090
private ComputerMode mMode;
9191
private FlightAttitude mAttitude;
9292
private float mThrottle;
93+
private FlightControlOutput mControlOutputMask = 0;
9394

9495
private String mPitch = "90";
9596
private String mRoll = "90";
@@ -190,6 +191,16 @@ public void Draw()
190191
RTUtil.MouseWheelTriggerField(ref mRoll, "rt_phr3", () => { Roll++; }, () => { Roll--; }, GUILayout.Width(width3));
191192
}
192193
GUILayout.EndHorizontal();
194+
GUILayout.Space(5);
195+
196+
GUILayout.BeginHorizontal();
197+
{
198+
RTUtil.FakeStateButton(new GUIContent(Localizer.Format("#RT_AttitudeFragment_IgnorePit"), Localizer.Format("#RT_AttitudeFragment_IgnorePit_desc")), () => RTCore.Instance.StartCoroutine(OnControlClick(FlightControlOutput.IgnorePitch)), (int)(mControlOutputMask & FlightControlOutput.IgnorePitch), (int)FlightControlOutput.IgnorePitch, GUILayout.Width(width3));//"IGN\nPIT", "Ignore pitch control."
199+
RTUtil.FakeStateButton(new GUIContent(Localizer.Format("#RT_AttitudeFragment_IgnoreHdr"), Localizer.Format("#RT_AttitudeFragment_IgnoreHdr_desc")), () => RTCore.Instance.StartCoroutine(OnControlClick(FlightControlOutput.IgnoreHeading)), (int)(mControlOutputMask & FlightControlOutput.IgnoreHeading), (int)FlightControlOutput.IgnoreHeading, GUILayout.Width(width3));//"IGN\nHDR", "Ignore heading control."
200+
RTUtil.FakeStateButton(new GUIContent(Localizer.Format("#RT_AttitudeFragment_IgnoreRll"), Localizer.Format("#RT_AttitudeFragment_IgnoreRll_desc")), () => RTCore.Instance.StartCoroutine(OnControlClick(FlightControlOutput.IgnoreRoll)), (int)(mControlOutputMask & FlightControlOutput.IgnoreRoll), (int)FlightControlOutput.IgnoreRoll, GUILayout.Width(width3));//"IGN\nRLL", "Ignore roll control."
201+
}
202+
GUILayout.EndHorizontal();
203+
GUILayout.Space(5);
193204

194205
GUILayout.BeginHorizontal();
195206
{
@@ -243,6 +254,43 @@ private IEnumerator OnAttitudeClick(FlightAttitude state)
243254
}
244255
}
245256

257+
private IEnumerator OnControlClick(FlightControlOutput output)
258+
{
259+
yield return null;
260+
if (mFlightComputer.InputAllowed)
261+
{
262+
switch(output)
263+
{
264+
case FlightControlOutput.IgnorePitch:
265+
if ((mControlOutputMask & FlightControlOutput.IgnorePitch) == FlightControlOutput.IgnorePitch)
266+
mControlOutputMask &= ~FlightControlOutput.IgnorePitch;
267+
else
268+
mControlOutputMask |= FlightControlOutput.IgnorePitch;
269+
break;
270+
271+
case FlightControlOutput.IgnoreHeading:
272+
if ((mControlOutputMask & FlightControlOutput.IgnoreHeading) == FlightControlOutput.IgnoreHeading)
273+
mControlOutputMask &= ~FlightControlOutput.IgnoreHeading;
274+
else
275+
mControlOutputMask |= FlightControlOutput.IgnoreHeading;
276+
break;
277+
278+
case FlightControlOutput.IgnoreRoll:
279+
if ((mControlOutputMask & FlightControlOutput.IgnoreRoll) == FlightControlOutput.IgnoreRoll)
280+
mControlOutputMask &= ~FlightControlOutput.IgnoreRoll;
281+
else
282+
mControlOutputMask |= FlightControlOutput.IgnoreRoll;
283+
break;
284+
}
285+
286+
bool pitch = (mControlOutputMask & FlightControlOutput.IgnorePitch) == FlightControlOutput.IgnorePitch,
287+
heading = (mControlOutputMask & FlightControlOutput.IgnoreHeading) == FlightControlOutput.IgnoreHeading,
288+
roll = (mControlOutputMask & FlightControlOutput.IgnoreRoll) == FlightControlOutput.IgnoreRoll;
289+
290+
mFlightComputer.Enqueue(FlightControlCommand.WithPHR(pitch, heading, roll));
291+
}
292+
}
293+
246294
private void Confirm()
247295
{
248296
ICommand newCommand;
@@ -264,22 +312,22 @@ private void Confirm()
264312
case ComputerMode.TargetPos:
265313
mAttitude = (mAttitude == FlightAttitude.Null) ? FlightAttitude.Prograde : mAttitude;
266314
newCommand =
267-
AttitudeCommand.WithAttitude(Attitude, ReferenceFrame.TargetParallel);
315+
AttitudeCommand.WithAttitude(mAttitude, ReferenceFrame.TargetParallel);
268316
break;
269317
case ComputerMode.Orbital:
270318
mAttitude = (mAttitude == FlightAttitude.Null) ? FlightAttitude.Prograde : mAttitude;
271319
newCommand =
272-
AttitudeCommand.WithAttitude(Attitude, ReferenceFrame.Orbit);
320+
AttitudeCommand.WithAttitude(mAttitude, ReferenceFrame.Orbit);
273321
break;
274322
case ComputerMode.Surface:
275323
mAttitude = (mAttitude == FlightAttitude.Null) ? FlightAttitude.Prograde : mAttitude;
276324
newCommand =
277-
AttitudeCommand.WithAttitude(Attitude, ReferenceFrame.Surface);
325+
AttitudeCommand.WithAttitude(mAttitude, ReferenceFrame.Surface);
278326
break;
279327
case ComputerMode.TargetVel:
280328
mAttitude = (mAttitude == FlightAttitude.Null) ? FlightAttitude.Prograde : mAttitude;
281329
newCommand =
282-
AttitudeCommand.WithAttitude(Attitude, ReferenceFrame.TargetVelocity);
330+
AttitudeCommand.WithAttitude(mAttitude, ReferenceFrame.TargetVelocity);
283331
break;
284332
case ComputerMode.Custom:
285333
mAttitude = FlightAttitude.Null;
@@ -344,6 +392,15 @@ public void getActiveFlightMode()
344392

345393
if(mMode == ComputerMode.Orbital || mMode == ComputerMode.Surface || mMode == ComputerMode.TargetPos || mMode == ComputerMode.TargetVel)
346394
mAttitude = mappedCommand.computerAttitude;
395+
396+
var activeIgnoreCmd = FlightControlCommand.findActiveControlCmd(mFlightComputer);
397+
if (activeIgnoreCmd != null)
398+
{
399+
mControlOutputMask = 0;
400+
if (activeIgnoreCmd.ignorePitchOutput) { mControlOutputMask |= FlightControlOutput.IgnorePitch; }
401+
if (activeIgnoreCmd.ignoreHeadingOutput) { mControlOutputMask |= FlightControlOutput.IgnoreHeading; }
402+
if (activeIgnoreCmd.ignoreRollOutput) { mControlOutputMask |= FlightControlOutput.IgnoreRoll; }
403+
}
347404
}
348405

349406
/// <summary>
@@ -354,6 +411,7 @@ public void Reset()
354411
// get active command
355412
mMode = ComputerMode.Off;
356413
mAttitude = FlightAttitude.Null;
414+
mControlOutputMask = 0;
357415
}
358416
}
359417
}

0 commit comments

Comments
 (0)