Visual representation of the direct kinematics problem for an ABB IRB 140 industrial robot using CoppeliaSim and Lazarus

When modeling robotic systems in the software package CoppeliaSim the user is faced with the need to create a custom user interface (custom user interfaces). CoppeliaSim offers the creation of a custom user interface using a standard tool – a built-in plugin Qt.

Unfortunately the plugin Qt limited in possibilities. However, it should be noted that this shortcoming stems from its main advantage – the simplicity of developing a user interface.

In this article, we will consider the process of creating a user interface in Lazarus (free analogue Delphi). As an example, let’s take a model of an industrial robot ABB IRB 140.

Let’s run CoppeliaSim and add a robot model ABB IRB 140 to the stage. To do this, in the model browser in the tree robots must choose no-mobile and drag industrial robot ABB IRB 140 to the stage. Industrial robot model ABB IRB 140 shown in Figure 1.

Figure 1 – Model of industrial robot ABB IRB 140
Figure 1 – Model of industrial robot ABB IRB 140

Next, you need to remove unnecessary objects from the scene hierarchy, as shown in Figure 2.

Figure 2 - Scene hierarchy after removing unnecessary objects
Figure 2 – Scene hierarchy after removing unnecessary objects

For all hinges (IRB140_joint1…IRB140_joint6) in the window Scene Object Properties tab joint in field mode meaning Torque/force mode needs to be changed to passive mode.

Next, let’s start developing a control script.

Communication between programs will be carried out through TCP/IP protocol on 5050 socket. The client will be an application created in Lazarus, as a server – CoppeliaSim.

The client will send information to the server in the following form:

