TCP/IP

Hello everybody!

I am working at a school project, which is about providing quality control in a process by using image processing ( NI LabView ) and an ABB robot.

I’ve done the image processing algorithm and I have the coordinates of the bad parts and I just have to send them to the controller robot :roll_eyes:, which I don’t know how:

so…I would be grateful if you can provide me some tips or point some documentation where I can find how to connect a PC to the robot controller using TCP/IP and some information on how to access the received information from RobotStudio.

Thanks. Have a nice day

Hi Mircea!

I’m working in something just like that, using LabView and IRC5 over an Eternet connection.

So, I need to know a little more to plenty help you.

Have you already stabilished the connection between the 2 systems using sockets?
If you haven’t, its a great stating point. First you’ll have to decide who will act as a server and ho will be the client. I used the robot as the server an dhe LV as the client. In fact, as long as I could understand, in therms of dataflow, there is no realy any difference in wich one is the server or the client. Take a look in the Socket related rapid instructions, such as SocketCreate, SocketBind, SocketConnect, SocketAccept, SocketSend and others. In LV you will also have to create sockets. I used the TCP Open Connection vi.

Once you already know thebad part position, create the robot program for it to keep the arm in a “resting” position. Use the MoveL or MoveJ with the Offs option. This Offs function allows you to move the arm according to an XYZ offset from the desired position.

Ex: MoveL Offs (Rest_Position, BadPart_X, BadPart_Y, BadPart_Z), zone, speed, wobject

This would move the arm from the rest position to the bad part position, but it will keep the tool orientation. If you need to reorient the tool, it will be a litte more difficult, but it is perfectly possible. When there are no bad parts in the process, all you’ll have to do is resetting BadPartX,Y and Z to 0 and the arm will return to the rest position.

Thus, build an state machine or any other program structure to organize your dataflow and moving sequences. Your LV software must pass to the robot the XYZ coordinate of the desired part. Maybe, the most anoying thing to do will be this dataflow structure. At least in my application it was… You will need to create a kind of protocol for the robot controller to recognize correctly wich data you are sending to him.

If you want a more sofisticated solution, you can send the whole robtarget variable to the robot controller. If you don’t really need to control the tool orientation, I think it’s worthless to try this. Except, of corse, if you want to learn some more tricks!

I hope this rough explanation could give you some light in your problem. If you need some more details, just let me know.

Best regards
Leo

Hi Leo!

First of all I would like to thank you for the explanation and for your advices.
I didn’t established the connection between LabView and RobotStudio, yet.

I will read the Socket related information that you specified and I’ll try to use them in RobotStudio, considering what you said.

I have the bad parts coordinates and the orientation, but for starting I’ll try without re-orienting the tool.

Thanks

Ok, Mircea, you’re welcome.

If you want some piece of code to guide you through your own implementation, just tell me.

Leo

As may be other people interested in this TCP/IP communication between LV and RobotStudio, i’m putting here some code I used to create in Rapid the sockets needed to handle this communication.

The first one belongs to the initializing funcion and is just related to the calling of the open connnection routines. The other ones are for effectively open, send and receive data. I tried to put all in english, but as I’m brazilian, maybe there are some text I did not realize that were left in poprtuguese. Sory in advance!

! Open TCP/IP connections
OpenTCPServerConnection;
OpenDebugServerConnection;

IF SocketGetStatus(Client_Socket) <> SOCKET_CONNECTED THEN
OpenTCPClientConnection;
ENDIF
IF SocketGetStatus(ClientDebug_Socket) <> SOCKET_CONNECTED THEN
OpenDebugClientConnection;
ENDIF
WriteDebugString “Debug connection activated.AD”;

!=========================================================================
PROC OpenTCPServerConnection()

! DescriA?A?o: Creates a server socket to the main connection

! Entradas: None

! SaA-das: None

! AlteraA?A?es: Flex screen
!*************************************************************************

! Close eventualy oppened connections
SocketClose Server_Socket;
SocketClose Client_Socket;
! Creates o socket server
SocketCreate Server_Socket;
SocketBind Server_Socket, server_ip, TCP_Port;
! Listen to and waits for the client connection (LV)
TPErase;
TPWrite “Waiting for conncetion at address: " + server_ip +”, porta: " Num := TCP_Port;
SocketListen Server_Socket;
SocketAccept Server_Socket, Client_Socket ClientAddress := client_ip;

TPWrite "Connection succeeded at address " + client_ip;

ENDPROC
!=========================================================================

!=========================================================================
PROC OpenDebugServerConnection()

! DescriA?A?o: Creates a server socket to a debug channel

! Entradas: Nenhuma

! SaA-das: Nenhuma

! AlteraA?A?es: Flex screen
!*************************************************************************

! Close eventually oppened connections
SocketClose ServerDebug_Socket;
SocketClose ClientDebug_Socket;
! Creates socket seriver
SocketCreate ServerDebug_Socket;
SocketBind ServerDebug_Socket, server_ip, Debug_Port;
! Listen and wait for the client connection
TPWrite “Waiting for conncetion at address: " + server_ip +”, porta: " Num := Debug_Port;
SocketListen ServerDebug_Socket;
SocketAccept ServerDebug_Socket, ClientDebug_Socket ClientAddress := client_ip;

