zoukankan      html  css  js  c++  java
  • 高博课程编程作业之计算小萝卜的坐标

    题目如下

    下面我们来练习如何使用 Eigen/Geometry 计算一个具体的例子。
    设有小萝卜 1 一号和小萝卜二号位于世界坐标系中。小萝卜一号的位姿为: q 1 = [0.55, 0.3, 0.2, 0.2], t 1 =
    [0.7, 1.1, 0.2] T (q 的第一项为实部)
    。这里的 q 和 t 表达的是 T cw ,也就是世界到相机的变换关系。小萝卜
    二号的位姿为 q 2 = [−0.1, 0.3, −0.7, 0.2], t 2 = [−0.1, 0.4, 0.8] T 。现在,小萝卜一号看到某个点在自身的坐
    标系下,坐标为 p 1 = [0.5, −0.1, 0.2] T ,求该向量在小萝卜二号坐标系下的坐标。请编程实现此事,并提交
    你的程序。
    提示:
    1. 四元数在使用前需要归一化。
    2. 请注意 Eigen 在使用四元数时的虚部和实部顺序。
    3. 参考答案为 p 2 = [1.08228, 0.663509, 0.686957] T 。你可以用它验证程序是否正确。

    1)用四元数的方法计算

    整体思路是由  p1,q1, t1 计算点在世界坐标下的坐标pw

    先把四元数归一化,题目给出的表达是Tcw,是世界到相机的变换关系,所以要先把q1转化为相机到世界的变换,也就是q1的逆可以表达相反的变换

    对于单位四元数,其逆和共轭就是同一个量,而四元数的共轭是把虚部取成相反数,所以在归一化的时候把q1的虚部取为相反数就行了。

    pw = q1wc * (p1 - t1)

    然后计算pw在萝卜二号坐标系的坐标

    p2 = pw * q2  + t2

    代码如下

     1 //writed by zhang ning 2018/3/5 20:11
     2 //本程序用来求解位姿变换问题
     3 #include <iostream>
     4 #include <cmath>
     5 using namespace std;
     6 
     7 #include <Eigen/Core>
     8 #include <Eigen/Dense>
     9 // Eigen 几何模块
    10 #include <Eigen/Geometry>
    11 
    12 int main( int argc, char** argv)
    13 {
    14   Eigen::Vector3d p1,t1,t2;
    15   p1 << 0.5,-0.1,0.2;
    16   t1 << 0.7,1.1,0.2;
    17   t2 << -0.1,0.4,0.8;
    18 // 四元数Eigen::Quaterniond 的正确初始化顺序为Eigen::Quaterniond(w,x,y,z)
    19 // 而 coeffs的顺序是(x,y,z,w),w 为实部,前三者为虚部 
    20 // 因为要表示相反的旋转,故输入为q1的共轭,即实部不变,虚部变为相反数
    21   Eigen::Quaterniond q1 = Eigen::Quaterniond(0.55,-0.3,-0.2,-0.2).normalized();
    22   cout << q1.coeffs().transpose() << endl;
    23 
    24 
    25   Eigen::Quaterniond q2 = Eigen::Quaterniond(-0.1,0.3,-0.7,0.2).normalized();
    26   cout << q2.coeffs().transpose() << endl;
    27   
    28   Eigen::Vector3d pw = q1*(p1-t1);  //数学上是qpq-1
    29   Eigen::Vector3d p2 = q2*pw + t2;
    30 
    31   cout << p2 << endl;
    32   
    33   return 0;
    34 }

    2)用变换矩阵的方法

    同样的思路,先求出两个变换矩阵T1和T2  ,p1和T1 的逆矩阵相乘得到 pw, 然后再和T2相乘得到 p2

    p2 = T2 * T1.inverse() * p1

    代码如下

     1 //writed by zhang ning 2018/3/5 20:11
     2 //本程序用来求解位姿变换问题
     3 #include <iostream>
     4 #include <cmath>
     5 using namespace std;
     6 
     7 #include <Eigen/Core>
     8 #include <Eigen/Dense>
     9 // Eigen 几何模块
    10 #include <Eigen/Geometry>
    11 //下面这段程序是用变换矩阵来计算的,可以得到相同的计算结果
    12 
    13 int main( int argc, char** argv)
    14 {
    15   Eigen::Vector3d p1,t1,t2;
    16   p1 << 0.5,-0.1,0.2;
    17   t1 << 0.7,1.1,0.2;
    18   t2 << -0.1,0.4,0.8;
    19   Eigen::Quaterniond q1 = Eigen::Quaterniond(0.55,0.3,0.2,0.2).normalized();
    20   
    21   Eigen::Isometry3d T1 = Eigen::Isometry3d::Identity();
    22   T1.rotate ( q1 );
    23   T1.pretranslate ( t1 );
    24   cout << "Transform matrix = 
    " << T1.matrix() << endl;
    25 
    26   Eigen::Quaterniond q2 = Eigen::Quaterniond(-0.1,0.3,-0.7,0.2).normalized();
    27 
    28   Eigen::Isometry3d T2 = Eigen::Isometry3d::Identity();
    29   T2.rotate ( q2 );
    30   T2.pretranslate ( t2 );
    31   cout << "Transform matrix = 
    " << T2.matrix() << endl;
    32   
    33   Eigen::Vector3d p2 = T2*T1.inverse()*p1;
    34   cout << p2 << endl;
    35   
    36   return 0;
    37 }

    CMakeLists.txt文件内容如下

     1 cmake_minimum_required( VERSION 2.8 )
     2 
     3 project( geometry )
     4 
     5 # 设置编译模式
     6 set( CMAKE_BUILD_TYPE "Debug" )
     7 
     8 # 添加头文件
     9 include_directories( "/usr/include/eigen3")
    10  
    11 add_executable( useGeometry useGeometry.cpp )

    相关源码可以在我的github仓库中下载,

    项目地址:https://github.com/feifanrensheng/useGeometry

  • 相关阅读:
    oracle 11g 断电后 无法启动 ora 00600 kcratr_scan_lastbwr 修复小计
    arcgis for python (arcpy) 入门
    解决 构造函数 包含业务逻辑 IDE无法初始化界面的问题
    arcgis 10.1 发布 气温插值GP服务小计
    执行 Animation先决条件
    ASP.NET MVC3学习心得视图和模型
    Axure使用心得分享
    ASP.NET MVC3学习心得表单和HTML辅助方法
    ASP.NET MVC3学习心得入门和控制器
    WindowsPhone 中SQL CE数据库的使用
  • 原文地址:https://www.cnblogs.com/feifanrensheng/p/8516302.html
Copyright © 2011-2022 走看看