[FK#J1=0.00,J2=0.00,J3=0.00,J4=0.00,J5=0.00,J6=0.00]

Our control script for CoppeliaSim:

local socket = require("socket")
local server = assert(socket.bind("*", 5050))
local tcp = assert(socket.tcp())

function sysCall_init() 
    simJoints={}
    for i=1,6,1 do
        simJoints[i]=sim.getObjectHandle('IRB140_joint'..i)
    end
end

function sysCall_actuation()

local client = server:accept()
     --print("request received")
     client:settimeout(10)
     local packet, err = client:receive()
     if not err then
        --print("received from client=",packet)
        
        cmd=string.sub(packet, 2,3)        
        -----------------------------------------------
        if string.find(cmd, "FK") then
        
             i= string.find(packet, "J1=")
             j= string.find(packet, ",J2=")
             j1=string.sub(packet, i+3, j-1)
             j1=string.gsub(j1, ",", ".")
             j1=tonumber(j1)
             
             -------------------------------
             i= string.find(packet, "J2=")
             j= string.find(packet, ",J3=")
             j2=string.sub(packet, i+3, j-1)
             j2=string.gsub(j2, ",", ".")
             j2=tonumber(j2) 
             -------------------------------
             i= string.find(packet, "J3=")
             j= string.find(packet, ",J4=")
             j3=string.sub(packet, i+3, j-1)
             j3=string.gsub(j3, ",", ".")
             j3=tonumber(j3)   
             -------------------------------
             i= string.find(packet, "J4=")
             j= string.find(packet, ",J5=")
             j4=string.sub(packet, i+3, j-1)
             j4=string.gsub(j4, ",", ".")
             j4=tonumber(j4)
             -------------------------------
             i= string.find(packet, "J5=")
             j= string.find(packet, ",J6=")
             j5=string.sub(packet, i+3, j-1)
             j5=string.gsub(j5, ",", ".")
             j5=tonumber(j5)   
             -------------------------------
             i= string.find(packet, "J6=")
             j= string.find(packet, "]")
             j6=string.sub(packet, i+3, j-1)
             j6=string.gsub(j6, ",", ".")
             j6=tonumber(j6)   
             -------------------------------
             --print("J1=",j1)
             --print("J2=",j2)
             --print("J3=",j3)
             --print("J4=",j4)
             --print("J5=",j5)
             --print("J6=",j6)
             -------------------------------
             sim.setJointPosition(simJoints[1],j1)
             sim.setJointPosition(simJoints[2],j2)
             sim.setJointPosition(simJoints[3],j3)
             sim.setJointPosition(simJoints[4],j4)
             sim.setJointPosition(simJoints[5],j5)
             sim.setJointPosition(simJoints[6],j6)
        end
        
client:send(packet .. "n") 
     end
     -- print("closing socket")
      client:close()

end

Via string.gsub in the received string, we replace all commas with dots. This action is necessary due to Russian-language localization Windows.

Next, let’s start creating a client.

Find out the maximum values ​​​​of the rotation angles of the axes for an industrial robot ABB IRB 140 from the documentation for it (or search on the Internet). Do not forget that we are sending the angle values ​​in radians to the server.

This article assumes some skill in working with Delphi/Lazarus and knowledge of their main components, so we will omit these points. We only emphasize that for transmission to the server, we form a sink in the following form:

[FK#J1=0.00,J2=0.00,J3=0.00,J4=0.00,J5=0.00,J6=0.00]

In chapter uses connect the library winsock.

In chapter var Let’s declare the following variables:

S:TSocket;
Addr:TSockAddr;
Data:TWSAData;
i: integer;
b: byte;
bfr: TBytes;

In the start button click handler, write the following code:

procedure TForm1.Button1Click(Sender: TObject);
begin
 WSAStartup($101, Data); //загружаем WinSock;
 Timer1.Enabled:=true;
end;

Adding a timer component to the form TTimer and in the timer event handler OnTimer write the following code:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 s:=Socket(AF_INET, SOCK_STREAM,IPPROTO_IP); //создаем сокет
 Addr.sin_family:=AF_Inet; //задаем семейство адресов
 Addr.sin_port:=HToNS(5050); //задаем номер порта
 Addr.sin_addr.S_addr:=Inet_Addr('127.0.0.1'); //задаем IP-адрес
 FillChar(Addr.Sin_Zero,SizeOf(Addr.Sin_Zero),0); //заполняем нулями поля
 Connect(S,Addr,SizeOf(TSockAddr)); //подключаемся к серверу
 st:='[FK#J1='+FloatToStr(j1)+',J2='+FloatToStr(j2)+',J3='+FloatToStr(j3)+',J4='+FloatToStr(j5)+',J5='+FloatToStr(j4)+',J6='+FloatToStr(j6)+']'; //передаваемая строка
 bfr:= SysUtils.TEncoding.ASCII.GetBytes(st + chr(13) + chr(10)); // переводим строку в массив байтов
 for i:=0 to ((Length(bfr))-1) do //отправляем данные на сервер по одному байту
  begin
  b:=bfr[i];
  Send(S,b,1,0);
  end;
 Shutdown (s, 1); //завершение соединения
 CloseSocket(S); //отключение от сервера
 sleep(1);
end;

In the click handler of the “Stop” button, write the following code:

procedure TForm1.Button2Click(Sender: TObject);
begin
 Timer1.Enabled:=false;
 Shutdown (s, 1); //завершение соединения
 CloseSocket(S); //отключение от сервера
 WSACleanup(); //выгрузка сетевой библиотеки
end;

In our case, the application has the form shown in Figure 3.

Figure 3 - Application created in Lazarus
Figure 3 – Application created in Lazarus

The source file of the project is located on the GitHub service at the following link.

Run an Industrial Robot Simulation ABB IRB 140 v CoppeliaSim, click on the “Start” button in the window of our application created Lazarus and we are happy with the result – now the industrial robot model can be controlled.

Thus, the use of an external integrated development environment can significantly improve the modeling process in CoppeliaSim.

Literature

1. Visual representation of the direct task of the kinematics of the ABB IRB 140 industrial robot using CoppeliaSim and Qt. – Text: electronic // Habr: [сайт]. — URL: https://habr.com/ru/post/598987/ (date of access: 01/29/2022).

2. LuaSocket API documentation. – Text : electronic // Defold : [сайт]. — URL: https://defold.com/ref/beta/socket/ (date of access: 01/29/2022).

3. Using sockets in Delphi. Part one: standard sockets. – Text : electronic // Kingdom of Delphi : [сайт]. — URL: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1021 (Accessed 01/29/2022).

4. Flenov, M. E. Delphi in jest and in earnest: what hackers can do (+CD) / M. E. Flenov. – St. Petersburg: Piter, 2006. – 271 p.

5. Lua 5.3 Manual. – Text : electronic // Lua : [сайт]. — URL: https://lua.org.ru/contents_ru.html (date of access: 01/29/2022).

6. String Library Tutorial. – Text : electronic // lua-users wiki : [сайт]. – URL: http://lua-users.org/wiki/StringLibraryTutorial (Accessed: 01/29/2022).

7. System.SysUtils.TEncoding.GetBytes.
– Text : electronic // RAD Studio API Documentation : [сайт]. – url:
https://docwiki.embarcadero.com/Libraries/Sydney/en/System.SysUtils.TEncoding.GetBytes
(date of access: 01/29/2022).

Similar Posts

Leave a Reply