Jogging past soft limits

Moderators: TomKerekes, dynomotion

Post Reply
boss4
Posts: 15
Joined: Sun Apr 29, 2018 9:36 pm

Jogging past soft limits

Post by boss4 » Sat Jul 29, 2023 11:41 pm

The application is a 3 axis mill with servos.

The machine can jog past soft limits, depending on the jogging speed. This hasn't been a problem in the past. I have just set the soft limits far enough from the hard limit switches that it couldn't happen (1/2in or so).

Recently i have been making things that are stretching the size limits for the machine and so I need the extra in that I am losing. I want to set the soft limits to be just before the hard limit switches (~.1 inch) or so but if I jog hard enough I know I can crash the machine into the hard stops at the ends of the ball screws.

Is there a better option to fix this?

Below is the axis setup code I am using. I could probably increase the jerk and acceleration some:


// params to change
#define maxyin 11
//note, zero is .5 inches after limit switch.
#define minyin 0
#define maxzin 0
#define minzin -4
#define maxxin 17
#define minxin 0
#define maxerrorxin .001
#define maxerroryin .001
#define maxerrorzin .001

#define xrapidips 4.5
#define yrapidips 4.5
#define zrapidips 2.5
#define xaccelips2 16
#define yaccelips2 16
#define zaccelips2 16

#define jerktimexms .0002
#define jerktimeyms .0002
#define jerktimezms .0002
// counts per inch
#define cntx 18720
#define cnty 18720
#define cntz 18720
// BACKLASH_OFF
#define backxin 0.00084
#define backyin 0.00085
#define backzin 0.0007

//lim switches
#define estop 136
#define zlim_dn 142
#define zlim_up 143
#define xlim 141
#define ylim 140
#define x 0
#define y 1
#define z 2
#define a -1

