所以,我有一个模拟汽车的C ++项目。我的程序是工作在2D(只在XY平面),它提供了由一个玫瑰花袋给出的里程数据,给他的位置在XYplane中取决于世界的起源。在2D中一切都很好。
但当我在3D模式下时,这意味着我可以绕几个轴旋转我的车,而不仅仅是Z轴。我意识到我的车正在围绕“世界”轴的轴旋转,当我想让它们绕着我的车辆轴旋转时。
我能让我的车绕着自己的轴旋转吗?数学会是怎样的呢?
下面的两个旋转是围绕世界轴进行的。
下面是我的一段代码来说明:
void NodeImpl::callback_odometry(motion_common_msg::Odometry input_msg)
{
//Getting Direction3D
//---
frame_id = input_msg.header.frame_id;
stamp = input_msg.header.stamp;
transform_from_odometry.setOrigin(new_position_3D);
tf::Quaternion q;
q.setRPY(0.0, 0.0, 0.0);
transform_from_odometry.setRotation(q);
if(input_msg.pos_x >= 5.0)
{
double cos90 = 0;
double sin90 = 1;
tf::Matrix3x3 Rz90;
tf::Matrix3x3 Ry90;
Rz90.setValue(cos90, - sin90, 0, sin90, cos90, 0, 0, 0, 1);
Ry90.setValue(cos90, 0, sin90, 0, 1, 0, -sin90, 0, cos90);
tf::Quaternion qz90;
tf::Quaternion qy90;
Rz90.getRotation(qz90);
Ry90.getRotation(qy90);
qz90.normalize();
qy90.normalize();
tf::Transform tf_new_rot;
tf_new_rot.setRotation(qz90);
transform_from_odometry.setRotation(qy90);
transform_from_odometry.mult (transform_from_odometry, tf_new_rot);
}
broadcast();
}
void NodeImpl::broadcast()
{
static tf::TransformBroadcaster br;
br.sendTransform(tf::StampedTransform(transform_from_odometry, stamp, frame_id, "ego_vehicle_rear_axis"));
}发布于 2018-10-15 20:33:28
我不确定您使用的是哪个库,因此我将尝试就此给出一些一般性的建议。
全局与局部旋转只是矩阵乘法顺序的问题。假设R是最终的旋转矩阵。当您使用以下顺序R=X*Y*Z乘以X、Y和Z矩阵时,这将为您提供全局旋转,而R=Z*Y*X将为您提供局部旋转。
上述方法的问题在于,它将局部旋转的自由度限制为特定的Z-Y-X阶。例如,如果要旋转,首先在x轴上旋转,然后在y轴上旋转,然后在z轴上旋转,上述方法就可以很好地工作。任何其他的,都不会给你想要的结果。您必须更改矩阵乘法的顺序。
如果你想绕一个轴旋转,比如说y轴,它是你的物体的局部,那么你需要知道这个轴的位置。您需要在每次变换后保留当前轴的引用,然后使用Rotation matrix from axis and angle围绕当前局部y轴旋转。
/* from the wiki link above */
Mat3 Axis_Matrix(float angle_, const Vec3 &axis_)
{
return Mat3{ cos(angle_)+pow(axis_.x,2)*(1.0-cos(angle_)) , (axis_.x*axis_.y*(1.0-cos(angle_)))-(axis_.z*sin(angle_)) , (axis_.x*axis_.z*(1.0-cos(angle_)))+(axis_.y*sin(angle_)),
(axis_.y*axis_.x*(1.0-cos(angle_)))+(axis_.z*sin(angle_)) , cos(angle_)+pow(axis_.y,2)*(1.0 - cos(angle_)) , (axis_.y*axis_.z*(1.0-cos(angle_)))-(axis_.x*sin(angle_)),
(axis_.z*axis_.x*(1.0-cos(angle_)))-(axis_.y*sin(angle_)) , (axis_.z*axis_.y*(1.0-cos(angle_)))+(axis_.x*sin(angle_)) , cos(angle_)+pow(axis_.z,2)*(1.0 - cos(angle_)) };
}基本上,您可以创建自己的结构来完成所有这些任务:
struct CoordinateSystem
{
Vec3 current_x_axis;
Vec3 current_y_axis;
Vec3 current_z_axis;
Mat3 local;
void setRotationX(float angle_)
{
local *= Axis_Matrix(angle_, current_x_axis);
update();
}
void setRotationY(float angle_)
{
local *= Axis_Matrix(angle_, current_y_axis);
update();
}
void setRotationZ(float angle_)
{
local *= Axis_Matrix(angle_, current_z_axis);
update();
}
void update()
{
current_x_axis = {-1.f, 0.f, 0.f} * local;
current_y_axis = { 0.f, 1.f, 0.f} * local;
current_z_axis = { 0.f, 0.f,-1.f} * local;
}
};然后你可以直接说:
setRotationX(45);
setRotationZ(10);
setRotationY(62);
setRotationX(34);
setRotationY(81);所有的旋转对于你的物体来说都是局部的。
https://stackoverflow.com/questions/52815475
复制相似问题