144 lines
5.8 KiB
C#
144 lines
5.8 KiB
C#
using System;
|
|
using System.Linq;
|
|
namespace FreeD
|
|
{
|
|
[Serializable]
|
|
public class Packet
|
|
{
|
|
|
|
// From https://github.com/stvmyr/freeD
|
|
//Offset Function Description
|
|
//0 Identifier Message Type.The Encode function always uses 0xD1. (see freeD manual section A.3.1 for further information)
|
|
//1 ID Camera ID.This is a relict when using multiple Systems via RS232 or RS422.
|
|
//2:5 Pitch Camera Pitch angle described in degree.
|
|
//5:8 Yaw Camera Yaw angle described in degree.
|
|
//8:11 Roll Camera Roll angle described in degree.
|
|
//11:14 Position Z Camera Z Offset from origin.Typically described in millimeter.
|
|
//14:17 Position Y Camera Y Offset from origin.Typically described in millimeter.
|
|
//17:20 Position X Camera X Offset from origin.Typically described in millimeter.
|
|
//20:23 Zoom Lens Zoom Position.Typically measured with an external encoder attached to the Lens.In the most cases this is a value between 0-4095.
|
|
//23:26 Focus Lens Focus Position. Typically measured with an external encoder attached to the Lens. In the most cases this is a value between 0-4095.
|
|
//26:28 Reserved Currently not used in freeD.
|
|
//28 Checksum Checksum of the first 28 bytes.The Decode function uses the checksum to verify if the incoming data is a valid freeD package.
|
|
|
|
public int Id;
|
|
public float Pan;
|
|
public float Tilt;
|
|
public float Roll;
|
|
public float PosZ;
|
|
public float PosX;
|
|
public float PosY;
|
|
public float Zoom;
|
|
public float Focus;
|
|
|
|
public static Packet Decode(byte[] data)
|
|
{
|
|
//if (Checksum(data) == data[28])
|
|
{
|
|
var trackingData = new Packet
|
|
{
|
|
Id = data.Skip(1).First(),
|
|
Pan = GetRotation(data.Skip(2).Take(3).ToArray()),
|
|
Tilt = GetRotation(data.Skip(5).Take(3).ToArray()),
|
|
Roll = GetRotation(data.Skip(8).Take(3).ToArray()),
|
|
PosZ = GetPosition(data.Skip(11).Take(3).ToArray()),
|
|
PosX = GetPosition(data.Skip(14).Take(3).ToArray()),
|
|
PosY = GetPosition(data.Skip(17).Take(3).ToArray()),
|
|
Zoom = GetPosition(data.Skip(20).Take(3).ToArray()),
|
|
Focus = GetPosition(data.Skip(23).Take(3).ToArray())
|
|
};
|
|
|
|
return trackingData;
|
|
}
|
|
throw new Exception("Calculated checksum does not match provided data. Probably not FreeD.");
|
|
}
|
|
|
|
public static byte[] Encode(Packet data)
|
|
{
|
|
byte[] output = { 0xD1 }; // Identifier
|
|
//output = output.Concat(new byte[] { 0xFF }).ToArray(); // ID
|
|
output = output.Concat(SetCameraId(data.Id)).ToArray(); // ID: LQ
|
|
output = output.Concat(SetRotation(data.Pan)).ToArray(); // Pitch
|
|
output = output.Concat(SetRotation(data.Tilt)).ToArray(); // Yaw
|
|
output = output.Concat(SetRotation(data.Roll)).ToArray(); // Roll
|
|
output = output.Concat(SetPosition(data.PosZ)).ToArray(); // X
|
|
output = output.Concat(SetPosition(data.PosX)).ToArray(); // Y
|
|
output = output.Concat(SetPosition(data.PosY)).ToArray(); // Z
|
|
output = output.Concat(SetPosition(data.Zoom)).ToArray(); // Zoom
|
|
output = output.Concat(SetPosition(data.Focus)).ToArray(); // Focus
|
|
output = output.Concat(new byte[] { 0x00, 0x00 }).ToArray(); // Reserved
|
|
output = output.Concat(new byte[] { (byte)Checksum(output) }).ToArray(); // Checksum
|
|
|
|
return output;
|
|
}
|
|
|
|
public static byte[] SetCameraId(int cameraId)
|
|
{
|
|
int id = (UInt16)(cameraId);
|
|
byte[] data = BitConverter.GetBytes(id);
|
|
if (!BitConverter.IsLittleEndian)
|
|
Array.Reverse(data);
|
|
return data.Skip(0).Take(1).ToArray();
|
|
}
|
|
|
|
public static byte[] SetPosition(float pos)
|
|
{
|
|
long position = (long)(pos * 64 * 256);
|
|
byte[] data = BitConverter.GetBytes(position);
|
|
Array.Reverse(data);
|
|
return data.Skip(4).Take(3).ToArray();
|
|
}
|
|
|
|
public static byte[] SetRotation(float rot)
|
|
{
|
|
long rotation = (long)(rot * 32768 * 256);
|
|
byte[] data = BitConverter.GetBytes(rotation);
|
|
Array.Reverse(data);
|
|
return data.Skip(4).Take(3).ToArray();
|
|
}
|
|
|
|
public static byte[] SetEncoder(int enc)
|
|
{
|
|
byte[] data = BitConverter.GetBytes(enc);
|
|
Array.Reverse(data);
|
|
return new byte[] { 0x00 }.Concat(data.Skip(5).Take(2)).ToArray();
|
|
}
|
|
|
|
public static float GetPosition(byte[] data)
|
|
{
|
|
return (float)(BitConverter.ToInt32(new byte[] { 0x00, data[2], data[1], data[0] }, 0) / 64 / 256);
|
|
}
|
|
|
|
public static float GetRotation(byte[] data)
|
|
{
|
|
return (float)(BitConverter.ToInt32(new byte[] { 0x00, data[2], data[1], data[0] }, 0) / 32768f / 256f);
|
|
}
|
|
|
|
public static int GetEncoder(byte[] data)
|
|
{
|
|
byte[] value = new byte[] { 0x00 }.Concat(data).ToArray();
|
|
Array.Reverse(value);
|
|
return BitConverter.ToInt32(value, 0);
|
|
}
|
|
|
|
public static int Checksum(byte[] data)
|
|
{
|
|
int sum = 64;
|
|
for (int i = 0; i < 28; i++)
|
|
{
|
|
sum -= data[i];
|
|
}
|
|
return Modulo(sum, 256);
|
|
}
|
|
|
|
public static int Modulo(int d, int m)
|
|
{
|
|
int res = d % m;
|
|
if ((res < 0 && m > 0) || (res > 0 && m < 0))
|
|
{
|
|
return res + m;
|
|
}
|
|
return res;
|
|
}
|
|
}
|
|
} |