-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAutoGimbal.cs
More file actions
138 lines (119 loc) · 5.8 KB
/
AutoGimbal.cs
File metadata and controls
138 lines (119 loc) · 5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using KSP;
using InfernalRobotics;
using MuMech;
namespace AutoGimbal
{
public class AutoGimbal : PartModule
{
[KSPField(isPersistant = true, guiActive = true)]
public double pos_X = 0;
[KSPField(isPersistant = true, guiActive = true)]
public double pos_Y = 0;
[KSPField(isPersistant = true, guiActive = true)]
public double pos_Z = 0;
[KSPField(isPersistant = true, guiActive = true)]
public string Target = "none";
[KSPField(isPersistant = true, guiActive = true)]
public float rotation = 0;
[KSPField(isPersistant = true, guiActive = true)]
public int TrackingState = 0;
[KSPField(isPersistant = true, guiActive = true)]
public int MoveState = 0;
private float min_Delta;
public AutoGimbalManager manager;
Vessel currentVess;
List<CelestialBody> body = FlightGlobals.Bodies;
List<Vessel> ship = FlightGlobals.Vessels;
public override void OnStart(StartState start)
{
print("Celestial Body count:" + body.Count);
print("Vessel count:" + ship.Count);
currentVess = FlightGlobals.fetch.activeVessel;
Debug.Log("[AutoGimbal] - Partmodule loaded");
}
//This override to the OnUpdate function runs on every physics frame, and updates all values and calculations we're interested in.
public override void OnUpdate()
{
var Robotics = part.FindModulesImplementing<MuMechToggle>().First();
rotation = Robotics.rotation;
min_Delta = float.Parse(Robotics.stepIncrement) * 2;
Vector3d position = currentVess.GetWorldPos3D();
Vector3d t_pos = body[2].position;
Quaternion q = currentVess.ReferenceTransform.rotation;
Vector3d delta = (position - t_pos);
//Rotate vector into ship frame. Unity does quaternion rotations implicitly.
Vector3d PV_ship = q * delta;
//Grab attachment rotation of the part, then rotate pointing vector into part frame.
Quaternion q_part = part.attRotation;
Vector3d PV_part = q_part * PV_ship;
//With the pointing vector in the part frame, project the pointing vector onto the rotation plane of the part itself. The rotation axis is available in the Robotics object Robotics.rotateAxis, just need to project onto the plane.
// believe the rotation value is relative
TrackingState = manager.TrackingState;
float Rotation_Target = manager.rotationTarget;
MoveState = IR_Commander(TrackingState, MoveState, Rotation_Target);
pos_X = delta.x;
pos_Y = delta.y;
pos_Z = delta.z;
}
//IR_Commander interfaces with Infernal Robotics to command motion to a specific point as specified on input.
// TrackingState is input from the GUI, commanded by user.
// MoveState keeps track of whether the part is in motion, and what direction.
// Rotation_Target is specified by math (or user input)
public int IR_Commander(int TrackingState, int MoveState, float Rotation_Target)
{
var Robotics = part.FindModulesImplementing<MuMechToggle>().First();
float Delta = Math.Abs(Robotics.rotation - Rotation_Target);
if (TrackingState == 1) //User has enabled motion, to track to rotation target.
{
//Logic to catch either case with the servo inverted or non-inverted.
if (((Robotics.rotation > Rotation_Target && !Robotics.invertAxis) ||
(Robotics.rotation < Rotation_Target && Robotics.invertAxis))
&& Delta > min_Delta && MoveState == 0) //Movestate = 0 defines stopped
{
Robotics.moveFlags |= 0x100; //Start negative motion
MoveState = 1; //MoveState = 1 defines negative motion
}
else if (((Robotics.rotation < Rotation_Target && !Robotics.invertAxis) ||
(Robotics.rotation > Rotation_Target && Robotics.invertAxis))
&& Delta > min_Delta && MoveState == 0) //Movestate = 0 defines stopped
{
Robotics.moveFlags |= 0x200; //Start positive motion
MoveState = 2; //MoveState = 2 defines positive motion
}
else if (((Robotics.rotation <= Rotation_Target && !Robotics.invertAxis) ||
(Robotics.rotation >= Rotation_Target && Robotics.invertAxis))
&& MoveState == 1)
{
Robotics.moveFlags &= ~0x100; //Stop negative motion
MoveState = 0;
}
else if (((Robotics.rotation >= Rotation_Target && !Robotics.invertAxis) ||
(Robotics.rotation <= Rotation_Target && Robotics.invertAxis))
&& MoveState == 2)
{
Robotics.moveFlags &= ~0x200; //Stop positive motion
MoveState = 0; //MoveState = 0 defines negative motion
}
}
else if (TrackingState == 0)
{
if (MoveState == 2)
{
Robotics.moveFlags &= ~0x200; //Stop positive motion
MoveState = 0; //MoveState = 0 defines negative motion
}
else if (MoveState == 1)
{
Robotics.moveFlags &= ~0x100; //Stop negative motion
MoveState = 0;
}
}
return MoveState;
}//end IR_Commander
}
}