向量到欧拉角

记录学习过程,向量到欧拉角
目的是将机器人工具指向目标平面法线

  1. 先通过点云拟合出平面,得到平面方程,相应得到平面法向量(A,B,C)
		typedef pcl::PointXYZ PointT;
		typedef pcl::PointCloud<PointT> PointCloudT;
		cout << "->正在估计平面..." << endl;
		pcl::SampleConsensusModelPlane<PointT>::Ptr model_plane(new pcl::SampleConsensusModelPlane<PointT>(cloud_transformed));	//选择拟合点云与几何模型
		pcl::RandomSampleConsensus<PointT> ransac(model_plane);	//创建随机采样一致性对象
		ransac.setDistanceThreshold(0.01);	//设置距离阈值,与平面距离小于0.01的点作为内点
		ransac.computeModel();				//执行模型估计

		PointCloudT::Ptr cloud_plane(new PointCloudT);

		vector<int> inliers;				//存储内点索引的向量
		ransac.getInliers(inliers);			//提取内点对应的索引
		pcl::copyPointCloud<PointT>(*cloud_transformed, inliers, *cloud_plane);

		//输出模型参数Ax+By+Cz+D=0
		Eigen::VectorXf coefficient;
		ransac.getModelCoefficients(coefficient);
		cout << "平面方程为:\n"
		<< coefficient[0] << "x + "
		<< coefficient[1] << "y + "
		<< coefficient[2] << "z + "
		<< coefficient[3] << " = 0"
		<< endl;
  1. 固定法线方向,因为法线有可能会为反向
		if (coefficient[2] > 0)
		{
			coefficient[0] = 0 - coefficient[0];
			coefficient[1] = 0 - coefficient[1];
			coefficient[2] = 0 - coefficient[2];
			cout << "翻转:\n" << endl;
		}
  1. 向量转换欧拉角,需要确定两个方向向量,如果只有一个方向,则存在不确定性,这里主要是让Z指向平面法向量,x就固定在45°位置
		Eigen::Matrix3f rotM = Eigen::Matrix3f::Identity();
		/*计算完都需要归一化处理
		* 如果放进去的Z方向和X方向不垂直,那就先计算出Y方向,在重新算出X方向
		* 例子
			curZ(0, 1, 0);将z指向本体坐标系下的Y方向
			curX(0, 0, 1); 将x指向本体坐标系下的Z方向
		*/
		Eigen::Vector3f curZ(coefficient[0], coefficient[1], coefficient[2]);//定义z的指向
		Eigen::Vector3f curX(1, 1, 0);//定义x的指向
		curX /= curX.norm();//归一化
		Eigen::Vector3f curY = curZ.cross(curX);
		curY /= curY.norm();
		//重新算出X方向
		curX = curY.cross(curZ);
		curX /= curX.norm();

		rotM(0, 0) = curX(0);
		rotM(0, 1) = curY(0);
		rotM(0, 2) = curZ(0);
		rotM(1, 0) = curX(1);
		rotM(1, 1) = curY(1);
		rotM(1, 2) = curZ(1);
		rotM(2, 0) = curX(2);
		rotM(2, 1) = curY(2);
		rotM(2, 2) = curZ(2);
		std::cout << rotM << std::endl;
		std::cout << rotM.eulerAngles(2, 1, 0) * 180 / 3.1415926 << std::endl;
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
以下是使用C++语言和PCL库生成的代码,可以求解平面向量,并换为欧拉角输出: ```c++ #include <iostream> #include <pcl/point_types.h> #include <pcl/features/normal_3d.h> #include <pcl/common/transforms.h> int main() { // 定义一个平面 pcl::PointCloud<pcl::PointXYZ>::Ptr plane(new pcl::PointCloud<pcl::PointXYZ>); plane->push_back(pcl::PointXYZ(1, 0, 0)); plane->push_back(pcl::PointXYZ(2, 0, 0)); plane->push_back(pcl::PointXYZ(3, 0, 0)); plane->push_back(pcl::PointXYZ(4, 0, 0)); // 计算向量 pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne; ne.setInputCloud(plane); pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>()); ne.setSearchMethod(tree); pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>); ne.setRadiusSearch(0.03); ne.compute(*cloud_normals); // 输出向量 std::cout << "The normal of the plane is: (" << cloud_normals->points[0].normal_x << ", " << cloud_normals->points[0].normal_y << ", " << cloud_normals->points[0].normal_z << ")" << std::endl; // 将向量换为欧拉角输出 Eigen::Vector3f euler_angles = cloud_normals->points[0].getNormalVector3fMap().cast<float>().eulerAngles(0, 1, 2); std::cout << "The Euler angles of the plane normal are: (" << euler_angles[0] << ", " << euler_angles[1] << ", " << euler_angles[2] << ")" << std::endl; return 0; } ``` 代码中使用了PCL库中的 NormalEstimation 类来计算平面向量,并使用 getNormalVector3fMap() 函数将向量换为 Eigen::Vector3f 类型的向量,再使用 Eigen 库中的 eulerAngles() 函数将向量换为欧拉角

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值