Primero, la visión se fija en el centro del tornillo del eje Z del robot para recoger el material. Durante este proceso, encontramos los siguientes problemas:
1. Después de la calibración de la visión y el manipulador, se encontró que la dirección del eje Y de la visión es opuesta a la dirección del eje Y del robot.
2. Después de establecer el sistema de coordenadas del usuario, el material se giró unos 10 grados y, después de tomar fotografías y capturarlo, se descubrió que no había ningún problema con el ángulo, pero las direcciones X e Y eran incorrectas.
3. Después de establecer el sistema de coordenadas del usuario, use el centro de la cámara y el centro de la varilla del tornillo para mover el origen de (0,0) en la coordenada del usuario No. 1 del sistema de coordenadas del usuario. Se descubre que no están en la vista visual. marcan el centro, por lo que se mueven a otra ubicación de manera simétrica como un espejo.
4. Cuando la calibración del robot, la calibración de la plantilla de material y la calibración del punto de recogida del robot son correctas, se descubre que el valor de compensación del eje Y es incorrecto.
En respuesta a los problemas anteriores, analice las causas y tome las medidas correspondientes de la siguiente manera:
Motivo: Los primeros tres problemas aparecen en la visión y la calibración del manipulador. Cuando la visión se fija en el eje Z, la dirección de marcado de nueve puntos será opuesta.
Solución: Durante el proceso de calibración, simplemente ejecute el manipulador en la dirección opuesta.
Motivo: El último problema ocurre al crear plantillas de puntos de marca visualmente. Si los puntos característicos identificados son incorrectos, la posición de recolección del robot será incorrecta.
Solución: rehacer la calibración de la plantilla de marcas
-------------------------------------------------- El siguiente es el paquete La función------------------------------------------- ----- --------
9). (tipo: número) \n </argument> --- <argument name="select_plane">Seleccione el plano de enseñanza, 0 es el plano XY, 1 es el plano XZ (tipo: número)\n</argument> - -- <argument name="Base_point">Punto original. (tipo: tabla)\n</argument> --- <argument name="X_point">Punto de dirección X. (tipo: tabla) \n</argument> --- <argument name="Y_or_Z_point">Punto de dirección Y o Z. (tipo: tabla)\n</argument> --- <argument name="ActiveTilt">Habilitar inclinación, habilitado cuando es 1, no habilitado cuando es 0 o nulo, se puede omitir (tipo: número)\n</ argumento> --- <argument name="ActiveOrthogonality">Habilita la no ortogonalidad. Se habilita cuando es 1. No se habilita cuando es 0 o nulo. Se puede omitir (tipo: número)\n</ argumento> --- <argumento nombre=" XScale ">barra de escala del eje X, unidad: μm. Se puede omitir (tipo: número)\n</argument> --- <argument name="YScale">Barra de escala del eje Y o del eje Z, unidad: μm. Se puede omitir (tipo: número)\n</argument>
función Local(UF_Idx, select_plane, Base_point
,
tValid local = _LUA_NONE_ERR
TmpValid local = {}
tmpIdx local = 1
TmpUserFrameP local = {}
Pn local = {}
--Juicio de error de parámetro entrante
si tipo(UF_Idx) ~= "número" o tipo(Base_point) ~= "tabla" o tipo(X_point) ~= "tabla" o tipo(Y_or_Z_point) ~= "tabla" o tipo(select_plane) ~= "número" y luego motion.ProgramStop(string.format("Función local(): ¡El tipo de entrada del argumento es error
! "))
--print("Función local(): ¡El tipo de entrada del argumento es error!",
--return tValid
end
si UF_Idx < 1 o UF_Idx > 9 entonces
motion.ProgramStop(string.format("Función local(): ¡El valor de UF_Idx está fuera de rango!"))
--print("Función local():Valor de UF_Idx está fuera de rango!", "\n")
--tValid = _LUA_IP_OUT_RANGE_ERR
--return tValid
end
si tipo(ActiveTilt) ~= "nil" entonces
si tipo(ActiveTilt) ~= "número" entonces
motion.ProgramStop( string.format("Función Local(): ¡El tipo de ActiveTilt es un error!"))
--print("Función Local(): ¡El tipo de ActiveTilt es un error!","\n")
--tValid = _LUA_IP_OUT_RANGE_ERR
--return tValid
más
si ActiveTilt < 0 o ActiveTilt > 1 entonces
motion.ProgramStop(string.format("Función Local():¡El valor de ActiveTilt está fuera de rango!"))
--print("Función Local():El valor de ActiveTilt está fuera de rango!" ¡rango!", "\n")
--tValid = _LUA_IP_OUT_RANGE_ERR
--return tValid
end
end
end
si tipo(ActiveOrthogonality) ~= "nil" entonces
si tipo(ActiveOrthogonality) ~= "número" luego
motion.ProgramStop(string.format ("Función Local(): ¡El tipo de ActiveOrthogonality es un error!"))
--print("Función Local(): ¡El tipo de ActiveOrthogonality es un error!","\norte")
--tValid = _LUA_IP_OUT_RANGE_ERR
--return tValid si
no
ActiveOrthogonality < 0 o ActiveOrthogonality > 1 entonces
motion.ProgramStop(string.format("Función local(): ¡El valor de ActiveOrthogonality está fuera de rango!"))
--print("Función Local(): ¡El valor de ActiveOrthogonality está fuera de rango!", "\n")
--tValid = _LUA_IP_OUT_RANGE_ERR
--return tValid
end
end
end
--索引值
local function_code_write_teach_buffer_1 = 0x00010013
local function_code_write_teach_buffer_2 = 0x01010013
local function_code_write_teach_buffer_3 = 0x02010013
--Código de función
local function_code_write_uf_volatile_teach_Point_1 = 0x00011142 + (UF_Idx*0x01000000) ----------Origen
local function_code_write_uf_volatile_teach_Point_2 = 0x00012142 + (UF_Id x *0x01000000) -------Punto de dirección X
local function_code_write_uf_volatile_teach_Point_3 = 0x00013142 + (UF_Idx*0x01000000) --Punto de dirección Y o Z
local function_code_write_uf_XY_Cal = 0x00000141 + (UF_Idx*0x01000000) ---------------- Calcular el punto de enseñanza del plano XY
local function_code_write_uf_XZ_Cal = 0x00001141 + (UF_Idx*0x01000000) ----------------Calcular el punto de enseñanza del plano XZ
local function_code_write_uf_Active_Tile_Or = 0x00012F42 + (UF_Idx * 0x01000000) ---------- Inclinado y no ortogonal
local function_code_write_uf_Active_Scale = 0x00014142 + (UF_Idx * 0x01000000) -----------X, Y escala
local function_code_save_uf_to_non_volatile_data = 0x00010D41 + (UF_Idx*0x01000000) ---Guardar sistema de usuario--
Origen de impresión
para k,v en pares(Base_point) do
Pn[k] = v
end
setmetatable(Pn, P.mt)
TmpUserFrameP = Pn
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_1)
tmpIdx = tmpIdx + 1
DELAY (0.004)
TmpValid [tmpIdx] = para.Write(0, 2, 08, TmpUserFrameP.x)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_2)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, TmpUserFrameP.y)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_3)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, TmpUserFrameP.z)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 06 , function_code_write_uf_volatile_teach_Point_1)
tmpIdx = tmpIdx + 1
DELAY(0.004)
--写入X方向点
for k,v en pares(X_point) do
Pn[k] = v
end
setmetatable(Pn, P.mt)
TmpUserFrameP = Pn
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_1)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, TmpUserFrameP.x)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_2)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, TmpUserFrameP.y)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_3)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, TmpUserFrameP .z)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 06, function_code_write_uf_volatile_teach_Point_2)
tmpIdx = tmpIdx + 1
DELAY(0.004)
--写入Y方向点
for k,v en pares(Y_or_Z_ punto ) hacer
Pn[k] = v
end
setmetatable(Pn, P.mt)
TmpUserFrameP = Pn
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_1)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, TmpUserFrameP.x)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_2)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, TmpUserFrameP.y)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 07, código_función_escritura_teach_buffer_3)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, TmpUserFrameP.z)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write( 0, 2, 06, function_code_write_uf_volatile_teach_Point_3)
tmpIdx = tmpIdx + 1
DELAY(0.004)
--倾斜与非正交
--TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_1)
--tmpIdx = tmp identificación + 1
--DELAY(0.004)
tmpActiveTile local = 0
tmpValue local = 0
si ActiveTilt == 1 entonces
tmpActiveTile = 1
de lo contrario
tmpActiveTile = 0 ---------------ActiveTilt(倾斜)为nil或0
finalizar
tmpOrthogonality local = 0
si ActiveOrthogonality == 1 entonces
tmpOrthogonality = 2
else
tmpOrthogonality = 0 --ActiveOrthogonality(非正交)为nil或0
end
tmpValue = tmpActiveTile + tmpOrthogonality;
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_1)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, tmpValue)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 06, function_code_write_uf_Active_Tile_Or)
tmpIdx = tmpIdx + 1
DELAY(0.004)
--X,Y轴比例尺
if (type(XScale) ~= "nil" y escriba(YScale) ~= "nil") luego
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_1)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write( 0, 2, 08, XScale)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 07, function_code_write_teach_buffer_2)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 08, YScale)
tmpIdx = tmpIdx + 1
DELAY(0.004)
TmpValid[tmpIdx] = para.Write(0, 2, 06, function_code_write_uf_Active_Scale)
tmpIdx = tmpIdx + 1
DELAY( 0.004)
elseif (tipo(XScale) == "nil" y tipo(YScale) ~= "nil") luego
motion.ProgramStop(string.format("Función local(): ¡El valor de XScale es nulo!"))
-- print("Función local(): ¡El valor de YScale es nulo!")
--tValid = _LUA_IP_NIL
--return tValid
elseif (tipo(XScale) ~= "nil" y tipo(YScale) == "nil") luego
movimiento. ProgramStop(string.format("Función local():¡El valor de YScale es nulo!"))
--print("Función local():¡El valor de XScale es nulo!")
--tValid = _LUA_IP_NIL
--return tValid
end
--计算XY或XZ平面教导点
if select_plane == 0 entonces ------XY平面
TmpValid[tmpIdx] = para.Write(0, 2, 06, function_code_write_uf_XY_Cal)
tmpIdx = tmpIdx + 1
DELAY(0.004)
--TmpValid[tmpIdx] = para.Write(0, 2, 06, function_code_save_uf_to_non_volatile_data)
--DELAY( 0.004)
elseif select_plane == 1 entonces --XZ平面
TmpValid[tmpIdx] = para.Write(0, 2, 06, function_code_write_uf_XZ_Cal)
tmpIdx = tmpIdx + 1
DELAY(0.004)
--TmpValid[tmpIdx] = para.Write(0, 2, 06, function_code_save_uf_to_non_volatile_data)
--DELAY(0.004)
else
motion.ProgramStop(string.format("Función local(): ¡Seleccione un error de plano!"))
-- print("Función Local():¡Seleccione un error de plano!")
--tValid = _LUA_IP_NIL
--return tValid
end
--for i = 1, tmpIdx do
--if (TmpValid[i] > 0x00) luego
--print( "Función Local(): ¡Los parámetros escritos fallan!")
--tValid = _LUA_PARA_W_ERR
--return tValid
--end
--end
return tValid
end
función UF_Model ( UF_Idx
, P_2_x = 100000 * math.cos(math.rad(C)) --X punto de dirección P_2_y = 100000 * math.sin(math.rad(C)) P_2 = CopyPoint(P_1) P_2.x = X + P_2_x P_2.y = Y + P_2_y P_3_x = 100000 * math.cos(math.rad(C + 90)) --Punto de dirección Y P_3_y = 100000 * math.sin(math.rad(C + 90)) P_3 = CopyPoint(P_1) P_3 .x = X + P_3_x P_3.y = Y + P_3_y --print(P_2_x, ",", P_2_y, ",", P_3_x, ",", P_3_y, "\n")
Local(UF_Idx, 0, P_1, P_2, P_3) --Generar
fin del sistema de coordenadas del usuario
------------------------------- --- ----------El siguiente es el proceso de acción------------------------------- --- ----------------------------------
-
FreePort.ECM_Close(1) --Abrir Ethernet como cliente
repita
FreePort.ECM_OpenAsClient (1,"192.168.1.10",60000,nil,CR_LF)
local aa = FreePort.ECM_ChkConnect(1)
DELAY(0.1)
hasta aa == 0
print('Conexión de cámara exitosa',"\n")
FreePort.ECM_Clear( 1)
FreePort.ECM_Tx(1,"M1".."\r")
repita
tcmd,CCDdata=FreePort.ECM_Rx(1)
hasta tcmd==0
data=string.split(CCDdata,",")
imprimir(datos[ 1],"\norte")
imprimir(datos[2],"\n")
imprimir(datos[3],"\n")
---------------------------------------Hay dos métodos para establecer un sistema de coordenadas de usuario dinámico --- ----------------------------------
-----------El primer tipo: use su propia función encapsulada para implementar
UF_Model(1,data[1]*1000,data[2]*1000,data[3]*1) --Establece un sistema de coordenadas de usuario
--Calcule la desviación XY entre la plantilla de marca visual y el punto de selección del robot (también use un método, después de generar el sistema de coordenadas del usuario, ejecute directamente el punto de enseñanza del sistema de coordenadas del usuario) X_pianyi = 376761 - 501153 Y_pianyi = -320074
+
249979
Quliao = P.nuevo(X_pianyi,Y_pianyi,-201618,0,0,-92729,1,0,0,0,1,0,1)
MovL(Quliao .. PZ(-50000))
MovL(Quliao)
------------Segundo: utilice los comandos de función proporcionados por Delta
UF.Clear(2) --Borra primero el sistema de coordenadas del usuario anterior
UF.Update.dXYZABC(2,0,data[1]*1000,data[2]*1000,0,0,0,data[3]* 1000) --Establecer el sistema de coordenadas del usuario
UF.Retain.dXYZABC(2) --Escribir el sistema de coordenadas del usuario
ModbusWrite16(0x1B00,1) ---Se completa la fotografía
--Después de generar el sistema de coordenadas del usuario, utilice el sistema de coordenadas del usuario para enseñar el punto 3 No. punto
MovL(Quliao .. PZ(-50000))
MovL(3)