精华内容
下载资源
问答
  • 用于教育用途的带 6DOF 的机械臂 恢复 用于教育环境具有六个自由度的机械臂。 该手臂已针对 3D 打印进行了开发和优化,并考虑了其低成本以及易于组装和使用特点。 它可以通过增加或减少自由度来定制,就像它可以...
  • 机械臂技术参数意义

    千次阅读 2019-07-31 20:54:06
    不管是任何种类的机械臂,不管...技术参数的用途机械臂的设计、选择、应用。 这个链接是协作机械臂Franka emika 的技术参数表格。 这里面主要需要关注的技术参数通常包括以下六个: 目录 一、自由度 二、分辨...

    不管是任何种类的机械臂,不管它长得有多么奇形怪状,它总有不得不考虑的一些参数,是一个搞机械的必须要知道、明白它们到底是什么意思的。

    技术参数的目的:反映了机械臂可胜任的工作、具有的最高操作性能等情况。

    技术参数的用途:机械臂的设计、选择、应用。

    这个链接是协作机械臂 Franka emika 的技术参数表格。

    这里面主要需要关注的技术参数通常包括以下六个:

    目录

    一、自由度

    二、分辨率

    1. 编程分辨率
    2. 控制分辨率

    三、精度

    1. 定位精度
    2. 重复定位精度

    四、工作范围

    五、承载能力

    六、最大速度(加速度)

    参考


     

    自由度

    自由度就是指其所具有的独立坐标轴运动的数目,不包括手爪(末端操作器,end-effector)的开合自由度。 

    这里的自由度(英文简写DOF,Degree Of Freedom),指的是机械专业,《机械原理》课程中所学的机械系统的自由度。

    计算公式如下:F=3n-\left ( 2P_{L}+P_{H} \right ) 其中,n:为活动构件数;PL:低副约束数;PH:高副约束数。

    所以计算一下上图 emika 机械臂的自由度:一共有7个活动构件,7个转动关节,如图:所以F=3*7-2*7=21-14=7 个自由度。机械臂的可动关节数一般就是等于独立坐标轴运动的数目的,因此在机械臂这块,自由度就数电机就可以了。

    在三维空间中描述一个物体的位置和姿态(位姿)需要六个自由度。但是就像emika机械臂,它有七个自由度,所以说,机械臂的自由度是根据它的用途而设计的,可能小于六个自由度,也可能大于六个自由度。小于六个的,就像只需要,在平面上动动,在电路板上插元器件、在白板上写个字,就只需要四个和三个自由度。

    如果用六个自由度的机械臂去插元器件,这就叫做冗余自由度机器人了,利用冗余自由度可以增加机器人的灵活性、躲避障碍物和改善动力性能。人的手臂(大臂、小臂、手腕)就共有七个自由度,所以人的手很灵巧,可以回避障碍,从不同方向到达同一个目的点。比较直观的可以试一下,当你的手指完全不动的时候,手肘还是可以动的。

    所以自由度这个参数,就是来表明机械臂的灵活性的,灵活性不同,应用范围以及场合就不同。

    分辨率

     

    这个参数经常会和机械臂的精度弄混。但实际上分辨率是指机械臂能够实现的最小移动距离或最小转动角度。

    是由系统设计检测参数决定,并受到位置反馈检测单元性能的影响。

    • 编程分辨率

    是指程序中可以设定的最小距离单位,又称基准分辨率。例如:当电动机旋转0.1°,机械臂手腕点机手臂尖端点(不安装夹爪之类的工具)的直线移动距离为0.01mm时,其基准分辨率为0.01mm。

    • 控制分辨率

    是指位置反馈电路能够检测到的最小位移量。例如:若每周(转)1000个脉冲的增量式编码盘与电动机同轴安装;则电动机每旋转0.36°(360°,1000r/min),编码盘就发出一个脉冲,0.36°以下的角度无法检测,就称该系统的控制分辨率为0.36°。显然,当编程分辨率与控制分辨率相等时,系统改的性能达到最高。

    这两种分辨率,统称为系统分辨率

    精度

    机械臂的精度主要取决于误差,误差又有下面三种原因;

    • 机械误差

    传动误差:由轮齿误差、螺距误差等所引起的;

    关节间隙:由关节处的轴承间隙、谐波齿隙等引起的;

    连杆机构的挠度:其随机械臂位形、负载的变化而变化。

    • 控制算法误差

    主要指算法能否得到直接解和算法在计算机内的运算字长所造成的bit(比特)误差。作为控制系统的设计者,使用16位以上CPU进行浮点运算,精度可达到82位以上,所以bit误差与机构误差相比基本可以忽略不计。

    • 分辨率系统误差

    可取三基准分辨率。其理由是基准分辨率以下的运动变位既无法编程又无法检测,故误差的平均值可取1/2基准分辨率。机械臂的精度可认为是1/2基准分辨率与机构误差之和,即:精度= 1/2基准分辨率 + 机构误差。

    如能够做到使机械臂整个机构的综合误差值达到三基准分辨率,则精度等于分辨率。但是,就目前的水平而言,除纳米领域的机械手以外,其他的机械臂还难以实现。

    在实际应用中,精度的测量方法会分为,定位精度和重复定位精度,一般的技术参数表会采用重复定位精度。

    • 定位精度

    如下图, 想到的位置与实际到的位置之间的差异 d 就是定位精度的值,这个值其实非常容易受各种情况的影响,比如温度变化,会导致机械臂各个关节等的伸长或缩短,可能变化1℃,几十个μm就出去了。

    • 重复定位精度

    指机器人重复到达某一目标位置的差异程度。或在相同的位置指令下,机器人连续重复若干次其实际到达位置的分散情况。 是关于定位精度的统计数据,是衡量一列误差值的密集程度(重复度)。

    如上图所示,重复定位精度是指各次不同位置平均值的偏差。若重复定位精度为+0.2 mm,则指所有的动作位置停止点均在以么为中心的左右0.2 mm以内。在测试机械手的重复定位精度时,不同速度、不同方位下,反复试验的次数越多,重复定位精度的评价就越准确。

    因重复定位精度不受工作载荷变化的影响,故通常用重复定位精度这一指标作为衡量 示教--再现 方式机械臂水平的重要指标。

    标定重复定位精度时一般同时给出测试次数、测试过程所加的负载和手臂的姿态。

    精度和重复定位精度测试的典型情况如下图所示。

     知道了这些概念,还需要了解一下怎么测这个东西,由上可以知道,我们要测的是用电脑算出来的机械臂末端某一点的坐标值(一般取末端安装盘中心点,被称作TCP:tool center point),与实际上机械臂这一点的坐标值,之间的距离。因此只需增加一个可测量空间坐标值的设备就可以了。实际中对机械臂末端坐标的测量使用的是类似这样的 激光跟踪仪,实际的测量方法还有很多,可以在《GB/T12642_2013 工业机器人性能规范及其试验方法》这个文件中查看。

    工作范围

     机械臂工作范围是指机械臂末端或手腕中心所能到达的所有点的集合,也叫做工作区域。

    由于末端执行器的形状和尺寸是多种多样的,为真实反映机械手的特征参数,故工作范围是指不安装末端执行器时的工作区域。

    工作范围的形状和大小是十分重要的,机械手在执行某作业时可能会因存在手部不能到达的作业死区(dead zone)而不能完成任务。

    承载能力

    承载能力是指机器人在工作范围内的任何位姿上所能承受的最大负载,一般用质量、力矩或惯性矩表示。承载能力还与机械臂运行的速度和加速度的大小、方向有关。为了安全起见,一般规定高速运行时所能抓取的最大重量(通常包括末端操作器的质量)作为承载能力的指标。

    机械臂有效负载的大小除受到驱动器功率的限制外,还受到杆件材料极限应力的限制,因而它又和环境条件(如地心引力)、运动参数(如运动速度、加速度)。

    例如下图三菱装配机器人不带夹爪,与带夹爪两种状态下的承载能力:

     

    最大速度(加速度)

    速度和加速度是机械臂运动特性的主要指标。说明书中通常提供了主要运动自由度的最大稳定速度,不同厂家对最大稳定速度规定的内容亦有不同之处,有的厂家定义为机械臂主要自由度上最大的稳定速度;有的厂家定义为工业机械手手臂末端最大的合成速度,通常在技术参数中如加以说明。

    显而易见,工作速度愈高,工作效率愈高,但是在实际应用中单纯考虑最大稳定速度是不够的。驱动器的输出功率限制了它,从启动到达到最大稳定速度,或者共最大稳定速度到停止,都需要一定时间。因此需要看有效速度

    如果最大稳定速度高,允许的极限加速度小,则加减速的时间会长一些,对应用而言的有效速度就要低一些;

    反之,最大稳定速度低,允许的极限加速度就大,则加减速时间就会短一点。

    加减速时的加速度大,就有利于提高有效速度,但加速度过大,有可能会引起定位超调或振荡夹具,使得到达目标位置后需要等待振荡衰减的时间增加,反而使有效速度降低。所以除了看参数里的最大稳定速度外,还要看加速度的大小。

    参考

    1. 百家号:RND非标机械手
    2. 百度文库:工业机器人的技术参数
    3. 一文看懂机器人结构、驱动及技术指标
    展开全文
  • 2、了解正逆运动学在机械臂控制中实际用途。 二、实验内容 1、机械臂模型DH参数计算。 2、机械臂正运动学计算。 3、机械臂逆运动学计算。 三、实验步骤 1、正运动学实验验证,编写程序计算以下三组关节角度...

    实验一 机械臂正逆运动学
    一、实验目的
    1、巩固正逆运动学基础概念。
    2、了解正逆运动学在机械臂控制中的实际用途。
    二、实验内容
    1、机械臂模型DH参数的计算。
    2、机械臂正运动学的计算。
    3、机械臂逆运动学的计算。
    三、实验步骤
    1、正运动学实验验证,编写程序计算以下三组关节角度对应的末端位姿,并通过位置控制使机器人运动到相应位置,将实际末端位置与你的计算值比较,求出绝对误差。
    第一组:[0.927, -0.687, -0.396, 0, 1.083, 0.927]
    第二组:[0.322, -0.855, -0.021, 0, 0.877, 0.322]
    第三组:[-0.322, -0.636, -0.011, 0, 0.647, -0.322]
    2、逆运动学实验验证,编写程序计算以下三组末端位姿对应的关节角度,并通过位置控制使机器人运动到你计算出的位置,将实际末端位置与所给的值比较,求绝对误差。
    第一组:[0.2, 0.2, 0.2007,1.57, -1.57, 0]
    第二组:[0.15 ,0.2, 0.2007, 0, 0, 0]
    第三组:[0.3 ,0, 0.122, 1.57, 0, 0]
    四、评定标准
    1、实验结果的准确性
    五、注意事项
    1、本实验中姿态欧拉角与ROS中一致,全部采用弧度制,坐标全部以米为单位。
    2、真实机器人实验中,如果机器人发生碰撞,一定要先扶住机械臂,再按下急停按钮,否则机械臂会倒下。
    3、按下急停按钮后需要手动将机械臂复原到门位置,并重置控制内部机械臂位置。
    4、真实机械臂实验过程中,按下急停按钮后复位的过程中最好按照原本的运动方向复位,不要让第一关节一直向着一个方向旋转以免造成线路缠绕。
    5、机械臂启动时的位置被称为初始门位置(如下图),其末端位姿为[0.2289, 0, 0.454, 1.57, 0, 0],机械臂各个关节的正方向如图所示。

    代码,部分行从助教例程中直接复制,因此部分代码为无用代码,以及代码写了两次,懒得去其进行精简,所以很长。ubuntu带到win的注释乱码,也懒得修改了
    正运动学

    #include <string>
    #include <ros/ros.h>
    #include <iostream>
    #include <time.h>
    #include <Eigen/Dense>
    #include <cmath>
    #include "vector"
    #include "std_msgs/Float32.h"
    #include "std_msgs/Float64MultiArray.h"
    #include "controller_manager_msgs/SwitchController.h"
    #include "controller_manager_msgs/ListControllers.h"
    #include "ikfast.h"
    #include "probot_anno_manipulator_ikfast_moveit_plugin.cpp"
    
    using namespace ikfast_kinematics_plugin;
    
    
    
    void PrintMatrix(Eigen::Matrix<double,4,4> t){
        for(int i=0;i<4;i++){
            cout<<setw(15)<<"|   ";
            for(int j=0;j<4;j++){
                cout<<setw(15)<<t(i,j);
            }
            cout<<setw(15)<<"   |"<<endl;
        }
        
        cout<<endl;
    }
    
    int main(int argc, char** argv){
        bool ret;
        //鑺傜偣鍒濆鍖?
        ros::init(argc,argv,"forward_kinematics");
        //鍒涘缓鑺傜偣鍙ユ焺瀵硅薄
        ros::NodeHandle node_handle;
        ros::AsyncSpinner spinner(1);
        ROS_INFO_STREAM("start");
    
        ros::Publisher pos_pub=node_handle.advertise<std_msgs::Float64MultiArray>("/probot_anno/arm_pos_controller/command",100);
    
        ikfast_kinematics_plugin::IKFastKinematicsPlugin ik;
    
        ret = ik.IKFastKinematicsPlugin::initialize("robot_description","manipulator","base_link","link_6",0.001);
        
        std_msgs::Float64MultiArray init_pos;
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        sleep(1);
    
        double theta[6];
         //杈撳叆鍚勫叧鑺傚叧鑺傝
        for(int i = 0;i<6;i++){
            cout<<"鍏宠妭瑙?<<i+1<<": ";
            cin>>theta[i];
        }
        theta[6] = 0;
        theta[7] = 0;
    
        init_pos.data.at(0) = theta[0];
        init_pos.data.at(1) = theta[1];
        init_pos.data.at(2) = theta[2];
        init_pos.data.at(3) = theta[3];
        init_pos.data.at(4) = theta[4];
        init_pos.data.at(5) = theta[5];
    //瀹氫箟DH鍙傛暟
        const double DH[8][3]={ 0,0,0.284,
                                                           M_PI/2,0,0,
                                                            0,0.225,0,
                                                            M_PI/2,0,0.2289,
                                                            -M_PI/2,0,0,
                                                            M_PI/2,0,0,
                                                            0,0,0.055,
                                                            -M_PI/2,0,0};
        Eigen::Matrix<double,4,4> T[8]; 
    //璁$畻鍙樻崲鐭╅樀
        for(int i=0;i<8;i++){
            T[i] << cos(theta[i]),-sin(theta[i]),0,DH[i][1],
                        sin(theta[i])*cos(DH[i][0]),cos(theta[i])*cos(DH[i][0]),-sin(DH[i][0]),-sin(DH[i][0])*DH[i][2],
                        sin(theta[i])*sin(DH[i][0]),cos(theta[i])*sin(DH[i][0]),cos(DH[i][0]),cos(DH[i][0])*DH[i][2],
                        0,0,0,1;
        }
        T[1] << cos(theta[1]+M_PI/2),-sin(theta[1]+M_PI/2),0,DH[1][1],
                        sin(theta[1]+M_PI/2)*cos(DH[1][0]),cos(theta[1]+M_PI/2)*cos(DH[1][0]),-sin(DH[1][0]),-sin(DH[1][0])*DH[1][2],
                        sin(theta[1]+M_PI/2)*sin(DH[1][0]),cos(theta[1]+M_PI/2)*sin(DH[1][0]),cos(DH[1][0]),cos(DH[1][0])*DH[1][2],
                        0,0,0,1;   
        T[4]<< cos(theta[4]-M_PI/2),-sin(theta[4]-M_PI/2),0,DH[4][1],
                        sin(theta[4]-M_PI/2)*cos(DH[4][0]),cos(theta[4]-M_PI/2)*cos(DH[4][0]),-sin(DH[4][0]),-sin(DH[4][0])*DH[4][2],
                        sin(theta[4]-M_PI/2)*sin(DH[4][0]),cos(theta[4]-M_PI/2)*sin(DH[4][0]),cos(DH[4][0]),cos(DH[4][0])*DH[4][2],
                        0,0,0,1;        
    //璁$畻鏈浣嶅Э鍙樻崲鐭╅樀
        Eigen::Matrix<double,4,4> result;
        result << 1,0,0,0,
                            0,1,0,0,
                            0,0,1,0,
                            0,0,0,1;
        
        for(int i = 0;i<8;i++){
            result = result * T[i];
            //PrintMatrix(result);
        }    
    //寰楀埌鏁版嵁
        double pos_x = result(0,3);
        double pos_y = result(1,3);
        double pos_z = result(2,3);
        double rot_x = atan2(result(2,1),result(2,2));
        double rot_y = atan2(-result(2,0),sqrt(result(1,0)*result(1,0)+result(0,0)*result(0,0)));
        double rot_z = atan2(result(1,0),result(0,0));
    //杈撳嚭浣嶅Э
        cout<<"pos_x:"<<pos_x<<endl;
        cout<<"pos_y:"<<pos_y<<endl;
        cout<<"pos_z:"<<pos_z<<endl;
        cout<<"rot_x:"<<rot_x<<endl;
        cout<<"rot_y:"<<rot_y<<endl;
        cout<<"rot_z:"<<rot_z<<endl;         
    
        pos_pub.publish(init_pos);
        ROS_INFO_STREAM("published");
    
    }
    

    逆运动学

    #include <string>
    #include <ros/ros.h>
    #include <iostream>
    #include <time.h>
    #include <Eigen/Dense>
    #include <math.h>
    #include "vector"
    #include "std_msgs/Float32.h"
    #include "std_msgs/Float64MultiArray.h"
    #include "controller_manager_msgs/SwitchController.h"
    #include "controller_manager_msgs/ListControllers.h"
    #include "ikfast.h"
    #include "probot_anno_manipulator_ikfast_moveit_plugin.cpp"
    
    using namespace ikfast_kinematics_plugin;
    
    //瀹氫箟涓€浜涘嚱鏁颁究浜庢暡鍏紡
    //骞虫柟
    double squa(double t){
        return t*t;
    }
    //cos姹傚拰
    double cosp(double theta1, double theta2){
        return (cos(theta1)*cos(theta2)-sin(theta1)*sin(theta2));
    }
    //sin姹傚拰
    double sinp(double theta1, double theta2){
        return (sin(theta1)*cos(theta2) + sin(theta2)*cos(theta1));
    }
    
    double judge(double theta){
        if(theta > -0.01 && theta < 0.01){
            return 0;
        }
        else return theta;
    }
    
    int main(int argc, char**argv){
    
        bool ret;
    
        ros::init(argc,argv,"inverse_kinematics");
    
        ros::NodeHandle node_handle;
        ROS_INFO_STREAM("start");
    
        ros::Publisher pos_pub=node_handle.advertise<std_msgs::Float64MultiArray>("/probot_anno/arm_pos_controller/command",100);
    
        ikfast_kinematics_plugin::IKFastKinematicsPlugin ik;
    
        ret = ik.IKFastKinematicsPlugin::initialize("robot_description","manipulator","base_link","link_6",0.001);
    
        double theta[6];
        double CarCoor[6];
    
    //杈撳叆绗涘崱灏斿潗鏍?
        cout << "pos_x:";
        cin >> CarCoor[0];
        cout << "pos_y:";
        cin >> CarCoor[1];
        cout << "pos_z:";
        cin >> CarCoor[2];
        cout << "rot_x:";
        cin >> CarCoor[3];
        cout << "rot_y:";
        cin >> CarCoor[4];
        cout << "rot_z:";
        cin >> CarCoor[5];
    //瀹氫箟涓€浜涘彉閲忎究浜庢暡鍏紡
        double px = CarCoor[0];
        double py = CarCoor[1];
        double pz = CarCoor[2];
        double gamma = CarCoor[3];
        double beta = CarCoor[4];
        double alpha = CarCoor[5];
    //璁$畻鍏舵鍙樻崲鐭╅樀
        Eigen::Matrix<double,3,3> R;
        
        R << cos(alpha)*cos(beta),cos(alpha)*sin(beta)*sin(gamma)-sin(alpha)*cos(gamma),cos(alpha)*sin(beta)*cos(gamma)+sin(alpha)*sin(gamma),
                  sin(alpha)*cos(beta),sin(alpha)*sin(beta)*sin(gamma)+cos(alpha)*cos(gamma),sin(alpha)*sin(beta)*cos(gamma)-cos(alpha)*sin(gamma),
                  -sin(beta),cos(beta)*sin(gamma),cos(beta)*cos(gamma);
    
        Eigen::Matrix<double,4,4>T0;
        T0 << R(0,0), R(0,1), R(0,2), CarCoor[0],
              R(1,0), R(1,1),R(1,2), CarCoor[1],
              R(2,0), R(2,1), R(2,2), CarCoor[2],
              0,0,0,1;
    //灏嗗潗鏍囩郴浠庣鍏釜鍧愭爣绯昏浆鎹㈠洖瀹氫箟鐨勭鍏釜鍧愭爣绯?
        Eigen::Matrix<double,4,4>Tw1,Tw2;
        Tw1 << 1,0,0,0,
               0,1,0,0,
               0,0,1,-0.055,
               0,0,0,1;
        Tw2 << 1,0,0,0,
               0,0,-1,0,
               0,1,0,0,
               0,0,0,1;
    //閫氳繃绗叚涓潗鏍囩郴涓嬬殑鍧愭爣閲嶆柊璁$畻浣嶅Э绛?
    
        T0 = T0 * Tw2 * Tw1;
        for(int i = 0;i<3;i++){
            CarCoor[i] = T0(i,3);
        }
        CarCoor[3] = atan2(T0(2,1),T0(2,2));
        CarCoor[4] = atan2(-T0(2,0),sqrt(squa(T0(1,0))+squa(T0(0,0))));
        CarCoor[5] = atan2(T0(1,0),T0(0,0));
        
        px = CarCoor[0];
        py = CarCoor[1];
        pz = CarCoor[2];
        gamma = CarCoor[3];
        beta = CarCoor[4];
        alpha = CarCoor[5];
    
        R << cos(alpha)*cos(beta),cos(alpha)*sin(beta)*sin(gamma)-sin(alpha)*cos(gamma),cos(alpha)*sin(beta)*cos(gamma)+sin(alpha)*sin(gamma),
             sin(alpha)*cos(beta),sin(alpha)*sin(beta)*sin(gamma)+cos(alpha)*cos(gamma),sin(alpha)*sin(beta)*cos(gamma)-cos(alpha)*sin(gamma),
             -sin(beta),cos(beta)*sin(gamma),cos(beta)*cos(gamma);
    //DH鍙傛暟琛?
    //\alpha_{i-1},a_{i-1},\theta_i,d_i
        const double DH[8][4]={0,0,0,0.284,
                                                           M_PI/2,0,M_PI/2,0,
                                                            0,0.225,0,0,
                                                            M_PI/2,0,0,0.2289,
                                                            -M_PI/2,0,-M_PI/2,0,
                                                            M_PI/2,0,0,0,
                                                            0,0,0,0.055,
                                                            -M_PI/2,0,0,0};
    //鎶奃H琛ㄩ噷涓€浜涗細鐢?
        double d1 = DH[0][3];
        double d4 = DH[3][3];
        double a3 = DH[2][1];
    //璁$畻\theta_1
        theta[0] = judge(atan2(py,px));
    //杩樻槸濂芥暡鍏紡
        double s1 = sin(theta[0]);
        double c1 = cos(theta[0]);
    //璁$畻\theta_2
        double K = (squa(d4) - squa(px/c1) - squa(pz - d1) - squa(a3))/(2*a3);
        theta[1] = atan2(pz-d1, px/c1) - atan2( -K , sqrt(squa(px/c1) + squa(pz - d1) - squa(K)));
        double s2 = sin(theta[1]);
        double c2 = cos(theta[1]);
    //璁$畻\theta_3
        double s23 = (pz - c2 * a3 - d1)/d4;
        double c23 = ((px/c1)+s2 * a3) / d4;
        theta[2] = judge(atan2(s23, c23) - theta[1]);
        double s3 = sin(theta[2]);
        double c3 = cos(theta[2]);
        c23 = cosp(theta[1],theta[2]);
        s23 = sinp(theta[1],theta[2]);
    //璁$畻寰楀埌^4_6T,鏉ヨ绠楀悗涓夎锛孯1涓篰1_0R,绫绘帹
        Eigen::Matrix<double,3,3> R1,R2,R3,result;
    
        R1 << c1, s1, 0,
              -s1, c1, 0,
              0, 0, 1;
        R2 << -s2, 0, c2,
              -c2, 0, -s2,
              0, -1, 0;
        R3 << c3, s3, 0,
              -s3, c3, 0,
              0, 0, 1;
        
        result = R3 * R2 * R1 * R;
    //璁$畻\theta_5
        theta[4] = judge(atan2(-result(1,2), sqrt(squa(result(1,0))+squa(result(1,1)))));
        double s5 = sin(theta[4]);
        double c5 = cos(theta[4]);
    //璁$畻\theta_4
        theta[3] = judge( atan2(-result(2,2)/c5, -result(0,2)/c5));
        double s4 = sin(theta[3]);
        double c4 = cos(theta[3]);
    //璁$畻\theta_6
        theta[5] = judge(atan2(result(1,1)/c5,-result(1,0)/c5));
    //鎶婅绠楀緱鍒扮殑鍏宠妭瑙掓墦鍑烘潵搴峰悍
            
            for(int i =0;i<6;i++){
              cout<<"theta"<<i+1<<": "<<theta[i]<<endl;
            }
        
    
         std_msgs::Float64MultiArray init_pos;
    
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        init_pos.data.push_back(0);
        sleep(1);
    
        init_pos.data.at(0) = theta[0];
        init_pos.data.at(1) = theta[1];
        init_pos.data.at(2) = theta[2];
        init_pos.data.at(3) = theta[3];
        init_pos.data.at(4) = theta[4];
        init_pos.data.at(5) = theta[5];
     
        pos_pub.publish(init_pos);
        ROS_INFO_STREAM("published");
    }
    
    展开全文
  • 红色的LED用来标志状态(LED说明:此LED有三种闪烁状态,机械臂动作时闪烁周期是1秒,机械手动作时闪烁周期是2秒,空闲阶段闪烁周期是3秒),开关用来进行不同功能的控制转换(开关用途:本来机械臂的机械手是想通过...
  • 机械臂探索——齐次变换

    千次阅读 2018-03-23 15:44:40
    先来介绍一下本文齐次变换的用途:是为了确定机械臂的位置和姿态的。机器人运动学也就是研究手臂末端执行器位置和姿态与关键转动角度之间的关系。•丹纳维特(Denavit)和哈顿贝格(Hartenberg)于1955年提出了...

    首先我们先来介绍一下什么是齐次变换?为什么要了解齐次变换?

    齐次坐标就是将一个原本是n维的向量用一个n+1维向量来表示。百度百科上说的太笼统,不靠谱!不过我们可以用一种简单的方式理解它。

    先来介绍一下本文齐次变换的用途:是为了确定机械臂的位置和姿态的。机器人运动学也就是研究手臂末端执行器位置和姿态与关键转动角度之间的关系。

    丹纳维特(Denavit)和哈顿贝格(Hartenberg)于1955年提出了一种矩阵代数方法解决机器人的运动学问题D-H方法
    具有直观的几何意义
    能表达动力学、计算机视觉和比例变换问题
    其数学基础即是齐次变换

    1.齐次变换坐标

             ->           

    先来认识一下上面的公式,第一个公式很简单,其实就是三维坐标系内某一点的向量表示。

    上图第二个公式就是我们这小节的主题:齐次变换坐标。我们利用齐次变换坐标来表示了三维坐标系内某一点的坐标。

    其中w相当于是一个比例系数。a=x/w,b=y/w,c=z/w。这是他们之间的转换关系,由于w的值式不一定的,所以会有很多种方式来表示一个三维坐标系内的空间坐标。

    2.增加一个坐标系

    如下图,我们在原有坐标系也就是参考坐标系xyz的基础上加了另外一个坐标系nao,现在我们要做的就是想办法利用参考坐标系来表示nao坐标系。怎么表示呢?很简单,我们从上图可以看出,nao坐标系的三条互相垂直的轴可以分别用参考坐标系的xyz来表示。如:nx,yx,zx,ax,ay,az,ox,oy,oz。于是我们得出下图结论:


    当我们新建的坐标系与参考坐标系不在同一原心时,如下图:


    我们增加了向量P用于表示新坐标系的位置。新坐标系的位姿由noa三个向量来表示,位置由p来表示。如此便得到了上面的公式来表示新建坐标系与参考坐标系之间的关系。







    展开全文
  • 舵机(英文叫Servo):它由直流电机、减速齿轮组、传感器和控制电路组成一套自动控制系统。通过发送信号,指定输出轴旋转角度。舵机一般而言都有最大旋转角度(比如180度。...用途也不同,普通直流电机一般是整...

    舵机(英文叫Servo):它由直流电机、减速齿轮组、传感器和控制电路组成的一套自动控制系统。通过发送信号,指定输出轴旋转角度。舵机一般而言都有最大旋转角度(比如180度。)与普通直流电机的区别主要在,直流电机是一圈圈转动的,舵机只能在一定角度内转动,不能一圈圈转(数字舵机可以在舵机模式和电机模式中切换,没有这个问题)。普通直流电机无法反馈转动的角度信息,而舵机可以。用途也不同,普通直流电机一般是整圈转动做动力用,舵机是控制某物体转动一定角度用(比如机器人的关节)。

    下图是一个普通模拟舵机的分解图,其组成部分主要有齿轮组、电机、电位器、电机控制板、壳体这几大部分。
    1
    电机控制板主要是用来驱动电机和接受电位器反馈回来的信息。电机嘛,动力的来源了,这个不用太多解释。电位器这里的作用主要是通过其旋转后产生的电阻的变化,把信号发送回电机控制板,使其判断输出轴角度是否输出正确。齿轮组的作用主要是力量的放大,使小功率电机产生大扭矩。
    2
    舵机底壳拆开后就可以看到,主要是电机与控制板
    在这里插入图片描述
    控制板拿起来后下方是与控制板连接的电位器
    3
    从顶部来看电机与电位器,与电机齿轮直接相连的为第一级放大齿轮。
    在这里插入图片描述
    经过一级齿轮放大后,再经过二、三、四级放大齿轮,最后再通过输出轴输出。
    在这里插入图片描述
    通过上面两图可以很清晰的看到,本舵机是4级齿轮放大机构,就是通过这么一层层的把小的力量放大,使得这么一个小小的电机能有15KG的扭力。

    看完了舵机的构造后咱么对舵机的控制系统进行详解。

    舵机的伺服系统由可变宽度的脉冲来进行控制,控制线是用来传送脉冲的。脉冲的参数有最小值,最大值,和频率。一般而言,舵机的基准信号都是周期为20ms,宽度为1.5ms。这个基准信号定义的位置为中间位置。舵机有最大转动角度,中间位置的定义就是从这个位置到最大角度与最小角度的量完全一样。最重要的一点是,不同舵机的最大转动角度可能不相同,但是其中间位置的脉冲宽度是一定的,那就是1.5ms。如下图:
    在这里插入图片描述
    角度是由来自控制线的持续的脉冲所产生。这种控制方法叫做脉冲调制。脉冲的长短决定舵机转动多大角度。例如:1.5毫秒脉冲会到转动到中间位置(对于180°舵机来说,就是90°位置,对于270°舵机来说,就是135°位置)。当控制系统发出指令,让舵机移动到某一位置,并让他保持这个角度,这时外力的影响不会让他角度产生变化,但是这个是由上限的,上限就是他的最大扭力。除非控制系统不停的发出脉冲稳定舵机的角度,舵机的角度不会一直不变。

    当舵机接收到一个小于1.5ms的脉冲,输出轴会以中间位置为标准,逆时针旋转一定角度。接收到的脉冲大于1.5ms情况相反。不同品牌,甚至同一品牌的不同舵机,都会有不同的最大值和最小值。一般而言,最小脉冲为1ms,最大脉冲为2ms。如下图:
    3

    展开全文
  • 一个openFrameworks插件,用于控制Universal Robots机械臂并与之交互。 ofxURDriver将适用于ROSThomasTimm软件包为openFrameworks。 有关如何使用此插件示例,请参见 。 发牌 ofxURDriver仅许可用于非商业...
  • 开发ROS 程序包控制机械臂

    千次阅读 2016-11-29 19:52:20
    ROS(Robot Operation System)是一个机器人软件平台,提供一些标准操作系统服务,例如硬件抽象,底层设备控制,常用...ROS(低层)使用BSD许可证,所有都是开源软件,并能免费用于研究和商业用途。由于其强大功能
  • 作为一个工程师,打造出一个机械臂不仅是很酷更是很有意义的一件事,分享电路城上8个精彩的机械臂的设计,寻找属于你的灵感吧! 1、【2017贸泽大赛】二等奖作品:VR视角远程牵引控制机械臂 项...
  • 本项目的控制目标为机械臂,通过LeapMotion识别手势,将其转换为控制信号,实现对机械臂的动作控制,实现与人手同步的效果。 视频演示: 源码地址:https://github.com/MotionArduino 附件内容截图: 可能感兴趣的项目...
  • 在Kickstarter上面出现了一款别致智能机器人白板众筹项目。 Joto是一款新颖别致硬件产品。...据悉,Joto由钢笔、橡皮擦、板和机械臂组成,非常轻盈,易于安装,你也可以将其想象...
  • 它还配备了一个机械臂,可以帮助我们拾取和放下小物体。 •使用Arduino和MATLAB收集并分析传感器数据,同时通过自制Web应用程序使用Raspberry-pi对电机和机器人手臂进行Web控制。 •可用于工业,农业和天文目的。 ...
  • 毕业设计-机械

    2011-10-19 10:36:03
    1.4装载机工作机构的用途 2 2 装载机装载过程分析 3 2.1装载过程描述: 3 2.2装载阻力计算 4 3 装载机工作机构的设计 6 3.1工作机构对铲斗运动的要求 6 3.2 铲斗的机构设计 6 3.3 斗容的计算和尺寸确定 7 3.4工作...
  • 协同动作应用手册.pdf

    2020-03-04 21:23:50
    MultiMove的用途在于让一个控制器操作数个机械臂,这不仅能节约硬件成本,还能 对不同机械臂和其他机械单元之间进行前进协调。
  • 现在也有较小型一般用途机器人,可帮助多种企业提升生产力,能在最小仅两平方英尺工作场所中与操作人员互相合作。 本文将探讨为何以前无法以协作型机器人形式,将机器人大规模部署在较小型企业中,以及为何...
  • 用什么样机械手好部署机械手或末端执行器使用感应器操纵机械臂和机械手设计带机械臂和机械手机器人在铰链式机械臂上安装机械手机械手种类V形机械手机器人原型设计和制造开始设计——从现有原型着手考虑你...
  • 【 声明:版权所有,欢迎转载,请勿...小到玩具、大到机械臂,里面都有电机影子,还是蛮有意思。趁着现在还有点印象,赶紧做个笔记,供后面使用。 1、学习视频 个人觉得这家开发板厂商出电机教学视频非常...
  • 工业机器人技术 工业机器人通常工作于工厂车间,能够执行各种任务,尤其是对人体有害或其所要求精度和速度人类很... 工业机器人技术指是对构成机器人电动机械臂和关节设计、构建、操作和装配。机器人控制
  • 计算机介绍

    2019-09-28 05:30:51
    机械手臂(计算机):加工产品 人(高贵人)--》奴隶 来做。 生产奴隶(机器(计算机)) 计算机对于我们人类而言:奴隶,完成我们需求, 计算机发展史 1946,军事用途,破译密码 设计导弹路程 如何通过...
  • 机械手臂(计算机):加工产品 小度(计算机):智能家居 1.2计算机发展史 1946,军事用途,破译密码 设计导弹路程 1.3如何通过计算机完成我们需求 如果没有操作系统,计算机就是废品 充电 开机(启动一操作...
  • 应用领域 Geomstats应用程序,说明了该软件包更多相关用途。 脑连接组分析 我们考虑了2014年MLSP精神分裂症分类挑战中...我们在此应用程序中考虑了机械臂。 在机器人技术中,通常在笛卡尔空间而不是配置空间中控
  • OWI 535 Robotic Arm Edge是一套非常流行五自由度机械臂套件,常见于创客改造与科研用途机械臂由USB通信实现控制,每个控制指令由3个字节组成,分别为Byte0,Byte1,Byte2。每个字节控制特定一部分手臂功能...
  • FOC控制原理

    2021-04-25 09:36:37
    ​ 电机分为有刷电机和无刷电机,这里主要描述FOC控制算法主要是针对无刷电机控制,无刷电机用于飞行器或者四足狗、机械臂等这种高精度环境当中。玩过四轴都比较清楚在,四轴飞行器中一般采用电调驱动方式...
  • day02作业

    2019-10-03 22:39:47
    机械手臂(计算机):加工产品 人(高贵人)--》奴隶 来做。 生产奴隶(机器(计算机)) 计算机对于我们人类而言:奴隶,完成我们需求, 计算机发展史 1946,军事用途,破译密码 设计导弹路程 如何通过...
  • 计算机基础知识

    2019-07-12 17:53:00
    机械手臂(计算机):加工产品 人(高贵人)--》奴隶 来做。 生产奴隶(机器(计算机)) 计算机对于我们人类而言:奴隶,完成我们需求, 计算机发展史 1946,军事用途,破译密码 设计导弹路程 如何通过...
  • TeleOp.c:包含主驱动器和机械臂控制功能远程操作模式程序 Auto.h:自治模式程序,包含自治代码主体(由“自动”文件夹使用) common.h:包含TeleOp.c和Auto.h使用各种功能 constants.h:包含用于将程序校准...
  • 1.4 机械零件功能分类 19 1.4.1 连接件 19 1.4.2 紧固件 20 1.4.3 密封件 20 1.4.4 弹簧类零件 21 1.4.5 轴类零件 21 1.4.6 轴承类零件 22 1.4.7 盘类零件 22 1.4.8 叉架类零件 23 1.4.9 箱体类零件 23 1.5 习题 ...
  • 其特点如下:1.ENC-03MB 为低成本单周机械陀螺仪传感器,用于检测角速度。2.模拟信号输出,关键电阻均采用1%精度电阻,且使用磁珠对地进行抗干扰处理。3.支持2.7V-5.25V宽电压输入。 角速度侦测 ENC-03MB 双轴陀螺仪...

空空如也

空空如也

1 2
收藏数 28
精华内容 11
关键字:

机械臂的用途