• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

【机器人学】机器人开源项目KDL源码学习:(5)KDL如何求解几何雅克比矩阵

人工智能 gpeng832 2135次浏览 0个评论

这篇文章试图说清楚两件事:1. 几何雅克比矩阵的本质;2. KDL如何求解机械臂的几何雅克比矩阵。   一、几何雅克比矩阵的本质   机械臂的关节空间的速度可以映射到执行器末端在操作空间的速度,这种映射可以通过一个矩阵来描述,就是几何雅克比矩阵,了解雅克比矩阵需要了解这种映射关系的本质,这有助于用代码实现。   机械臂是一种开链式的机构,如下图所示,那么每个连杆的速度和加速度可以表示为式(1),这样机械臂末端的速度可以认为是各个关节的运动导致末端的速度的叠加之后的效果。   【机器人学】机器人开源项目KDL源码学习:(5)KDL如何求解几何雅克比矩阵(1)   机器人学教材和KDL中都会把机器人末端的线速度和角速度组合成一个向量,那么末端的速度v和角速度w和机械臂关节角速度的关系可以用下式表示:   【机器人学】机器人开源项目KDL源码学习:(5)KDL如何求解几何雅克比矩阵(2)   把上式写成:   【机器人学】机器人开源项目KDL源码学习:(5)KDL如何求解几何雅克比矩阵(3)     (3)式中等号后的每一列((4)式)就代表第i个关节对末端的造成的线速度和角速度.   【机器人学】机器人开源项目KDL源码学习:(5)KDL如何求解几何雅克比矩阵(4)     二、KDL如何求几何雅克比矩阵   现在介绍KDL中如何逐列的求雅克比矩阵。   如果有同学看过我的上一篇博客(【机器人学】机器人开源项目KDL源码学习:(2)牛顿拉普森迭代法求机器人的数值解)的话,应该明白我们的目的不是求机械臂末端的速度,而是在已知机械臂构型和每个关节角度位移的情况下,求解雅克比矩阵各项的值。   好的,在编程的时候,我们依然采用上边叙述的运动传递的思想,希望能够逐列地将雅克比矩阵求出来,明白了它的每一列表示什么意思,才能动手写代码,那它的每一列代表什么意思呢?代表的是关节i在角速度为1的时候对机械臂最末端造成的速度!如果再乘以关节i的角速度的值,就得到了机械臂最末端的速度。从这个角度看(2)和(3)式就比较直观了,所有的关节对末端这也是KDL的巧妙之处.   【机器人学】机器人开源项目KDL源码学习:(5)KDL如何求解几何雅克比矩阵(4)   有了这种理念,就可以看懂KDL中的求雅克比矩阵的代码了(orocos_kinematics_dynamics-master\orocos_kdl\src\chainjnttojacsolver.cpp)   形参q_in 表示机械臂在某一时刻的所有关节角位移,jac用来存放雅克比矩阵的值。  

 int ChainJntToJacSolver::JntToJac(const JntArray& q_in, Jacobian& jac, int seg_nr)
    {
        unsigned int segmentNr;
        if(seg_nr<0)
            segmentNr=chain.getNrOfSegments();
        else
            segmentNr = seg_nr;
 
        //Initialize Jacobian to zero since only segmentNr colunns are computed
        SetToZero(jac) ;
 
        if( q_in.rows()!=chain.getNrOfJoints() || jac.columns() != chain.getNrOfJoints())
            return (error = E_SIZE_MISMATCH);
        else if(segmentNr>chain.getNrOfSegments())
            return (error = E_OUT_OF_RANGE);
 
        T_tmp = Frame::Identity();
        SetToZero(t_tmp);
        int j=0;
        int k=0;
        Frame total;
        for (unsigned int i=0;i<segmentNr;i++) {
            //Calculate new Frame_base_ee
            if(chain.getSegment(i).getJoint().getType()!=Joint::None){
            	//pose of the new end-point expressed in the base
                total = T_tmp*chain.getSegment(i).pose(q_in(j));
                //changing base of new segment's twist to base frame if it is not locked
                //t_tmp = T_tmp.M*chain.getSegment(i).twist(1.0);
                if(!locked_joints_[j])
                    t_tmp = T_tmp.M*chain.getSegment(i).twist(q_in(j),1.0);
            }else{
                total = T_tmp*chain.getSegment(i).pose(0.0);
 
            }
 
            //Changing Refpoint of all columns to new ee
            changeRefPoint(jac,total.p-T_tmp.p,jac);
 
            //Only increase jointnr if the segment has a joint
            if(chain.getSegment(i).getJoint().getType()!=Joint::None){
                //Only put the twist inside if it is not locked
                if(!locked_joints_[j])
                    jac.setColumn(k++,t_tmp);
                j++;
            }
 
            T_tmp = total;
        }
        return (error = E_NOERROR);
    }
}

  关键代码详解: total和T_tmp用来处理坐标变换。  

total = T_tmp*chain.getSegment(i).pose(q_in(j));//表示第i个连杆末端在基座标中的表示

 

T_tmp = total;//这行在循环体的最后,表示第i个连杆的起点在基坐标中的表示

 

t_tmp = T_tmp.M*chain.getSegment(i).twist(q_in(j),1.0);//求的是第i个关节对第i个连杆末端的速度(在基座标中的表示),设关节i的角速度为1,

 

changeRefPoint(jac,total.p-T_tmp.p,jac);//将雅克比矩阵更新,第k列表示第k个关节角速度为1时对末端的造成的线速度和角速度

 

 jac.setColumn(k++,t_tmp);//为雅克比矩阵添加新的一列(t_tmp)  

 



开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明【机器人学】机器人开源项目KDL源码学习:(5)KDL如何求解几何雅克比矩阵
喜欢 (0)

您必须 登录 才能发表评论!

加载中……