Create non Persistent Global Variables in a Kawasaki Program

Hi,
I am creating a program that gets the coordinates for the robot via TCP from a server. There are a lot of paths that need to be send with varying lengths. The coordinates come in structured strings with this form: #Type/(x1/y1/z1/x2/y2/z2)/speed in mm/s/accuracy/end_of_line_distance#
Depending on the path type (circle/line) x2,y2 and z2 are used. One path consists of multiple of such segments and sometimes there are up to 20 paths. Since the parsing of the string using $DECOMPOSE takes too long, I created a PC program to do the transmission of paths and the parsing while the Robot already moves (the first path is parsed, then the robot starts moving and the next path is received and parsed). First, I only had two buffers and once the first path was done I overrode it with a new path. But this also lead to delays when the second path was very short and the third one long (the robot would finish the second one before the third one was ready). So I just parse every path in one separate dimension of an array. This works fine, but it creates a lot of global variables (every speed of each path segment is stored in one array dimension, and each path in a seperate dimension like this:

Path1 Path2 Path3
v[p1,s3} v[p3,s3]
v[p1,s2] v[p2,s2]
v[p1,s1] v[p2,s1]

The same is done for the accuracy, for the distance value at the end and for the x,y and z coordinates (since there are potentially 2 coordinates, this array as 2 dimensions already)

Since all those array variables are stored as global variables (they are created in the PC program and are used in the motion program) they are not deleted. So I end up with 2000 real variables in memory. From what I have seen, it still works without a problem. But it looks messy and feels useless.
Is there a way to not have those variables as persistent or to free them up after a path has been used (I tried the DELETE/R command, but since I use the variables in the program, it does not work)?
Has anyone else done something similar before and what was the solution?

Thanks a lot in advance and have a nice day,

Arwed

I think you can use nested arrays, if not you could create multiple separate arrays with the:

  • Paths
  • Speeds
  • Accuracies
  • Etc.

Then with a for loop you can go through all the paths.

Within the loop you can set the speed / accuracy before doing the movements.

Is this what you are looking for?

Hi,

Thank you for your reply. I realize I didn’t explain my problem clearly enough. I have already implemented the approach you outlined.

Current Implementation

  • I store motion path data using arrays:
    • Separate arrays for x, y, and z coordinates.
    • Another set of arrays for velocity, acceleration, and distance (v, a, d).
  • The structure of these arrays:
    • The first dimension represents different velocity values for each path.
    • The second dimension represents different paths.

PathGeneration.pg (5.1 KB)

Program Code

.PROGRAM ReceiveData.pc() #2
; *******************************************************************
;
; Program: ReceiveData.pc
; Description: Program to receive the motion data asynchronously.
; Needs to be called in the motion program once the robot moves
; to the first waypoint. After that, the paths are received in
; this program and buffered in a separate variable to be used.
;
; Author: User
; Date: 24.02.2025
;
; *******************************************************************

.$ack = “ACK”
.ret = -1
.ret2 = -1
.timeout = 1
.max_length = 100
.$send_buf[1] = .$ack
.buf_n = 1
buffer_no = 0
.path = 0

PRINT "Socket ID PC: ", socketid
TCP_SEND .ret2, socketid, .$send_buf[1], .buf_n, .timeout ; First ACK to indicate the start
SIGNAL -TransmissionEnd
SIGNAL -MotionReceived

WHILE NOT SIG(TransmissionEnd) DO
.ret = -1
WHILE .ret < 0 DO
TCP_RECV .ret, socketid, $recv_dt[0], rcv_cnt, .timeout, 100 ; Receive data
TWAIT 0.2
END

IF $recv_dt[0] == "End" THEN ; Indicates the end of the transmission 
  SIGNAL TransmissionEnd ; Set signal for motion program 
ELSE
  .$command = $recv_dt[0] ; Start saving received data
  .ret = -1
  .chunk = 1
  PRINT "Received Command: ", .$command

  ; Parse first data chunk
  .$temp = $DECODE(.$command, "(")
  .$temp = $DECODE(.$command, "(", 1)
  $x1 = $DECODE(.$command, "/")
  .$temp = $DECODE(.$command, "/", 1)
  $y1 = $DECODE(.$command, "/")
  .$temp = $DECODE(.$command, "/", 1)
  $z1 = $DECODE(.$command, ")")

  ; Store initial values
  $move_command[0, buffer_no] = "L"
  x_coord[0, 0, buffer_no] = VAL($x1)
  y_coord[0, 0, buffer_no] = VAL($y1)
  z_coord[0, 0, buffer_no] = VAL($z1)
  stop_dist[0, buffer_no] = 0
  speed_cmd[0, buffer_no] = 20
  accuracy_cmd[0, buffer_no] = 20
  .i_1 = 1

  IF buffer_no < 1 THEN
    SIGNAL MotionReceived
  END

  WHILE .$command <> "E#" DO ; Process remaining chunks
    IF (LEN(.$command) < 155 AND .chunk < rcv_cnt) THEN
      .$command = .$command + $recv_dt[.chunk]
      .chunk = .chunk + 1
    END

    $move_command[.i_1, buffer_no] = $DECODE(.$command, "/")
    .$temp = $DECODE(.$command, "(")
    .$temp = $DECODE(.$command, "(", 1)
    $x1 = $DECODE(.$command, "/")
    .$temp = $DECODE(.$command, "/", 1)
    $y1 = $DECODE(.$command, "/")
    .$temp = $DECODE(.$command, "/", 1)
    $z1 = $DECODE(.$command, "/")

    x_coord[.i_1, 0, buffer_no] = VAL($x1)
    y_coord[.i_1, 0, buffer_no] = VAL($y1)
    z_coord[.i_1, 0, buffer_no] = VAL($z1)

    IF $move_command[.i_1, buffer_no] <> "C" THEN
      x_coord[.i_1, 1, buffer_no] = 0
      y_coord[.i_1, 1, buffer_no] = 0
      z_coord[.i_1, 1, buffer_no] = 0
      .$temp = $DECODE(.$command, ")")
      .$temp = $DECODE(.$command, "/")
      .$temp = $DECODE(.$command, "/", 1)
    END

    IF $move_command[.i_1, buffer_no] == "C" THEN
      .$temp = $DECODE(.$command, "/", 1)
      $x1 = $DECODE(.$command, "/")
      .$temp = $DECODE(.$command, "/", 1)
      $y1 = $DECODE(.$command, "/")
      .$temp = $DECODE(.$command, "/", 1)
      $z1 = $DECODE(.$command, "/")
      x_coord[.i_1, 1, buffer_no] = VAL($x1)
      y_coord[.i_1, 1, buffer_no] = VAL($y1)
      z_coord[.i_1, 1, buffer_no] = VAL($z1)
      .$temp = $DECODE(.$command, "/")
      .$temp = $DECODE(.$command, "/", 1)
    END

    .$speed_temp = $DECODE(.$command, "/")
    speed_cmd[.i_1, buffer_no] = VAL(.$speed_temp)
    .$temp = $DECODE(.$command, "/", 1)
    .$acc_cmd = $DECODE(.$command, "/")
    accuracy_cmd[.i_1, buffer_no] = VAL(.$acc_cmd)
    .$stop_cmd = $DECODE(.$command, "#")
    stop_dist[.i_1, buffer_no] = VAL(.$stop_cmd)
    .$temp = $DECODE(.$command, "#", 1)
    .i_1 = .i_1 + 1
  END

  FOR .i = .chunk TO 1
    $recv_dt[.i] = ""
  END
END

i[buffer_no] = .i_1
IF NOT SIG(TransmissionEnd) THEN
  buffer_no = buffer_no + 1
END

.path = .path + 1
$send_buf[1] = .$ack
buf_n = 1
TCP_SEND .ret2, socketid, $send_buf[1], buf_n, .timeout ; Send ACK
.ret2 = -1

END
.END

The Problem

  • These values must be accessible as global variables so the motion program can use them.
  • However, in AS, global variables persist even when the program stops.
  • As a result, I now have over 2,500 real-number variables stored in the controller.
  • If I send a path with more waypoints, even more variables are created—but they cannot be deleted since the program uses them.

What I Want to Improve

  • While the solution works, I don’t like having thousands of unused variables cluttering the system.
  • Ideally, I’d like a way for these variables to automatically clear after use to keep the system manageable.
  • I want to avoid unnecessary memory usage while ensuring the motion program still has access to the required data.

I am used to program ABB robots and there, the value of those variables would only be saved until a new array is initialized.
The Kawasaki controller already feels very slow (that’s why I had to do the parsing asynchronously to avoid waiting times). And I dont think having 2500 variables in memory helps.

I hope I could clear up misunderstandings,

Arwed

I thought you somehow made thousands of unique variables, but you were refering to the array elements that persist. Is that correct?

Did the program fully close properly? You probably have to abort and pcabort followed by kill and pckill to fully close the main and background program.

It might be worth to try if DELETE/R/D works. The /D will force delete if possible.

1 Like