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)

// 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}",

}
}
}

#include <iostream>
#include <iomanip>
#include <tuple>
#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::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};
if (std::get<2>(horizon_direction) < 0)

// 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 << ", "
<< "roll = " << roll << std::endl;

}
}

#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};
if (horizon_direction.e2 < 0)

// 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;

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);
if (horizonDirection.getValue2() < 0) {
}

// 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",
}
}
}

local krpc = require 'krpc'
local platform = require 'krpc.platform'
local math = require 'math'
local List = require 'pl.List'
local vessel = conn.space_center.active_vessel

function cross_product(u, v)
return List{u*v - u*v,
u*v - u*v,
u*v - u*v}
end

function dot_product(u, v)
return u*v + u*v + u*v
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, vessel_direction}

-- 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 < 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}
if horizon_direction < 0 then
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 > 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',

platform.sleep(1)

end

import math
import time
import krpc
vessel = conn.space_center.active_vessel

def cross_product(u, v):
return (u*v - u*v,
u*v - u*v,
u*v - u*v)

def dot_product(u, v):
return u*v + u*v + u*v

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, vessel_direction)

# 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:
pitch = -pitch

# Compute the heading - the angle between north and
# the direction in the horizon plane
north = (0, 1, 0)
if horizon_direction < 0:

# 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:
roll *= -1
elif roll < 0:
roll += 180
else:
roll -= 180

print('pitch = % 5.1f, heading = % 5.1f, roll = % 5.1f' %