FireFenix писал(а):http://cpu.h17.ru/net/15/
Спасибо за ссылку. Regasm SomeManagedClass.dll /tlb как одно из решений.
Правда комрады из-за бугра мозги уже проели.
-----------------------------------------------------------
...переписал 27 файлов в одно решение из примерно 20-30 строк (мне нужны были координаты только)
В итоге могу сказать - устройство тупо работает примерно как модем на COM порту (пробовал в ходе тестов также как FDTI).
типа этого примера из док.,
- Код: Выделить всё
COMM OPEN "COM3" AS #hComm
COMM SET hComm, BAUD = 115200 ' baud
COMM SET hComm, BYTE = 8 ' 8 bits
COMM SET hComm, PARITY = %FALSE ' No parity
COMM SET hComm, STOP = 0 ' 1 stop bit
'' comM set hComm, RTSFLOW = 2
COMM SET hComm, TXBUFFER = 256 ' 1 Kb transmit buffer
COMM SET hComm, RXBUFFER = 256 ' 1 Kb receive buffer
Скорость по порту фиксированная 115200, на других скоростях не работает.
Больше всего убила реализация протокола. Вменяемой документации по протоколу нет.
Преобразования для координат по Элеру тупо вынесли на сторону клиента, как впрочем и всю основную тригонометрию по обработке преобразований и работы протокола. Устройство выдает только Quaternion значения (четыре двухбайтовых Integer)
После того как программное решение заработало - выяснилось, что значения "горизонтального" угла: 0+90+0 ~ 0-90-0 градусов (360 градусов)
и нужно использовать векторное преобразования для получения значения угла в градусах. Что-то наподобие:
- Код: Выделить всё
void QuatToEuler(const tQuaternion *quat, CVertex *euler)
{
/// Local Variables ///////////////////////////////////////////////////////////
float matrix[3][3];
float cx,sx,x;
float cy,sy,y,yr;
float cz,sz,z;
///////////////////////////////////////////////////////////////////////////////
// CONVERT QUATERNION TO MATRIX - I DON'T REALLY NEED ALL OF IT
matrix[0][0] = 1.0f - 2.0f * (quat->y * quat->y + quat->z * quat->z);
matrix[0][1] = (2.0f * quat->x * quat->y) - (2.0f * quat->w * quat->z);
// matrix[0][2] = (2.0f * quat->x * quat->z) + (2.0f * quat->w * quat->y);
matrix[1][0] = 2.0f * (quat->x * quat->y + quat->w * quat->z);
matrix[1][1] = 1.0f - (2.0f * quat->x * quat->x) - (2.0f * quat->z * quat->z);
// matrix[1][2] = (2.0f * quat->y * quat->z) - (2.0f * quat->w * quat->x);
matrix[2][0] = 2.0f * (quat->x * quat->z - quat->w * quat->y);
matrix[2][1] = 2.0f * (quat->y * quat->z + quat->w * quat->x);
matrix[2][2] = 1.0f - 2.0f * (quat->x * quat->x - quat->y * quat->y);
sy = -matrix[2][0];
cy = sqrt(1 - (sy * sy));
yr = (float)atan2(sy,cy);
euler->y = (yr * 180.0f) / (float)M_PI;
// AVOID DIVIDE BY ZERO ERROR ONLY WHERE Y= +-90 or +-270
// NOT CHECKING cy BECAUSE OF PRECISION ERRORS
if (sy != 1.0f && sy != -1.0f)
{
cx = matrix[2][2] / cy;
sx = matrix[2][1] / cy;
euler->x = ((float)atan2(sx,cx) * 180.0f) / (float)M_PI; // RAD TO DEG
cz = matrix[0][0] / cy;
sz = matrix[1][0] / cy;
euler->z = ((float)atan2(sz,cz) * 180.0f) / (float)M_PI; // RAD TO DEG
}
else
{
// SINCE Cos(Y) IS 0, I AM SCREWED. ADOPT THE STANDARD Z = 0
// I THINK THERE IS A WAY TO FIX THIS BUT I AM NOT SURE. EULERS SUCK
// NEED SOME MORE OF THE MATRIX TERMS NOW
cx = matrix[1][1];
sx = -matrix[1][2];
euler->x = ((float)atan2(sx,cx) * 180.0f) / (float)M_PI; // RAD TO DEG
cz = 1.0f;
sz = 0.0f;
euler->z = ((float)atan2(sz,cz) * 180.0f) / (float)M_PI; // RAD TO DEG
}
}