# ABB RAPID - calculating seam length

I have an Arc welding RAPID program with many seams. One of them looks like this:

ArcLStart W007_On, vtoArc, sm01, s_12, fine, R1_tWeld\WObj:=R1_wFix;
ArcL W007_1, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcC W007_2, W007_3, Vweld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcL W007_4, vWeld, sm01, s_8, z10, R1_tWeld\WObj:=R1_wFix;
ArcL W007_5, vWeld, sm01, s_8, z5, R1_tWeld\WObj:=R1_wFix;
ArcLEnd W007_Off, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;


What I want to do is measure/calculate the seam length programatically. Calculation can take place during normal program execution or in specialised routine (doesn't matter). How can I do that in RAPID?

• Why the downvote? – Electrix Jan 29 '20 at 14:02
• I agree, this should not have been downvoted! – 50k4 Jan 29 '20 at 15:55
• I am not familiar with Rapid, but can you set a flag/variable at the start of the welding and use a parallel routine (Kuka has the subinterpreter) to save the position to a variable if the flag is set. Set a different flag (or reset the same one) at the end of the seam and save the position also in a parelllel routine. Now you have start and end cartesian coordinates and you can calculate distance from there? Ot just do this in the main program, not a parallel routine if the calls function calls in rapid listed in the question do not block the exection of the code for a longer time – 50k4 Jan 29 '20 at 15:59
• @50k4: I could do that for straight seams, but not for curves. And it gets more complicated with corner paths and multiple points. In theory it is possible, but the program will be messy and probably very slow to execute. – Electrix Jan 29 '20 at 16:06
• Can you trigger a trace of the TCP from Rapid and save the trace after the seam is completed, transfer the trace file and post process on a pc? – 50k4 Jan 29 '20 at 16:08

Can you run something like this, parallel a parallel task (623-1: Multitasking) to the welding process?

VAR iodev Pos_file;
VAR string FilePath:="TCPPos";
VAR string TCP_str;
FilePath:=FilePath+"_"+CDate()+".log";

Open FilePath, Pos_file\Append;

//Cycle until Welding process is active
TCP_str:= .. Add current TCP position
WRITE TCP_str;

Close FilePath


Then you can take the TCPPos_DATE_.log file and post process it on a PC

• Thank you for your suggestion. Unfortunately I'm not allowed to create new task for this. It also seems to be potentially very inaccurate - depending on the sampling frequency and I/O speed. – Electrix Feb 14 at 19:48

This is a good robotics question, IMHO. A 3D printer extruding molten plastic has to do this task, so the right amount of plastic is squeezed out (e.g. Marlin, Repetier). The slicer can give the total amount needed for a given object (e.g. Cura by Ultimaker). It is not a trivial thing to calculate, yet very useful to know (so you don't run out of filament before object finishes printing). But all the 3D printers I work with use GCODE as file format. I do not know RAPID, but a pre-processor must be possible to create. Effectively, just need to parse the file, adding up lengths as they occur (and quietly ignoring anything irrelevant). Is there a simulator available (that might already implement the parsing part)?

• @Electrix, I've found the ABB RAPID manual, and I am prepared to have a go at a pre-processor. Please provide a link to a complete file, for testing. – user24605 Jan 31 '20 at 22:17

Thanks everyone for useful suggestions!

I ended up using module with ArcX instruction aliases. It calculates seam length during program execution. Following is a simplified example of implementation:

MODULE ArcEx(NOSTEPIN)
CONST robtarget ArcEx_pNonePoint := [[0,0,0],[0,0,0,0],[0,0,0,0],[9E9,9E9,9E9,9E9,9E9,9E9]];
TASK VAR robtarget ArcEx_pRefPoint := ArcEx_pNonePoint; ! Variable for storing previous point
TASK VAR num ArcEx_nWeldDistance := 0; ! Calculated weld distance

PROC ArcLStartEx(robtarget ToPoint) ! Arguments ommited for readibility (same as original ArcLStart)
ArcEx_nWeldDistance := 0;
ArcEx_pRefPoint := ToPoint;

ENDPROC

PROC ArcLEx() ! Arguments ommited for readibility (same as original ArcL)
ArcEx_nWeldDistance := ArcEx_nWeldDistance + Distance(ArcEx_pRefPoint.trans, ToPoint.trans);
ArcEx_pRefPoint := ToPoint;

ArcL ToPoint, \ID?ID, Speed, Seam, Weld, \Weave?Weave, Zone, Tool, \WObj?WObj, \Corr?Corr, \Track?Track, \Time?Time, \T1?T1, \T2?T2, \T3?T3, \T4?T4, \T5?T5, \T6?T6, \T7?T7, \TLoad?TLoad;
ENDPROC

PROC ArcLEndEx() ! Arguments ommited for readibility (same as original ArcLEnd)
ArcEx_nWeldDistance := ArcEx_nWeldDistance + Distance(ArcEx_pRefPoint.trans, ToPoint.trans);
ArcEx_pRefPoint := ArcEx_pNonePoint;

TPWrite "Seam length: "\num:=ArcEx_nWeldDistance

ArcLEnd ToPoint, \ID?ID, Speed, Seam, Weld, \Weave?Weave, Zone, Tool, \WObj?WObj, \Corr?Corr, \Track?Track, \Time?Time, \T1?T1, \T2?T2, \T3?T3, \T4?T4, \T5?T5, \T6?T6, \T7?T7, \TLoad?TLoad;
ENDPROC
ENDMODULE


Example usage:

ArcLStartEx W007_On, vtoArc, sm01, s_12, fine, R1_tWeld\WObj:=R1_wFix\SeamName:="W007";
ArcLEx W007_1, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcCEx W007_2, W007_3, Vweld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcLEx W007_4, vWeld, sm01, s_8, z10, R1_tWeld\WObj:=R1_wFix;
ArcLEx W007_5, vWeld, sm01, s_8, z5, R1_tWeld\WObj:=R1_wFix;
ArcLEndEx W007_Off, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;


This obviously needs a lot of work for handling circular movements, zones etc. That's why I'm not marking this question answered yet.