void setup(int disable_x_limits, int disable_y_limits, int disable_z_limits){
ClearStopImmediately();


DefineCoordSystem(x,y,z,a);
FPGA(STEP_PULSE_LENGTH_ADD)= 32 ;

ch0->InputMode=ENCODER_MODE;
ch0->OutputMode=CL_STEP_DIR_MODE;
ch0->Vel=cntx*xrapidips;
ch0->Accel=cntx*xaccelips2;
ch0->Jerk= (cntx*xaccelips2)/jerktimexms;
ch0->P=0.1;
ch0->I=0.018;

ch0->D=0.000;
ch0->FFAccel=0;
ch0->FFVel=0;
ch0->MaxI=400;
ch0->MaxErr=maxerrorxin*cntx;
ch0->MaxOutput=400;
ch0->DeadBandGain=0;
ch0->DeadBandRange=2;
ch0->InputChan0=0;
ch0->InputChan1=0;
ch0->OutputChan0=20;
ch0->OutputChan1=1;
ch0->MasterAxis=-1;
ch0->LimitSwitchOptions=0x11f;
ch0->LimitSwitchNegBit=xlim;
ch0->LimitSwitchPosBit=xlim;
ch0->SoftLimitPos=maxxin*cntx;
ch0->SoftLimitNeg=minxin*cntx;
ch0->InputGain0=-.5;
ch0->InputGain1=0;
ch0->InputOffset0=0;
ch0->InputOffset1=0;
ch0->OutputGain=1;
ch0->OutputOffset=0;
ch0->SlaveGain=1;
ch0->BacklashMode=BACKLASH_OFF; //BACKLASH_LINEAR
ch0->BacklashAmount=backxin *cntx;
ch0->BacklashRate=10000;
ch0->invDistPerCycle=0;
ch0->Lead=0;
ch0->MaxFollowingError=maxerroryin*cnty;
ch0->StepperAmplitude=20;

ch0->iir[0].B0=1;
ch0->iir[0].B1=0;
ch0->iir[0].B2=0;
ch0->iir[0].A1=0;
ch0->iir[0].A2=0;

ch0->iir[1].B0=1;
ch0->iir[1].B1=0;
ch0->iir[1].B2=0;
ch0->iir[1].A1=0;
ch0->iir[1].A2=0;

ch0->iir[2].B0=0.000768788;
ch0->iir[2].B1=0.00153758;
ch0->iir[2].B2=0.000768788;
ch0->iir[2].A1=1.92076;
ch0->iir[2].A2=-0.923833;

ch1->InputMode=ENCODER_MODE;
ch1->OutputMode=CL_STEP_DIR_MODE;
ch1->Vel=cnty*yrapidips;
ch1->Accel=cnty*yaccelips2;
ch1->Jerk= (cnty*yaccelips2)/jerktimeyms;
ch1->P=0.1;
ch1->I=0.01;
ch1->D=0;
ch1->FFAccel=0;
ch1->FFVel=0;
ch1->MaxI=400;
ch1->MaxErr=maxerroryin*cnty;
ch1->MaxOutput=400;
ch1->DeadBandGain=0;
ch1->DeadBandRange=2;
ch1->InputChan0=3;
ch1->InputChan1=0;
ch1->OutputChan0=21;
ch1->OutputChan1=0;
ch1->MasterAxis=-1;
ch1->LimitSwitchOptions=0x11f;
ch1->LimitSwitchNegBit=ylim;
ch1->LimitSwitchPosBit=ylim;
ch1->SoftLimitPos=maxyin*cnty;
ch1->SoftLimitNeg=minyin*cnty;
ch1->InputGain0=-.5;
ch1->InputGain1=0;
ch1->InputOffset0=0;
ch1->InputOffset1=0;
ch1->OutputGain=1;
ch1->OutputOffset=0;
ch1->SlaveGain=1;
ch1->BacklashMode=BACKLASH_OFF; //BACKLASH_LINEAR
ch1->BacklashAmount=backyin *cnty;
ch1->BacklashRate=10000;
ch1->invDistPerCycle=0;
ch1->Lead=0;
ch1->MaxFollowingError=maxerroryin*cnty;
ch1->StepperAmplitude=20;

ch1->iir[0].B0=1;
ch1->iir[0].B1=0;
ch1->iir[0].B2=0;
ch1->iir[0].A1=0;
ch1->iir[0].A2=0;
ch1->iir[1].B0=1;
ch1->iir[1].B1=0;
ch1->iir[1].B2=0;
ch1->iir[1].A1=0;
ch1->iir[1].A2=0;

ch1->iir[2].B0=0.000769;
ch1->iir[2].B1=0.001538;
ch1->iir[2].B2=0.000769;
ch1->iir[2].A1=1.92081;
ch1->iir[2].A2=-0.923885;



ch2->InputMode=ENCODER_MODE;
ch2->OutputMode=CL_STEP_DIR_MODE;
ch2->Vel=cntz*zrapidips;
ch2->Accel=cntz*zaccelips2;
ch2->Jerk= (cntz*zaccelips2)/jerktimezms;
ch2->P=0.1;
ch2->I=0.01;

ch2->D=0.002;
ch2->FFAccel=0;
ch2->FFVel=0;
ch2->MaxI=400;
ch2->MaxErr=maxerrorzin*cntz;
ch2->MaxOutput=400;
ch2->DeadBandGain=0;
ch2->DeadBandRange=2;
ch2->InputChan0=2;
ch2->InputChan1=0;
ch2->OutputChan0=22;
ch2->OutputChan1=0;
ch2->MasterAxis=-1;
ch2->LimitSwitchOptions=0x11f;
ch2->LimitSwitchNegBit=zlim_dn;
ch2->LimitSwitchPosBit=zlim_up;
ch2->SoftLimitPos=maxzin*cntz;
ch2->SoftLimitNeg=minzin*cntz;
ch2->InputGain0=.5;
ch2->InputGain1=0;
ch2->InputOffset0=0;
ch2->InputOffset1=0;
ch2->OutputGain=-1;
ch2->OutputOffset=0;
ch2->SlaveGain=1;
ch2->BacklashMode=BACKLASH_OFF; //BACKLASH_LINEAR
ch2->BacklashAmount=backzin *cntz;
ch2->BacklashRate=10000;
ch2->invDistPerCycle=0;
ch2->Lead=0;
ch2->MaxFollowingError=maxerrorzin*cntz;
ch2->StepperAmplitude=20;

ch2->iir[0].B0=1;
ch2->iir[0].B1=0;
ch2->iir[0].B2=0;
ch2->iir[0].A1=0;
ch2->iir[0].A2=0;
ch2->iir[1].B0=1;
ch2->iir[1].B1=0;
ch2->iir[1].B2=0;
ch2->iir[1].A1=0;
ch2->iir[1].A2=0;

ch2->iir[2].B0=0.056495;
ch2->iir[2].B1=0.112989;
ch2->iir[2].B2=0.056495;
ch2->iir[2].A1=1.22565;
ch2->iir[2].A2=-0.451634;

if (!disable_x_limits && !disable_y_limits && !disable_z_limits){

EnableAxisDest(x,ch0->Dest);
EnableAxisDest(y,ch1->Dest);
EnableAxisDest(z,ch2->Dest);
printf("enabled all machine axis \n");
}
else{
if (disable_x_limits || disable_y_limits || disable_z_limits){

printf("disabled soft limits\n");

ClearBit(disable_x_limits);
ClearBit(disable_y_limits);
ClearBit(disable_z_limits);


ch0->SoftLimitPos=10e8;
ch0->SoftLimitNeg=-10e8;
ch1->SoftLimitPos=10e8;
ch1->SoftLimitNeg=-10e8;
ch2->SoftLimitPos=10e8;
ch2->SoftLimitNeg=-10e8;


//EnableAxisDest(x,ch0->Position);
//EnableAxisDest(x,ch1->Position);
//EnableAxisDest(x,ch2->Position);

ch0->LimitSwitchNegBit=estop;
ch0->LimitSwitchPosBit=estop;
ch1->LimitSwitchNegBit=estop;
ch1->LimitSwitchPosBit=estop;
ch2->LimitSwitchNegBit=estop;
ch2->LimitSwitchPosBit=estop;
}

}


}

User avatar
TomKerekes
Posts: 2604
Joined: Mon Dec 04, 2017 1:49 am

Re: Jogging past soft limits

Post by TomKerekes » Sun Jul 30, 2023 5:54 pm

There is an example AdjustSoftLimits.c that contains a function to stop based on acceleration and velocity to properly stop at the SoftLimits and AdjustSoftLimitsTest.c can be used to test it. After it is working it can be added to the forever loop in your Init Program.
Regards,

Tom Kerekes
Dynomotion, Inc.

boss4
Posts: 15
Joined: Sun Apr 29, 2018 9:36 pm

Re: Jogging past soft limits

Post by boss4 » Wed Aug 02, 2023 5:41 am

That worked great!!

User avatar
TomKerekes
Posts: 2604
Joined: Mon Dec 04, 2017 1:49 am

Re: Jogging past soft limits

Post by TomKerekes » Wed Aug 02, 2023 8:58 pm

Great. Thanks for taking the time to post back.
Regards,

Tom Kerekes
Dynomotion, Inc.

Post Reply