Reverse-engineering AS programs

  • G'day, all. Been away from AS language programming for a loooong time, and need a sanity check on the SPEED command. I need to reverse-engineer a series of path programs (sealer-type) from a backup, and I'm finding that these programs mix SPEED xx ALWAYS and SPEED xx mm/s ALWAYS semi-randomly throughout. All the critical motions are LMOVEs.


    Now, IIRC, a SPEED xx ALWAYS command with no units simply sets the robot speed to xx% of... robot physical maximum? Any "upstream" settings of mm/s have no effect, correct? That is, any SPEED command overwrites any previous SPEED commands, without any interaction between their settings, correct?


    The bottom line here is that I need to convert some of these programs to run on a non-Kawasaki robot (identical EAOT and dispenser), but the other robot needs mm/s values for its LMOVE-equivalent commands. I'm painfully aware that, at best, I'll only be able to get a rough approximation of the speed and have to hand-tune the final output on the other robot, but I'm open to suggestions from anyone whose Kawasaki experience is stronger than mine (certainly fresher! :uglyhammer2: )

  • Very nice to see you over here..... :top:

    I'm finding that these programs mix SPEED xx ALWAYS and SPEED xx mm/s ALWAYS semi-randomly throughout.

    Unfortunately you will see this in the AS Language and from various programs from time to time as there is really no restrictions on when and where you to use different units and ALWAYS as the commands are freely accepted.

    However, some snippets from the AS Manual should clear some things up for you and a lot of users overlook the full explanation as below:



    SPEED xx ALWAYS will set that unit of speed and apply it to every following motion segment, unless specified with another SPEED xx command without ALWAYS, then that speed unit is applied to the next following motion segment and will return to the ALWAYS that preceded it once complete.


    ACCURACY, ACCEL and DECEL commands operate in exactly the same way as far as ALWAYS is concerned.

    Example code for SPEED.

    Code
    SPEED 100 ALWAYS; This will apply to the following 2 motion segments
    JMOVE #test[1]
    JMOVE #test[2]
    ;
    SPEED 100 MM/S; This applies to the next motion segment only
    LMOVE test[1]
    ;
    JMOVE #test[3]; This motion segment will run with ALWAYS Unit as previously used


    The bottom line here is that I need to convert some of these programs to run on a non-Kawasaki robot

    :AR15firing: Traitor


    I personally apply the following to sealing applications:

    LMOVES 'transformation value' using absolute speeds MM/S for product delivery.

    JMOVES 'transformation value' or 'precision point' using percentage speeds for transition moves (air moves).


    If someone has been using percentages and not absolutes for the actual sealing, I would disagree with this approach whole heartedly as there is such a speed differential when controlling the TCP speed, as opposed to the individual motor speeds (percentages) as proper flow control cannot be maintained/managed as effectively when using percentages as the overall synchronised speed is usually determined by the joint that has to travel the furthest and is not relative to the true TCP speed.


    Using proper flow control and absolute speeds for sealing (IMHO) is the only true way to go, as then the bead width/volume can be controlled very effectively and quality maintained throughout the full motion segments, including circular/arc motion segments.


    Can you provide a 'brief' example of code of what you're presented with (without compromising IP)?

  • :AR15firing: Traitor

    Hey, don't shoot the integrator! :away:

    This is customer-driven. They have three different brands of robot within 20ft of each other, all running identical EOATs and essentially the same process, just on different size/shape parts. They've hit the point where the demand for specific parts has the Kawasaki over-utilized, so they want to shift certain parts to another robot that currently has spare cycle time.

    I personally apply the following to sealing applications:

    LMOVES 'transformation value' using absolute speeds MM/S for product delivery.

    JMOVES 'transformation value' or 'precision point' using percentage speeds for transition moves (air moves).

    Oh, I agree totally. But in this case, I need to reverse-engineer the speeds that already work to something in mm/s so I can translate the programs to Fanuc TP.

    Can you provide a 'brief' example of code of what you're presented with (without compromising IP)?

    I think so, yes.

    Multiply that by many "layers" in each style, and many different styles. They appear to be using the fr0 variable as an ersatz Base/UFrame, as each style program re-writes fr0 to a value stored in an array (similar to the rec_spd array you can see in the SPEED commands).


    Looking at the code, it's fairly obvious that someone built this "skeleton" of programs, then just did a lot of copypasta and hand-tuning each one as each style was added. So they work in production okay, but present issues trying to duplicate them on a different robot.

  • SkyeFire

    Changed the title of the thread from “AS Speed command units” to “Reverse-engineering AS programs”.
  • So, this has expanded beyond just the SPEED commands. Most of the AS program is pretty clear, but I want to make sure I'm sanity-checking my assumptions.


    For comparison purposes, I threw both the Kawasaki robot (the program source) and the Fanuc that I need to translate the programs to into RoboDK:

    Both robots have rotations relative to the Cell of 0,0,0. So it looks like the "UFrame 0" equivalent in the Kawasaki has Y+ pointing "forward" (away from the cable connections), where the Fanuc has X+ pointing forward. This seems familiar from my hazy memories, but... am I just screwing this up?


    The Kawasaki programs never use the BASE command, instead making every move a "point+point", with the first "point" being used as a reference frame. And multiple "frames" are generated for each program:

    Code
    fr_t[1] 687.000000 545.000000 -436.693268 -30.387331 179.999069 149.976456

    So, those TRANS commands. As written, they area creating each frX as a point with values 0,0,something, correct? And zlayer is a 2D array with an entry for each layer's Z value for each recipe.


    The point names with a '.' in the middle threw me a bit -- I don't recall encountering that before. But it looks like '.' is a legal character in AS variable names, and doesn't have any special significance?


    This chunk of code is a bit confusing, since it uses some commands that don't show up in any of my AS manuals:

    Code
    .i = 1
      FOR .i = 1 TO 16
        POINT fr0+ztemp = STRTOPOS($ENCODE(/L,"fr",.i))
        checkz[.i] = DEXT(ztemp,3)
        IF checkz[.i]>maxzdist[recipe] THEN
          .err = 1
        END
      END

    It's pretty obviously a limit check, but I'm not clear on how the POINT fr0+ztemp works. It seems to be creating/changing ztemp without altering fr0? I'm not accustomed to seeing math operators like '+' on the left side of the '='.

    The STRTOPOS isn't documented, but looks like (with the $ENCODE) it's an "indirect addressing" way of accessing each of the frX variables in the .TRANS section of the program file. Then the DEXT extracts the Z value of ztemp to be checked against the maxdist array value for the current recipe.


    Right now, my game plan is to convert ft_t into an equivalent on the Fanuc, then translate all the pt points to Fanuc coordinates, and use UFrame offsets to substitute for the frX+pt.XX.YY the current Kawasaki program uses.

  • Yes indeed, from your program snippet, there doesn't appear to be any GUN commands, such as GUNONTIMER and GUNOFFTIMER and GUNON and GUNON.


    Just simply dispensing by way of output toggling and relying on the pump being at the correct pressure and the material viscosity and velocity out of the nozzle to be instantaneous......just like dispensing water.


    Kawasaki always uses a BASE value.

    In cases where no BASE command is used in any program, the system BASE values are used and you can view and adjust this in Aux Function 0506 - Base Coordinates.

    This as default is always null values.


    Yes, Fanuc cartesian and Kawasaki are slightly different, right hand vs left hand from memory.

    Also, JT1 positive and negative directions are opposite too (FYI).

    So, those TRANS commands. As written, they area creating each frX as a point with values 0,0,something, correct?

    Correct and personally I hate that style where programmers just use commas.

    Using commas, could result in misplacing a comma and applying a value to the incorrect element.

    My philosophy, always enter exactly what you want, that way there is no ambiguity.


    eg: both result in the same

    POINT fr1 = TRANS(,,zlayer[recipe,1])+fr0

    POINT fr1 = TRANS(0,0,zlayer[recipe,1])+fr0


    You could also use the following before to make sure all elements are set 0

    POINT fr1 = NULL

    And zlayer is a 2D array with an entry for each layer's Z value for each recipe.

    Correct, that's how it appears to be.

    The point names with a '.' in the middle threw me a bit -- I don't recall encountering that before. But it looks like '.' is a legal character in AS variable names, and doesn't have any special significance?

    Correct, in this case it is just being used as a separator.

    I alternate between '.' and '_' when using locations or real variables.


    if the '.' is used as a prefix to the variable name, then this is a 'local or temp' variable and not a global one.

    POINT fr0+ztemp = STRTOPOS($ENCODE(/L,"fr",.i))

    The programmer appears to have created string variables to match the location variable names used.

    Do a LIST/S and you should see string variables with data the same as the location names.


    So to just break this down and explain the above out from right to left:

    $ENCODE(/L,"fr",.i)


    $ENCODE is used to create string data using the parameters inside the parentheses.

    .i is the incremented value from the FOR indexing result (1-16) to include in the string data.

    "fr" is string data to include.

    /L removes all spaces.


    eg.

    So the 1st iteration of the FOR/END loop would be:

    $ENCODE(/L,"fr",1)

    This will create string data "fr1"


    STRTOPOS = String to Position function.

    This will return the value of a pose variable (transform or precision point) that is specified by the string data (not string variable name) if it exists or else an error will occur.


    eg.

    HERE test

    $monkey = "test"

    JMOVE STRTOPOS($monkey) - The robot will move to position variable named test.


    POINT fr0+ztemp = HERE (This may be easier to understand if you haven't seen before).

    Will define ztemp (XYZOAT values) with the values of where the current TCP is in relation to fr0.

    Anytime you create a location using compound instructions (a+b+c+d+e), the right most variable is the variable that is defined/redefined.


    So what you have in that command:

    POINT fr0+ztemp = STRTOPOS($ENCODE(/L,"fr",.i))

    - ztemp is being redefined on each iteration with fr1, fr2 - fr16 location values.


    So to remove the FOR/END of your code and as an example, the 1st iteration.

    Code
    POINT fr0+ztemp = STRTOPOS($ENCODE(/L,"fr",1))
    checkz[1] = DEXT(ztemp,3)
    IF checkz[1]>maxzdist[recipe] THEN
      .err = 1
    END

    As you correctly stated, checking the Z value of fr1.

    If greater than max z distance for recipe then define local .err variable value to 1.

    Attached is the later version AS Manual for you which includes the STRTOPOS.


    Hope this helps............

  • Yes, Fanuc cartesian and Kawasaki are slightly different, right hand vs left hand from memory.

    :icon_eek: Geez, I hope not. I'm doing this all offline ATM, so I don't have a robot to try it on, but at least in RoboDK the coordinate systems all seem to be right-hand rule.


    That said, I also remember when Kawasakis were left-handed. I'm pretty sure that the AD-series controllers worked that way, but from what I recall, when we jumped to the C-series, we all had to relearn Kawasaki coordinates b/c they switched to right-hand to join the rest of the industry.


    Of course, this was all ~25 years ago, and my memory isn't what it used to be... :party21:

    Also, JT1 positive and negative directions are opposite too (FYI).

    RoboDK confirms this --- at least, comparing a Kawasaki to a Fanuc.

  • That said, I also remember when Kawasakis were left-handed. I'm pretty sure that the AD-series controllers worked that way, but from what I recall, when we jumped to the C-series, we all had to relearn Kawasaki coordinates b/c they switched to right-hand to join the rest of the industry.

    It's always been left hand rule as far as I can remember from A controller through to the latest F and T Controllers (unless I am missing something).



    But funnily enough, as I'm looking through D, E and F and T Controller manuals, Kawasaki do not stipulate ANY information as to whether it's left hand or right hand rule.


    References in A and C Controller manuals do stipulate left hand rule.


    You have now given me cause to question myself.

    You may wish to explore this further before ploughing ahead.

    Something I shall have to investigate further I think.......... :hmmm:


    Kawasaki still don't include 'world' frame references or an interpolation mode on the robot, just the Tool, Fixed Tool, Base.

    You can of course create frame locations and set BASE command to set the frame as the base coordinate system and be able to use base interpolation to move the robot relative to it.


    Manipulation of the BASE T value ( -90) aligns the coordinate system to right hand from memory, but don't quote me on that.

  • ...yowza. Now you've got me worried. And it seems my memory is worse than I thought! Too much head trauma? :waffen100:


    Digging through the .AS file, all of the BASE-related values appear to be null:

    Code
    ROT_BASE          0.000     0.000     0.000     0.000     0.000     0.000          -1
     ZSWITCH ZCBS_DWLD_AS_BASE OFF  -525
     BASE              0.000     0.000     0.000     0.000     0.000     0.000
    : SYS_BASE          0.000     0.000     0.000     0.000     0.000     0.000
    : BASE_LOAD         0.000     0.000     0.000     0.000     0.000

    And there aren't any BASE commands in the executable code to change it. So I don't think anyone's tampered with it, or set the T value to -90.


    But, in RoboDK, all the frames on the Kawasaki model are right-hand. But I don't know which generation controller RDK is simulating. And I suppose it's possible RDK is wrong.


    ...guess it's time to download the trial version of K-ROSET and see what that says.

  • But, in RoboDK, all the frames on the Kawasaki model are right-hand. But I don't know which generation controller RDK is simulating. And I suppose it's possible RDK is wrong.

    This maybe the case.


    I haven't used RoboDK in a while (my trial has run out - reminds me I must renew it), but I'm sure I needed to change something in RoboDK to match the Kawasaki and I'm fairly sure it was relative to the base and possibly the kinematic model setting in RoboDK.


    I would double check this with Jeremy RoboDK or/and post in the RoboDK board and ask the question, confirm what settings should be used with Kawasaki.

    Wouldn't want to steer you down the incorrect path (pun intended).

  • Well, a quick check with K-ROSET Lite appears to agree with RDK -- if I put the the sample virtual robots into Base mode and jog it, they appear to move in right-hand coordinates. But I haven't figured out how to select specific controller models in that software yet.

  • Well if what you are seeing is correct for you, then should be ok.

    I don't think you can select specific controllers in RoboDK, you can in KROSET Lite no problem.


    I'm confused...... :hmmm:.......are we speaking about the same thing here?


    Standard Kawasaki floor mount with a NULL base as viewed from the rear of the robot and in base mode interpolation in KROSET lite and in real world:

    X+ jogs linear right

    Y+ jogs linear forward

    Z+ jogs linear upward


    Standard Fanuc floor mount with a NULL user frame as viewed from the rear of the robot and in user/jgfrm/world modes interpolation in Roboguide and real world:

    X+ jogs linear forward

    Y+ jogs linear left

    Z+ jogs linear upward


    Are you saying RoboDK is automatically correcting this so that any robots you use are operating the same?

  • Well, RDK is definitely showing the Kawasaki as having a RHR base frame. But the Base is rotated 90deg relative to the robot's physical base, compared to Fanuc. So Y+ points forward (away from the base cable connectors), X+ points right, and Z+ points up.


    But, when adding the Kawasaki to the RDK project, the robot "lands" with the Base frame aligned to the RDK Cell(?) frame. Then you have the option to move/rotate each robot in the Cell frame.


    This is a shot of both robots with rotations of 0,0,0 relative to the Cell frame. Both robots are at 0 on all axes, except the Kawasaki's J3 is at -90:

    You can see that each robot's Base frame (however RDK is defining that) are aligned, but their physical bases are 90deg from each other.


    So if I put both robots into Base Jog mode in RDK, they jog in the same directions.


    I haven't figured out how to create a cell from scratch in K-ROSET Lite, but I opened up several of the sample cells just to see how the robot moved:

    With this robot at the same joint pose, in Base mode Y+ moves the robot forward (left from this POV), and X+ moves it right (away from this POV), and Z+ up. I couldn't figure out how to change Base selection, but I tried the same test with a half-dozen different sample cells, and they all move the same way.


    Selecting World mode made the robot jog like a KUKA or Fanuc, but I think the World of each sample cell was created like the frame you can just barely see below the base of this robot -- X+ "forward", Y+ "left", Z+ up.

  • Ah, I see where I have misunderstood regarding RHR.


    Fanuc and Kawasaki do indeed have different reference coordinates.

    This is what I was referring to regarding the base adjustment.


    As far as RoboDK representation, it appears to use the null base coordinate of the selected robot in order to place the robot into the environment.

    I'm no expert in RoboDK at all, so this is something you will need clarifying with them I think.


    KROSET is very similar, origins of STL models are snapped to the world coordinate of the environment, unless you make it a 'child' to a parent object, then it snaps the origin to the origin of the parent instead.

  • As far as RoboDK representation, it appears to use the null base coordinate of the selected robot in order to place the robot into the environment.

    I'm no expert in RoboDK at all, so this is something you will need clarifying with them I think.

    That does appear to be the case. Whenever I add a robot to a cell in RDK, I get an option to change it's placement relative to the Cell main frame of reference. In that screenshot I posted, both robots have their "mounting" offsets set to 0, except that the Kawasaki is 2000mm in Y to keep the robots from overlapping.

  • That's good to know and it seems to follow with what I've seen.

    A previous test pick and place I did in RoboDK has a BASE 'T' value of 180 and I know I implemented that and not RoboDK.


    I need to get my trial renewed I think, then I can have a play around with it to be certain.

Advertising from our partners