• 手眼标定


      在基于位置的视觉控制中,手眼标定起着关键性作用,手眼标定是解决相机与机器人之间位置关系的理论,手眼关系一般有两种形式,一种是相机固定在机器人执行器末端随机器人运动,称为Eye-in-Hand,另一种为相机固定在机器人附近的地面或设备上,不随机器人运动,称为Eye-to-Hand.无论是怎样的形式,最终解决的问题都是同样的,即看到目标物在什么位置,告诉机器人去什么位置执行加工动作。Eye-in-Hand的形式中,相机随机器人运动视野比较宽不会受到机械臂的阻挡,但是存在运动过量可能看不到目标物体,导致目标丢失。Eye-to-Hand的形式中,相机不随机器人运动,固定在一处,能够看到在视野中目标,但是在机械臂移动的过程中容易受到阻挡。两种形式各有利弊,下面是每种形式求取手眼关系的过程。

      在上图Eye-in-Hand关系图中,机械臂末端带着相机从{C1}移动到{C2}的过程中相机和机械臂末端执行器的固定关系保持不变即:

    [{}^{C1}{T_{H1}} = {}^{C2}{T_{H2}}]

      同时带有Marker的目标物在机器人世界坐标系中的关系也不变。

    [{}^B{T_O} = {}^{ m{B}}{T_{H1}} ullet {}^{C1}T_{H1}^{ - 1} ullet {}^{C1}{T_O} = {}^{ m{B}}{T_{H2}} ullet {}^{C2}T_{H2}^{ - 1} ullet {}^{C2}{T_O}]

    [({}^{ m{B}}T_{H2}^{ - 1} ullet {}^{ m{B}}{T_{H1}}) ullet {}^{C1}T_{H1}^{ - 1} = {}^{C2}T_{H2}^{ - 1} ullet ({}^{C2}{T_O} ullet {}^{C1}T_O^{ - 1})]

      写作:$AX = XB$,求解X即可得出手眼之间的关系。

      在上图Eye-to-Hand关系图中对于机器人末端执行器夹着Marker从{O1}移动到和{O2}执行任务时,执行器末端和Marker之间的位置关系保持不变,因此在两个位置存在如下的转换关系:

    [{}^{O1}{T_{H1}} = {}^CT_{O1}^{ - 1} ullet {}^C{T_B} ullet {}^{ m{B}}{T_{H1}}]

    [{}^{O2}{T_{H2}} = {}^CT_{O2}^{ - 1} ullet {}^C{T_B} ullet {}^{ m{B}}{T_{H2}}]

    [{}^CT_{O1}^{ - 1} ullet {}^C{T_B} ullet {}^{ m{B}}{T_{H1}} = {}^CT_{O2}^{ - 1} ullet {}^C{T_B} ullet {}^{ m{B}}{T_{H2}}]

    [({}^C{T_{O2}} ullet {}^CT_{O1}^{ - 1}) ullet {}^C{T_B} = {}^C{T_B} ullet ({}^{ m{B}}{T_{H2}} ullet {}^{ m{B}}T_{H1}^{ - 1})]

      写作:$AX = XB$,求解X即可得出手眼之间的关系。

    注意在求取的过程中多采集几组A,B的数据结果才会准确,不然无法求解。

      1 //向量转反对称矩阵
      2 
      3 cv::Mat Calculate::skew(cv::Mat vec)
      4 {
      5 
      6     cv::Mat skewM(3, 3, CV_64FC1);
      7 
      8     double vx = vec.at<double>(0, 0);
      9 
     10     double vy = vec.at<double>(1, 0);
     11 
     12     double vz = vec.at<double>(2, 0);
     13 
     14     skewM.at<double>(0, 0) = 0.0; skewM.at<double>(0, 1) = -vz; skewM.at<double>(0, 2) = vy;
     15 
     16     skewM.at<double>(1, 0) = vz; skewM.at<double>(1, 1) = 0.0; skewM.at<double>(1, 2) = -vx;
     17 
     18     skewM.at<double>(2, 0) = -vy; skewM.at<double>(2, 1) = vx; skewM.at<double>(2, 2) = 0.0;
     19 
     20     return skewM;
     21 
     22 }
     23 Solve AX=XB, A-RT_Tcpij, B-RT_Camij, B2A
     24 
     25 Tsai_HandEye(cv::Mat Hcg, vector<cv::Mat> Hgij, vector<cv::Mat> Hcij)
     26 
     27 {
     28 
     29     CV_Assert(Hgij.size() == Hcij.size());
     30 
     31     int nStatus = Hgij.size();
     32 
     33     cv::Mat Rgij(3, 3, CV_64FC1);
     34 
     35     cv::Mat Rcij(3, 3, CV_64FC1);
     36 
     37     cv::Mat rgij(3, 1, CV_64FC1);
     38 
     39     cv::Mat rcij(3, 1, CV_64FC1);
     40 
     41     double theta_gij;
     42 
     43     double theta_cij;
     44 
     45     cv::Mat rngij(3, 1, CV_64FC1);
     46 
     47     cv::Mat rncij(3, 1, CV_64FC1);
     48 
     49     cv::Mat Pgij(3, 1, CV_64FC1);
     50 
     51     cv::Mat Pcij(3, 1, CV_64FC1);
     52 
     53     cv::Mat tempA(3, 3, CV_64FC1);
     54 
     55     cv::Mat tempb(3, 1, CV_64FC1);
     56 
     57     cv::Mat A;
     58 
     59     cv::Mat b;
     60 
     61     cv::Mat pinA;
     62 
     63     cv::Mat Pcg_prime(3, 1, CV_64FC1);
     64 
     65     cv::Mat Pcg(3, 1, CV_64FC1);
     66 
     67     cv::Mat PcgTrs(1, 3, CV_64FC1);
     68 
     69     cv::Mat Rcg(3, 3, CV_64FC1);
     70 
     71     cv::Mat eyeM = cv::Mat::eye(3, 3, CV_64FC1);
     72 
     73     cv::Mat Tgij(3, 1, CV_64FC1);
     74 
     75     cv::Mat Tcij(3, 1, CV_64FC1);
     76 
     77     cv::Mat tempAA(3, 3, CV_64FC1);
     78 
     79     cv::Mat tempbb(3, 1, CV_64FC1);
     80 
     81     cv::Mat AA;
     82 
     83     cv::Mat bb;
     84 
     85     cv::Mat pinAA;
     86 
     87     cv::Mat Tcg(3, 1, CV_64FC1);
     88 
     89     for (int i = 0; i < nStatus; i++)
     90 
     91     {
     92 
     93         Hgij[i](cv::Rect(0, 0, 3, 3)).copyTo(Rgij);
     94 
     95         Hcij[i](cv::Rect(0, 0, 3, 3)).copyTo(Rcij);
     96 
     97         Rodrigues(Rgij, rgij);
     98 
     99         Rodrigues(Rcij, rcij);
    100 
    101         theta_gij = norm(rgij);
    102 
    103         theta_cij = norm(rcij);
    104 
    105         rngij = rgij / theta_gij;
    106 
    107         rncij = rcij / theta_cij;
    108 
    109         Pgij = 2 * sin(theta_gij / 2)*rngij;
    110 
    111         Pcij = 2 * sin(theta_cij / 2)*rncij;
    112 
    113         tempA = skew(Pgij + Pcij);
    114 
    115         tempb = Pcij - Pgij;
    116 
    117         A.push_back(tempA);
    118 
    119         b.push_back(tempb);
    120 
    121     }
    122 
    123     //Compute rotation
    124 
    125     invert(A, pinA, cv::DECOMP_SVD);
    126 
    127     Pcg_prime = pinA * b;
    128 
    129     Pcg = 2 * Pcg_prime / sqrt(1 + norm(Pcg_prime) * norm(Pcg_prime));
    130 
    131     PcgTrs = Pcg.t();
    132 
    133     Rcg = (1 - norm(Pcg) * norm(Pcg) / 2) * eyeM + 0.5 * (Pcg * PcgTrs + sqrt(4 - norm(Pcg)*norm(Pcg))*skew(Pcg));
    134 
    135     //Compute Translation
    136 
    137     for (int i = 0; i < nStatus; i++)
    138 
    139     {
    140 
    141         Hgij[i](cv::Rect(0, 0, 3, 3)).copyTo(Rgij);
    142 
    143         Hcij[i](cv::Rect(0, 0, 3, 3)).copyTo(Rcij);
    144 
    145         Hgij[i](cv::Rect(3, 0, 1, 3)).copyTo(Tgij);
    146 
    147         Hcij[i](cv::Rect(3, 0, 1, 3)).copyTo(Tcij);
    148 
    149         tempAA = Rgij - eyeM;
    150 
    151         tempbb = Rcg * Tcij - Tgij;
    152 
    153         AA.push_back(tempAA);
    154 
    155         bb.push_back(tempbb);
    156 
    157     }
    158 
    159     invert(AA, pinAA, cv::DECOMP_SVD);
    160 
    161     Tcg = pinAA * bb;
    162 
    163     Rcg.copyTo(Hcg(cv::Rect(0, 0, 3, 3)));
    164 
    165     Tcg.copyTo(Hcg(cv::Rect(3, 0, 1, 3)));
    166 
    167     Hcg.at<double>(3, 0) = 0.0;
    168 
    169     Hcg.at<double>(3, 1) = 0.0;
    170 
    171     Hcg.at<double>(3, 2) = 0.0;
    172 
    173     Hcg.at<double>(3, 3) = 1.0;
    174 
    175 
    176 }
  • 相关阅读:
    P2610 [ZJOI2012]旅游
    P2323 [HNOI2006]公路修建问题
    P3629 [APIO2010]巡逻
    ARC059F
    AGC004D Teleporter
    p3203 弹飞绵羊
    bzoj5450 轰炸
    bzoj4313 三维积木
    cf123E Maze
    bzoj4423 [AMPPZ2013]Bytehattan
  • 原文地址:https://www.cnblogs.com/fuzhuoxin/p/12436223.html
Copyright © 2020-2023  润新知