TPWrite "Connection succeeded at address " + client_ip;

ENDPROC
!=========================================================================

!=========================================================================
PROC ReadTCPData()

! DescriA?A?o: Reads incoming data from the TCP connection.

! Entradas: None

! SaA-das: None

! AlteraA?A?es: None
!*************************************************************************

! Clears input buffer.
ClearRawBytes InputBuffer;
! Reads data from the oppened connection.
SocketReceive Client_SocketRawData:= InputBufferTime:=TPC_Timeout;

! Got an error?
ERROR
IF ERRNO = 0 THEN
int_data1 := 0;
ELSEIF ERRNO=ERR_SOCK_TIMEOUT THEN
SkipWarn;
ClearRawBytes InputBuffer;
!TPWrite “Receive Timeout”;
RETURN;
ELSEIF ERRNO = ERR_SOCK_CLOSED THEN
SkipWarn;
ClearRawBytes InputBuffer;
SocketClose Client_Socket;
SocketClose Server_Socket;
TPWrite “Socket closed error. Program terminated.”;
EXIT;
ENDIF

ENDPROC
!=========================================================================

!=========================================================================
PROC SendFloat4(num DT, num Data)

! DescriA?A?o: Sends a 4 bytes float value trhough the TCP connection.

! Entradas: DT: 8 bits code that identifies DataType of the value. Ex: X coordinate, Y coordinate
Quaternion value, etc.

Data: 4 bytes float value to be sent.

! SaA-das: None

! AlteraA?A?es: None
!*************************************************************************

! Preparing data pack:
! Clear output buffer
ClearRawBytes OutputBuffer;
! Add the StatOfPacket marker (#)
PackRawBytes PackStart, OutputBuffer, PackStartOffsIntX:= USINT;
! Add DataType field
PackRawBytes DT, OutputBuffer, DataTypeOffsIntX:= USINT;
! Add Data field
PackRawBytes Data, OutputBuffer, DataOffs Float4;
! PackRawBytes Data, OutputBuffer, (RawBytesLen(OutputBuffer)+1) Float4;
! Send data pack
SocketSend Client_Socket RawData := OutputBuffer;

ENDPROC
!=========================================================================

The TCP/IP connection goups together data received in a certain period in a big bulky data frame.
That’s why I used a start of packet marker (#) preceeding the data type identifier and the sent value.
The sent packet gets like this: |#|DataType|Value|. The receiver buffer, after two sending opperations,
seems like this: #a$fA?A?#A35n’A?

Another thing that is important to be said is that IRC5 input buffer seems to suport large data.
On the other hand, you can only read 1024 bytes at once, because that’s the RawBytes size limitation.
So, you will need to handle your communicatoin cycle with special care, because if you receive more than 1024 bytes, you will have a reading index error.

I think this is good satarting point. If anything else is needed, feel free to ask me.

Best regards
Leo

There are some things that must be planned before you ecffectively starts working with sockets.
In a previous stage you must decide witch side will be the server and witch will be the client. I’m not a specialist on TCP communication, so I don’t know what mus be considered when deciding who will be server and who will be client. One thing I know is that the server must be started first, because it is necessary it to be already running when client attempts to connect.
It is also important to create a kind of protocol for communication. Here I mean a high-level protocol, not those bit checking and handshaking stuff. With the socket connection you will receve a stream of bytes, so you must organize the set bytes in order to be able to restore them ant the receiver. For fixed lenght and data you can ude a very simple one, as first 4 bytes are X and second 4 are Y. But this is a very stuck way and one may prefer a more flexible one, such as: [Marker][Lenght][DataType][Data]. This is a bit harder to code, but allows you to work on further improvements on your communication channel.

So, with those in mind, the first step in a MAIN routine is to open the socket and await for the connection. Once the connection is stabilished you are ready to transmit and receive bytes using your protocol. So, there is no other but that you need to close sockets when you are not using them any more.

Any other points, feel free to ask, preferebly by here.
Leo

In my opinion, the PC or device the robot communicates with would be the SERVER, and the robot a CLIENT - this way, if required, multiple robots can connect to the same server, and most Cognex Cameras wtih TCP/IP for expample provide a very nice SERVER implimentation. Since the robot acts more like an interpretor, and without the use of multitasking - it makes more sense for the robot(s) to be clients.

Regarding protocal of communication, with many or multiple response combinations required, I find it easier to format all communication responses from the server in strings - preferably CSV - comma seperated variables and parse that string response in RAPID - you can then deal with numerical and ascii respoonses in the same response, and based on the number of “nums” and “strings” in the parsed string determine what kind of response has been received - since most applications can either respond with location, inspection, status or fault responses from the server application.

Using CSV string responses makes the applicaiton more suitable to debug and logging responses than using raw packed bytes etc. - which can be useful in certain situations.

Thankyou for adding your comments Thomas. I think it will be helpfull for people trying to stabilish TCP/IP connection.

About using the CSV I totaly agree with you when the information exchanged has a deterministic sequence and content. But when it’s up to send non deterministc types of data and whitout a specific formating, I think rawdata packs used like messages could be more suited. As you said, it depends on the situation!

Best regards, Leo