1、前记:这篇来自一西班牙某大学的一篇论文。因为涉及有Sokect和收发数据的格式例子,所以花时间整理了下,但是水平有限,原本打算复现论文做的东西,也没有完成!!!花费了两天记了些关键的,希望后续可以复现吧!!!
另:论文名字“Desarrollo de una interfaz para el control del robot IRB120 desde Matlab”,想知道论文详细可以搜索一下,找不到的可在我的资源下。载https://download.csdn.net/download/weixin_39090239/10777107。
2、该项目的目标是与机器人手臂IRB120进行通信,通过Matlab的数学软件工具。为此,我们将开发一个通信套接字,负责发送和处理数据。 验证通信是否正常以及发送是否正常数据正确完成后,它们将在Matlab中实现一系列接口与机器人的通信和最终的应用程序,如下结构。
第一个是通过GUIDE工具制作的图形界面。
第二个接口的设计将通过在Matlab中创建类来实现稍后我们将用它来开发最终的应用程序。
第三个界面在沟通方面,我们将使用Simulink工具。
其实在实践的时候已经可以完成GUI以及Class类的方式与RS通信,收发数据,只是没有按照论文中的数据格式(规定)来完成,还是以 MATLAB与Robotstudio建立socket通信(初探)中的方式完成数据传送。所以在控制机器人上还是存在需解决的问题,即RS中收到的数据做何处理,如何实现RS中机器人的单轴动MoveAbsj方式和线性运动,据了解线性运动---即笛卡尔运动会比单轴运动容易???如果定义一个目标点,以此点做offset可能要好些,这样在机器人的可达空间中设置满足在可达空间运动数据范围就可以了、、、、、或者一系列的欧拉角、四元数、刚体变换矩阵(齐次变换)操作。查Robotstudio中指令:EulerZYX,OrientZYX等。
使用工具MATLAB+Robotstudio。
Robotstudio端:必要工具---PC-interface
MODULE TCPIPConnectionHandler
VAR socketdev socketServer;
VAR socketdev socketClient;
VAR bool connectionStatus := FALSE;
LOCAL VAR string ipAddress := "127.0.0.1";
LOCAL VAR num portNumber := 1024;
LOCAL VAR string receivedString;
PROC EstablishConnection()
SocketCreate socketServer;
SocketBind socketServer, ipAddress, portNumber;
SocketListen socketServer;
SocketAccept socketServer,socketClient,\ClientAddress:=ipAddress,\Time:=WAIT_MAX;
connectionStatus := TRUE;
ENDPROC
PROC DataProcessing()
SocketSend client_socket \Str := "Connection successfully established!";
WHILE connectionStatus DO
SocketReceive client_socket \Str := receivedString;
processData receivedString;
ENDWHILE
ERROR
IF ERRNO=ERR_SOCK_CLOSED THEN
RETURN;
ENDIF
ENDPROC
RS中的程序结构:论文中只能查看到打开通信的程序---TCPIPConnectionHandler,其他的程序没有附上。
MATLAB端发数据的格式以及RS中接受的数据格式一致,如下划分。以自己的理解记录的,具体可在论文中看到!
发送关节数据包的结构图:
ID:标识符--默认为1;S:关节符号------0或1为正或负;J:关节标号---绝对值,0-255,单位‘度’。
TCP信息数据包结构:TCP参考的系统方向,由欧拉角获得。
ID:默认为2; S:同上; RX/Y/Z:欧拉旋转绝对值0-255.
TCP定位数据包结构:该数据包含TCP定位过程的数据。它允许执行线性类型或关节类型的运动。
ID:默认为3;S:同上; X/Y/Z---XR/YR/ZR:位置的绝对值,0-255---0-99;M:运动类型--0为关节,1为线性。
TCP的姿态和位置数据包结构:2和3的结合。
ID:默认为4,其他同上。X real = 100 · X frame + XR, XR - the rest of value ( >100)
TCP速度数据包的结构,工具和限制。
ID:5; T:工具,0或1,1标记为有工具; Vt Vtr:TCP速度---0-1999mm/s,V TCP = 100·V T + V TR;
X l / Zl XlR ZlR:limit。。。
MATLAB端:必要工具---Instrument Control Toolbox
关键代码:创建--- obj = tcpip('rhost'); obj = tcpip('rhost',rport) ;obj = tcpip('localhost', 30000, 'NetworkRole', 'client');
打开与数据收发---- fopen(obj); fclose(obj);fwrite (obj,A,'precision','mode'); A = fread (obj,size,'precision');
4、图形界面(GUI)的开发:控件布局略,以图站位!
控制关键代码:
IP + Port:
function pushbutton1_Callback(hObject, eventdata, handles)
%Definición de variables globales utilizadas para este control.
72
global t
global IP
global Port
% Establecemos la conexión mediante el protocolo TCP/IP utilizando las funciones de
la toolbox de Matlab correspondiente.
t=tcpip(IP, Port); fopen(t);
msgbox('La Conexión se ha establecido'); % Abrimos un cuadro de diálogo al haberse
establecido de forma correcta la conexión
guidata(hObject, handles); %Salvar datos de la aplicación
滑块----关节Ji /1--6:以下为关节1,其他同。
function slider1_Callback(hObject, eventdata, handles)
%Definición de variables globales utilizadas para este control.
global J1
global sj1
% cogemos el valor del slider y nos quedamos con su valor absoluto y su signo para
asignárselo a las variables J y sj
ang =get(hObject,'Value');
signo = sign(ang);
J1 = uint8(round(abs(ang)));
if signo == -1
sj1 = 0;
else
sj1=1;
end
angulo =round(ang);
% actualizamos el valor del static text correspondiente a este Joint Value
set(handles.text2,'String',angulo);
guidata(hObject, handles); %Salvar datos de la aplicación
按钮Enviar Joint Values,发送关节值。
function pushbutton2_Callback(hObject, eventdata, handles)
%Definición de variables globales utilizadas para este control.
global J1
global J2
global J3
global J4
global J5
global J6
global t
global sj1
global sj2
global sj3
global sj4
global sj5
global sj6
% Construimos el datagrama
D1=uint8([1 sj1 J1 sj2 J2 sj3 J3 sj4 J4 sj5 J5 sj6 J6]);
%Enviamos el datagrama realizando una pausa de dos segundos, para dar tiempo al
robot a realizar la instrucción ordenada.
fwrite(t, D1);
pause(2);
guidata(hObject, handles); %Salvar datos de la aplicación
Reset Joint Values按钮:位置重置
function pushbutton3_Callback(hObject, eventdata, handles)
%Definición de variables globales utilizadas para este control.
global J1
global J2
global J3
global J4
global J5
global J6
global sj1
global sj2
global sj3
global sj4
global sj5
global sj6
global t
% Enviamos el robot a la posición de Reposo
set(handles.slider1,'Value',0) ; set(handles.text2,'String',0);
set(handles.slider2,'Value',0); set(handles.text3,'String',0);
[…]
%Y así sucesivamente con los demás valores Joint del robot.
sj1=1; J1=0; sj2=1; J2=0; sj3=1; J3=0; sj4=1; J4=0; sj5=1; J5=0; sj6=1;J6=0;
% asignamos los varales de reset y enviamos el datagrama
D1=uint8([1 sj1 J1 sj2 J2 sj3 J3 sj4 J4 sj5 J5 sj6 J6]);
fwrite(t, D1);
pause(2);
guidata(hObject, handles); % Salvar datos de la aplicación
可编辑的文本框Z,Y,X:欧拉角,位姿。。?
function edit3_Callback(hObject, eventdata, handles)
%Definición de variables globales utilizadas para este control.
global sz
global Rz
% Obtenemos de los cuadros de texto las variables de Rotación para construir el
datagrama
vble = str2double(get(hObject,'String'));
signo = sign (vble);
if signo == -1
sz=0;
else
sz=1;
end
Rz= uint8(round(abs(vble))); % Obtenemos la variable de rotación Rz.
guidata(hObject, handles); %Salvar datos de la aplicación
可编辑的文本框X,Y,Z:位置单位,mm。
function edit6_Callback(hObject, eventdata, handles)
%Definición de variables globales utilizadas para este control.
global spx
global X
global xr
%Obtenemos las variables en este caso correspondientes a la coordenada x para construir el %datagrama
x=str2double(get(hObject,'String'));
xr=rem(x,100);
X=floor(x/100);
signo = sign (x);
if signo == -1
spx=0;
else
spx=1;
y,z同
end
guidata(hObject, handles); %Salvar datos de la aplicación
发送旋转,发送位置和发送旋转和位置对于这些控件,只需要解释其中一个,因为其余的都是类似。
对应于命令“发送TCP旋转”的控制代码是:
function pushbutton4_Callback(hObject, eventdata, handles)
%Definición de variables globales utilizadas para este control.
global sz
global sx
global sy
global Rz
global Rx
global Ry
global t
D2=uint8([2 sz Rz sy Ry sx Rx]); % Construimos el datagrama
fwrite(t, D2); %Enviamos datagrama realizando una pausa de 2 segundos entre medias
pause(2);
guidata(hObject, handles); %Salvar datos de la aplicación
TCP Velocity:此控件是一个“弹出”菜单,也就是我们可以使用的下拉列表选择末端执行器的速度。
function popupmenu2_Callback(hObject, eventdata, handles)
%definimos las variables globales utilizadas en este control.
global t;
global Vt;
global Vtr;
global Vr;
global Vrr;
sxl=1; xl=0; xlr=0; szl=1; zl=0; zlr=0;
vel= get(hObject,'Value'); % Ajustamos valores de velocidad a partir del control del
popup menu
Vtr=rem(vel,100);
Vt=floor(vel/100);
Vrr=rem(vel,100);
Vr=floor(vel/100);
D5=uint8([5 1 Vt Vtr Vr Vrr sxl xl xlr szl zl zlr]);
% construimos y enviamos en datagrama.
fwrite(t,D5);
pause(2);
guidata(hObject, handles); %Salvar datos de la aplicación
测试效果:
5、在Matlab中创建类--Mathworks官网查找实例。
MATLAB语言允许您使用以下两种技术创建程序:程序性程序和面向对象的程序设计因此使用程序中的常用对象和函数创建任何应用程序。类描述了一组具有共同特征的对象。该对象是类的特定实例。包含在中的值对象的属性是使对象与其他对象不同的属性同一类。
创建类的例子:
%创建TensileData类,并在属性中放置特征,要评估的材料的必要性
classdef TensileData
properties
Material = '';
SampleNumber = 0;
Stress
Strain
Modulus = 0;
end
%我们创建一个示例并分配数据。
td = TensileData;
td.Material = 'Carbon Steel';
td.SampleNumber = 001;
td.Stress = [2e4 4e4 6e4 8e4];
td.Strain = [.12 .20 .31 .40];
td.Modulus = mean(td.Stress./td.Strain);
%添加方法。定义的功能是确保用户正确输入材料。
methods
function obj = set.Material(obj,material)
if ~(strcmpi(material,'aluminum') ||...
strcmpi(material,'stainless steel') ||...
strcmpi(material,'carbon steel'))
error('Material must be aluminum, stainless steel, or carbon steel')
end
%为了简化类的创建,创建了一个构造函数。
function td = TensileData(material,samplenum,stress,strain)
if nargin > 0 % Support calling with 0 arguments
td.Material = material;
td.SampleNumber = samplenum;
td.Stress = stress;
td.Strain = strain;
end
end % TensileData
%此构造函数将按以下方式使用:
>> td = TensileData('carbon steel',1,[2e4 4e4 6e4 8e4],[.12 .20 .31 .40]);
演示以下俩图站位---类的方式在命令行完成:这一块后续文章推出,以类Class的方式实现通信。
注意MATLAB中命令行命令,即只需要有对应的类,即可发送数据----数据格式同上规定。
6、Simulink方式:难,论文中具体模块不清楚!
为了实现这个接口,我们将使用Matlab工具,Simulink和初始化文件.m。因此,该接口由两个主要文件组成:.m文件初始化和创建的Simulink块所在的.mdl文件。首先,定义了一系列将在以后和之后使用的全局变量Simulink的文件我们找到了我们创建的用于连接的块机器人并发送我们认为方便的数据。我们还必须提到在初始化文件中,进行了打开与服务器通信。通Simulink,我们处理并发送信息。在下图中,我们观察了创建的Simulink文件的内容。它由两个元素:第一个是常量向量,我们将在其中介绍我们想要发送给机器人的关节角度的值,在第二个我们找到的值创建了irb120块。irb120块可用于任何其他Simulink框图。此接口设计为仅执行关节配置的交付机器人。
采样时间:参数Ts(Time Step)进行仿真。
演示:
(1)初始化建立通信?
(2)发送数据
修改数据,再次发送。
所以猜测通信建立是ini完成,数据发送应该是在模块中,具体应该写在MATLAB-function中。
7、应用开发
该应用的主要目的是让我们的机器人手臂根据用户的要求进行喷漆,在数字面板上创建从0到9的数字,使用两个开发的通信接口:通过接口在Matlab中创建类,通过块“Simulink的irb120”创建接口。在应用开发中,我们将在RobotStudio中进行不同的模拟对真实机器人进行测试,专门为此安装了Robotics Toolbox。我们已经知道,建模和模拟的机器人是IRB120的模型ABB。通过这个应用程序,我们可以深化建模的概念如;工业机器人的运动学和动力学,轨迹生成和控制。
建模DH参数:
用Robotics toolbox建模代码及结果:irb120Module.m
l1=0.29;
l2=0.27;
l3=0.07;
l4=0.302;
l5=0.072;
% D-H
L(1)=Link([0 l1 0 -pi/2]);
L(2)=Link([0 0 l2 0]);
L(3)=Link([0 0 l3 -pi/2]);L(4)=Link([0 l4 0 pi/2]);
L(5)=Link([0 0 0 -pi/2]);
L(6)=Link([0 l5 0 0]);
irb120=SerialLink(L,'name','IRB120');
irb120.offset=[0 -pi/2 0 0 0 pi];
>> irb120.plot([0 0 0 0 0 0])
论文在此处说明了用工具箱中的函数做逆解不能实现应用开发的要求!所以论文中使用了自己建立的逆解函数,具体查论文,目前没整明白,后续加上!
后记:论文中这样做是在MATLAB环境下完成对数字1-9的书写---逆解求解问题,然后将结果通过Socket发给RS中的机器人,在仿真环境下书写,最后在实际机器人上测试。因为用Google翻译的西班牙语,翻译结果很乱---不是正常的语句,所以好多东西靠猜测的。本篇幅略大,后续整理好续写!
参考:MATLAB与Robotstudio建立socket通信(自我学习记、实践1)中仿真模型的逆运动学和控制
MATLAB与Robotstudio建立socket通信(初探)