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

MODULE SWDEFUSR (SYSMODULE, NOVIEW)

!---------------------------------------
! G L O B A L  D A T A
!--------------------------------------- 

  ! Definition of force data
  RECORD forcedata
    num tip_force;
    num force_time;
    num plate_thickness;
    num plate_tolerance;
  ENDRECORD

  ! Definition of simulate data
  RECORD simdata
    num sim_type;
    num sim_time;
    bool inhib_close;
    bool no_plates;
  ENDRECORD

  ! Definition of process spot data
  RECORD spotdata
    num prog_no;
    num tip_force;
    num plate_thickness;
    num plate_tolerance;
  ENDRECORD

  ! Definition of process gun data
  RECORD gundata
    string gun_name;
    num pre_close_time;
    num pre_equ_time;
    num weld_counter;
    num max_nof_welds;
    num curr_tip_wear;
    num max_tip_wear;
    num weld_timeout;
    bool softw_equ;
    num curr_wear_fix;
    num release_dist;
    num deflection_dist;
    num deflection_force;
    num deflection_time;
    num tip_wear_ratio;
    num tipwear_sup_pos;
    num tipwear_sup_neg;
    num tipchg_sup_pos;
    num tipchg_sup_neg;
  ENDRECORD

  ! Description: 
  ! CONST string Version_XXXXXXXX := "1.2";
  !
  !          XXXXXXXX - Module name
  !                 1 - version number  (changed of SEROP) 
  !                 2 - revision number (changed of SEROP)
  CONST string Version_SWDEFUSR := "4.2";

  ! Allowed instruction parameter values
  ! These variable names is used
  ! internally. Don't change the names.
  PERS maxnum MAX_TIP_FORCE := 6000;   !N
  CONST maxnum MAX_PRE_CLOSE_T := 0.5; !sec
  CONST maxnum MAX_PRE_EQU_T := 0.1;   !sec
  CONST maxnum MAX_PLATE_THICK := 40;  !mm
  CONST maxnum MAX_PLATE_TOLER := 1;   !mm 
  CONST maxnum MAX_PROG_NO := 64;      !dimensionless
  CONST minnum MIN_WELD_TOUT := 2;     !sec
  CONST maxnum MAX_WELD_TOUT := 10;    !sec
  CONST minnum MIN_FORCE_T := 0.05;    !sec
  CONST maxnum MAX_FORCE_T := 10;      !sec
  CONST maxnum MAX_REL_DIST := 15;     !mm       
  CONST maxnum MAX_DEFLECTION := 15;   !mm

  ! Number of defined guns.
  ! The variable name is used internally.
  ! Don't change the name.
  CONST num SW_NOF_GUNS := 2;

  ! Active gun when SpotL/J is used.
  ! These variable names is used
  ! internally. Don't change the names.
  PERS gunnum gun1 := 1;
  PERS gunnum gun2 := 2;

  ! Automatic reweld: Number of automatic tries to reweld
  ! after weld_complete timeout.
  ! This variable name is used internally.
  ! Don't change the name.
  PERS num auto_reweld := 0;

  ! Program parity: 0 = none, 1 = odd, 2 = even
  ! This variable name is used internally.
  ! Don't change the name.
  PERS num prog_num_parity := 0;

  ! If the equalize signal should be set/reset from the process kernel
  ! then set this variable to TRUE
  ! This variable name is used internally.
  ! Don't change the name.
  PERS bool manage_equalize := TRUE;

  ! Spotdata
  PERS spotdata spot1:=[1, 1000, 0, 0];

  ! Forcedata
  PERS forcedata force1:=[1000, 1, 0, 0];

  ! Reset pulse (s)
  PERS num reset_fault_time := 0.5;

  ! Wait time after reset pulse (s)
  PERS num reset_fault_idle := 0.5;

  ! Distance between programmed weld position and sheet surface
  PERS num teach_dist := 0;
  
  ! Defined z-direction for TCP (gives move direction for tip measurement)
  PERS bool opposite_z := FALSE;
  
  ! Search speed during tip measurement (between 1 - 5 mm/s)
  PERS num m_search_speed := 5;
  
  ! Contact force (in N) during tip measurement (typically between 50 - 150N)
  PERS num m_touch_force := 100;
  
  ! Maximal distance (mm) from programmed point to search for reference surface
  PERS num m_movein_dist := 10;

  ! Filter parameter for the tip measurement
  PERS num mea_T1_filt:=0;
  
  ! Filter parameter for the tip measurement
  PERS num mea_T2_filt:=0;
  
  ! Incremental step used for the manual touch up
  PERS num touch_up_stepL := 1;
  PERS num touch_up_stepS := 0.1;
  
  ! Customer value to supervise the tip wear
  ! PERS num tip_supervision:=0.2;
    
  ! Value to supervise a missing tip or a wrong size of the tip
  ! PERS num tipchg_superv:=2;
  
  ! Total wear of the moveable tip used by UpdateCalibData
  PERS num wear_moveable:=0;
