Posts by hoitzing

    User frames are defined with respect to the world frame; so you should set the frame to an XYZWPR position with all elements 0. Either create your own zeropos variable, or use the sysvar $MOR_GRP[1].$NILPOS


    Code
    $GROUP[1].$UFRAME=zeropos_variable
    $GROUP[1].$UFRAME=$MOR_GRP[1].$NILPOS

    I'm not aware of any system variables that can be set for the port configuration, but afaik there are two options:


    1) Load a DIOCFGSV file containing the desired IO configuration, I would expect this can be done using a *.CM file


    2) Use a KAREL program with the built-in function SET_PORT_ASG that you can RUN with a KCL command


    Sidenote, when looking into the ASCII version of DIOCFGSV.VA, this is just a list of variables in 'program'/namespace/... [MDIO_MAIN]. This makes me wonder if it's possible to 'KCL SET VAR' on these variables to directly change port configurations from a *.CM file. If the other two options aren't quite what you need it might be worth checking out

    In order to update a KAREL program where the new version contains updated type definitions, I need to delete the original *.PC program and its corresponding *.VR file. Deleting the *.VR doesn't work, and the variables file remains on the controller which means I can't upload the updated version as it leads to variable mismatch errors. Any ideas?


    EDIT:

    After restarting a couple of times I've got it working in the sense that I could delete A.VR which was referenced in B.PC/B.VR. Still could not delete B.VR, but since A.VR was now deleted, I could reload A.PC and then B.PC with the updated type.


    Still interested if anyone knows what's going on since this feels like I just got lucky with restarting a couple of times

    Use the n_ports parameter to specify how many (incremental) ports should start counting from the port nr

    SET_PORT_ASG(log_port_typ, log_port_no, rack_no, slot_no, phy_port_typ, phy_port_no, n_ports, status

    So in your case you would want n_ports=3 to be assigned starting from DO 4 and port 1, corresponding to DO's 4, 5, and 6, mapped to ports 1, 2, and 3.

    One setting to keep in mind is the 'Offset accumulate' option:


    I haven't really played around very much with this setting but it seems like you can go one of two ways:

    1) Set to TRUE and keep track of what offsets you've already written; then for a new offset you only write the difference between previous and current offset.

    2) Set to FALSE and simply write the offset that you require at that moment. In this case you'll probably need to make sure the "min/max offset/ITP" settings are big enough for the largest offset you're expecting


    I've only simulated with option 1, and it works well; haven't really spent too much time on option 2 since I've tested with pretty large offsets which would give trouble with the maximum offset settings.

    I'm looking for an easy way to distinguish between robots with 6 and 7 axes (some of our cells have a linear track, some don't). I'm sure there has to be a system variable hidden somewhere that either describes the total number of axes or the number of extended axes that are configured, but I don't know where it's hidden in the system variables.

    Yes you need to offset the sensor value (distance from robot to surface) with the target distance from the surface. So your DPM offset should be the difference between the sensor value and target distance (in opposite direction to negate the difference):

    DPM_offset = -(sensor_value - target_distance) = target_distance - sensor_value

    Hmm, seems like the 75.0 value is wrong then. If you want to continue with GROUP channel input you might want to play around with the value a bit to find what works.


    As for the system variable; you're right it's too long for TP it seems.. I have been using KAREL to set the variable.


    If KAREL is not an option for you I'd suggest diving into the scaling factor. Increase the maximum offset value (temporarily only) to allow the robot to always complete the DPM movement. Then you can compare the input offset (your GI) to the realized 'output' offset (the robot's movement) and go from there.

    Keep in mind it's possible that FANUC uses the inverse of the scaling factor to rescale the input; i.e. check if the input scaling is done by multiplication or division by the scaling factor.


    --- EDIT ---

    Did some quick testing in roboguide and what I found was the following:

    axis_offset = GI * 120/scale_factor

    I think it's about the scale factor, like mentioned. Since GI's are 16-bit integers, if you use the integer value directly as DPM offset, you are stuck with an offset range of [-32768 .. 32767] with a precision of 1. With the scale factor you're able to redefine your range and precision to suit your application (and input).

    I believe the DPM control has an internal scaling factor. If I recall correctly, when you set a scale factor of 75.0 in the DPM schedule settings, GI values are directly applied as offset 1:1.


    Just to let you know, I've switched my simulations to use the 'SYSVAR' channel input type, as it gets rid of these scaling issues. So now I just directly write an offset for DPM schedule i and axis j to a system variable

    $DPM_SCH[i].$GRP[1].$OFS[j].$INI_OFS

    First off it's important to know if you're dealing with 8/16/32 bit integer values since the behaviour of grouped inputs is different for them.


    Reading GIN in a TP program via register assignment (R[n]=GI[m]) will simply give you the unsigned value. To convert to signed representation, subtract 2**p where p is the integer's precision. So for example to get a 16-bit signed integer from a 16-bit GI you need to subtract 2**16=65536: R[n]=GI[m]-65536.

    Reading GIN via KAREL can be a little funky, as the assignment int_var = GIN[n] always reads the grouped input as a 16-bit signed integer. So up to 15-bit precision it'll always be unsigned/positive, but as you exceed 32767=2**15-1, you get negative numbers.


    And to make it more compicated, if you require higher precision than 16-bit you can use multiple GI's to represent a single value (up to 32-bit precision is supported). But this is not worth getting into in this thread unless this is something your application requires.


    Secondly double-check if the negative number that the GI represents is indeed encoded in two's complement if you're getting weird results.

    That is what I get when I try to build a KAREL program in Roboguide that is also currently selected on the roboguide TP. Simply selecting another program is enough, no need to delete the program (*.pc or *.vr) that is only needed if you want to change array lengths or make named variables a different type than before.

    I believe there is no dedicated function for checking if a program exists (ie is loaded onto the robot), but you could easily test it using the GET_ATTR_PRG procedure. Just use any of the attributes (for example AT_PROG_TYPE) and check if the returned status is 0 (or at least is not 7073)

    I almost forgot that I also did it using explicit computations instead of scipy's functions...


    Check euler.pdf publication for the background behind the computations (Figure 1, page 5) in a paper by G. Slabaugh.


    Basically, if you have a rotation matrix R with elements:

    Code
    R_11, R_12, R_13
    R_21, R_22, R_23
    R_31, R_32, R_33

    You can compute the extrinsic xyz Euler angles 'wpr' as follows:


    Where

    Code
    W = ψ
    P = θ
    R = φ



    I suggest reading (or at the very least skipping through) the paper to understand better what's going on.

    I've got the conversion from a rotation matrix to WPR working in Python using the scipy module. Since I use the module's functionality I don't have the 'behind the scenes' computations that are done so you won't be able to copy it into your own Excel program; but if the python code is helpful to you let me know and I'll post what I have.

    I don't think this is possible. You can do multitasking (RUN PROGRAM instead of CALL PROGRAM, but this would require you to have a main program from which you start your 'background' tasks. So if you want manual control over a program while already running something in the background, I don't think you'll be able to do it. Maybe look if it's possible for you to start your program(s) from a very simple shell:

    Code
    RUN KL_SERVER
    CALL TP_PROGRAM


    Besides this, if you want to execute the TP program in step mode won't this also put the Karel server in step mode? Maybe if you RUN the server it won't.. but something to think about/look into.

Advertising from our partners