ABB EGM概述


EGM概述

EGM Position Guidance is designed for advanced users and provides a low level interface to the robot controller, by by-passing the path planning that can be used when highly responsive robot movements are needed. EGM Position Guidance can be used to read positions from and write positions to the motion system at a high rate. This can be done every 4 ms with a control lag of 10–20 ms depending on the robot type. The references can either be specified using joint values or a pose. The pose can be defined in any work object that is not moved during the EGM Position Guidance movement. All necessary filtering, supervision of references, and state handling is handled by EGM Position Guidance. Examples of state handling are program start/stop, emergency stop, etc.
The main advantage of EGM Position Guidance is the high rate and low delay/latency compared to other means of external motion control. The time between writing a new position until that given position starts to affect the actual robot position, is usually around 20 ms.

方法1:

The data flow for the UdpUc interface is illustrate below:

1. Motion control calls EGM.
2. EGM reads feedback data from motion control.
3. EGM sends feedback data to the sensor.

4. EGM checks the UDP queue for messages from the sensor.
5. If there is a message, EGM reads the next message and step 5 writes the position data to motion control. If no position data had been sent, motion control continues to use the latest position data previously written by EGM

The sensor sends position data to the controller (EGM). Our recommendation is to couple this to step 3. Then the sensor will be in phase with the controller.
The control loop is based on the following relation between speed and position:
speed = k * (pos_ref – pos) + speed_ref k – factor

pos_ref - reference position
pos - desired position
speed_ref - reference speed

方法2:

The data flow for the signal interface is illustrated below:

1. Motion control calls EGM.
2. EGM reads the position values from the signals.
3. EGM writes the position data to motion control.
The sensor writes position data to the signals.
If signals are used as data source, the input is limited to 6 for the robot, i.e. 6 joint values or 3
Cartesian position values (x, y, z) plus 3 Euler angle values (rx, ry, rz), and up to 6 values for
additional axes.
When using EGM joint mode with a 7-axis robot, then the first additional axis input provides
the position for the additional robot axis.

ABB EGM接口使用步骤

1、系统配置

关于通信网络设置:

使用X4网卡,ip 192.168.125.1 ,该网卡ip不可设置,为了实现通信需要将与之通信的工控机设置为同一网段,如192.168.125.99

(参见帮助文档:RobotStudio->help->System Parameters->Topic Communication)

(ip查看路径与设置位置:控制器->控制面板->Configuretioon->IP Setting)

关于UdpUc devices配置

设置与之通信的工控机的ip及端口号

(设置位置:控制器->控制面板->Configuretioon->Transmission Protocol)

2、在ABB控制器上编写启动ABB EGM控制程序

参见:《Using EGM Position Guidance with an UdpUc device》

MODULE MainModule

VAR egmident egmID1;

VAR egmstate egmSt1;

! limits for cartesian convergence: +-1 mm

CONST egm_minmax egm_minmax_lin1:=[-1,1];

! limits for orientation convergence: +-2 degrees

CONST egm_minmax egm_minmax_rot1:=[-0.001,0.001];

! Start position

