RobotStudio event

ERROR Handler not catching overload error: 50055 Joint Load too high

Hello,

I have an application where the robot arm is pulling on something under tension.  If something goes wrong, the tension gets too high and it should run my error handler.

At low speed, it works fine and catches the error as 1070 ERR_COLL_STOP.

But when I increase the speed to my production level, the same code doesn't catch the error, instead it ends being handled by the system error handler which stops execution and displays an event message 50055 Joint Load too high.

My ERROR handler is not conditional, it catches everything (even div by zero and bad array index).  Can someone explain why this changes from a collision to a joint overload and tell me how to catch and handle it.

Any help is much appreciated,
Dave

Best Answers

  • lemster68
    lemster68 ✭✭✭
    Answer ✓
    The problem here is mostly that the program has stopped executing.  The error handler does not work if the program is not executing.  Maybe you can try to put that error for the main routine's error handler. Do you have multitasking?
    Lee Justice
  • lemster68
    lemster68 ✭✭✭
    Answer ✓
    It really might just not work because the program has stopped. However, since you have multitasking you could at least deal with the gripper in a background task if there is a collision. As far as the error handler goes, use a TEST CASE ENDTEST, and include a default CASE. Put a program stop or placeholder, to stop program execution. I usually use , that will stop execution for sure. In that default case, compare the system error number, ERRNO with the predefined errors to see if an unanticipated error occurred. Maybe you could examine the robot position at the time of error in the background task also. You cannot do motions in that task, but you could write values to a robtarget that the motion task can move to.
    Lee Justice
  • Tompanhuhu
    Tompanhuhu ✭✭
    Answer ✓
    Have you activated "CollisionErrorHandling" in the system parameters?
    Configuration -> Controller -> General Rapid

    I think @lemster68 is thinking about the system output "Motion Supervision Triggered" that maybe it can notify the background task's that a collision has occurred. 

    In that case you can either force an interupt in the maintask from a background task with system inputs.
    Or you can set a bool in the background task, and then check that bool in a event routine at program startup. And you can start the robottask with a simulated I/O system input. 
    Systemintegrator - Web / C# / Rapid / Robotstudio

    If I helped, please press Vote Up  :smile:
  • Newman
    Newman
    edited April 2022 Answer ✓
    I have never been able to recover from a joint collision with the error handler. Usually the only way I get the error handler to catch the collision is by lowering the speed. In my case this often occurs when picking rolling parts from vision camera.

    But as lemster68 said, try to lower the supervision trigger level e.g.  "MotionSup\On\TuneValue:=50;" But that only works if you have option Collision detection.

    -----------------
    David
    Swedish freelance ABB robot programmer
  • lemster68
    lemster68 ✭✭✭
    Answer ✓
    You can look in the backinfo text file from a backup.  It will show your options listed.  You can still get motion supervision without the option.  If you do have the option you will be able to insert the instruction MotionSupOn or Off \tunevalue:=xx (might not be exact correct sysntax).
    Lee Justice
  • Forge_Engineering
    Answer ✓
    Hi Dave, 

    I think the function ReadErrData does what you are looking for.
    It can be used in a Trap routine to get the Error Domain (errdomain datatype) that gives you the prefix, which is 5, for motion errors. 
    It is explained with basic examples in the Rapid Instructions Help available through RobotStudio.

    Good Luck,

    Harry
  • SomeTekk
    SomeTekk
    edited May 2022 Answer ✓
    Here's background task I use for catching errors (parts of dealing with regain distances are dis-included because in this facility the regain distances are VERY small ≈1mm). A log is written to on an external PC that I have NOT included the parameters for:


        VAR intnum intMotErr_interrupt;
        VAR intnum intHWareErr_interrupt;
        VAR intnum intRegain_interrupt;
        VAR errdomain err_domain;
        VAR num err_number;
        VAR errtype err_type;
        VAR trapdata err_data;
        VAR string strCtrlId;
        VAR string string1;
        VAR string string2;
        VAR string stEorW;

        VAR iodev textfile;
        VAR iodev io_DeviceName;
        VAR string tempstring;
        PERS num nProgNum:=88;

        PROC main()
            IDelete intMotErr_interrupt;
            IDelete intHWareErr_interrupt;
            IDelete intRegain_interrupt;
            WHILE TRUE DO
                IDelete intMotErr_interrupt;
                IDelete intHWareErr_interrupt;
                IDelete intRegain_interrupt;
                CONNECT intMotErr_interrupt WITH trErrLog;
                IError MOTION_ERR,err_type,intMotErr_interrupt;
                CONNECT intHWareErr_interrupt WITH trErrLog;
                IError HARDWARE_ERR,err_type,intHWareErr_interrupt;
                CONNECT intRegain_interrupt WITH trRegain;
                ISignalDO do_Eax_RegainErr1,1,intRegain_interrupt;
                WaitTime 0.01;
            ENDWHILE
        ENDPROC

        TRAP trErrLog
            strCtrlId:=GetSysInfo(\CtrlId);
            GetTrapData err_data;
            ReadErrData err_data,err_domain,err_number,err_type;
            IF err_number<10 THEN
                string1:=ValToStr(err_number);
                string2:="000"+string1;
            ELSEIF err_number>=10 AND err_number<=99 THEN
                string1:=ValToStr(err_number);
                string2:="00"+string1;
            ELSEIF err_number>=100 AND err_number<=999 THEN
                string1:=ValToStr(err_number);
                string2:="0"+string1;
            ELSEIF err_number>999 THEN
                string2:=ValToStr(err_number);
            ENDIF
            Open "ExternalPC:"\File:="ErrLogging.txt",io_DeviceName\Append;
            Write io_DeviceName,strCtrlId;
            Write io_DeviceName,CDate()\NoNewLine;
            Write io_DeviceName," "+CTime();
            Write io_DeviceName,stEmpty;
            tempstring:=ValToStr(err_domain);
                    IF err_type=2 THEN
                stEorW:="Warning";
            ELSEIF err_type=3 THEN
                stEorW:="ERROR";
            ELSE
                stEorW:="\A0";
            ENDIF
            Write io_DeviceName,stEorW+" number = "\NoNewLine;
            Write io_DeviceName,tempstring+string2;
            Write io_DeviceName,stEmpty;
            Write io_DeviceName,"************";
            Write io_DeviceName,stEmpty;
            Close io_DeviceName;
        ERROR
            IF ERRNO=ERR_FILEACC OR ERRNO=ERR_FILNOTFND OR ERRNO=ERR_FILEOPEN THEN
                SkipWarn;
                TRYNEXT;
            ENDIF
        ENDTRAP

    Sample Output:

    ************

    6640-103713
    2022-05-05 09:35:11

    ERROR number = 50056

    ************

  • SomeTekk
    SomeTekk
    Answer ✓
    IDelete is in both those places in case, probably irrationally, a colleague changes the Task Type. 

Answers

  • Thank you for the fast response Lemster68.

    Yes, I have multitasking.  One motion task and some background stuff for cameras, socket comms, etc.  Does that change anything?

    As you suggested, I moved the error handler to my main routine but nothing changed.  At low speed, it handles it as a 1070 collision and runs my recovery commands, but at high speed it doesn't catch it.  Instead, it shuts down and throws a system error 50055 Joint Load too high.  My understanding was that an error handler would catch any error, but apparently I'm wrong.

    My test is quite simple: I have a main Proc that is a continuous While loop.  Then I have a another Proc ErrTest that simply grabs a fixed object and starts to pull, which results in an error when the tension gets too high.  ErrTest is called in the main loop by a boolean.

    WHILE TRUE DO
    IF testError THEN                testError:=FALSE;                errTest;            ENDIF
    ENDWHILE
    ERROR
            TPWrite("error handler test - main");        TPWrite(NumToStr(ERRNO,0));
            here:=CRobT(\Tool:=grip_B,\WObj:=wind_fixture);        StorePath;        reset outCloseGripper;        set outOpenGripper;        waittime 1;        MoveL offs(here,0,0,40),v100,fine,grip_B,\WObj:=wind_fixture;        WaitRob\InPos;        RestoPath;        StartMove;ENDPROC

    I'm not too clear on how to structure the error handler so feel free to comment on that too.  But my main concern is catching the error and recovering.
  • I don't see how the background task will be aware of a collision event in the motion task.  An error handler there only catches errors caused by routines from its own task.  Are you suggesting that I try to set a PERS variable as a signal before main execution stops?

    And thank you for the general error handling tips.
  • Yes, I double checked my configuration and I do have CollisionErrorHandling=Yes.  I also noticed in Control Panel > Supervision there is a setting for Non motion execution.  Do you know what this does?

    So it looks like I need to accept that there is no way to directly handle this fault because the system fault is shutting down the main routine - is that correct?  

    Now to figure out the solution suggested by you and lemster68:
    • Configure a system output MotSupTrigg and connect it to a digital output.
    • In a background task, connect a trap to ISignalDO.

    This works, but maybe I shouldn't assume a trap is necessary, I can just watch for the digital output to go high.

    I might need some help with the next step:
    You said, "force an interrupt in the maintask from a background task with system inputs".

    How can I do this if the main task was stopped by the system error?

    Your other suggestion, "Or you can set a bool in the background task, and then check that bool in a event routine at program startup."

    Are you referring to a configured event routine like Start or Restart, or do you just mean that my main routine should check for this boolean?  Then if I see this boolean true, I take care of cleaning up the collision before starting the normal business of the main routine?

    Assuming I'm still with you up to here, can you provide more detail for: "start the robottask with a simulated I/O system input"?  Is this the background task setting a digital input that is configured to a system input like "Start at Main"?

    Now, taking a step back, am I missing something obvious that gotten me this deep into a fairly complex solution?  Other than preventing the collision from ever happening.  Seems like a very common thing to recover 
    from a motion supervision event without manual intervention . How am I getting into something that's so hard to recover from? 

    Thanks to both of you for jumping in to help.






  • lemster68
    lemster68 ✭✭✭
    Non-motion execution puts the robot into simulated motion mode.  Servo power is off and even jogging is simulated.  Great tool for cell startup and debug sometimes.
    It is odd that you say collision error handling is already enabled.  But, then again, the error is joint load too high, not a collision.  Perhaps is you make your motion supervision setting to be more sensitive, it will trigger a collision before you get to the joint load too high.
    Lee Justice
  • It looks like I don't have the Collision Detection option, unless it is included in Path Recovery, or SoftMove.  According to the manual, Manipulator supervision level is only active if the option Collision Detection is installed. 
  • You can also try to set a higher mass to your tool and see if the system behaves differently?

    I think you understood me correct, it is a complex workaround for sure but as said before, the fault is not recognized as a collision. 

    Systemintegrator - Web / C# / Rapid / Robotstudio

    If I helped, please press Vote Up  :smile:
  • lemster68
    lemster68 ✭✭✭
    edited April 2022
    Some years ago I coded a background task to open the gripper if there was a collision.  At that point, the robot was given a startmain system input and needed to run a homing/recovery routine at the beginning if it was not at home.
    PROC Main()
        WHILE (TRUE) DO
          IF  fiNewTray_11_1=1 ResetTray_1MD11;
          IF  fiNewTray_11_2=1 ResetTray_2MD11;
          IF  fiNewTray_13_1=1 ResetTray_1MD13;
          IF  fiNewTray_13_2=1 ResetTray_2MD13;
          IF bInstallMotion AND DOutput(foMotionSupTrig) = 1 THEN
          	Reset doClampJet;
          	Set doUnclampJet;
          	Set foPartRejected;
          	bInstallMotion := FALSE;
          ENDIF
          WaitTime 0.5;
        ENDWHILE
      ENDPROC
    In the motion task the boolean, bInstallMotion, was set to true in the final motion to install a part, this was where the collision would occur, if at all.

    Lee Justice
  • lemster68
    lemster68 ✭✭✭
    @DaveCleveland If it is really that critical to what you are doing, you could contact ABB to purchase the motion supervision and collision detection option.  With my limited experience with getting quotes for options, they seem to usually fall in around $1200 USD.
    Lee Justice
  • I checked with my reseller and he said both were included in my purchase.  I told him it did not appear when I list options from Control Panel > Installed Systems.  He thinks they don't appear as options because they are part of the system and don't need to be added.  I'm not sure about that.

    Would I get motion supervision errors like I do (at slower speeds anyway) if I didn't have Motion Supervision?  Or is there some baseline functionality that will always catch some errors?

    And would my configuration screen allow me to edit the values for Manipulator supervision and supervision level?

    I tried a whole range of values for supervision level but noticed no change.  Could it be that the settings are enabled even without those options but they are non-functional?
  • Try opening installation manager and check that the options are selected.

    Make a backup before because when changing options the system can get restored. 

    Installation manager is available in the controller tab in robotstudio. 
    Unless it's a omnicore system you should use installation manager 6 ✌️
    Systemintegrator - Web / C# / Rapid / Robotstudio

    If I helped, please press Vote Up  :smile:
  • It is not listed in the backinfo file.  And trying to use MotionSup \On in a program brings up an error saying the system does not have that option.  

    Do you think adding this option might enable error handling for joint overloads?
  • lemster68
    lemster68 ✭✭✭
    Well, possibly.  I had mentioned earlier that I think that if you tuned the supervision to be more sensitive, then you could catch it as a supervision error, rather than let it escalate to the joint load too high error.
    Lee Justice
  • Have you checked installation manager as i suggested ? 
    Systemintegrator - Web / C# / Rapid / Robotstudio

    If I helped, please press Vote Up  :smile:
  • If you are still willing to help, I have a follow-up question.

    I am using IError to successfully trap the joint overload errors that seem to evade the Error handler.  The motion task still gets shut down but I am catching them in a background task as recommended by several responses here.

    But this leads to another question:  How can I recognize the errors I want to trap?  The reported error number from IError drops the first digit for some reason which leads to ambiguity because I need to trap 50052:Joint speed error.  But when the first digit is missing, I can't differentiate between 50052:Joint speed error and 10052:Regain start.  This causes problems because I am restarting the motion task from the background task which causes the trap to see 52 again (as Regain start) and creates an endless restart loop.

    I am working around this by using ReadErrData to get the error title, then parsing that string to look for some text that is unique to the joint overload errors.  This is not a very robust solution.  Can anyone show me a better way to identify the error?
     
  • Thank you Harry.  That's what I needed.  I had it in my head that err_domain was the error type (state, warn, err).

    And thank you SomeTekk for the example.  Logging is on my list of things to get done.  I'm curious why you use IDelete when you enter the routine and again inside the loop.