Pitch, Heading and RollΒΆ
This example calculates the pitch, heading and rolls angles of the active vessel once per second.
using System;
using KRPC.Client;
using KRPC.Client.Services.SpaceCenter;
using Vector3 = System.Tuple<double, double, double>;
class AngleOfAttack
{
static Vector3 CrossProduct (Vector3 u, Vector3 v)
{
return new Vector3 (
u.Item2 * v.Item3 - u.Item3 * v.Item2,
u.Item3 * v.Item1 - u.Item1 * v.Item3,
u.Item1 * v.Item2 - u.Item2 * v.Item1
);
}
static double DotProduct (Vector3 u, Vector3 v)
{
return u.Item1 * v.Item1 + u.Item2 * v.Item2 + u.Item3 * v.Item3;
}
static double Magnitude (Vector3 v)
{
return Math.Sqrt (DotProduct (v, v));
}
// Compute the angle between vector x and y
static double AngleBetweenVectors (Vector3 u, Vector3 v)
{
double dp = DotProduct (u, v);
if (dp == 0)
return 0;
double um = Magnitude (u);
double vm = Magnitude (v);
return Math.Acos (dp / (um * vm)) * (180f / Math.PI);
}
public static void Main ()
{
var conn = new Connection ("Angle of attack");
var vessel = conn.SpaceCenter ().ActiveVessel;
while (true) {
var vesselDirection = vessel.Direction (vessel.SurfaceReferenceFrame);
// Get the direction of the vessel in the horizon plane
var horizonDirection = new Vector3 (
0, vesselDirection.Item2, vesselDirection.Item3);
// Compute the pitch - the angle between the vessels direction and
// the direction in the horizon plane
double pitch = AngleBetweenVectors (vesselDirection, horizonDirection);
if (vesselDirection.Item1 < 0)
pitch = -pitch;
// Compute the heading - the angle between north and
// the direction in the horizon plane
var north = new Vector3 (0, 1, 0);
double heading = AngleBetweenVectors (north, horizonDirection);
if (horizonDirection.Item3 < 0)
heading = 360 - heading;
// Compute the roll
// Compute the plane running through the vessels direction
// and the upwards direction
var up = new Vector3 (1, 0, 0);
var planeNormal = CrossProduct (vesselDirection, up);
// Compute the upwards direction of the vessel
var vesselUp = conn.SpaceCenter ().TransformDirection (
new Vector3 (0, 0, -1),
vessel.ReferenceFrame, vessel.SurfaceReferenceFrame);
// Compute the angle between the upwards direction of
// the vessel and the plane normal
double roll = AngleBetweenVectors (vesselUp, planeNormal);
// Adjust so that the angle is between -180 and 180 and
// rolling right is +ve and left is -ve
if (vesselUp.Item1 > 0)
roll *= -1;
else if (roll < 0)
roll += 180;
else
roll -= 180;
Console.WriteLine ("pitch = {0:F1}, heading = {1:F1}, roll = {2:F1}",
pitch, heading, roll);
System.Threading.Thread.Sleep (1000);
}
}
}
#include <iostream>
#include <iomanip>
#include <tuple>
#include <thread>
#include <chrono>
#include <cmath>
#include <krpc.hpp>
#include <krpc/services/space_center.hpp>
static const double pi = 3.1415926535897;
typedef std::tuple<double, double, double> vector3;
vector3 cross_product(const vector3& u, const vector3& v) {
return std::make_tuple(
std::get<1>(u)*std::get<2>(v) - std::get<2>(u)*std::get<1>(v),
std::get<2>(u)*std::get<0>(v) - std::get<0>(u)*std::get<2>(v),
std::get<0>(u)*std::get<1>(v) - std::get<1>(u)*std::get<0>(v));
}
double dot_product(const vector3& u, const vector3& v) {
return
std::get<0>(u)*std::get<0>(v) +
std::get<1>(u)*std::get<1>(v) +
std::get<2>(u)*std::get<2>(v);
}
double magnitude(const vector3& v) {
return std::sqrt(dot_product(v, v));
}
// Compute the angle between vector u and v
double angle_between_vectors(const vector3& u, const vector3& v) {
double dp = dot_product(u, v);
if (dp == 0)
return 0;
double um = magnitude(u);
double vm = magnitude(v);
return std::acos(dp / (um*vm)) * (180.0 / pi);
}
int main() {
krpc::Client conn = krpc::connect("Pitch/Heading/Roll");
krpc::services::SpaceCenter space_center(&conn);
auto vessel = space_center.active_vessel();
while (true) {
vector3 vessel_direction = vessel.direction(vessel.surface_reference_frame());
// Get the direction of the vessel in the horizon plane
vector3 horizon_direction {
0, std::get<1>(vessel_direction), std::get<2>(vessel_direction)
};
// Compute the pitch - the angle between the vessels direction
// and the direction in the horizon plane
double pitch = angle_between_vectors(vessel_direction, horizon_direction);
if (std::get<0>(vessel_direction) < 0)
pitch = -pitch;
// Compute the heading - the angle between north
// and the direction in the horizon plane
vector3 north {0, 1, 0};
double heading = angle_between_vectors(north, horizon_direction);
if (std::get<2>(horizon_direction) < 0)
heading = 360 - heading;
// Compute the roll
// Compute the plane running through the vessels direction
// and the upwards direction
vector3 up {1, 0, 0};
vector3 plane_normal = cross_product(vessel_direction, up);
// Compute the upwards direction of the vessel
vector3 vessel_up = space_center.transform_direction(
std::make_tuple(0, 0, -1),
vessel.reference_frame(),
vessel.surface_reference_frame());
// Compute the angle between the upwards direction of
// the vessel and the plane normal
double roll = angle_between_vectors(vessel_up, plane_normal);
// Adjust so that the angle is between -180 and 180 and
// rolling right is +ve and left is -ve
if (std::get<0>(vessel_up) > 0)
roll *= -1;
else if (roll < 0)
roll += 180;
else
roll -= 180;
std::cout << std::fixed << std::setprecision(1);
std::cout << "pitch = " << pitch << ", "
<< "heading = " << heading << ", "
<< "roll = " << roll << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
#include <math.h>
#include <unistd.h>
#include <krpc_cnano.h>
#include <krpc_cnano/services/space_center.h>
static double pi = 3.1415926535897;
typedef krpc_tuple_double_double_double_t vector3;
vector3 cross_product(vector3 u, vector3 v) {
vector3 result = {
u.e1*v.e2 - u.e2*v.e1,
u.e2*v.e0 - u.e0*v.e2,
u.e0*v.e1 - u.e1*v.e0
};
return result;
}
double dot_product(vector3 u, vector3 v) {
return u.e0*v.e0 + u.e1*v.e1 + u.e2*v.e2;
}
double magnitude(vector3 v) {
return sqrt(dot_product(v, v));
}
// Compute the angle between vector u and v
double angle_between_vectors(vector3 u, vector3 v) {
double dp = dot_product(u, v);
if (dp == 0)
return 0;
double um = magnitude(u);
double vm = magnitude(v);
return acos(dp / (um*vm)) * (180.0 / pi);
}
int main() {
krpc_connection_t conn;
krpc_open(&conn, "COM0");
krpc_connect(conn, "");
krpc_SpaceCenter_Vessel_t vessel;
krpc_SpaceCenter_ActiveVessel(conn, &vessel);
krpc_SpaceCenter_ReferenceFrame_t srf_ref;
krpc_SpaceCenter_Vessel_SurfaceReferenceFrame(conn, &srf_ref, vessel);
krpc_SpaceCenter_ReferenceFrame_t vessel_ref;
krpc_SpaceCenter_Vessel_ReferenceFrame(conn, &vessel_ref, vessel);
while (true) {
vector3 vessel_direction;
krpc_SpaceCenter_Vessel_Direction(conn, &vessel_direction, vessel, srf_ref);
// Get the direction of the vessel in the horizon plane
vector3 horizon_direction = {
0, vessel_direction.e1, vessel_direction.e2
};
// Compute the pitch - the angle between the vessels direction
// and the direction in the horizon plane
double pitch = angle_between_vectors(vessel_direction, horizon_direction);
if (vessel_direction.e0 < 0)
pitch = -pitch;
// Compute the heading - the angle between north
// and the direction in the horizon plane
vector3 north = {0, 1, 0};
double heading = angle_between_vectors(north, horizon_direction);
if (horizon_direction.e2 < 0)
heading = 360 - heading;
// Compute the roll
// Compute the plane running through the vessels direction
// and the upwards direction
vector3 up = {1, 0, 0};
vector3 plane_normal = cross_product(vessel_direction, up);
// Compute the upwards direction of the vessel
vector3 vessel_up;
vector3 tmp = { 0, 0, -1 };
krpc_SpaceCenter_TransformDirection(conn, &vessel_up, &tmp, vessel_ref, srf_ref);
// Compute the angle between the upwards direction of
// the vessel and the plane normal
double roll = angle_between_vectors(vessel_up, plane_normal);
// Adjust so that the angle is between -180 and 180 and
// rolling right is +ve and left is -ve
if (vessel_up.e0 > 0)
roll *= -1;
else if (roll < 0)
roll += 180;
else
roll -= 180;
printf("pitch = %.1f, heading = %.1f, roll = %.1f\n", pitch, heading, roll);
sleep(1);
}
}
import krpc.client.Connection;
import krpc.client.RPCException;
import krpc.client.services.SpaceCenter;
import org.javatuples.Triplet;
import java.io.IOException;
import java.lang.Math;
public class PitchHeadingRoll {
static Triplet<Double,Double,Double> crossProduct(
Triplet<Double,Double,Double> u, Triplet<Double,Double,Double> v) {
return new Triplet<Double,Double,Double>(
u.getValue1() * v.getValue2() - u.getValue2() * v.getValue1(),
u.getValue2() * v.getValue0() - u.getValue0() * v.getValue2(),
u.getValue0() * v.getValue1() - u.getValue1() * v.getValue0()
);
}
static double dotProduct(Triplet<Double,Double,Double> u,
Triplet<Double,Double,Double> v) {
return u.getValue0() * v.getValue0() +
u.getValue1() * v.getValue1() +
u.getValue2() * v.getValue2();
}
static double magnitude(Triplet<Double,Double,Double> v) {
return Math.sqrt(dotProduct(v, v));
}
// Compute the angle between vector x and y
static double angleBetweenVectors(Triplet<Double,Double,Double> u,
Triplet<Double,Double,Double> v) {
double dp = dotProduct(u, v);
if (dp == 0) {
return 0;
}
double um = magnitude(u);
double vm = magnitude(v);
return Math.acos(dp / (um * vm)) * (180f / Math.PI);
}
public static void main(String[] args)
throws IOException, RPCException, InterruptedException {
Connection connection = Connection.newInstance();
SpaceCenter spaceCenter = SpaceCenter.newInstance(connection);
SpaceCenter.Vessel vessel = spaceCenter.getActiveVessel();
while (true) {
Triplet<Double,Double,Double> vesselDirection =
vessel.direction(vessel.getSurfaceReferenceFrame());
// Get the direction of the vessel in the horizon plane
Triplet<Double,Double,Double> horizonDirection =
new Triplet<Double,Double,Double>(
0.0, vesselDirection.getValue1(), vesselDirection.getValue2());
// Compute the pitch - the angle between the vessels direction
// and the direction in the horizon plane
double pitch = angleBetweenVectors(vesselDirection, horizonDirection);
if (vesselDirection.getValue0() < 0) {
pitch = -pitch;
}
// Compute the heading - the angle between north
// and the direction in the horizon plane
Triplet<Double,Double,Double> north =
new Triplet<Double,Double,Double>(0.0,1.0,0.0);
double heading = angleBetweenVectors(north, horizonDirection);
if (horizonDirection.getValue2() < 0) {
heading = 360 - heading;
}
// Compute the roll
// Compute the plane running through the vessels direction
// and the upwards direction
Triplet<Double,Double,Double> up =
new Triplet<Double,Double,Double>(1.0,0.0,0.0);
Triplet<Double,Double,Double> planeNormal =
crossProduct(vesselDirection, up);
// Compute the upwards direction of the vessel
Triplet<Double,Double,Double> vesselUp = spaceCenter.transformDirection(
new Triplet<Double,Double,Double>(0.0,0.0,-1.0),
vessel.getReferenceFrame(), vessel.getSurfaceReferenceFrame());
// Compute the angle between the upwards direction
// of the vessel and the plane normal
double roll = angleBetweenVectors(vesselUp, planeNormal);
// Adjust so that the angle is between -180 and 180 and
// rolling right is +ve and left is -ve
if (vesselUp.getValue0() > 0) {
roll *= -1;
} else if (roll < 0) {
roll += 180;
} else {
roll -= 180;
}
System.out.printf("pitch = %.1f, heading = %.1f, roll = %.1f\n",
pitch, heading, roll);
Thread.sleep(1000);
}
}
}
local krpc = require 'krpc'
local platform = require 'krpc.platform'
local math = require 'math'
local List = require 'pl.List'
local conn = krpc.connect('Pitch/Heading/Roll')
local vessel = conn.space_center.active_vessel
function cross_product(u, v)
return List{u[3]*v[3] - u[3]*v[2],
u[1]*v[1] - u[1]*v[3],
u[2]*v[2] - u[2]*v[1]}
end
function dot_product(u, v)
return u[1]*v[1] + u[2]*v[2] + u[3]*v[3]
end
function magnitude(v)
return math.sqrt(dot_product(v, v))
end
function angle_between_vectors(u, v)
-- Compute the angle between vector u and v
dp = dot_product(u, v)
if dp == 0 then
return 0
end
um = magnitude(u)
vm = magnitude(v)
return math.acos(dp / (um*vm)) * (180. / math.pi)
end
while true do
local vessel_direction = vessel:direction(vessel.surface_reference_frame)
-- Get the direction of the vessel in the horizon plane
local horizon_direction = List{0, vessel_direction[2], vessel_direction[3]}
-- Compute the pitch - the angle between the vessels direction and
-- the direction in the horizon plane
local pitch = angle_between_vectors(vessel_direction, horizon_direction)
if vessel_direction[1] < 0 then
pitch = -pitch
end
-- Compute the heading - the angle between north and
-- the direction in the horizon plane
local north = List{0, 1, 0}
local heading = angle_between_vectors(north, horizon_direction)
if horizon_direction[3] < 0 then
heading = 360 - heading
end
-- Compute the roll
-- Compute the plane running through the vessels direction
-- and the upwards direction
local up = List{1, 0, 0}
local plane_normal = cross_product(vessel_direction, up)
-- Compute the upwards direction of the vessel
local vessel_up = conn.space_center.transform_direction(
List{0, 0, -1}, vessel.reference_frame, vessel.surface_reference_frame)
-- Compute the angle between the upwards direction of
-- the vessel and the plane normal
local roll = angle_between_vectors(vessel_up, plane_normal)
-- Adjust so that the angle is between -180 and 180 and
-- rolling right is +ve and left is -ve
if vessel_up[1] > 0 then
roll = -roll
elseif roll < 0 then
roll = roll + 180
else
roll = roll - 180
end
print(string.format('pitch = %1.f, heading = %.1f, roll = %.1f',
pitch, heading, roll))
platform.sleep(1)
end
import math
import time
import krpc
conn = krpc.connect(name='Pitch/Heading/Roll')
vessel = conn.space_center.active_vessel
def cross_product(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])
def dot_product(u, v):
return u[0]*v[0] + u[1]*v[1] + u[2]*v[2]
def magnitude(v):
return math.sqrt(dot_product(v, v))
def angle_between_vectors(u, v):
""" Compute the angle between vector u and v """
dp = dot_product(u, v)
if dp == 0:
return 0
um = magnitude(u)
vm = magnitude(v)
return math.acos(dp / (um*vm)) * (180. / math.pi)
while True:
vessel_direction = vessel.direction(vessel.surface_reference_frame)
# Get the direction of the vessel in the horizon plane
horizon_direction = (0, vessel_direction[1], vessel_direction[2])
# Compute the pitch - the angle between the vessels direction and
# the direction in the horizon plane
pitch = angle_between_vectors(vessel_direction, horizon_direction)
if vessel_direction[0] < 0:
pitch = -pitch
# Compute the heading - the angle between north and
# the direction in the horizon plane
north = (0, 1, 0)
heading = angle_between_vectors(north, horizon_direction)
if horizon_direction[2] < 0:
heading = 360 - heading
# Compute the roll
# Compute the plane running through the vessels direction
# and the upwards direction
up = (1, 0, 0)
plane_normal = cross_product(vessel_direction, up)
# Compute the upwards direction of the vessel
vessel_up = conn.space_center.transform_direction(
(0, 0, -1), vessel.reference_frame, vessel.surface_reference_frame)
# Compute the angle between the upwards direction of
# the vessel and the plane normal
roll = angle_between_vectors(vessel_up, plane_normal)
# Adjust so that the angle is between -180 and 180 and
# rolling right is +ve and left is -ve
if vessel_up[0] > 0:
roll *= -1
elif roll < 0:
roll += 180
else:
roll -= 180
print('pitch = % 5.1f, heading = % 5.1f, roll = % 5.1f' %
(pitch, heading, roll))
time.sleep(1)