CONST jointtarget jpos10:=[[0,0,0,0,40,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];

! Used tool

TASK PERS tooldata tFroniusCMT:=[TRUE,[[12.3313,-0.108707,416.142], [0.903899,-0.00320735,0.427666,0.00765917]], [2.6,[-111.1,24.6,386.6],[1,0,0,0],0,0,0.072]];

! corr-frame: wobj, sens-frame: wobj

TASK PERS wobjdata wobj_EGM1:=[FALSE,TRUE,"", [[150,1320,1140],[1,0,0,0]], [[0,0,0],[1,0,0,0]]];

! Correction frame offset: none

VAR pose corr_frame_offs:=[[0,0,0],[1,0,0,0]];

PROC main()

! Move to start position. Fine point is demanded.

(运动到初始位置,必须有,否则,EGMRunJoint 不能运动机器人)

MoveAbsJ jpos10\NoEOffs, v1000, fine, tFroniusCMT;

testuc;

ENDPROC

PROC testuc()

EGMReset egmID1;

EGMGetId egmID1;

egmSt1:=EGMGetState(egmID1);

TPWrite "EGM state: "\Num:=egmSt1;

IF egmSt1 <= EGM_STATE_CONNECTED THEN

! Set up the EGM data source: UdpUc server using device "EGMsensor:"

! and configuration "default"

EGMSetupUC ROB_1, egmID1, "default", "UCdevice"\Joint;

("UCdevice"为配置UdpUc devices 使用的名字)

ENDIF

! Correction frame is the World coordinate system and the sensor

! measurements are relative to the tool frame of the used tool

! (tFroniusCMT)

EGMActJoint egmID1\J1:=egm_minmax_rot1\J2:=egm_minmax_rot1\J3:=egm_minmax_rot1\J4:=egm_minmax_rot1\J5:=egm_minmax_rot1\J6:=egm_minmax_rot1\MaxPosDeviation:=1000\MaxSpeedDeviation:=10000;

(egm_minmax***:设置收敛阈值不能过大,否则控制精度低)

(MaxSpeedDeviation:默认加速度较小,需要重新设置,否则,运动较慢,无法快速跟踪期望输入。)

! Run: the convergence condition has to be fulfilled during

! 2 seconds before RAPID execution continues to the next

! instruction

WHILE TRUE DO

EGMRunJoint egmID1, EGM_STOP_HOLD\J1\J2\J3\J4\J5\J6\CondTime:=2\RampInTime:=0.001\RampOutTime:=0.001;

(1、再使用之前需要调用运动指令,否则,该指令不能运动机器人。

2、运动的期望关节角度单位为度, 反馈的角度单位为rad。

3、该指令达到收敛精度后会退出,未达到精度会阻塞。)

ENDWHILE

!EGMRunJoint egmID1, EGM_STOP_HOLD\J1\J2\J3\J4\J5\J6\CondTime:=2\RampInTime:=0.001\RampOutTime:=0.001;

egmSt1:=EGMGetState(egmID1);

IF egmSt1 = EGM_STATE_CONNECTED THEN

TPWrite "Reset EGM instance egmID1";

EGMReset egmID1;

ENDIF

ENDPROC

ENDMODULE

3、在外部设备上(如:PC机)编写引导ABB机器人程序

参见《The EGM sensor protocol》

The EGM sensor (泛指外部引导设备) protocol is not a request/response protocol, the sensor can send data at any frequency after the sensor gets the first message from the robot. The EGM sensor protocol has two main data structures, EgmRobot and EgmSensor. EgmRobot is sent from the robot and EgmSensor is sent from the sensor. All message fields in both the data structures are defined as optional which means that a field may or may not be present in a message. Applications using Google Protocol Buffers must check if optional fields are present or not.

Google Protocol Buffers or Protobuf are used by EGM. Examples are as follows.

/////////////////////////////////////////////////////////////////////////

// Sample using Google protocol buffers C++

//

#include "stdafx.h"

#include <WinSock2.h>

#include <iostream>

#include <fstream>


#include "egm.pb.h" // generated by Google protoc.exe


#pragma comment(lib, "Ws2_32.lib") // socket lib

#pragma comment(lib, "libprotobuf.lib") // protobuf lib


static int portNumber = 6510;

static unsigned int sequenceNumber = 0;


using namespace std;

using namespace abb::egm;



// Protobuf-C++ is supported by Google and no other third party libraries needed for the protobuf part.

// It can be a bit tricky to build the Google tools in Windows but here is a guide on how to build

// protobuf for Windows (Building protobuf examples on Windows with MSVC).

//

// When you have built libprotobuf.lib and protoc.exe:

// Run Google protoc to generate access classes, protoc --cpp_out=. egm.proto

// Create a win32 console application

// Add protobuf source as include directory

// Add the generated egm.pb.cc to the project (exclude the file from precompile headers)

// Copy the file below

// Compile and run

//

//

// Copyright (c) 2014, ABB

// All rights reserved.

//

// Redistribution and use in source and binary forms, with

// or without modification, are permitted provided that

// the following conditions are met:

//

// * Redistributions of source code must retain the

// above copyright notice, this list of conditions

// and the following disclaimer.

// * Redistributions in binary form must reproduce the

// above copyright notice, this list of conditions

// and the following disclaimer in the documentation

// and/or other materials provided with the

// distribution.

// * Neither the name of ABB nor the names of its

// contributors may be used to endorse or promote

// products derived from this software without

// specific prior written permission.

//

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE

// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER

// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,

// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF

// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


//////////////////////////////////////////////////////////////////////////

// Create a simple sensor message

void CreateSensorMessage(EgmSensor* pSensorMessage)

{

EgmHeader* header = new EgmHeader();

header->set_mtype(EgmHeader_MessageType_MSGTYPE_CORRECTION);

header->set_seqno(sequenceNumber++);

header->set_tm(GetTickCount());


pSensorMessage->set_allocated_header(header);


EgmCartesian *pc = new EgmCartesian();

pc->set_x(1.1);

pc->set_y(2.2);

pc->set_z(3.3);


EgmQuaternion *pq = new EgmQuaternion();

pq->set_u0(1.0);

pq->set_u1(0.0);

pq->set_u2(0.0);

pq->set_u3(0.0);


EgmPose *pcartesian = new EgmPose();

pcartesian->set_allocated_orient(pq);

pcartesian->set_allocated_pos(pc);


EgmPlanned *planned = new EgmPlanned();

planned->set_allocated_cartesian(pcartesian);


pSensorMessage->set_allocated_planned(planned);

}


//////////////////////////////////////////////////////////////////////////

// Display inbound robot message

void DisplayRobotMessage(EgmRobot *pRobotMessage)

{

if (pRobotMessage->has_header() && pRobotMessage->header().has_seqno() && pRobotMessage->header().has_tm() && pRobotMessage->header().has_mtype())

{

printf("SeqNo=%d Tm=%u Type=%d\n", pRobotMessage->header().seqno(), pRobotMessage->header().tm(), pRobotMessage->header().mtype());

}

else

{

printf("No header\n");

}

}


int _tmain(int argc, _TCHAR* argv[])

{

SOCKET sockfd;

int n;

struct sockaddr_in serverAddr, clientAddr;

int len;

char protoMessage[1400];


/* Init winsock */

WSADATA wsaData;

if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)

{

fprintf(stderr, "Could not open Windows connection.\n");

exit(0);

}


// create socket to listen on

sockfd = ::socket(AF_INET,SOCK_DGRAM,0);


memset(&serverAddr, sizeof(serverAddr), 0);

serverAddr.sin_family = AF_INET;

serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

serverAddr.sin_port = htons(portNumber);


// listen on all interfaces

bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));


string messageBuffer;

for (int messages = 0; messages < 100; messages++)

{

// receive and display message from robot

len = sizeof(clientAddr);

n = recvfrom(sockfd, protoMessage, 1400, 0, (struct sockaddr *)&clientAddr, &len);

if (n < 0)

{

printf("Error receive message\n");

continue;

}


// deserialize inbound message

EgmRobot *pRobotMessage = new EgmRobot();

pRobotMessage->ParseFromArray(protoMessage, n);

DisplayRobotMessage(pRobotMessage);

delete pRobotMessage;


// create and send a sensor message

EgmSensor *pSensorMessage = new EgmSensor();

CreateSensorMessage(pSensorMessage);

pSensorMessage->SerializeToString(&messageBuffer);


// send a message to the robot

n = sendto(sockfd, messageBuffer.c_str(), messageBuffer.length(), 0, (struct sockaddr *)&clientAddr, sizeof(clientAddr));

if (n < 0)

{

printf("Error send message\n");

}

delete pSensorMessage;

}

return 0;

}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM