%%%
  VERSION:1
  LANGUAGE:ENGLISH
%%%

MODULE CARC(SYSMODULE,NOVIEW)
  ! Record definitions
  RECORD weldpoint
    weldpar weld_par;
    num weld_speed;
    num weld_voltage;
    num weld_wirefeed;
  ENDRECORD
  RECORD weldline
    weldpoint point1;
    weldpoint point2;
    weldpoint point3;
    weldpoint point4;
    weldpoint point5;
  ENDRECORD

  LOCAL PERS seamdata WldSm:=[0,0,3,4.16667,0,0,0,0,0,0,0];
  LOCAL PERS weavedata WldWv:=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
  LOCAL PERS welddata WldWd:=[23.3333,3.66667,5.66667,0,0,0];
  LOCAL VAR num ZOffs:=0;
  CONST num ZOffs_UP:= -15;
  LOCAL VAR intnum WldUpIntNo:=0;
  LOCAL VAR intnum WldDwnIntNo:=0;
  LOCAL VAR shapedata WldSphShape;
  VAR wztemporary WldSphId;
  !*******************************************************************
  !
  ! CARC.SYS
  !
  ! DESCRIPTION:
  !  This file contains the RAPID code for the for
  !  CARC.SYS rapid system module.
  !  The module is used to generate synergic lines and to execute
  !  Arc Welding using the generated lines
  !
  ! MODIFICATIONS:
  ! 960912  Initial revision
  ! 970814  Final revision
  !
  CONST string version_string:="970814 CompactArc 1.0";
  !
  ! Copyright (c) ABB Robotics Products AB 1997  All rights reserved
  ! Global Module data
  LOCAL CONST num WLD_SPH_RAD:=30;
  LOCAL CONST num WLD_N:=25;
  LOCAL CONST num WLD_IGN_VLT:=13;
  LOCAL CONST num WLD_IGN_WFD:=8;
  LOCAL CONST num WLD_RAISE:=1;
  LOCAL CONST num WLD_RETRY:=2;
  LOCAL CONST num WLD_REPAIR_SPEED:=100;
  LOCAL CONST num WLD_SKIP_SPEED:=100;
  LOCAL CONST num WLD_MODE_WELD:=0;
  LOCAL CONST num WLD_MODE_REPAIR:=1;
  LOCAL CONST num WLD_MODE_SKIP:=2;
  LOCAL PERS bool WldIgnErr:=FALSE;
  LOCAL PERS bool WldTuning:=FALSE;
  LOCAL PERS num WldRepairSeam:=2;
  LOCAL PERS num WldSeamCtr:=2;
  LOCAL PERS num WldRepairInst:=12;
  LOCAL PERS num WldInstCtr:=10;
  LOCAL PERS num WldSpd{25}:=[10,10.8333,11.6667,12.5,13.3333,14.1667,15,15.8333,16.6667,17.5,18.3333,19.1667,20,20.8333,21.6667,22.5,23.3333,24.1667,25,25.8333,26.6667,27.5,28.3333,29.1667,30];
  LOCAL PERS num WldVlt{25}:=[1,1.16667,1.33333,1.5,1.66667,1.83333,2,2.16667,2.33333,2.5,2.66667,2.83333,3,3.16667,3.33333,3.5,3.66667,3.83333,4,4.16667,4.33333,4.5,4.66667,4.83333,5];
  LOCAL PERS num WldWfd{25}:=[3,3.16667,3.33333,3.5,3.66667,3.83333,4,4.16667,4.33333,4.5,4.66667,4.83333,5,5.16667,5.33333,5.5,5.66667,5.83333,6,6.16667,6.33333,6.5,6.66667,6.83333,7];
  LOCAL PERS num WldIndx:=17;
  LOCAL PERS weldpar WldLowlim:=1;
  LOCAL PERS weldpar WldHighlim:=5;
  LOCAL PERS weldpar WldRes:=0.166667;
  LOCAL PERS pos WldRepairPos:=[627.005,819.956,385.273];
  LOCAL PERS weldpar WldOwr:=0;
  LOCAL PERS weldpar WldCurr:=0;
  ! WldMode defined as WLD_MODE_WELD
  LOCAL PERS num WldMode:=0;
  LOCAL VAR num WldErrCnt;
  LOCAL PERS string WldArgName:="w30";
  LOCAL PERS num TxtTabNo:=29997;
  LOCAL PERS string WldTxtPar:="Weld value:     ";
  LOCAL PERS string WldTxtParName:="Weld par:       ";
  LOCAL PERS string WldTxtVolt:="Voltage:        ";
  LOCAL PERS string WldTxtWfd:="Wirefeed:       ";
  LOCAL PERS string WldTxtSpd:="Speed:          ";

  !***********************************************************************
  !
  ! CArcVersion - Class identification routine
  !
  ! DESCRIPTION:
  !   This method returns the standard identification string.
  !
  ! RETURNS:
  !   A version string
  !
  ! NOTE:
  !
  ! EXAMPLE:
  !  TpWrite CArcVersion;
  !
  ! INTERNAL:
  !
  !
  FUNC string CArcVersion()
    RETURN (version_string);
  ENDFUNC

  !***********************************************************************
  !
  ! SetupWld  - Setup trackdata
  !
  ! DESCRIPTION:
  !   This routine is used to setup Wldive tracking.
  !   Five welddata are specified together with a limit value.
  !   Voltage, Wirefeed and Speed data in the five welddata sets
  !   define how to Wld the process according to meassured volume.
  !
  !   Speed, Voltage or Wirefeed
  !            
  !            |
  !            |                                            +
  !            |
  !            |
  !            |                                +
  !            |
  !            |
  !            |                       +
  !            |
  !            |                     
  !            |                +
  !            |
  !            |    +
  !            |
  !            |
  !             ----|-----------|------|--------|-----------|------>  Volume
  !               lim1        lim2   lim3      lim4       lim5
  !
  !   Three arrays are setup with process data.
  !   WldSpd{}  - process speed
  !   WldVlt{}  - voltage referens
  !   WldWfd{}  - wirefeed speed
  !  
  !   Intermediate points are interpolated using the 5 given samples.
  !
  ! 
  ! RETURNS:
  !   Nothing
  !
  ! EXAMPLE: 
  !
  PROC SetupWld(
    INOUT weldline Line
    \PERS seamdata Sm
    \PERS weavedata Wv)

    WldWd.weld_speed:=Line.point3.weld_speed;
    WldWd.weld_voltage:=Line.point3.weld_voltage;
    WldWd.weld_wirefeed:=Line.point3.weld_wirefeed;
    WldLowlim:=Line.point1.weld_par;
    WldHighlim:=Line.point5.weld_par;
    WldRes:=(WldHighlim-WldLowlim)/(WLD_N-1);
    SetupWldPar Line.point1,Line.point2;
    SetupWldPar Line.point2,Line.point3;
    SetupWldPar Line.point3,Line.point4;
    SetupWldPar Line.point4,Line.point5;
    IF Present(Sm) THEN
      WldSm:=Sm;
    ELSE
      WldSm:=[0,0,WldVlt{WLD_IGN_VLT},WldWfd{WLD_IGN_WFD},0,0,0,0,0,0,0];
    ENDIF
    IF Present(Wv) THEN
      WldWv:=Wv;
    ELSE
      WldWv:=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
    ENDIF
  ENDPROC

  !***********************************************************************
  !
  ! WeldStart - Weld start instruction
  !
  ! DESCRIPTION:
  !   This routine starts linear welding
  !
  ! RETURNS:
  !   Nothing
  !
  ! EXAMPLE:
  !  
  PROC WeldStart(
    robtarget ToPoint,
    PERS weldpar WeldP
    \PERS tooldata Tool
    \PERS wobjdata WObj)

    WldSeamCtr:=WldSeamCtr+1;
    IF Present(Tool) THEN
      WldTool:=Tool;
    ENDIF
    WldSetup WeldP;
    Revert_WeldP WeldP;
    
    IF WldMode=WLD_MODE_REPAIR AND WldRepairSeam=WldSeamCtr AND WldIgnErr THEN
      WldIgnErr:=FALSE;
      Reset WELD_INHIB_ERR;
      Reset WLD_ERROR;
      WldMode:=WLD_MODE_WELD;
    ENDIF

    ArcL\On, RelTool(ToPoint,0,0,ZOffs),v100,WldSm,WldWd,WldWv,fine,WldTool\Wobj?WObj;
    WldTuning:=TRUE;
    WeldP:=WeldP+(WldOwr*WldRes);
    
  BACKWARD
    ArcL\On, RelTool(ToPoint,0,0,ZOffs),v100,WldSm,WldWd,WldWv,fine,WldTool\Wobj?WObj;
  ERROR
    TEST (WldError())
    CASE WLD_RAISE:
      RAISE;
    CASE WLD_RETRY:
      RETRY;
    DEFAULT:
      RAISE;
    ENDTEST
  ENDPROC

  !***********************************************************************
  !
  ! Weld - Intermediate linear weld instruction
  !
  ! DESCRIPTION:
  !   Routine for intermediate linear welding
  !
  ! RETURNS:
  !   Nothing
  !
  ! EXAMPLE:
  !    
  PROC Weld(
    robtarget ToPoint,
    PERS weldpar WeldP
    \PERS wobjdata WObj)

    WldSetup WeldP;
    Revert_WeldP WeldP;
    IF WldMode=WLD_MODE_REPAIR AND WldRepairInst=WldInstCtr THEN
      WZSphDef\Inside,WldSphShape,WldRepairPos,WLD_SPH_RAD;
      WZDOSet\Temp,WldSphId\Before,WldSphShape,WLD_ERROR_POS,1;
      WZEnable WldSphId;
    ENDIF
    
    ArcL RelTool(ToPoint,0,0,ZOffs),v100,WldSm,WldWd,WldWv,z10,WldTool\Wobj?WObj;      
       
    WeldP:=WeldP+(WldOwr*WldRes);
    
  BACKWARD
    ArcL RelTool(ToPoint,0,0,ZOffs),v100,WldSm,WldWd,WldWv,z10,WldTool\Wobj?WObj;
  ERROR
    TEST (WldError())
    CASE WLD_RAISE:
      RAISE;
    CASE WLD_RETRY:
      RETRY;
    DEFAULT:
      RAISE;
    ENDTEST
  ENDPROC

  !***********************************************************************
  !
  ! WeldC - Intermediate circular weld instruction
  !
  ! DESCRIPTION:
  !   Routine for intermediate circular welding
  !
  ! RETURNS:
  !   Nothing
  !
  ! EXAMPLE:
  !      
  PROC WeldC(
    robtarget CirPoint,
    robtarget ToPoint,
    PERS weldpar WeldP
    \PERS wobjdata WObj)

    WldSetup WeldP;
    Revert_WeldP WeldP;
    IF WldMode=WLD_MODE_REPAIR AND WldRepairInst=WldInstCtr THEN
      WZSphDef\Inside,WldSphShape,WldRepairPos,WLD_SPH_RAD;
      WZDOSet\Temp,WldSphId\Before,WldSphShape,WLD_ERROR_POS,1;
      WZEnable WldSphId;
    ENDIF

    ArcC RelTool(CirPoint,0,0,ZOffs),RelTool(ToPoint,0,0,ZOffs),v100,WldSm,WldWd,WldWv,z10,WldTool\Wobj?WObj;

    WeldP:=WeldP+(WldOwr*WldRes);

    BACKWARD
    ArcC RelTool(CirPoint,0,0,ZOffs),RelTool(ToPoint,0,0,ZOffs),v100,WldSm,WldWd,WldWv,z10,WldTool\Wobj?WObj;
  ERROR
    TEST (WldError())
    CASE WLD_RAISE:
      RAISE;
    CASE WLD_RETRY:
      RETRY;
    DEFAULT:
      RAISE;
    ENDTEST
  ENDPROC

  !***********************************************************************
  !
  ! WeldEnd - Weld end instruction
  !
  ! DESCRIPTION:
  !   This routine ends linear welding
  !
  ! RETURNS:
  !   Nothing
  !
  ! EXAMPLE:
  ! 
  PROC WeldEnd(
    robtarget ToPoint,
    PERS weldpar WeldP
    \PERS wobjdata WObj)

    WldSetup WeldP;
    Revert_WeldP WeldP;
    IF WldMode=WLD_MODE_REPAIR AND WldRepairInst=WldInstCtr THEN
      WZSphDef\Inside,WldSphShape,WldRepairPos,WLD_SPH_RAD;
      WZDOSet\Temp,WldSphId\Before,WldSphShape,WLD_ERROR_POS,1;
      WZEnable WldSphId;
    ENDIF

    ArcL\Off,RelTool(ToPoint,0,0,ZOffs),v100,WldSm,WldWd,WldWv,fine,WldTool\Wobj?WObj;
    WldTuning:=FALSE;
    WeldP:=WeldP+(WldOwr*WldRes);
    
  BACKWARD
    ArcL\Off,RelTool(ToPoint,0,0,ZOffs),v100,WldSm,WldWd,WldWv,fine,WldTool\Wobj?WObj;
  ERROR
    TEST (WldError())
    CASE WLD_RAISE:
      RAISE;
    CASE WLD_RETRY:
      RETRY;
    DEFAULT:
      RAISE;
    ENDTEST
  ENDPROC

  !***********************************************************************
  !
  ! SetupWldPar - Setup AW parameters
  !
  ! DESCRIPTION:
  !   This routine sets up AW parameters.
  !   Arrays of process parameters are calculated from input values.
  !   
  ! RETURNS:
  !   Noting
  !
  ! EXAMPLE:
  !
  LOCAL PROC SetupWldPar(
    INOUT weldpoint P1,
    INOUT weldpoint P2)

    VAR num low_indx;
    VAR num high_indx;
    VAR num indx;

    low_indx:=ArrIndx(P1.weld_par);
    high_indx:=ArrIndx(P2.weld_par);
    FOR indx FROM low_indx TO high_indx DO
      WldSpd{indx}:=IpolArr(indx,low_indx,P1.weld_speed,high_indx,P2.weld_speed);
      WldVlt{indx}:=IpolArr(indx,low_indx,P1.weld_voltage,high_indx,P2.weld_voltage);
      WldWfd{indx}:=IpolArr(indx,low_indx,P1.weld_wirefeed,high_indx,P2.weld_wirefeed);
    ENDFOR
  ENDPROC

  !***********************************************************************
  !
  ! ArrIndx - Array Index
  !
  ! DESCRIPTION:
  !   This routine takes a volume input and calculates an index in
  !   the precalculate arrays of process parameters
  !
  ! RETURNS:
  !   Array index
  !
  ! EXAMPLE:
  !
  LOCAL FUNC num ArrIndx(
    weldpar lim)

    VAR num indx;
    VAR string err1;
    VAR string err2;
    VAR string err3;

    IF (lim<=WldLowlim) THEN
      indx:=1;
      IF (lim<WldLowlim) THEN
        err1:="  "+TextGet(TxtTabNo,29)+" "+WldArgName;
        err2:="  "+TextGet(TxtTabNo,26)+" "+NumToStr(lim,1);
        err3:="  "+TextGet(TxtTabNo,28)+" "+NumToStr(WldLowlim,1);
        TPShow TP_PROGRAM;
        ErrWrite TextGet(TxtTabNo,25),err1\RL2:=err2\RL3:=err3;
      ENDIF
    ELSE
      IF (lim>=WldHighlim) THEN
        indx:=WLD_N;
        IF (lim>WldHighlim) THEN
          err1:="  "+TextGet(TxtTabNo,29)+" "+WldArgName;
          err2:="  "+TextGet(TxtTabNo,26)+" "+NumToStr(lim,1);
          err3:="  "+TextGet(TxtTabNo,27)+" "+NumToStr(WldHighlim,1);
          TPShow TP_PROGRAM;
          ErrWrite TextGet(TxtTabNo,25),err1\RL2:=err2\RL3:=err3;
        ENDIF
      ELSE
        indx:=1+Round(0.001+(lim-WldLowlim)/WldRes);
      ENDIF
    ENDIF
    RETURN (indx);
  ENDFUNC

  !***********************************************************************
  !
  ! IpolArr - Array Index
  !
  ! DESCRIPTION:
  !   This routine interpolates intermediate values between a start and
  !   an end value.
  !
  ! RETURNS:
  !   Interpolated intermediate num value
  !
  ! EXAMPLE:
  !
  LOCAL FUNC num IpolArr(
    num indx,
    num low_lim,
    num low_value,
    num high_lim,
    num high_value)

    VAR num rel;
    VAR num value;

    IF (indx=low_lim) THEN
      value:=low_value;
    ELSE
      IF (indx=high_lim) THEN
        value:=high_value;
      ELSE
        rel:=(indx-low_lim)/(high_lim-low_lim);
        value:=(high_value-low_value)*rel+low_value;
      ENDIF
    ENDIF
    RETURN (value);
  ENDFUNC

  !***********************************************************************
  !
  ! WldSetup - Setup up weld parameters
  !
  ! DESCRIPTION:
  !   This routine gets the current welding parameters from the
  !   interpolated welding data.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !  
  PROC WldSetup(
    PERS weldpar WeldP)

    WldArgName:=ArgName(WeldP);
    WldCurr:=WeldP;
    WldOwr:=0;
    WldErrCnt:=0;
    WldInstCtr:=WldInstCtr+1;
    WldIndx:=ArrIndx(WeldP);
    WldWd.weld_voltage:=WldVlt{WldIndx};
    WldWd.weld_wirefeed:=WldWfd{WldIndx};
    
    IF (WldMode=WLD_MODE_REPAIR AND (WldSeamCtr<>WldRepairSeam OR WldInstCtr < WldRepairInst - 2)) OR WldMode=WLD_MODE_SKIP THEN
      ZOffs:=ZOffs_UP;
    ELSE
      ZOffs:=0;
    ENDIF

    TEST WldMode
    CASE WLD_MODE_REPAIR:
      IF WldSeamCtr<>WldRepairSeam THEN
        WldWd.weld_speed:=WLD_REPAIR_SPEED;
      ELSE
        WldWd.weld_speed:=WldSpd{WldIndx};
      ENDIF
    CASE WLD_MODE_SKIP:
      WldWd.weld_speed:=WLD_SKIP_SPEED;
    CASE WLD_MODE_WELD:
      WldWd.weld_speed:=WldSpd{WldIndx};
    DEFAULT:
      WldWd.weld_speed:=WldSpd{WldIndx};
    ENDTEST
    WldDisp;
  ENDPROC

  !***********************************************************************
  !
  ! WldError - Error handler
  !
  ! DESCRIPTION:
  !   This routine verifies the number od retries and acts upon the result.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !    
  LOCAL FUNC num WldError()
    VAR num ret_val;

    TEST (ERRNO)
    CASE AW_STOP_ERR:
      WldIgnErr:=FALSE;
      WZFree WldSphId;
      Reset WELD_INHIB_ERR;
      Reset WLD_ERROR_POS;
      ret_val:=WldErrorHandler();
    CASE AW_IGNI_ERR:
      IF WldErrCnt=0 THEN
        WldIgnErr:=TRUE;
      ENDIF
      ret_val:=WldErrorHandler();
    CASE AW_WELD_ERR:
      WldIgnErr:=FALSE;
      ret_val:=WldErrorHandler();
    DEFAULT:
      WldIgnErr:=FALSE;
      ret_val:=WLD_RAISE;
    ENDTEST
    RETURN ret_val;
  ENDFUNC

  !***********************************************************************
  !
  ! WldErrorHandler - Error handler
  !
  ! DESCRIPTION:
  !   This routine verifies the number od retries and acts upon the result.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !    
  LOCAL FUNC num WldErrorHandler()
    VAR num ret_val;
    VAR num key;
    VAR errnum err_flag;

    Set WLD_ERROR;
    WldErrCnt:=WldErrCnt+1;
    IF (WldErrCnt<2) THEN
      Reset WLD_ERROR;
      WldMode:=WLD_MODE_WELD;
      ret_val:=WLD_RETRY;
    ELSE
      StorePath;
      ! Store error position
      WldRepairPos:=CPos(\Tool:=WldTool);
      MoveL RelTool(CRobT(),0,0,-5),v100,fine,WldTool;
      IF (WldErrCnt<3) THEN
        TPErase;
        TPReadFK key,TextGet(TxtTabNo,4),"","","",TextGet(TxtTabNo,2),TextGet(TxtTabNo,1)\DIBreak:=WLD_MMI_1\BreakFlag:=err_flag;
        TPErase;
        IF err_flag=ERR_TP_DIBREAK THEN
          IF WLD_START_DI=1 THEN
            key:=5;
          ENDIF
          IF WLD_REPAIR_DI=1 THEN
            key:=4;
          ENDIF
        ENDIF
        TEST key
        CASE 4:
          ! Repair
          Set WELD_INHIB_ERR;
          WldMode:=WLD_MODE_SKIP;
          WldRepairSeam:=WldSeamCtr;
          WldRepairInst:=WldInstCtr;
          ret_val:=WLD_RETRY;
          TPErase;
          TPWrite " ";
          TPWrite TextGet(TxtTabNo,7);
        CASE 5:
          ! Weld
          Reset WLD_ERROR;
          Reset WELD_INHIB_ERR;
          Reset WLD_ERROR_POS;
          WldMode:=WLD_MODE_WELD;
          ret_val:=WLD_RETRY;
        ENDTEST
      ELSE
        ! Repair
        Set WELD_INHIB_ERR;
        WldMode:=WLD_MODE_SKIP;
        WldRepairSeam:=WldSeamCtr;
        WldRepairInst:=WldInstCtr;
        ret_val:=WLD_RETRY;
        TPErase;
        TPWrite " ";
        TPWrite TextGet(TxtTabNo,7);
      ENDIF
      RestoPath;
    ENDIF
    RETURN (ret_val);
  ENDFUNC

  !***********************************************************************
  !
  ! WldDisp - Welding parameter display
  !
  ! DESCRIPTION:
  !   This routine displays the welding parameters on TP.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !    
  LOCAL PROC WldDisp()
    IF WldMode=WLD_MODE_WELD THEN
      TPErase;
      TPWrite " ";
      TPWrite WldTxtParName+WldArgName;
      TPWrite WldTxtPar\Num:=WldCurr+(WldOwr*WldRes);
      TPWrite WldTxtVolt\Num:=WldWd.weld_voltage;
      TPWrite WldTxtWfd\Num:=WldWd.weld_wirefeed;
      TPWrite WldTxtSpd\Num:=WldWd.weld_speed;
    ENDIF
  ENDPROC

  !***********************************************************************
  !
  ! WldOwrDwnTrp - Decreasing synergic tuning
  !
  ! DESCRIPTION:
  !   This trap routine decreases the synergic welding data.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !      
  TRAP WldOwrDwnTrp
    IF WldIndx>1 AND WldMode=WLD_MODE_WELD AND WldTuning THEN
      WldOwr:=WldOwr-1;
      WldIndx:=WldIndx-1;
      WldWd.weld_voltage:=WldVlt{WldIndx};
      WldWd.weld_wirefeed:=WldWfd{WldIndx};
      WldWd.weld_speed:=WldSpd{WldIndx};
      ArcRefresh;
      WldDisp;
    ENDIF
  ENDTRAP

  !***********************************************************************
  !
  ! WldOwrUpTrp - Increasing synergic tuning
  !
  ! DESCRIPTION:
  !   This trap routine increases the synergic welding data.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !      
  TRAP WldOwrUpTrp
    IF WldIndx<WLD_N AND WldMode=WLD_MODE_WELD AND WldTuning THEN
      WldOwr:=WldOwr+1;
      WldIndx:=WldIndx+1;
      WldWd.weld_voltage:=WldVlt{WldIndx};
      WldWd.weld_wirefeed:=WldWfd{WldIndx};
      WldWd.weld_speed:=WldSpd{WldIndx};
      ArcRefresh;
      WldDisp;
    ENDIF
  ENDTRAP

  !***********************************************************************
  !
  ! WldStopShelf - Stop shelf routine.
  !
  ! DESCRIPTION:
  !   This trap routine is hooked to the STOP and QUICK STOP event and 
  !   takes some actions upon this event.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !        
  PROC WldStopShelf()
    WldErrCnt:=0;
    TPShow TP_PROGRAM;
  ENDPROC
  
  !***********************************************************************
  !
  ! WldPowerShelf - Power on routine.
  !
  ! DESCRIPTION:
  !   This trap routine is hooked to the POWER ON event and 
  !   takes some actions upon this event.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !        
  PROC WldPowerShelf()
    ArcTool WldTool;
  ENDPROC  
  
  !***********************************************************************
  !
  ! WldTxt - String padding.
  !
  ! DESCRIPTION:
  !   This routine adds blank characters to a string.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !        
  LOCAL FUNC string WldTxt(
    string Str,
    num Len)

    VAR num StrLength:=0;
    VAR string StrResult;

    StrResult:=Str;
    StrLength:=StrLen(Str);
    FOR i FROM 1 TO Len-StrLength DO
      StrResult:=StrResult+" ";
    ENDFOR
    RETURN StrResult;
  ENDFUNC
  
  !***********************************************************************
  !
  ! Revert_WeldP - Revert WeldP
  !
  ! DESCRIPTION:
  !   Check and revert WeldP if necessary.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !        
  LOCAL PROC Revert_WeldP(
    PERS weldpar WeldP)

    IF (WeldP<WldLowlim) THEN
       WeldP:=WldLowlim;
       WldCurr:=WeldP;
       WldDisp;
    ENDIF

    IF (WeldP>WldHighlim) THEN
       WeldP:=WldHighlim;
       WldCurr:=WeldP;
       WldDisp;
    ENDIF
  ENDPROC
  
  !***********************************************************************
  !
  ! WeldMain - Weld main routine
  !
  ! DESCRIPTION:
  !   This routine adds blank characters to a string.
  !
  ! RETURNS:
  !   Nothing.
  !
  ! EXAMPLE:
  !        
  PROC WeldMain(
    robtarget HomePoint)

    VAR num key;
    VAR errnum err_flag;
    VAR bool home_position;

    MoveL HomePoint,v1000,fine,WldTool;
    home_position:=TRUE;
    TxtTabNo:=TextTabGet("CompactArcText");
    WldTxtPar:=WldTxt(TextGet(TxtTabNo,20),16);
    WldTxtParName:=WldTxt(TextGet(TxtTabNo,21),16);
    WldTxtVolt:=WldTxt(TextGet(TxtTabNo,22),16);
    WldTxtWfd:=WldTxt(TextGet(TxtTabNo,23),16);
    WldTxtSpd:=WldTxt(TextGet(TxtTabNo,24),16);
    WldSeamCtr:=0;
    WldInstCtr:=0;
    WldTuning:=FALSE;
    
    ! Setup tuning key events
    IDelete WldDwnIntNo;
    IDelete WldUpIntNo;
    CONNECT WldDwnIntNo WITH WldOwrDwnTrp;
    ISignalDI WLDPAR_DWN,1,WldDwnIntNo;
    CONNECT WldUpIntNo WITH WldOwrUpTrp;
    ISignalDI WLDPAR_UP,1,WldUpIntNo;    
    
    IF WldMode = WLD_MODE_REPAIR THEN
      WldMode:=WLD_MODE_WELD;
      TPShow TP_PROGRAM;
      ErrWrite TextGet(TxtTabNo,30), TextGet(TxtTabNo,31);
      Stop;
    ENDIF
	  
    WHILE home_position DO
      MoveL HomePoint,v1000,fine,WldTool;
      Reset WLD_SERVICE;
      Set WLD_HOME;
      
      TEST (WldMode)
      CASE WLD_MODE_WELD:
        TPErase;
        TPReadFK key,TextGet(TxtTabNo,5),"","","",TextGet(TxtTabNo,3),TextGet(TxtTabNo,1)\DIBreak:=WLD_MMI_2\BreakFlag:=err_flag;
        TPErase;
        IF err_flag=ERR_TP_DIBREAK THEN
          IF WLD_START_DI=1 THEN
            key:=5;
          ENDIF
          IF WLD_SERVICE_DI=1 THEN
            key:=4;
          ENDIF
        ENDIF
        TEST key
        CASE 4:
          ! Service
          Reset WLD_HOME;
          Set WLD_SERVICE;
          Reset WLD_ERROR;
          %"ServiceRoutine"%;
        CASE 5:
          ! Weld
          WldMode:=WLD_MODE_WELD;
          WldIgnErr:=FALSE;
          home_position:=FALSE;
          Reset WELD_INHIB_ERR;
          Reset WLD_ERROR;
          Reset WLD_HOME;
        ENDTEST
      CASE WLD_MODE_SKIP:
        TPErase;
        TPReadFK key,TextGet(TxtTabNo,6),"","",TextGet(TxtTabNo,3),TextGet(TxtTabNo,2),TextGet(TxtTabNo,1)\DIBreak:=WLD_MMI_3\BreakFlag:=err_flag;
        TPErase;
        IF err_flag=ERR_TP_DIBREAK THEN
          IF WLD_START_DI=1 THEN
            key:=5;
          ENDIF
          IF WLD_SERVICE_DI=1 THEN
            key:=3;
          ENDIF
          IF WLD_REPAIR_DI=1 THEN
            key:=4;
          ENDIF
        ENDIF
        TEST (key)
        CASE 3:
          ! Service
          Reset WLD_HOME;
          Set WLD_SERVICE;
           %"ServiceRoutine"%;
        CASE 4:
          ! Repair
          WldMode:=WLD_MODE_REPAIR;
          home_position:=FALSE;
          Reset WLD_HOME;
          TPErase;
          TPWrite " ";
          TPWrite TextGet(TxtTabNo,8);
        CASE 5:
          ! Weld
          WldMode:=WLD_MODE_WELD;
          home_position:=FALSE;
          WldIgnErr:=FALSE;
          Reset WELD_INHIB_ERR;
          Reset WLD_ERROR;
          Reset WLD_HOME;
        ENDTEST
      ENDTEST
    ENDWHILE
  ERROR
    TEST (ERRNO)
    CASE ERR_REFUNKPRC:
      TPShow TP_PROGRAM;
      ErrWrite TextGet(TxtTabNo,32), TextGet(TxtTabNo,33);
      Stop;
    CASE ERR_CALLPROC:
      TPShow TP_PROGRAM;
      ErrWrite TextGet(TxtTabNo,32), TextGet(TxtTabNo,33);
      Stop;
    ENDTEST
  ENDPROC
    
ENDMODULE
