Good day all,
Can someone tell me how I can write some rapid / PLC code that will modify the XYZ of a robtarget from an HMI. Basically I want the weld operator to be able to adjust a weld point from the HMI.
Any help would be much appreciated.
Good day all,
Can someone tell me how I can write some rapid / PLC code that will modify the XYZ of a robtarget from an HMI. Basically I want the weld operator to be able to adjust a weld point from the HMI.
Any help would be much appreciated.
Easiest way I've found is to add Offs or Reltool to the target depending on how you'd like to apply the offset. Then use a group input for the x, y, z offsets. And, since you can't do negative numbers for group inputs, you have to include a sign bit for each value to declare positive/negative. Make sense?
Do you have a bit of rapid code examples?
Try this example:
MODULE mTemp
! created in I/O: giOffsetX, giOffsetY, giOffsetZ, diOffsetX_Neg, diOffsetY_Neg, diOffsetZ_Neg
CONST robtarget tExample:=[[100,200,300],[1,0,0,0],[0,0,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
FUNC robtarget tOffset(robtarget target)
VAR num OffsetX;
VAR num OffsetY;
VAR num OffsetZ;
OffsetX:=giOffsetX;
OffsetY:=giOffsetY;
OffsetZ:=giOffsetZ;
IF diOffsetX_Neg=1 OffsetX:=-1*OffsetX;
IF diOffsetY_Neg=1 OffsetY:=-1*OffsetY;
IF diOffsetZ_Neg=1 OffsetZ:=-1*OffsetZ;
RETURN Offs(target, OffsetX, OffsetY, OffsetZ);
ENDFUNC
PROC main()
TPErase;
TPWrite ValToStr(tExample);
TPWrite "----------------------------------------";
TPWrite ValToStr(tOffset(tExample));
ENDPROC
ENDMODULE
You can create the signals however make sense, here's the signals that I used for the example:
EIO:CFG_1.0:5:0::
#
EIO_BUS:
-Name "Virtual1" -ConnectorID "SIM1"
#
EIO_UNIT_TYPE:
-Name "Virtual" -VendorName "ABB" -ProductName "Virtual unit"
#
EIO_UNIT:
-Name "Sim1" -UnitType "LOCAL_GENERIC" -Bus "Virtual1"
#
EIO_SIGNAL:
-Name "giOffsetX" -SignalType "GI" -Unit "Sim1" -UnitMap "0-15"\
-Access "All"
-Name "giOffsetY" -SignalType "GI" -Unit "Sim1" -UnitMap "16-31"\
-Access "All"
-Name "giOffsetZ" -SignalType "GI" -Unit "Sim1" -UnitMap "32-47"\
-Access "All"
-Name "diOffsetX_Neg" -SignalType "DI" -Unit "Sim1" -UnitMap "48"\
-Access "All"
-Name "diOffsetY_Neg" -SignalType "DI" -Unit "Sim1" -UnitMap "49"\
-Access "All"
-Name "diOffsetZ_Neg" -SignalType "DI" -Unit "Sim1" -UnitMap "50"\
-Access "All"
#
EIO_ACCESS:
-Name "All" -Rapid -LocalManual -LocalAuto -RemoteManual -RemoteAuto
Thank you!
Question though, how does it know it offset tExample?
Ok. Figured out how it offsets Texample. now when i run it it doesn't actually overwrite the data. it shows what the difference is but doesn't change it.
Also do you have a good solution that will allow me to do multiple points using the same structure without the need to write this code for each point?
Handshaking and the timing of the handshakes are always fun. Basically, the robot needs to say it's ready for the offsets and waits until the PLC says they're ready --> PLC sets the offsets and says they're ready to get --> robot grabs the offsets and uses them. If the motion is slow enough, you can grab the offsets on the fly -- I've see this on a palletizing program where only the pallet positions were offset and the PLC had plenty of time to populate the offset values based on current count while going to the pick position. For faster processes, all the offsets are fed into the robot ahead of time before any motion is initiated. Example below.
MODULE mTemp
! created in I/O: giOffsetX, giOffsetY, giOffsetZ, diOffsetX_Neg, diOffsetY_Neg, diOffsetZ_Neg
! also add goReadyForOffsets, giOffsetsReady
CONST robtarget tTarget001:=[[100,200,300],[1,0,0,0],[0,0,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
CONST robtarget tTarget002:=[[100,200,300],[1,0,0,0],[0,0,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
CONST robtarget tTarget003:=[[100,200,300],[1,0,0,0],[0,0,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
PERS robtarget tTarget001_Offset:=[[101,201,301],[1,0,0,0],[0,0,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
PERS robtarget tTarget002_Offset:=[[102,202,302],[1,0,0,0],[0,0,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
PERS robtarget tTarget003_Offset:=[[103,203,303],[1,0,0,0],[0,0,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]];
FUNC robtarget tOffset(robtarget target, num offsetnumber)
VAR num OffsetX;
VAR num OffsetY;
VAR num OffsetZ;
SetGO goReadyForOffsets, offsetnumber;
WaitGI giOffsetsReady, offsetnumber;
OffsetX:=giOffsetX;
OffsetY:=giOffsetY;
OffsetZ:=giOffsetZ;
IF diOffsetX_Neg=1 OffsetX:=-1*OffsetX;
IF diOffsetY_Neg=1 OffsetY:=-1*OffsetY;
IF diOffsetZ_Neg=1 OffsetZ:=-1*OffsetZ;
SetGO goReadyForOffsets, 0;
RETURN Offs(target, OffsetX, OffsetY, OffsetZ);
ENDFUNC
PROC ApplyOffsets()
tTarget001_Offset:=tOffset(tTarget001, 1);
tTarget002_Offset:=tOffset(tTarget002, 2);
tTarget003_Offset:=tOffset(tTarget003, 3);
ENDPROC
PROC main()
ApplyOffsets;
! after offsets applied, now start motion
TPErase;
TPWrite ValToStr(tTarget001);
TPWrite "----------------------------------------";
TPWrite ValToStr(tTarget001_Offset);
Stop;
TPErase;
TPWrite ValToStr(tTarget002);
TPWrite "----------------------------------------";
TPWrite ValToStr(tTarget002_Offset);
Stop;
TPErase;
TPWrite ValToStr(tTarget003);
TPWrite "----------------------------------------";
TPWrite ValToStr(tTarget003_Offset);
Stop;
ENDPROC
ENDMODULE
EIO:CFG_1.0:5:0::
#
EIO_BUS:
-Name "Virtual1" -ConnectorID "SIM1"
#
EIO_UNIT_TYPE:
-Name "Virtual" -VendorName "ABB" -ProductName "Virtual unit"
#
EIO_UNIT:
-Name "Sim1" -UnitType "LOCAL_GENERIC" -Bus "Virtual1"
#
EIO_SIGNAL:
-Name "giOffsetX" -SignalType "GI" -Unit "Sim1" -UnitMap "0-15"\
-Access "All"
-Name "giOffsetY" -SignalType "GI" -Unit "Sim1" -UnitMap "16-31"\
-Access "All"
-Name "giOffsetZ" -SignalType "GI" -Unit "Sim1" -UnitMap "32-47"\
-Access "All"
-Name "diOffsetX_Neg" -SignalType "DI" -Unit "Sim1" -UnitMap "48"\
-Access "All"
-Name "diOffsetY_Neg" -SignalType "DI" -Unit "Sim1" -UnitMap "49"\
-Access "All"
-Name "diOffsetZ_Neg" -SignalType "DI" -Unit "Sim1" -UnitMap "50"\
-Access "All"
-Name "goReadyForOffsets" -SignalType "GO" -Unit "Sim1" -UnitMap "63-80"\
-Access "All"
-Name "giOffsetsReady" -SignalType "GI" -Unit "Sim1" -UnitMap "63-80"\
-Access "All"
#
EIO_ACCESS:
-Name "All" -Rapid -LocalManual -LocalAuto -RemoteManual -RemoteAuto
*Edited above: I moved "SetGO goReadyForOffsets, 0;" from before to after the robot used the offsets -- to not accidentally have the PLC clear the offsets prior to robot having a chance to use them.
When i use
PROC ApplyOffsets()
tTarget001_Offset:=tOffset(tTarget001, 1);
tTarget002_Offset:=tOffset(tTarget002, 2);
tTarget003_Offset:=tOffset(tTarget003, 3);
ENDPROC
I'm getting the following error. "The call to routine tOffset has to many arguments.
Any idea?
Thanks!
Check line: "FUNC robtarget tOffset(robtarget target, num offsetnumber)"
You could actually set up a group input to be used like an analog signal, giving you the ability to have a signed integer value. You would have to size it and scale it to suit your use. But then you could merely use MoveL Offset(p10, aiX, aiY, aiZ). Good luck.
Good point! I shouldn't have assumed you were using the ABB EtherNet/IP Field Bus Adapter to communicate with the PLC.
Lemster68, What kind of hardware can be used to make the analog connection between the robot and PLC?
Any communication protocol over which you could make a group input. It's just how you configure your EIO. For quite some time we have set up dispense like that. Here is an example of it:
-Name "aoEqu1F1" -SignalType "AO" -Unit "nordson" -UnitMap "32-43"\
-EncType "UNSIGNED" -MaxLog 100 -MaxPhys 10 -MaxPhysLimit 10\
-MaxBitVal 4095
-Name "aoEqu1F2" -SignalType "AO" -Unit "DP_SIMBOARD1" -UnitMap "20-31"\
-EncType "UNSIGNED" -MaxLog 100 -MaxPhys 10 -MaxPhysLimit 10\
-MaxBitVal 4095
This was over Profinet, and is unsigned. I have another somewhere when I set it up to give a signed integer value.
So if I want to set up 100 points to be offset should I go about it like this:
AnalogIO from PLC sends value (1-100)
Rapid code is one big IF statement
IF analogIO=1 THEN
Offest point 1
ELSE IF analogIO=2 THEN
Offset point
...... all the way to 100?
Is there a better way to write that?
Thanks!!
Much more simple, look at my earlier post.
Are you referring to "MoveL Offset(p10, aiX, aiY, aiZ)"?
In this example I was taking it that the PLC actually holds the robtarget data and then sends the info to to p10. I'm looking for the PLC to send the rapid an offset value. The rapid will offset the correct robtarget.
My fear (If I am correct on the above assumption) Is if the PLC ever drops out then we will actually lose the robot as well. or if a handshake fails.
Lemster68, What kind of field bus slave adapter have you used analog signals between the PLC and the robot controller in the past?
BwillieS, If you're looking to offset a group of targets with one offset, look into offsetting the work object. If you're looking for different offset values for different targets, analog or group, you'll still have to figure out handshakes/timing to use the same inputs to communicate different offsets.
BwillieS, if you're worried about the PLC dropping out mid robot motion, just populate the targets before it starts as shown in my previous handshaking example. Analogy only allows you to get out of using a sign bit / and the "IF diOffsetX_Neg=1 OffsetX:=-1*OffsetX;" lines -- still have the same handshake problem to solve...
Soupy, I used devicenet on the other setup I did. S4c+, looks like this:
-Name "aiLVDT1" -Type "AI" -Unit "PLC_IO" -Phsig 7 -LogMax 12.5\
-LogMin -12.5 -PhMax 4.96
-Name "aiLVDT2" -Type "AI" -Unit "PLC_IO" -Phsig 8 -LogMax 12.5\
-LogMin -12.5 -PhMax 4.96
EIO_UNIT_MAP = EIO_PHS_MAP:
-Phsig 1 -Type "AO" -Unit "Nordson" -StartBit 32 -NoOfBits 8\
-EncType "UNSIGNED" -HighAnalog 10 -HighDigital 4095
-Phsig 1 -Type "AI" -Unit "PLC_IO" -StartBit 65 -NoOfBits 8 -HighAnalog 10\
-HighDigital 255
-Phsig 2 -Type "AI" -Unit "PLC_IO" -StartBit 81 -NoOfBits 8 -HighAnalog 10\
-HighDigital 255
BWillies, I took it to mean that the robot has to have it's own robtargets stored, and just the amount to offset would be added to them.