!----------------------------------------------------
! D A T A  D E F I N I T I O N  R O U T I N E S
!----------------------------------------------------

  ! These routines are used to connect user defined data component names to internal used names.

  ! Called in the beginnning of each Spot shell routine.
  PROC DefineSpotData (spotdata Spot, num GunNum)

    int_spotdata{GunNum}.prog_no:= 		Spot.prog_no;
    int_spotdata{GunNum}.tip_force:= 		Spot.tip_force;
    int_spotdata{GunNum}.plate_thickness:= 	Spot.plate_thickness;
    int_spotdata{GunNum}.plate_tolerance:= 	Spot.plate_tolerance;

  ENDPROC

  ! Called just before execution of SwPowerOn, SwStart or SwReStart.
  PROC DefineGunData ()

    FOR i FROM 1 TO SW_NOF_GUNS DO
      int_gundata{i}.gun_name :=		curr_gundata{i}.gun_name;
      int_gundata{i}.gun_type := 1;
      int_gundata{i}.softw_equ :=      curr_gundata{i}.softw_equ;
      int_gundata{i}.pre_close_time :=		curr_gundata{i}.pre_close_time;
      int_gundata{i}.pre_equ_time :=		curr_gundata{i}.pre_equ_time;
      int_gundata{i}.weld_timeout:= 		curr_gundata{i}.weld_timeout;
      int_gundata{i}.deflection_dist:= curr_gundata{i}.deflection_dist;
      int_gundata{i}.deflection_force:= curr_gundata{i}.deflection_force;
      int_gundata{i}.deflection_time:= curr_gundata{i}.deflection_time;
      int_gundata{i}.release_dist:=    curr_gundata{i}.release_dist;
      int_gundata{i}.curr_wear_fix:=   curr_gundata{i}.curr_wear_fix;
    ENDFOR
    DefIntGunData(SW_NOF_GUNS);

  ENDPROC

  ! Called in the beginnning of each SetForce instruction.
  PROC DefineForceData (forcedata Force, num GunNum)

    int_forcedata{GunNum}.tip_force:= 			Force.tip_force;
    int_forcedata{GunNum}.force_time:= 			Force.force_time;
    int_forcedata{GunNum}.plate_thickness:= 		Force.plate_thickness;
    int_forcedata{GunNum}.plate_tolerance:= 		Force.plate_tolerance;

  ENDPROC

  ! Called just before execution of SwPowerOn, SwStart or SwReStart.
  ! Also called in the beginning of all shell routines if they are
  ! not equal.
  PROC DefineSimData ()

    int_simdata.sim_type :=			curr_simdata.sim_type;
    int_simdata.sim_time :=			curr_simdata.sim_time;
    int_simdata.inhib_close :=			curr_simdata.inhib_close;
    int_simdata.no_plates :=			curr_simdata.no_plates;

  ENDPROC

