Jogging past soft limits
Posted: 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;
}
}
}
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;
}
}
}