在c ++中,如何根据最新一个的四元数旋转在三维空间中附着到另一个点 [英] In c++, how to traslate a point attached to another in 3D space according to the latest one's quaternion rotations

查看:172
本文介绍了在c ++中,如何根据最新一个的四元数旋转在三维空间中附着到另一个点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

p1和p2,p2连接到p1,不仅连接到p1的位置,而且连接到它的旋转,因此q1是代表p1旋转的四元数。
如果q1旋转,则p1的位置也必须围绕p1旋转。
我只需要计算p2的位置,而不是旋转,我已经完成了旋转。
所以基本上是一个飞船停靠到一个车站,我需要移动和旋转站与周围的船停靠到它。
我如何做?



我写的代码工作,只要车站在对接期间不旋转​​:

  bool docked [100]; 
Quaternion quatTarget [100];
double distance_dock [100];

vector3 docking_position(int ship,int station)
{
if(!docked [ship])
{
docked [ship] = true;
distance_dock [ship] = distance(position [ship],position [station]);
vector3 direcc = normalized(position [station] - position [ship]);
quatTarget [ship] = vecToVecRotation(direcc,{0,0,1});
QuaternionNormalize(& quatTarget [ship],& quatTarget [ship]);
}

四元方位= total_rotation [station] * quatTarget [ship];

Matrix docking_place;

MatrixRotationQuaternion(& docking_place,& orientation);

vector3 axis_z = {docking_place(0,2),docking_place(1,2),docking_place(2,2)};

return position [station] + -axis_z * distance_dock [ship];
}

我在这里做的是从船到车站采取四元数停靠时间,然后沿着定向的负z轴翻转船distance_dock单位,因此船舶将总是相应地移动,但是如果我在船只已经旋转的情况下停泊船舶,则我得到初始停靠位置

解决方案

如果我正确理解你,你有两个对象,有一个它们之间的刚性变换。问题是,你想计算一个姿势(位置+方向),给定另一个的姿势。



假设您有三个框架;车架S,车架V和全局框架G(我假设您的图形环境具有全局3D笛卡尔坐标系)。
帧S和V之间的变换是完全已知的(平移和定向)和常数,并且表示为S_p_SV(车站位置,以Station帧表示)和SV_q(四元数方向车辆,在车站框架中表示)。



如果你没有刚体力学的经验,这将是令人困惑的,在这种情况下,你应该阅读一些介绍性的笔记/



我已在LATEX中编写了表达式,但不幸的是StackOverflow不支持它,所以我附上它作为一个图像。可以在此处找到原始的LATEX。
在下面的符号中,例如 Sp_SV 的第一行是 V 车辆w.r.t.的 p 位置。 S (旋转)框架中表示的 S
前缀上标表示旋转框架。例如,对于四元数 G_Sq ,这表示 S 圆形框架中 S 框架的方向。





在C ++中实现这一点,我不确定你使用的是什么库,但是你需要以下函数:




  • 将欧拉转换为四元数 - 如果您要手动指定旋转SV q (Vehicle wrt Station的旋转)

  • 将四元数转换为DCM - 适用于LATEX中的第一种方法

  • 四元数乘法 - 适用于LATEX中的第二种方法

  • < Conjugate - 对于LATEX

中的第二种方法

I have to possitions, p1 and p2, p2 is attached to p1, not only to p1's position but also to it's rotation, so q1 is a quaternion which represents p1's rotation. If q1 rotates, then p1's position must also rotate around p1 accordingly. I only need to calculate p2's position, not it's rotation, I worked the rotation out already. So basically is a spaceship docked to a station, I need to move and rotate the station around with the ship docked to it. How do I do it?

the code i wrote for it works as long as the station is not rotated during the time of docking:

bool docked[100];
Quaternion quatTarget[100];
double distance_dock[100];

vector3 docking_position(int ship, int station)
{
    if (!docked[ship])
    {
        docked[ship] = true;
        distance_dock[ship] = distances(position[ship], position[station]);
        vector3 direcc = normalized(position[station] - position[ship]);
        quatTarget[ship] = vecToVecRotation(direcc, { 0, 0, 1 });
        QuaternionNormalize(&quatTarget[ship], &quatTarget[ship]);
    }

    Quaternion orientation = total_rotation[station] * quatTarget[ship];

    Matrix docking_place;

    MatrixRotationQuaternion(&docking_place, &orientation);

    vector3 axis_z = { docking_place(0, 2), docking_place(1, 2), docking_place(2, 2) };

    return position[station] + -axis_z * distance_dock[ship];
}

What I do here is take an orientation quaternion from the ship to the station at the time of docking and then traslate the ship "distance_dock" units along the negative z axis of the orientation, so the ship will always move accordingly, but somehow if I dock the ship when the station is already rotated then I get the initial docking position wrong, though it still rotates perfectly along with the station.

解决方案

If I understand you correctly, you have two objects that have a rigid transformation between them. The problem is that you want to calculate the pose (position + orientation) of one, given the pose of the other.

Let's say you have three frames; the Station frame "S", the Vehicle frame "V" and the Global frame "G" (I assume your graphics environment has a global 3D Cartesian frame). The transformation between frames S and V is fully known (translation and orientation) and constant, and is denoted S_p_SV (the position of the Vehicle w.r.t the Station, expressed in the Station frame) and SV_q (the quaternion orientation of the Vehicle, expressed in the Station frame).

This will be confusing if you have not had experience in rigid-body mechanics, in which case you should read some introductory notes/slideshows on "Rigid-Body Mechanics" which are plentiful on Google results.

I have written the expression in LATEX but unfortunately StackOverflow does not support it, so I have attached it as an image. The original LATEX can be found here. In my notation below, for example on the first line Sp_SV , is the position of the Vehicle w.r.t. the Station, expressed in the Station frame (of rotation). The prefixed superscript indicates the rotation frame. For the quaternion G_Sq for example, this represents the orientation of the Station frame from the Ground Frame.

In terms of implementing this in C++, I am unsure of what library you are using for Quaternions, but you will need the following functions:

  • Convert Euler to Quaternions - If you are going to manually specify the rotation SVq (rotation of Vehicle w.r.t Station)
  • Convert Quaternion to DCM - For the first method in the LATEX
  • Quaternion Multiply - For the second method in the LATEX
  • Quaternion Conjugate - For the second method in the LATEX

这篇关于在c ++中,如何根据最新一个的四元数旋转在三维空间中附着到另一个点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