!------------------------------------------------------
! U P D A T E  P R O C E S S  D A T A   R O U T I N E S
!------------------------------------------------------

  ! Update current tipwear in curr_gundata.
  ! Called at the end of each CalibL/J and Calib instruction.
  PROC UpdateCalibData (num CurrTipWear,
                        num RetPosAdj,
                        num GunNum
                        \switch ToolChg | switch TipChg | switch TipWear | switch FineCalib)
    VAR num tip_diff;
    VAR num tipwear_old;
    VAR num tip_wear;
    VAR num input_value;
    VAR bool wear_ratio:=FALSE;
    VAR string Txt_TipSize;
    VAR string Txt_Diff2LstTp;

    ! Update total tip wear in gundata
    tipwear_old := curr_gundata{GunNum}.curr_tip_wear;
    curr_gundata{GunNum}.curr_tip_wear :=	CurrTipWear;

    ! Check if wear of fixed tip is measured separately or determined by tip_wear_ratio
    IF curr_gundata{GunNum}.tip_wear_ratio>=0 AND curr_gundata{GunNum}.tip_wear_ratio<=100 THEN
      wear_ratio := TRUE;
    ENDIF
    
    IF Present(ToolChg) THEN
      ! Called after calibration after a change of the gun
      ! (CurrTipWear = total tip wear of both tips;
      !  RetPosAdj = difference to the last calibration of the gun)
      wear_moveable:=CurrTipWear-curr_gundata{GunNum}.curr_wear_fix;
    ELSEIF Present(FineCalib) THEN
      ! Called after fine calibration of the gun (ManServiceCalib, ServiceCalib)
      ! (CurrTipWear = measured wear after calibration;
      !  RetPosAdj = difference to the last calibration of the gun)
      wear_moveable:=CurrTipWear;
    ELSEIF Present(TipChg) THEN
      ! Called after calibration after a tip change
      ! (CurrTipWear = reset to 0;
      !  RetPosAdj = difference to the last calibration of the gun
      !              (total difference between new and old (worn) tips))
      wear_moveable:=0;
      IF wear_ratio THEN
        tip_diff:=RetPosAdj - tipwear_old;
        tw_ref_dist{GunNum,2}:=tw_ref_dist{GunNum,2}+tip_diff/2;
        Txt_TipSize:="New tips with unexpected size";
        Txt_Diff2LstTp:="Difference to last tips = ";
      ELSE
      tip_diff:=RetPosAdj - tipwear_old - (tw_ref_dist{GunNum,1}-tw_ref_dist{GunNum,2});
        Txt_TipSize:=TxtMovTipSize;
        Txt_Diff2LstTp:=TxtDiffMov2LstTp;
      ENDIF
      IF tip_diff>curr_gundata{GunNum}.tipchg_sup_pos OR tip_diff<curr_gundata{GunNum}.tipchg_sup_neg THEN
        ErrWrite TxtNewTipOutOfRg,Txt_TipSize
                 \RL2:=TxtDiffToLast + NumToStr(tip_diff,2)
                 \RL3:=TxtTipChgTol + NumToStr(curr_gundata{GunNum}.tipchg_sup_pos,2)
                 \RL4:="                      " + NumToStr(curr_gundata{GunNum}.tipchg_sup_neg,2);
        Stop;
      ELSE
        TPWrite Txt_Diff2LstTp + NumToStr(tip_diff,2);
      ENDIF
    ELSEIF Present(TipWear) THEN
      ! Called after a tip wear measurement
      ! (CurrTipWear = total wear of both tips;
      !  RetPosAdj = actual tip wear of both tips)
      IF CurrTipWear > curr_gundata{GunNum}.max_tip_wear THEN
        TPErase;
        TPWrite TxtTotTWReachMax;
        TPWrite TxtTotTipWrBoth + NumToStr(CurrTipWear,2);
        TPReadFK input_value,"","","","","","Ok";
      ENDIF
      IF wear_ratio THEN
        tip_wear:=CurrTipWear*(1-curr_gundata{GunNum}.tip_wear_ratio/100);
      ELSE
        tip_wear:=CurrTipWear-curr_gundata{GunNum}.curr_wear_fix;
      ENDIF
      tip_diff:=tip_wear - wear_moveable;
      wear_moveable:=tip_wear;
      IF tip_diff>curr_gundata{GunNum}.tipwear_sup_pos OR tip_diff<curr_gundata{GunNum}.tipwear_sup_neg THEN
        ErrWrite TxtTipWrOutOfRg,TxtActTipWearMov + NumToStr(tip_diff,2)
                 \RL2:=TxtTipWearTol + NumToStr(curr_gundata{GunNum}.tipwear_sup_pos,2)
                 \RL3:="                    " + NumToStr(curr_gundata{GunNum}.tipwear_sup_neg,2);
        Stop;
      ELSE
        TPWrite TxtActWearMov + NumToStr(tip_diff,2);
        TPWrite TxtTotWearMov + NumToStr(tip_wear,2);
        TPWrite TxtActTipWrBoth + NumToStr(CurrTipWear-tipwear_old,2);
        TPWrite TxtTotTipWrBoth + NumToStr(CurrTipWear,2);
      ENDIF
    ENDIF
  ENDPROC
  
  ! Update current fixed tipwear in curr_gundata.
  ! Called at the end of each MeasureWearL instruction.
  ! Return value status with: 1 = OK; 4 = Skip; 5 = Retry
  PROC UpdateFixTipData(num CurrTipWear,
                        num RetPosAdj,
                        num GunNum,
                        INOUT num status
                        \switch Reference |switch TipChange |switch TipWear |switch RefChange)
    
    status := 1;
    IF Present(Reference) THEN
      ! Called after reference measurement 
      ! (CurrTipWear=0, RetPosAdj = measured reference distance)
      TPWrite TxtMeasRefDist + NumToStr(RetPosAdj,2);
    ELSEIF Present(TipChange) THEN
      ! Called after reference measurement for a new fixed tip (after tip change)
      ! (CurrTipWear = 0; RetPosAdj = difference between actual tip and reference tip)
      ! check if the new tip is in tolerance
      IF RetPosAdj>curr_gundata{GunNum}.tipchg_sup_pos OR RetPosAdj<curr_gundata{GunNum}.tipchg_sup_neg THEN
        ErrWrite \W, TxtNewTipOutOfRg,TxtFixTipSize
                 \RL2:=TxtDiffToRefTip + NumToStr(RetPosAdj,2)
                 \RL3:=TxtTipChgTol + NumToStr(curr_gundata{GunNum}.tipchg_sup_pos,2)
                 \RL4:="                      " + NumToStr(curr_gundata{GunNum}.tipchg_sup_neg,2);
        TPErase;
        TPWrite TxtNewTipOutOfRg;
        TPWrite TxtFixTipSize;
        TPWrite TxtDiffToRefTip + NumToStr(RetPosAdj,2);
        TPWrite TxtTipChgTol + NumToStr(curr_gundata{GunNum}.tipchg_sup_pos,2);
        TPWrite "                      " + NumToStr(curr_gundata{GunNum}.tipchg_sup_neg,2);
        TPReadFK status,"","OK","","",TxtSkip,TxtRetry;
        TPErase;
      ENDIF
      IF status = 1 THEN
        TPWrite TxtDiffFixToRef + NumToStr(RetPosAdj,2);
      ENDIF
    ELSEIF Present(TipWear) THEN
      ! Called after each tip wear measurement
      ! (CurrTipWear = total wear fixed tip; RetPosAdj = actual wear fixed tip)
      ! check if actual tip wear is in tolerance
      IF RetPosAdj>curr_gundata{GunNum}.tipwear_sup_pos OR RetPosAdj<curr_gundata{GunNum}.tipwear_sup_neg THEN
        ErrWrite \W, TxtTipWrOutOfRg,TxtActTipWearFix + NumToStr(RetPosAdj,2)
                 \RL2:=TxtTipWearTol + NumToStr(curr_gundata{GunNum}.tipwear_sup_pos,2)
                 \RL3:="                    " + NumToStr(curr_gundata{GunNum}.tipwear_sup_neg,2);
        TPErase;
        TPWrite TxtTipWrOutOfRg;
        TPWrite TxtActTipWearFix + NumToStr(RetPosAdj,2);
        TPWrite TxtTipWearTol + NumToStr(curr_gundata{GunNum}.tipwear_sup_pos,2);
        TPWrite "                    " + NumToStr(curr_gundata{GunNum}.tipwear_sup_neg,2);   
        IF curr_gundata{GunNum}.tip_wear_ratio < 0 OR curr_gundata{GunNum}.tip_wear_ratio > 100 THEN
          ! called from MeasureWearL
          TPReadFK status,"","OK","","",TxtSkip,TxtRetry;
        ELSE
          ! called from ReCalcTCP
          TPReadFK status,"","OK","","",TxtSkip,"";
        ENDIF
        TPErase;
      ENDIF
      IF status =1 THEN
        TPWrite TxtActWearFixTip + NumToStr(RetPosAdj,2);
        TPWrite TxtTotwearFixTip + NumToStr(CurrTipWear,2);
      ENDIF
    ELSEIF Present(RefChange) THEN
      ! Called after new reference measurement when reference surface was moved
      ! (CurrTipWear = total wear fixed tip; RetPosAdj = difference between actual and old tip reference)
      TPWrite TxtMeasRefDist + NumToStr(RetPosAdj,2);
    ENDIF

    ! Update tip wear of fixed tip in gundata only if status = OK
    IF status = 1 curr_gundata{GunNum}.curr_wear_fix := CurrTipWear;
    
  ENDPROC

  ! Update curr_spotdata.
  ! Called at the start of motion.
  PROC UpdateSpotData (z_int_spotdata Spot, num GunNum)

    curr_spotdata{GunNum}.prog_no :=		Spot.prog_no;
    curr_spotdata{GunNum}.tip_force :=		Spot.tip_force;
    curr_spotdata{GunNum}.plate_thickness :=	Spot.plate_thickness;
    curr_spotdata{GunNum}.plate_tolerance :=	Spot.plate_tolerance;

  ENDPROC

ENDMODULE
