Hi,
ich arbeite gerade an einem G-Code Interpreter auf Basis eines ATXMEGA32A4, programmiert wird in C (AVR Studio). Der µC soll nur Takt / Richtungssignale ausgeben und soll in Zukunft bis zu 6 Achsen "gleichzeitig" handeln können. Ich bin gerade dabei, die Helix-Berechnung zu implementieren. Hab mir dazu einige Gedanken gemacht (auch speziell zum Thema FeedRate) und möchte wissen, was ihr davon haltet bzw. obs funktionieren KANN.
Input sieht z.b. so aus:
Code:
G00 X0 Y0 Z0 //Gehe auf (0/0/0)
G02 X20 Y0 Z0 I10 J0 K0 F600 //Halbkreis von (0/0/0) auf (20/0/0) um (10/0/0) mit Feedrate = 600(mm/min)
Hier mal meine Routine:
Code:
void ProcessArc(PunkteVektor StartPunkt , PunkteVektor EndPunkt , ArcParams Vars , Ebene ArbeitsEbene , uint16_t Feedrate)
{
//
float StartAngle;
float EndAngle;
float Angle;
float AngleStep;
//Feedrate
float WegArc;
float FeedrateMMS;
float TimeArc;
float AngleVelocityArc;
float FeedrateTime;
//
uint8_t StepMade;
float TmpSingle;
//
uint16_t TimeHigh = 20;
//the following is only correct for XY-Arbeitsebene
//Calculate Radius for later use
if(Vars.R==0) {Vars.R = sqrt((Vars.I*Vars.I)+(Vars.J*Vars.J));}
//Calculate IJK for later use
if((Vars.I==0) && (Vars.J==0) && (Vars.K==0)) {Vars.I = Vars.J = (sqrt(2)/2)*Vars.R;}
//Calculate StartingAngle
StartAngle = atan2f(Vars.I,Vars.J) * 57.2957795; //evtl. needs some modification
EndAngle = atan2f(-Vars.I,-Vars.J) * 57.2957795;
Angle = StartAngle;
//choose which Axis has the smallest Step
OneStep.Smallest = OneStep.X;
if(OneStep.Smallest<OneStep.Y) {OneStep.Smallest = OneStep.Y;}
//Calculate AngleStep
AngleStep = acos(((Vars.R*Vars.R)+(Vars.R*Vars.R)-((0.707106*OneStep.Smallest)*(0.707106*OneStep.Smallest)))/(2*Vars.R*Vars.R)); //0.707106 = (sqrt(2)/2)
//DEBUG
AngleStep = 0.05;
//gesamter Weg in Arbeitsebene (XY)
WegArc = 3.14159265359 * Vars.R * ((fabs(EndAngle)-fabs(StartAngle))/180); //evtl. ohne fabs()
FeedrateMMS = Feedrate / 60;
TimeArc = WegArc / FeedrateMMS;
AngleVelocityArc = (fabs(EndAngle)-fabs(StartAngle))/TimeArc; //evtl. ohne fabs()
FeedrateTime = (1/(AngleVelocityArc/AngleStep))*1000000;
//Arc Test Nr. 2
while(fabs(EndAngle-Angle)>=AngleStep)
{
StepMade = 0;
//deside in which direction to go
if(Vars.Dir==0) {Angle -= AngleStep;} //CW
else if(Vars.Dir==1) {Angle += AngleStep;} //CCW
Angle = fmod(Angle,360); //Angle %= 360;
//Calculate X & Y & Z Delta
Delta.X = cos((Angle*0.01745329))*Vars.R - Position.X;
Delta.Y = sin((Angle*0.01745329))*Vars.R - Position.Y;
Delta.Z = (((Angle-StartAngle)/(EndAngle-StartAngle))*(EndPunkt.Z-StartPunkt.Z))-Position.Z; //evtl. VZ beachten
//Generate Stepper-Signals
if(Delta.X>=OneStep.X)
{
Position.X += OneStep.X;
PORTD.OUTSET = 0x02;
PORTD.OUTSET = 0x01;
WaitUs(TimeHigh); //5
PORTD.OUTCLR = 0x01;
StepMade += 1;
}else if(Delta.X<=-OneStep.X)
{
Position.X -= OneStep.X;
PORTD.OUTCLR = 0x02;
PORTD.OUTSET = 0x01;
WaitUs(TimeHigh); //5
PORTD.OUTCLR = 0x01;
StepMade += 1;
}
if(Delta.Y>=OneStep.Y)
{
Position.Y += OneStep.Y;
PORTD.OUTSET = 0x08;
PORTD.OUTSET = 0x04;
WaitUs(TimeHigh); //5
PORTD.OUTCLR = 0x04;
StepMade += 1;
}else if(Delta.Y<=-OneStep.Y)
{
Position.Y -= OneStep.Y;
PORTD.OUTCLR = 0x08;
PORTD.OUTSET = 0x04;
WaitUs(TimeHigh); //5
PORTD.OUTCLR = 0x04;
StepMade += 1;
}
if(Delta.Z>=OneStep.Z)
{
Position.Z += OneStep.Z;
PORTD.OUTSET = 0x20;
PORTD.OUTSET = 0x10;
WaitUs(TimeHigh); //5
PORTD.OUTCLR = 0x10;
StepMade += 1;
}else if(Delta.Z<=-OneStep.Z)
{
Position.Z -= OneStep.Z;
PORTD.OUTCLR = 0x20;
PORTD.OUTSET = 0x10;
WaitUs(TimeHigh); //5
PORTD.OUTCLR = 0x10;
StepMade += 1;
}
//FeedRate
if(StepMade>=1)
{
TmpSingle = FeedrateTime - (StepMade*TimeHigh); //15 <==> High-Time Step-Signal
if(TmpSingle<0) {TmpSingle=0;}
WaitUs((uint16_t)TmpSingle);
}else
{
WaitUs((uint16_t)FeedrateTime);
}
}
}
Wäre nett, wenn jemand mal drüberschauen würde!
Vielen Dank & Gruß
Chris
Lesezeichen