精华内容
下载资源
问答
  • ABBROS功能更新2021

    2021-07-24 21:58:07
    很久很久以前,2016记录过一篇ROSABB机械臂的博客: ROS连接ABB机械臂调试详细教程-ROS(indigo)和ABB RobotStudio 6.03.02 现在官方早已更新了…… 这里再记录一下。 ros-industrial/abb_robot_driver: The ...

    很久很久以前,2016记录过一篇ROS和ABB机械臂的博客:

    现在官方早已更新了……

    这里再记录一下。

    同步支持Ubuntu 和 Windows 

    ABB也要进军移动机器人领域啦

     强者恒强……

     

    展开全文
  • 安装ABB ROS服务器

    2019-08-28 19:16:13
    安装ABB ROS服务器1.先决条件2.安装服务器代码3.配置控制器设置3.1文件概述3.2创建任务3.3创建信号3.4将信号绑定到系统输出3.5将模块加载到任务3.6更新软件 介绍在ABB机器人控制器上安装ROS服务器代码并配置所需...

    介绍在ABB机器人控制器上安装ROS服务器代码并配置所需控制器设置的步骤。包含两部分:安装服务器代码和使用适当的任务配置控制器。

    1.先决条件

    ABB ROS服务器代码使用套接字接口和多个并行任务以RAPID编写。该代码最初是在带有IRB-2400机器人的IRC-5控制器上测试的,但其他组合也应该有效。需要以下控制器选项:

    • 623-1:多任务处理
    • 672-1:套接字消息传递(在最近的RobotWare版本中,此选项包含在616-1:PC接口中)

    由于使用了某些套接字选项,因此需要RobotWare OS版本5.13或更高版本。早期版本可能有效,但需要修改RAPID代码。

    2.安装服务器代码

    应将abb_common / rapid(Hydro和旧版)或abb_driver / rapid(Indigo和更高版本)目录中的所有文件复制到机器人控制器。本教程假定文件被复制到系统HOME目录下的“ ROS ”子目录(例如/ / HOME / ROS / *)。

    有关文件传输方法,请参阅制造商的文档。RobotStudio Online和USB驱动器通常是将文件传输到控制器的便捷方法。

    3.配置控制器设置

    ROS服务器代码需要3个任务。某些模块加载到特定任务,其他模块在任务之间共享,如下所述:

    3.1文件概述

    • 由所有任务共享
      ROS_common.sys - 所有文件共享的全局变量和数据类型
      ROS_socket.sys - 套接字处理和simple_message实现
      ROS_messages.sys - 特定消息类型的实现

    • 具体任务模块
      ROS_stateServer.mod - 广播联合位置和状态数据
      ROS_motionServer.mod - 接收机器人动作命令
      ROS_motion.mod - 向机器人发出动作命令

    3.2创建任务

    1. 浏览到ABB - >控制面板 - >配置 - >主题 - >控制器 - >任务(在RobotStudio 6中,可以在Controller选项卡 - > Configuration Editor - > Controller - > Task下找到,然后右键单击New Task)
    2. 创建3个任务如下:
    NameTypeTrust LevelEntryMotion Task
    ROS_StateServerSEMISTATICNoSafetymainNO
    ROS_MotionServerSEMISTATICSysStopmainNO
    T_ROB1NORMALmainYES
    在重新启动控制器之前,最简单的方法是等待所有配置任务完成。

    注意:

    1. T_ROB1运动任务可能已存在于您的控制器上。
    2. 如果T_ROB1具有现有的运动控制模块,则可能需要将ROS_Motion.mod中的main()例程重命名为ROS_main()。在这种情况下,将T_ROB1任务的入口点设置为ROS_main()。
    3. 对于多机器人控制器,请为每个任务指定所需的机器人(例如rob1)
    4. SEMISTATIC任务将在控制器启动时自动启动。它们是可见的,但不容易看到故障排除。出于调试或开发目的,可能需要将ROS_ * Server任务设置为Type = NORMAL。

    3.3创建信号

    1. 浏览到ABB - >控制面板 - >配置 - >主题 - > I / O - >信号(在RobotStudio 6中,可在Controller选项卡 - > Configuration Editor - > I / O System - > Signal下找到,然后右键单击New Signal)
    2. 创建4个信号如下:
    NameType of Signal
    signalExecutionErrorDigital Output
    signalMotionPossibleDigital Output
    signalMotorOnDigital Output
    signalRobotActiveDigital Output
    signalRobotEStopDigital Output
    signalRobotNotMovingDigital Output
    signalRosMotionTaskExecutingDigital Output
    在重新启动控制器之前,最简单的方法是等待所有配置任务完成。

    3.4将信号绑定到系统输出

    1. 浏览到ABB - >控制面板 - >配置 - >主题 - > I / O - >系统输出(在RobotStudio 6中,可以在Controller选项卡 - > Configuration Editor - > I / O System - > System Output下找到,然后右键单击New System Output)
    2. 为信号添加一个条目,如下所示:
    Signal NameStatusArg 1Arg 2Arg 3Arg 4
    signalExecutionErrorExecution ErrorN/AT_ROB1N/AN/A
    signalMotionPossibleRunchain OKN/AN/AN/AN/A
    signalMotorOnMotors On StateN/AN/AN/AN/A
    signalRobotActiveMechanical Unit ActiveROB_1N/AN/AN/A
    signalRobotEStopEmergency StopN/AN/AN/AN/A
    signalRobotNotMovingMechanical Unit Not MovingROB_1N/AN/AN/A
    signalRosMotionTaskExecutingTask ExecutingN/AT_ROB1N/AN/A

    3.5将模块加载到任务

    1. 浏览到ABB - >控制面板 - >配置 - >主题 - >控制器 - >模块的自动加载(在RobotStudio 6中,可以在Controller选项卡 - > Configuration Editor - > Controller - > Automatic Loading of Modules下找到,然后右键单击New Automatic Loading of Modules)
    2. 为每个服务器文件添加一个条目,如下所示:
    FileTaskInstalledAll TasksHidden
    HOME:/ROS/ROS_common.sysNOYESNO
    HOME:/ROS/ROS_socket.sysNOYESNO
    HOME:/ROS/ROS_messages.sysNOYESNO
    HOME:/ROS/ROS_stateServer.modROS_StateServerNONONO
    HOME:/ROS/ROS_motionServer.modROS_MotionServerNONONO
    HOME:/ROS/ROS_motion.modT_ROB1NONONO
    1. 在最后一次更改后,选择“YES”以重新启动控制器并应用更改。

    3.6更新软件

    要使用新代码版本更新机械手 - 服务器文件,请使用以下过程确保实际应用更改:

    1. 像以前一样将新的/更新的文件复制到机器人控制器上。

    2. 使用P-Start重新启动控制器
      ▪ ABB - >重启 - >高级 - > P-Start - >确定
      ▪ 注意:这将擦除已加载到内存的任何现有模块。这可能会导致重新启动时出现编译问题。如果这是一个问题,请尝试另一种方法:热启动,手动重新加载模块(可能需要将SEMISTATIC任务设置为NORMAL任务)等。

    3. 控制器重新启动后,新的更改应该是活动的。

    展开全文
  • ROS与ABB120

    千次阅读 2017-03-15 15:11:26
    http://wiki.ros.org/abb http://rosindustrial.org/ 1.安装MoveIt sudo apt-get install ros-indigo-moveit-full2.安装sudo apt-get install ros-in

    http://blog.csdn.net/zhangrelay/article/details/52687545
    http://wiki.ros.org/abb
    http://rosindustrial.org/
    1.安装MoveIt

    sudo apt-get install ros-indigo-moveit-full

    2.安装

    sudo apt-get install ros-indigo-industrial-robot-client
    sudo apt-get install ros-indigo-industrial-core
    sudo apt-get install ros-indigo-industrial-msgs
    sudo apt-get install ros-indigo-industrial-trajectory-filters
    sudo apt-get install ros-indigo-industrial-deprecated
    sudo apt-get install ros-indigo-industrial-robot-client
    sudo apt-get install ros-indigo-industrial-utils
    sudo apt-get install ros-indigo-industrial-desktop
    sudo apt-get install ros-indigo-industrial-robot-simulator      

    2、关于IP设置:
    安装ros的台式机ip设置为192.168.3.242,
    安装studio的ip设置为192.168.3.124.

    3.rospc Ip 多少?

    ifconfig
    4.

    sudo apt-get install ros-indigo-mongodb-log
    sudo apt-get install ros-indigo-mongodb-store
    sudo apt-get install ros-indigo-mongodb-store-msgs
    cd ~/catkin_ws/
    catkin_make
    sudo service mongodb start
    cd ~/catkin_ws/src
    cd abb_experimental

    https://www.mongodb.com/download-center?jmp=nav#community
    https://docs.mongodb.com/master/tutorial/install-mongodb-on-ubuntu/?_ga=1.249145863.1843349037.1489732581

    sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
    echo "deb [ arch=amd64 ] http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
    sudo apt-get update
    sudo apt-get install -y mongodb-org

    运行MongoDB

    sudo service mongod start

    先测试

    roslaunch abb_irb120_moveit_config demo.launch

    运行

    roslaunch abb_irb120_moveit_config moveit_planning_execution.launch sim:=true robot_ip:=192.168.3.124
    或
    roslaunch abb_irb120t_moveit_config moveit_planning_execution.launch sim:=true robot_ip:=192.168.3.124

    关于Gazebo

    roslaunch abb_irb120_gazebo irb120_gazebo.launch
    roslaunch abb_experimental demo.launch
    展开全文
  • 为了研究ABB机器人与ROS的交互控制,最近和ABB的机器人还有ROS-Industrial杠上了,之前把ROSLAUNCH的.launch/XML文件的语法格式弄清楚了,现在搞abb_driver的东西!ABB_Driver是ROS-Industrial的一部分,而其中的ABB...

    为了研究ABB机器人与ROS的交互控制,最近和ABB的机器人还有ROS-Industrial杠上了,之前把ROSLAUNCH的.launch/XML文件的语法格式弄清楚了,现在搞abb_driver的东西!

    1. 概述与前置条件

    ABB_DriverROS-Industrial的一部分,而其中的ABB ROS Server是其中最重要的组成部分之一,其是用ABB自己开发的机器人编程语言RAPID编写的,通过Socket接口和多任务处理完成与ROS的交互。ROS Server的代码在IRC5控制器上测试可以使用,在其它类型的ABB控制器可能要经过调整,要在ABB机器人控制器上安装ROS Server首先要满足以下两个条件:

    • 623-1: Multitasking
    • 616-1: PC Interface

    就是说你的控制器里要启动这两个功能组件。
    上述条件满足后先从机器人端开始研究ROS Server到底怎么用。

    2. ROS Server

    ROS Server的文件组成

    ROS Server按照功能主要由六类文件组成,对于单臂机器人来讲每一类文件包含一个程序文件,但对于双臂机器人来说,每类文件要包含两个程序文件,因为在程序执行的时候会在每一个单臂下生成各自的执行程序文件。从功能上讲,这六类文件为:

    文件名功能
    ROS_common.sys对共用的数据进行定义与赋值
    ROS_messages.sys对轨迹与关节点数据进行定义,并定义数据的接收与发送函数
    ROS_socket.sys定义Socket通讯功能相关的所有函数
    ROS_stateServer.mod状态反馈服务器,向ROS发送机器人相关状态
    ROS_motionServer.mod运动控制服务器
    ROS_motion.mod机器人实际运动控制程序

    以上文件是于2017-12-22从GitHub里直接下载下来的,还没有进行代码的修改,接下来先分析每一个文件的功能。

    哎,等一下:关于权利声明和软件License什么的都放在这里了,适用于后面所有ROS Server的代码,后面就不写在代码里了。

    Software License Agreement (BSD License)
    Copyright (c) 2012, Edward Venator, Case Western Reserve University
    Copyright (c) 2012, Jeremy Zoss, Southwest Research Institute

    下面开始真正的程序内容。

    ROS_common.sys

    MODULE ROS_common(SYSMODULE)
    RECORD ROS_joint_trajectory_pt
        robjoint joint_pos;
        num duration;
    ENDRECORD
    CONST num MAX_TRAJ_LENGTH := 100;
    PERS bool ROS_trajectory_lock := false;
    PERS ROS_joint_trajectory_pt ROS_trajectory{MAX_TRAJ_LENGTH};
    PERS num ROS_trajectory_size := 0;
    PERS bool ROS_new_trajectory := false;
    ENDMODULE

    此程序文件作为控制器中的一个系统模块对以下各大程序共用的变量和结构体进行了定义,下面一行一行分析每一行代码的意思。
    第一行代码与最后一行代码合起来看:

    MODULE ROS_common(SYSMODULE)
    ······
    ENDMODULE

    这两行代码在RAPID中的意思是,在控制器中定义一个名为ROS_common的系统模块。MODULE和ENDMODULE是其中的关键字。(SYSMODULE)是程序属性声明。ROS_common就是定义的模块名字了。

    RECORD ROS_joint_trajectory_pt
        robjoint joint_pos;
        num duration;
    ENDRECORD

    定义一个关节空间内机器运行路径的结构体,RECORD 和ENDRECORD为定义结构体的关键字,ROS_joint_trajectory_pt为定义的结构体的名称,其中robjoint为定义机器目标点的关键字,robjoint类数据用于储存机械臂轴1到6的轴位置,以度计。将轴位置定义为各轴(臂)从轴校准位置沿正方向或负方向旋转的度数。其结构为:

    RECORD robjoint
        num rax_1; 
        num rax_2; 
        num rax_3; 
        num rax_4; 
        num rax_5; 
        num rax_6; 
    ENDRECORD

    也就是说robjoint是用于六轴机器人进行关节位置定义的数据结构,但对于像Yumi这类七轴的机器人,则要用另一种数据结构进行定义,等我们对Yumi进行控制的时候会说明如何对程序进行修改,现在的任务是弄懂每类程序的意思。

    num duration;

    这一行代码用来进行关节空间的周期控制,通过对周期进行控制进而控制关节空间点到点的关节速度。

    CONST num MAX_TRAJ_LENGTH := 100;

    此行代码是定义关节点序列最大序列点的个数为100,是一个常量,也就是说控制器最多从ROS端接收100个关节位置序列。CONST代表常量,num代表数值类型,MAX_TRAJ_LENGTH := 100是将名为MAX_TRAJ_LENGTH 的数值类型变量赋值为100,而 :=为RAPID里的赋值运算符。

    PERS bool ROS_trajectory_lock := false;

    此行代码对是对关节轨迹数据定义一个读写信号量,读的时候可以不调用信号量,但是在写的时候要对路径数据进行锁定,隔断其它的读操作。其中PERS是定义永久变量的关键字,可以类似的理解为C++中的全局变量。bool是逻辑变量的关键字,在RAPID中其与C++中定义逻辑变量的关键字是一样的。

    PERS ROS_joint_trajectory_pt ROS_trajectory{MAX_TRAJ_LENGTH};

    此行代码定义全局的机器人运行路径数据,是一个结构体数组,基础元素为ROS_joint_trajectory_pt,其中包括关节轴的度数数据与对应的关节空间点到点的周期,数组长度为100。

    PERS num ROS_trajectory_size := 0;

    此行代码定义机器人路径数据中实际关节空间点的个数。初始值为0。

    PERS bool ROS_new_trajectory := false;

    此行代码定义机器人控制器是否有新的路径轨迹。
    总体上来讲ROS_common.sys程序文件中定义了机器人运动的路径信息及对路径信息进行读写等控制的相关对应数据。

    ROS_messages.sys

    整个ROS_messages.sys的代码如下所示:

    MODULE ROS_messages(SYSMODULE)
    
    RECORD ROS_msg_header
        num msg_type;
        num comm_type;
        num reply_code;
    ENDRECORD
    
    RECORD ROS_msg
        ROS_msg_header header;
        rawbytes data;
    ENDRECORD
    
    RECORD ROS_msg_joint_traj_pt
        ROS_msg_header header;
        num sequence_id;
        robjoint joints;  ! in DEGREES
        num velocity;
        num duration;
    ENDRECORD
    
    RECORD ROS_msg_joint_data
        ROS_msg_header header;
        num sequence_id;
        robjoint joints;  ! in DEGREES
    ENDRECORD
    
    ! Message Type Codes (from simple_message/simple_message.h)
    CONST num ROS_MSG_TYPE_INVALID       := 0;
    CONST num ROS_MSG_TYPE_JOINT         := 10;  ! joint-position feedback
    CONST num ROS_MSG_TYPE_JOINT_TRAJ_PT := 11;  ! joint-trajectory-point (for path downloading)
    CONST num ROS_COM_TYPE_TOPIC         := 1;
    CONST num ROS_COM_TYPE_SRV_REQ       := 2;
    CONST num ROS_COM_TYPE_SRV_REPLY     := 3;
    CONST num ROS_REPLY_TYPE_INVALID     := 0;
    CONST num ROS_REPLY_TYPE_SUCCESS     := 1;
    CONST num ROS_REPLY_TYPE_FAILURE     := 2;
    
    ! "Special" Sequence Codes (from simple_message/joint_traj_pt.h)
    CONST num ROS_TRAJECTORY_START_DOWNLOAD := -1;
    CONST num ROS_TRAJECTORY_END := -3;
    CONST num ROS_TRAJECTORY_STOP := -4;
    
    ! Other message constants
    CONST num ROS_MSG_MAX_JOINTS := 10;  ! from joint_data.h
    
    PROC ROS_receive_msg_joint_traj_pt(VAR socketdev client_socket, VAR ROS_msg_joint_traj_pt message, \num wait_time)
        VAR ROS_msg raw_message;
    
        ! Read raw message data
        IF Present(wait_time) THEN
            ROS_receive_msg client_socket, raw_message, \wait_time:=wait_time;
        ELSE
            ROS_receive_msg client_socket, raw_message;
        ENDIF
    
        ! Integrity Check: Message Type
        IF (raw_message.header.msg_type <> ROS_MSG_TYPE_JOINT_TRAJ_PT) THEN
            ErrWrite \W, "ROS Socket Type Mismatch", "Unexpected message type",
                    \RL2:="expected: " + ValToStr(ROS_MSG_TYPE_JOINT_TRAJ_PT),
                    \RL3:="received: " + ValToStr(raw_message.header.msg_type);
            RAISE ERR_ARGVALERR;  ! TBD: define specific error code
        ENDIF
    
        ! Integrity Check: Data Size
        IF (RawBytesLen(raw_message.data) < 52) THEN
            ErrWrite \W, "ROS Socket Missing Data", "Insufficient data for joint_trajectory_pt",
                    \RL2:="expected: 52",
                    \RL3:="received: " + ValToStr(RawBytesLen(raw_message.data));
            RAISE ERR_OUTOFBND;  ! TBD: define specific error code
        ENDIF
    
        ! Copy Header data
        message.header := raw_message.header;
    
        ! Unpack data fields
        UnpackRawBytes raw_message.data, 1, message.sequence_id, \IntX:=DINT;
        UnpackRawBytes raw_message.data, 5, message.joints.rax_1, \Float4;
        UnpackRawBytes raw_message.data, 9, message.joints.rax_2, \Float4;
        UnpackRawBytes raw_message.data, 13, message.joints.rax_3, \Float4;
        UnpackRawBytes raw_message.data, 17, message.joints.rax_4, \Float4;
        UnpackRawBytes raw_message.data, 21, message.joints.rax_5, \Float4;
        UnpackRawBytes raw_message.data, 25, message.joints.rax_6, \Float4;
        ! Skip bytes 29-44.  UNUSED.  Reserved for Joints 7-10.  TBD: copy to extAx?
        UnpackRawBytes raw_message.data, 29+(ROS_MSG_MAX_JOINTS-6)*4, message.velocity, \Float4;
        UnpackRawBytes raw_message.data, 33+(ROS_MSG_MAX_JOINTS-6)*4, message.duration, \Float4;
    
        ! Convert data from ROS units to ABB units
        message.joints := rad2deg_robjoint(message.joints);
        ! TBD: convert velocity
    
    ERROR
        RAISE;  ! raise errors to calling code
    ENDPROC
    
    PROC ROS_send_msg_joint_data(VAR socketdev client_socket, ROS_msg_joint_data message)
        VAR ROS_msg raw_message;
        VAR robjoint ROS_joints;
        VAR num i;
    
        ! Force message header to the correct values
        raw_message.header.msg_type := ROS_MSG_TYPE_JOINT;
        raw_message.header.comm_type := ROS_COM_TYPE_TOPIC;
        raw_message.header.reply_code := ROS_REPLY_TYPE_INVALID;
    
        ! Convert data from ABB units to ROS units
        ROS_joints := deg2rad_robjoint(message.joints);
    
        ! Pack data into message
        PackRawBytes message.sequence_id, raw_message.data,  1, \IntX:=DINT;
        PackRawBytes ROS_joints.rax_1,    raw_message.data,  5, \Float4;
        PackRawBytes ROS_joints.rax_2,    raw_message.data,  9, \Float4;
        PackRawBytes ROS_joints.rax_3,    raw_message.data, 13, \Float4;
        PackRawBytes ROS_joints.rax_4,    raw_message.data, 17, \Float4;
        PackRawBytes ROS_joints.rax_5,    raw_message.data, 21, \Float4;
        PackRawBytes ROS_joints.rax_6,    raw_message.data, 25, \Float4;
        FOR i FROM 1 TO ROS_MSG_MAX_JOINTS-6 DO   
        ! Insert placeholders for joints 7-10 (message expects 10 joints)
            PackRawBytes 0,               raw_message.data, 25+i*4, \Float4;
        ENDFOR
    
        ROS_send_msg client_socket, raw_message;
    
    ERROR
        RAISE;  ! raise errors to calling code
    ENDPROC
    
    LOCAL FUNC num deg2rad(num deg)
        RETURN deg * pi / 180;
    ENDFUNC
    
    LOCAL FUNC robjoint deg2rad_robjoint(robjoint deg)
        VAR robjoint rad;
        rad.rax_1 := deg2rad(deg.rax_1);
        rad.rax_2 := deg2rad(deg.rax_2);
        rad.rax_3 := deg2rad(deg.rax_3);
        rad.rax_4 := deg2rad(deg.rax_4);
        rad.rax_5 := deg2rad(deg.rax_5);
        rad.rax_6 := deg2rad(deg.rax_6);
    
        RETURN rad;
    ENDFUNC
    
    LOCAL FUNC num rad2deg(num rad)
        RETURN rad * 180 / pi;
    ENDFUNC
    
    LOCAL FUNC robjoint rad2deg_robjoint(robjoint rad)
        VAR robjoint deg;
        deg.rax_1 := rad2deg(rad.rax_1);
        deg.rax_2 := rad2deg(rad.rax_2);
        deg.rax_3 := rad2deg(rad.rax_3);
        deg.rax_4 := rad2deg(rad.rax_4);
        deg.rax_5 := rad2deg(rad.rax_5);
        deg.rax_6 := rad2deg(rad.rax_6);
    
        RETURN deg;
    ENDFUNC
    
    ENDMODULE

    接下来分段的理解:

    RECORD ROS_msg_header
        num msg_type;
        num comm_type;
        num reply_code;
    ENDRECORD

    这部分结构体对机器人与控制器交换的信息的开头端ROS_msg_header进行定义,在其中分别定义了信息的类型msg_type,向机器人传递的命令的类型comm_type,以及向ROS进行回复的代码reply_code,所有的类型表示与代码表示都是num数值类型的。

    RECORD ROS_msg
        ROS_msg_header header;
        rawbytes data;
    ENDRECORD

    这部分结构体对机器人控制器与ROS交互的信息整体进行了定义,ROS_msg的信息整体包含信息帧的开头ROS_msg_header header和其后所接收到的对应指令的数据rawbytes datarawbytes 通过支持指令/函数,可用任意类型数据 num、byte、string来填充rawbytes数据。在rawbytes的任意变量中,系统同时储存当前有效字节的长度。

    RECORD ROS_msg_joint_traj_pt
        ROS_msg_header header;
        num sequence_id;
        robjoint joints;  ! in DEGREES
        num velocity;
        num duration;
    ENDRECORD

    定义关节空间运行机器人运行路径的数据结构,包括信息头,序列ID,关节位置,速度和周期。这个数据结构主要是机器人控制器的内部使用,用于对机器人的运动进行控制,所以需要的信息全面一些。

    RECORD ROS_msg_joint_data
        ROS_msg_header header;
        num sequence_id;
        robjoint joints;  ! in DEGREES
    ENDRECORD

    定义关节位置数据的结构体,包括信息头,序列ID和关节位置数据,比上一种数据类型少了速度与周期。这种数据格式主要用于向ROS发送机器人的状态,也就是机器人的当前关节角度,所以需要的数据类型数量相对上一种数据格式要少。

    ! Message Type Codes (from simple_message/simple_message.h)
    CONST num ROS_MSG_TYPE_INVALID       := 0;
    CONST num ROS_MSG_TYPE_JOINT         := 10;  ! joint-position feedback
    CONST num ROS_MSG_TYPE_JOINT_TRAJ_PT := 11;  ! joint-trajectory-point (for path downloading)
    CONST num ROS_COM_TYPE_TOPIC         := 1;
    CONST num ROS_COM_TYPE_SRV_REQ       := 2;
    CONST num ROS_COM_TYPE_SRV_REPLY     := 3;
    CONST num ROS_REPLY_TYPE_INVALID     := 0;
    CONST num ROS_REPLY_TYPE_SUCCESS     := 1;
    CONST num ROS_REPLY_TYPE_FAILURE     := 2;

    这一段定义信息的类型对应于ROS_msg_header中的msg_type,是非常重要的一段代码,对不同的信息类型进行数值划分,用于数据的封装与解析。无效数据都定义为0,不管是接收的还是回复的数据;关节位置反馈为10,用于向ROS反馈当前关节位置;关节轨迹序列数据用11,代表后面还要进行序列的下载与解析;与ROS话题相关的数据用1表示,与ROS服务相关的数据用2表示,对服务的回复数据用3表示;回复无效为0,成功为1,失败为2。

    CONST num ROS_TRAJECTORY_START_DOWNLOAD := -1;
    CONST num ROS_TRAJECTORY_END := -3;
    CONST num ROS_TRAJECTORY_STOP := -4;

    特殊的序列代码,轨迹开始下载到控制器为-1,轨迹结束为-3,轨迹停止为-4。

    CONST num ROS_MSG_MAX_JOINTS := 10;

    此行代码为定义最大的关节轴数为10。接下来这段函数很重要,关系到ROS的数据是否能够正确的接收到解析,长的代码直接把对每一行的理解写在代码段里了。

    PROC ROS_receive_msg_joint_traj_pt(VAR socketdev client_socket, VAR ROS_msg_joint_traj_pt message, \num wait_time)
    <!---定义关节序列接收函数,参数分别为客户端(ROS)设备的套接字,关节空间路径数据(解析的数据要写入的变量),可选参数处理时间,最终函数返回的为ROS_msg_joint_traj_pt类型信息--->
    
        VAR ROS_msg raw_message;
        <!---定义存储socket数据的变量,ROS_msg只包含头与字节数据--->
    
        IF Present(wait_time) THEN
        <!---Present()函数用来检查对就的参数变量是否存在,如果存在则执行下一行代码--->
    
            ROS_receive_msg client_socket, raw_message, \wait_time:=wait_time;
            <!---通过ROS_receive_msg ()函数将Socket数据从客户端client_socket写入到raw_message,并限定执行时间为wait_time(可选参数)--->
        ELSE
            ROS_receive_msg client_socket, raw_message;
        ENDIF
    
        IF (raw_message.header.msg_type <> ROS_MSG_TYPE_JOINT_TRAJ_PT) THEN
            ErrWrite \W, "ROS Socket Type Mismatch", "Unexpected message type",
                    \RL2:="expected: " + ValToStr(ROS_MSG_TYPE_JOINT_TRAJ_PT),
                    \RL3:="received: " + ValToStr(raw_message.header.msg_type);
            RAISE ERR_ARGVALERR;  ! TBD: define specific error code
        ENDIF
         <!---检查数据类型是否为下载轨迹数据类型,否则输出错误,并进行错误处理--->
    
        IF (RawBytesLen(raw_message.data) < 52) THEN
            ErrWrite \W, "ROS Socket Missing Data", "Insufficient data for joint_trajectory_pt",
                    \RL2:="expected: 52",
                    \RL3:="received: " + ValToStr(RawBytesLen(raw_message.data));
            RAISE ERR_OUTOFBND;  ! TBD: define specific error code
        ENDIF
        <!---检查数据大小是否为满足最小的数据大小,否则输出错误,并进行错误处理,为什么是52呢,其中包括sequence_id,还有10个轴和速度与周期,是13num的数据量,而每个num4个字节--->
    
        message.header := raw_message.header;
        <!---ROS_msg raw_message变量作为临时变量接收ROS传递过来的单个关节空间数据,并将解析后的数据赋值给ROS_msg_joint_traj_pt message,此行代码为头信息的赋值,后面分别为对应的ID,关节,速度与周期的赋值--->
    
        UnpackRawBytes raw_message.data, 1, message.sequence_id, \IntX:=DINT;
        <!---将raw_message.data的数据的1-4字节数据写入message.sequence_id,\IntX指待装入的Value具有num或dnum格式,数据类型为inttypes,DINT为有符号4字节整数--->
        UnpackRawBytes raw_message.data, 5, message.joints.rax_1, \Float4;
        UnpackRawBytes raw_message.data, 9, message.joints.rax_2, \Float4;
        UnpackRawBytes raw_message.data, 13, message.joints.rax_3, \Float4;
        UnpackRawBytes raw_message.data, 17, message.joints.rax_4, \Float4;
        UnpackRawBytes raw_message.data, 21, message.joints.rax_5, \Float4;
        UnpackRawBytes raw_message.data, 25, message.joints.rax_6, \Float4;
        <!---跳过了字节29-44,为轴7-10进行保留--->
        UnpackRawBytes raw_message.data, 29+(ROS_MSG_MAX_JOINTS-6)*4, message.velocity, \Float4;
        UnpackRawBytes raw_message.data, 33+(ROS_MSG_MAX_JOINTS-6)*4, message.duration, \Float4;
        <!---UnpackRawBytes为解析函数,UnpackRawBytes用于将rawbytes型容器的内容解包至byte、num、dnum或string型变量中--->
    
        message.joints := rad2deg_robjoint(message.joints);
        <!---将关节数据从弧度转换到角度,rad2deg_robjoint函数为自定义的转换函数--->
        ! TBD: convert velocity
    
    ERROR
        RAISE;  
        <!---错误处理--->
    ENDPROC

    以上是对socket接收到的数据进行解析的功能函数,下面分析数据发送函数。

    PROC ROS_send_msg_joint_data(VAR socketdev client_socket, ROS_msg_joint_data message)
    <!---数据发送函数,参数为socket客户端的有效套接字socketdev ,还有要发送的目标关节数据ROS_msg_joint_data --->
        VAR ROS_msg raw_message;
        <!---定义最终用于发送的数据格式--->
        VAR robjoint ROS_joints;
        <!---定义关节数据格式--->
        VAR num i;
    
        ! Force message header to the correct values
        raw_message.header.msg_type := ROS_MSG_TYPE_JOINT;
        raw_message.header.comm_type := ROS_COM_TYPE_TOPIC;
        raw_message.header.reply_code := ROS_REPLY_TYPE_INVALID;
        <!---定义要发送数据格式的头信息--->
    
        ROS_joints := deg2rad_robjoint(message.joints);
        <!---将要发送的关节数据从角度值转换到弧度值--->
    
        ! Pack data into message
        PackRawBytes message.sequence_id,raw_message.data,  1, \IntX:=DINT;
        PackRawBytes ROS_joints.rax_1,   raw_message.data,  5, \Float4;
        PackRawBytes ROS_joints.rax_2,   raw_message.data,  9, \Float4;
        PackRawBytes ROS_joints.rax_3,   raw_message.data, 13, \Float4;
        PackRawBytes ROS_joints.rax_4,   raw_message.data, 17, \Float4;
        PackRawBytes ROS_joints.rax_5,   raw_message.data, 21, \Float4;
        PackRawBytes ROS_joints.rax_6,   raw_message.data, 25, \Float4;
        <!---将要发送的关节数据写入raw_message的对应位置--->
        FOR i FROM 1 TO ROS_MSG_MAX_JOINTS-6 DO
            PackRawBytes 0,               raw_message.data, 25+i*4, \Float4;
        ENDFOR
        <!---将7-10轴的关节数据(无则用0填充)写入raw_message的对应位置--->
        ROS_send_msg client_socket, raw_message;
        <!---将填充好的数据发送到ROS客户端--->
    ERROR
        RAISE;
    ENDPROC

    以上代码段用于控制器向ROS进行关节位置的反馈上传。好了,上面两个大的函数分析完了,下面来几个简单的函数压压惊:

    LOCAL FUNC num deg2rad(num deg)
        RETURN deg * pi / 180;
    ENDFUNC

    上面定义了一个局部函数,这个说明一上PROC定义一个可调用程序(也可以理解为函数,但是无返回值),FUNC定义一个函数,有返回值。上面这个函数的作用就是将角度值向弧度值进行转换。

    LOCAL FUNC robjoint deg2rad_robjoint(robjoint deg)
        VAR robjoint rad;
        rad.rax_1 := deg2rad(deg.rax_1);
        rad.rax_2 := deg2rad(deg.rax_2);
        rad.rax_3 := deg2rad(deg.rax_3);
        rad.rax_4 := deg2rad(deg.rax_4);
        rad.rax_5 := deg2rad(deg.rax_5);
        rad.rax_6 := deg2rad(deg.rax_6);
    
        RETURN rad;
    ENDFUNC

    上面这一段代码就是将结构体robjoint 中的关节数据对应的转换为弧度值。

    LOCAL FUNC num rad2deg(num rad)
        RETURN rad * 180 / pi;
    ENDFUNC

    这段代码与上面的转换函数类似不过是进行弧度到角度的转换。

    LOCAL FUNC robjoint rad2deg_robjoint(robjoint rad)
        VAR robjoint deg;
        deg.rax_1 := rad2deg(rad.rax_1);
        deg.rax_2 := rad2deg(rad.rax_2);
        deg.rax_3 := rad2deg(rad.rax_3);
        deg.rax_4 := rad2deg(rad.rax_4);
        deg.rax_5 := rad2deg(rad.rax_5);
        deg.rax_6 := rad2deg(rad.rax_6);
    
        RETURN deg;
    ENDFUNC

    通过上面三个代码段的理解,这个应该就比较好理解了,就是将对应数据结构中的弧度值转换为角度值。
    本来想一次性把六类文件都写完,但是写到这里发现已经好长了,如果太长估计我自己以后就不会看了,所以这次先分析两个程序文件,把后面的四类程序文件分成两组放在后面的两篇博客中。

    展开全文
  • ROS industrial介绍中,给出了ROS和常用机械臂的连接方式。...ROS连接ABB机械臂调试详细教程-ROS(indigo)和ABB RobotStudio 6.03.02- 补充:https://github.com/robotics/open_abb open-abb-driver Contro...
  • Driver——ROS Server (1/3)对ABB_Driver中的ROS Server部分中的ROS_common和ROS_messages两个功能文件进行了分析与学习,现在继续分析接下来的内容,最终的目的就是彻底搞清楚ROS Server里到底是如何实现ROS与...
  • ROS(indigo)ABB机器人MoveIt例子

    千次阅读 热门讨论 2016-08-31 09:32:53
    ROS(indigo)ABB机器人例子 参考网址: 1  http://wiki.ros.org/Industrial 2  http://wiki.ros.org/abb 3  https://github.com/ros-industrial/abb 4  https://github.com/ros-industrial/abb_experime
  • 目录 目录 逻辑联系 文件内容 1 ROS_common 2 ROS_messages 3 ROS_socket 4 ROS_stateServer 5 ROS_motionServer 6 ROS_motion ...经过几天的时间,对不同的ROS Server的RAPID程序已经搞懂了每个文件的功
  • 经过前面的两篇文章,已经对ABB_Driver中的ROS Server的数据类型Socket的相关功能牢记于心,总的来说之前分析的四类功能程序文件的同一目的就是确保通信通道的畅通,并能及时的接收传送消息,接下来这篇文章分析...
  • ABB实验 ABB实验中继套件。 有关更多信息,请参见页面。 内容 此存储库包含在接受足够的测试后将迁移到存储库的软件包。 这些软件包的内容如有更改,恕不另行通知。 任何可用的API都被认为是不稳定的,并且不保证...
  • 配置ROS和ABB Robot Studio,实现ROS与ABB IRC5机械臂控制器之间的以太网连接。文章主要介绍了Windows10如何设定静态IP地址,虚拟机Ubuntu如何连接到网络并设定静态IP,如何在ABB Robot Studio中配置ROS驱动包ABB ...
  • 使用ABB RobotStudio和ROS进行联合调试,请参考下文:http://blog.csdn.net/ZhangRelay/article/category/6189225Github重要参考链接如下:1 https://github.com/OrebroUniversity/yumi2 https://git
  • ROS中下载abb机械臂文件 工具:ubuntu16.04、ros kinetic 创建abb的工作空间 mkdir -p ~/abb_ws/src cd ~/abb_ws/src catkin_init_workspace //工作空间初始化, 产生一个 CMakelist 文件 cd ~/abb_ws catkin_make ...
  • 已达到通过操控ROS来控制机械臂?机械臂是ABB 六轴,带32路舵机接口板
  • 前段时间测试wsl2安装ROS引导ABB机器人,碰了钉子。今天网上搜了一下wsl的网络配置,发现用wsl要比wsl2简单很多。 WSL1 是共享宿主机的网络栈,即 WSL1 共享主机 IP,并没有自己独立的逻辑网卡,也即没有自己独享的 ...
  • 建立虚拟机Ubuntu中ROS与Windows10中ABB Robot Studio的通信连接 https://blog.csdn.net/u014697321/article/details/106434289#comments_12532558 写的挺详细,这里我用的是真实的ABB机器人,方法大同小异 以及官方...
  • abb_experimental使用说明 http://wiki.ros.org/abb_experimental InstallationAsall the packages in this repository are experimental, they will not be releasedthrough the official channels and must be ...
  • ROS(indigo)MoveIt!控制ABB RobotStudio 5.6x 6.0x中机器人运动

    千次阅读 热门讨论 2016-08-31 23:30:22
    ROS(indigo)ABB机器人MoveIt例子 这里需要配置RobotStudio,请参考ROS官网教程。下面列出要点:   window端配置结束后,在Ubuntu中启动ROS和MoveIt!就可以规划并控制RobotStudio中机器人运动,...
  • ROS-Industrial中的ABB机械手实验包实验包摘要1. 状态2. 概述3. 兼容性4. 安装5. 教程6. 联系我们/技术支持7. 报告错误 实验包摘要 维护者状态:已开发 维护者:Levi Armstrong(西南研究院)<levi....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 452
精华内容 180
关键字:

abb与ros