program gcodegenerator; uses SysUtils, StrUtils, Math; type TPoint = record X, Y: double; end; type TStatorParams = record StatorName: String; BaseDiameter: Double; BaseRadius: Double; NumberOfRays: Integer; RayShape: string; RayDiameter: Double; RayWidth: Double; RayHeight: Double; RayLength: Double; RayTopShape: string; RayTopDiameter: Double; RayTopWidth: Double; RayTopHeight: Double; RayCenterOffset: Double; WireDiameter: Double; NeedleDiameter: Double; PathClearance: Double; WorkSpeed :integer; end; type TLayer = record Turns: Integer; // ���������� ������ StartZ: double; // ��������� ���������� EndZ: double; // �������� ���������� end; var StartTime, EndTime, ExecutionTime: TDateTime; InputFileName, OutputFileName, CoilGeometryFileName: string; StatorParams: TStatorParams; InFile, OutFile, CoilGeometryFile: TextFile; Line: string; CoilRadius,CoilWidth,CoilHeight :double; CurrentZ: double; coords: TPoint; normalizecoords: TPoint; Layers: array[1..10] of TLayer; i, j, k: Integer; CoilLength :double; CurrentCoilTurns, CoilTurnsSum :Integer; AngleBetweenRays :double; RequiredSpacing: Double; LayerNumber :Integer; MaxLayers :Integer; angle :double; MaxDepth,MaxPath :double; MoveForward:boolean; OperationMode:string; function ParseLine(Line: string): Boolean; var Parts: array of string; Value: string; TrimmedLine: string; begin TrimmedLine := Trim(Line); // ������� ������� � ������ � ����� ������ if Length(TrimmedLine) = 0 then begin exit(true); // ������ ������ - ���������� end else if TrimmedLine[1] in [';','#'] then begin exit(true); // ������ ����������� - ���������� end; Parts := SplitString(TrimmedLine, '='); // ���������� TrimmedLine Result := Length(Parts) = 2; if Result then begin Value := LowerCase(Trim(Parts[1])); // �������� � ������� �������� case Trim(Parts[0]) of 'stator_name': begin StatorParams.StatorName := Value; writeln('StatorName: ', StatorParams.StatorName); writeln(); end; 'Operation_Mode': begin OperationMode := Value; writeln('Operation Mode: ', OperationMode); writeln(); end; 'base_dia': begin StatorParams.BaseDiameter := StrToFloat(Value); writeln('Base Diameter: ', StatorParams.BaseDiameter:8:2); writeln(); StatorParams.BaseRadius := StatorParams.BaseDiameter/2; writeln('Base Radius: ', StatorParams.BaseRadius:8:2); writeln(); end; 'num_rays': begin StatorParams.NumberOfRays := StrToInt(Value); writeln('Number of Rays: ', StatorParams.NumberOfRays); AngleBetweenRays := 360/StatorParams.NumberOfRays; writeln('Angle Between Rays: ', AngleBetweenRays); writeln(); end; 'ray_shape': begin if Pos(Value, 'circle, rect, superellipse') = 0 then raise Exception.Create('Invalid value for ray_shape: ' + Value); StatorParams.RayShape := Value; writeln('Ray Shape: ', StatorParams.RayShape); writeln(); end; 'ray_dia': begin StatorParams.RayDiameter := StrToFloat(Value); writeln('Ray Diameter: ', StatorParams.RayDiameter:8:2); writeln(); end; 'ray_w': begin StatorParams.RayWidth := StrToFloat(Value); writeln('Ray Width: ', StatorParams.RayWidth:8:2); writeln(); end; 'ray_h': begin StatorParams.RayHeight := StrToFloat(Value); writeln('Ray Height: ', StatorParams.RayHeight:8:2); writeln(); end; 'ray_len': begin StatorParams.RayLength := StrToFloat(Value); writeln('Ray Length: ', StatorParams.RayLength:8:2); writeln(); end; 'raytop_shape': begin if Pos(Value, 'circle, rect, superellipse') = 0 then raise Exception.Create('Invalid value for ray_top: ' + Value); StatorParams.RayTopShape := Value; writeln('Ray Top Shape: ', StatorParams.RayTopShape); end; 'raytop_dia': begin StatorParams.RayTopDiameter := StrToFloat(Value); writeln('Ray Top Diameter: ', StatorParams.RayTopDiameter:8:2); writeln(); end; 'raytop_w': begin StatorParams.RayTopWidth := StrToFloat(Value); writeln('Ray Top Width: ', StatorParams.RayTopWidth:8:2); writeln(); end; 'raytop_h': begin StatorParams.RayTopHeight := StrToFloat(Value); writeln('Ray Top Height: ', StatorParams.RayTopHeight:8:2); writeln(); end; 'ray_offset': begin StatorParams.RayCenterOffset := StrToFloat(Value); writeln('Ray Center Offset: ', StatorParams.RayCenterOffset:8:2); writeln(); end; 'wire_diameter': begin StatorParams.WireDiameter := StrToFloat(Value); writeln('Wire Diameter: ', StatorParams.WireDiameter:8:2); writeln(); end; 'needle_diameter': begin StatorParams.NeedleDiameter := StrToFloat(Value); writeln('Needle Diameter: ', StatorParams.NeedleDiameter:8:2); writeln(); end; 'path_clearance': begin StatorParams.PathClearance := StrToFloat(Value); writeln('Path Clearance: ', StatorParams.PathClearance:8:2); writeln(); end; 'work_speed': begin StatorParams.WorkSpeed := StrToInt(Value); writeln('Work Speed: ', StatorParams.WorkSpeed); writeln(); end; else Result := False; end; if not Result then begin writeln('Error: Unknown parameter: ', Parts[0]); exit; end; end; end; procedure ReadInputFile(); Begin // **Opening the input file** AssignFile(InFile, InputFileName); try Reset(InFile); // **This line opens the file for reading** while not EOF(InFile) do begin ReadLn(InFile, Line); if Length(Line) > 0 then if not ParseLine(Line) then writeln('Error: Invalid line: ', Line); end; except on E: Exception do begin writeln('Error opening or reading input file: ', E.Message); Halt(1); end; end; CloseFile(InFile); end; function CircleCoordinates(diameter, angleDegrees: Double): TPoint; var radius: Double; angleRadians: Double; begin radius := diameter / 2; // angleRadians := -1*angleDegrees * PI / 180; // ������� �������� � ������� angleRadians := -1 * DegToRad(angleDegrees); Result.X := radius * Cos(angleRadians); Result.Y := radius * Sin(angleRadians); end; function CalculateAngle(opposite, adjacent: Double): Double; begin if adjacent = 0 then raise Exception.Create('Adjacent side cannot be zero'); // CalculateAngle := ArcTan(opposite / adjacent) * 180 / PI; CalculateAngle := RadToDeg(ArcTan(opposite / adjacent)); end; function NormalizeZ(radius: Real; thetaDeg: Real): Real; var thetaRad, alphaRad, xKas, yKas, mTang, bTang: Real; begin // 1. �������������� ���� �� �������� � �������. thetaRad := DegToRad(thetaDeg); // 2. ���������� ��������� ����� ������� �� ���������� (������������ ������ 0,0). xKas := radius * Cos(thetaRad); yKas := radius * Sin(thetaRad); // 3. ���������� ����, ����������������� ������-������� (�����������). alphaRad := thetaRad + PI / 2; // 4. ���������� �������� ������������ �����������. mTang := Tan(alphaRad); // 5. ���������� ���������� ����� ��������� ����������� (y = mTang * x + bTang). bTang := yKas - mTang * xKas; // 6. ���������� ���������� X ����� ����������� ����������� � ���� X (y = 0). // 0 = mTang * x + bTang // x = -bTang / mTang if mTang = 0 then begin // ����������� ����������� ��� X - ��� ����� �����������. ���������� NaN. NormalizeZ := NaN; end else begin NormalizeZ := -bTang / mTang; end; end; function DepthCheck(thickness, lineLength, angleDeg: double): double; var xIntersection, distanceToIntersection, radius: double; begin xIntersection := (thickness/2 + thickness/2 * cos(DegToRad(angleDeg)))/sin(DegToRad(angleDeg)); distanceToIntersection := sqrt(sqr(xIntersection) + sqr(1.2)); radius := lineLength / (2 * tan(DegToRad(angleDeg) / 2)); DepthCheck := distanceToIntersection + radius; end; function CalculateMaxPath(length, width, angleDegrees: double): double; //������� ��������� ������������ ���������� ����� ������. ��� ����� �� ������ ������� �� var topLeftX, topLeftY, rotatedX, rotatedY, angleRadians, distance: double; begin // ��������� ���������� �������� ������ ���� �������������� topLeftX := -length; topLeftY := width / 2; // ����������� ���� � ������� (� ������ �������� �� ������� �������) angleRadians := degToRad(-angleDegrees); // ��������� ���������� ����������� ������� ������ ���� ������� �������������� rotatedX := -length * cos(angleRadians) - (-width / 2) * sin(angleRadians); rotatedY := -length * sin(angleRadians) + (-width / 2) * cos(angleRadians); // ��������� ���������� ����� ������� distance := sqrt(sqr(rotatedX - topLeftX) + sqr(rotatedY - topLeftY)); // ���������� ��������� MaxPath := distance; end; procedure CalculateCoilGeometry(); var StartZ, EndZ: double; begin writeln('CalculateCoilGeometry'); AssignFile(CoilGeometryFile, CoilGeometryFileName); try Rewrite(CoilGeometryFile); //�������, ������� ���� ����� ��������. MaxPath:=CalculateMaxPath((StatorParams.RayLength+StatorParams.BaseRadius), StatorParams.RayWidth, AngleBetweenRays); //writeln(CoilGeometryFile, ';MaxPath:', MaxPath); //MaxLayers :=trunc(((MaxPath-RequiredSpacing)/2/StatorParams.WireDiameter)); MaxLayers :=round((MaxPath-StatorParams.NeedleDiameter)/2/(StatorParams.WireDiameter+RequiredSpacing)); if (MaxLayers mod 2 <> 0) then writeln(CoilGeometryFile, ';MaxLayers ', MaxLayers) else begin dec(MaxLayers); writeln(CoilGeometryFile, ';�alculations resulted in MaxLayers=', MaxLayers+1, ' because it is even, MaxLayers=MaxLayers-1 and equal ',MaxLayers); end; MoveForward:=true; for i := 1 to MaxLayers do begin write(CoilGeometryFile, ';Lair:', i, ' have '); //������� ����� ������� � ���������� ������ //��� ����� ������� ����������� ���������� ����� ������. 2 �������� ������� + ������� ���� + 2 ������ ������������ RequiredSpacing:=StatorParams.PathClearance*2+(i-1)*StatorParams.WireDiameter*2+StatorParams.NeedleDiameter; //��������� ����������� ����������, ������������ �� �����, ������������ ������� ����� ����������� ������. (���������� �� ������ �������) MaxDepth:=DepthCheck(StatorParams.RayWidth, RequiredSpacing, AngleBetweenRays); //writeln(OutFile, ';RayWidth ', StatorParams.RayWidth:0:5); //writeln(OutFile, ';RequiredSpacing ', RequiredSpacing:0:5); //writeln(OutFile, ';AngleBetweenRays ', AngleBetweenRays:0:5); //writeln(CoilGeometryFile, ';MaxDepth ', MaxDepth:0:5); //writeln(OutFile); //���� ���������� ������� ������, ��� ������� ���������, ����� ����� ������� ����� ����� ����. //���� ���������� ������� ������, ��� ������� + ����� ����, ���������� ����. //����� ����� ������� ����� "������_��������� + �����_���� - �������) If (MaxDepth < (StatorParams.BaseRadius)) then CoilLength:=StatorParams.RayLength else if (MaxDepth > (StatorParams.RayLength+StatorParams.BaseRadius)) then break else CoilLength:=StatorParams.RayLength+StatorParams.BaseRadius-MaxDepth; //writeln(CoilGeometryFile, '!!!'); write(CoilGeometryFile, CoilLength:0:5, 'mm '); //CurrentCoilTurns := ceil(CoilLength/StatorParams.WireDiameter); //������ �� ����� ������� ������� ���������� ������. � ���������� ������� ����� ������ �� �������. CurrentCoilTurns := round(CoilLength/StatorParams.WireDiameter); write(CoilGeometryFile, CurrentCoilTurns, ' Turns'); CoilTurnsSum := CoilTurnsSum+CurrentCoilTurns; //����� ������ ����� ����� ����������� ���������� Z //writeln(CoilGeometryFile,' StartZ=',CurrentZ:0:5); // if (MoveForward = false) then CurrentZ:=StatorParams.RayLength+StatorParams.BaseRadius-StatorParams.WireDiameter/2 // else CurrentZ:=StatorParams.RayLength+StatorParams.BaseRadius-StatorParams.WireDiameter*(CurrentCoilTurns-0.5); if (MoveForward = false) then StartZ:=StatorParams.RayLength+StatorParams.BaseRadius-StatorParams.WireDiameter/2 else StartZ:=StatorParams.RayLength+StatorParams.BaseRadius-StatorParams.WireDiameter*(CurrentCoilTurns-0.5); write(CoilGeometryFile,' NewStartZ=',StartZ:0:5); if (MoveForward = true) then EndZ:=StartZ+StatorParams.WireDiameter*CurrentCoilTurns else EndZ:=StartZ-StatorParams.WireDiameter*CurrentCoilTurns; writeln(CoilGeometryFile,' EndZ=',EndZ:0:5); //Inc(LayerNumber); CoilWidth:=CoilWidth+StatorParams.WireDiameter*2; MoveForward:= not MoveForward; //writeln(CoilGeometryFile,';MoveForward: ', MoveForward); //writeln(CoilGeometryFile); writeln(CoilGeometryFile, CurrentCoilTurns, ' ',StartZ:0:5, ' ',EndZ:0:5); Layers[i].Turns := CurrentCoilTurns; Layers[i].StartZ := StartZ; Layers[i].EndZ := EndZ; end; writeln(CoilGeometryFile); writeln(CoilGeometryFile,';CoilTurnsSum: ', CoilTurnsSum); except on E: Exception do begin writeln('Error writing to coil_geometry file: ', E.Message); Halt(1); end; end; CloseFile(CoilGeometryFile); end; procedure ReadCoilGeometry(); var // Parts: array of string; // Value: string; TrimmedLine: string; line: string; count, i, turns: Integer; startZ: float; endZ: float; spacePos: Integer; err: Integer; begin writeln('ReadCoilGeometry'); AssignFile(CoilGeometryFile, CoilGeometryFileName); try Reset(CoilGeometryFile); // **This line opens the file for reading** i := 0; while not EOF(CoilGeometryFile) do begin //writeln('!!!'); ReadLn(CoilGeometryFile, Line); if Length(Line) > 0 then begin TrimmedLine := Trim(Line); // ������� ������� � ������ � ����� ������ if (Length(TrimmedLine) = 0) then continue //exit() // ������ ������ - ���������� else if TrimmedLine[1] in [';','#'] then continue; // exit(); // ������ ����������� - ���������� inc(i); spacePos := Pos(' ', TrimmedLine); //writeln(spacePos); //writeln('!', TrimmedLine); Val(Copy(TrimmedLine, 1, spacePos - 1), turns, err); spacePos := 1 + spacePos; //writeln('? ',spacePos); //i:=1; TrimmedLine:=Copy(TrimmedLine, spacePos, Length(TrimmedLine)); spacePos := Pos(' ',TrimmedLine); //writeln(spacePos); //writeln('!!', TrimmedLine); Val(Copy(TrimmedLine, 1, spacePos - 1), startZ, err); TrimmedLine:=Copy(TrimmedLine, spacePos, Length(TrimmedLine)); //writeln('!!!', TrimmedLine); spacePos := Pos(' ',TrimmedLine); //writeln(spacePos); Val(Copy(TrimmedLine, 1, Length(TrimmedLine)), endZ, err); writeln('layer:',i,' turns:', turns,' startX:', startZ:0:3,' endX:', endZ:0:3); Layers[i].Turns := turns; Layers[i].StartZ := StartZ; Layers[i].EndZ := EndZ; //for i := 1 to CurrentCoilTurns do //begin // writeln(Layers[i].Turns,Layers[i].StartZ,Layers[i].EndZ); //end; //MaxLayers //writeln(); end; //if not ParseLine(Line) then // writeln('Error: Invalid line: ', Line); end; MaxLayers:=i; except on E: Exception do begin writeln('Error opening or reading Coil Geometry File: ', E.Message); Halt(1); end; end; CloseFile(CoilGeometryFile); end; begin // Command line argument handling StartTime := Now; if ParamCount < 3 then begin Writeln('Usage: GCodeGenerator '); Halt(1); end; InputFileName := ParamStr(1); OutputFileName := ParamStr(2); CoilGeometryFileName := ParamStr(3); ReadInputFile(); // G-code generation AssignFile(OutFile, OutputFileName); try Rewrite(OutFile); // *** Your G-code generation logic here *** writeln(OutFile, ';Generate G-code file for ',StatorParams.StatorName,' stator. At ',FormatDateTime('dd.mm.yyyy hh:nn:ss.zzz', StartTime)); writeln(OutFile, '; G-code for stator winding'); writeln(OutFile, 'G90 ; Absolute coordinate system'); writeln(OutFile, 'G1 Y-10'); writeln(OutFile, 'G28 X Y Z'); writeln(OutFile, 'G1 X0 Y0'); //writeln(OutFile, 'G28 O'); //Home all "untrusted" axes writeln(OutFile); // Move to center of ray along Y axis and reset coordinate writeln(OutFile, 'G1 X', StatorParams.RayCenterOffset:0:2); writeln(OutFile, 'G92 X0'); //������� ���� ����� � ���� ������� ���� CoilRadius:=(StatorParams.RayTopHeight/2+StatorParams.NeedleDiameter/2+StatorParams.PathClearance); CoilWidth:=(StatorParams.RayTopWidth+StatorParams.NeedleDiameter+StatorParams.PathClearance*2); CoilHeight:=(StatorParams.RayTopHeight+StatorParams.NeedleDiameter+StatorParams.PathClearance*2); writeln(OutFile, ';CoilRadius = ', CoilRadius:0:3); writeln(OutFile, ';CoilWidth = ', CoilWidth:0:3); writeln(OutFile, ';CoilHeight = ', CoilHeight:0:3); writeln(OutFile, 'G1 X', -1*CoilHeight/2:0:3, ' Y',-1*AngleBetweenRays/2:0:3); //������������ � ��������� �������. CurrentZ:=(StatorParams.BaseDiameter/2)+StatorParams.PathClearance; writeln(OutFile, 'G1 Z', CurrentZ:0:2, ' F', StatorParams.WorkSpeed); //����� �� ����� ��� ����, ����� ��������� ����� ��������� writeln(OutFile, 'M0'); if (OperationMode = 'auto') then CalculateCoilGeometry() else if (OperationMode = 'manual') then ReadCoilGeometry() else begin writeln('Error determining operation mode.'); writeln('You should use auto or manual.'); Readln; Halt(1); end; writeln(); writeln(OutFile, ';Information about layers'); writeln(OutFile, ';MaxLayers: ', MaxLayers); for i := 1 to MaxLayers do begin writeln(OutFile, ';', i, ' ',Layers[i].Turns,' ',Layers[i].StartZ:0:5,' ',Layers[i].EndZ:0:5); end; Inc(LayerNumber); //�������� ������ �������. writeln(OutFile); writeln(OutFile, ';Start winding'); //��������� �� ������ � ���� MoveForward:=true; if (StatorParams.RayShape = 'circle') then begin for j := 0 to CurrentCoilTurns do begin for i := 0 to 360 do begin coords := CircleCoordinates(CoilRadius*2, i+180); // writeln(OutFile,'CoilRadius*2= ',CoilRadius*2:0:5,' X=', coords.X:0:3, ' Y=', coords.Y:0:5); angle := CalculateAngle(coords.Y, CurrentZ); // writeln(OutFile, ';G1 X', coords.X:0:3, ' Y', angle:0:5,' Z', CurrentZ:0:5); writeln(OutFile, 'G1 X', coords.X:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5); // writeln(OutFile); CurrentZ:=CurrentZ+StatorParams.WireDiameter/360; end; writeln(OutFile, ';Next coil.'); end; writeln(OutFile, ';Second coil'); Inc(LayerNumber); // RequiredSpacing:=StatorParams.RayWidth+StatorParams.NeedleDiameter+StatorParams.PathClearance*2+LayerNumber*StatorParams.WireDiameter*2; // writeln(OutFile, ';RequiredSpacing = ',RequiredSpacing:0:5); RequiredSpacing:=StatorParams.RayTopWidth; writeln(OutFile, ';RequiredSpacing = ',RequiredSpacing:0:5); RequiredSpacing:=RequiredSpacing+StatorParams.NeedleDiameter; writeln(OutFile, ';RequiredSpacing = ',RequiredSpacing:0:5); RequiredSpacing:=RequiredSpacing+StatorParams.PathClearance*2+LayerNumber*StatorParams.WireDiameter*2; writeln(OutFile, ';RequiredSpacing = ',RequiredSpacing:0:5); CurrentZ:=RequiredSpacing/(2 * tan(AngleBetweenRays*PI/180/2)); writeln(OutFile, ';CurrentZ = ',CurrentZ:0:3); end else if (StatorParams.RayShape = 'rect') then begin // writeln(OutFile, ';Rect? '); for LayerNumber := 1 to MaxLayers do begin writeln(OutFile, ';Layer ', LayerNumber); if (Layers[LayerNumber].StartZ > Layers[LayerNumber].EndZ) then CoilLength:=Layers[LayerNumber].StartZ-Layers[LayerNumber].EndZ else CoilLength:=Layers[LayerNumber].EndZ-Layers[LayerNumber].StartZ; writeln(OutFile, ';CoilLength ', CoilLength:0:5); CurrentCoilTurns:=Layers[LayerNumber].Turns; //writeln(OutFile, ';CurrentCoilTurns ', CurrentCoilTurns); CoilTurnsSum := CoilTurnsSum+CurrentCoilTurns; writeln(OutFile, ';CoilTurnsSum ', CoilTurnsSum); CurrentZ:=Layers[LayerNumber].StartZ; writeln(OutFile,'; NewZ=',CurrentZ:0:5); //�������� ������. writeln(OutFile, ';We make ',CurrentCoilTurns, ' turns on ', LayerNumber, ' layer.' ); writeln(OutFile); for j := 1 to CurrentCoilTurns do begin writeln(OutFile,';Coil� = ',j); writeln(OutFile,'M117 ',j); //angle := CalculateAngle(CoilWidth/2, CurrentZ); angle := AngleBetweenRays/2; //Divide the path into 100 points //Move from left-down to left-up for k := 1 to 100 do begin angle := AngleBetweenRays/2; angle := ((-1*angle)+2*(angle/100*k)); writeln(OutFile, 'G1 X', -1*CoilHeight/2:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5, ' ;CurrentZ= ',CurrentZ:0:5); // Top Left Corner end; if MoveForward then CurrentZ:=CurrentZ+StatorParams.WireDiameter/4 else CurrentZ:=CurrentZ-StatorParams.WireDiameter/4; // angle := CalculateAngle(CoilWidth/2, CurrentZ); angle := AngleBetweenRays/2; writeln(OutFile, 'G1 X', CoilHeight/2:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5, ' ;CurrentZ= ',CurrentZ:0:5); // Top Right Corner if MoveForward then CurrentZ:=CurrentZ+StatorParams.WireDiameter/4 else CurrentZ:=CurrentZ-StatorParams.WireDiameter/4; //writeln(OutFile, 'M0'); //Divide the path into 100 points //Move from left-down to rt-up for k := 1 to 100 do begin angle := AngleBetweenRays/2; angle := (angle-(2*(angle/100*k))); writeln(OutFile, 'G1 X', CoilHeight/2:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5, ' ;CurrentZ= ',CurrentZ:0:5); // Bottom Right Corner end; if MoveForward then CurrentZ:=CurrentZ+StatorParams.WireDiameter/4 else CurrentZ:=CurrentZ-StatorParams.WireDiameter/4; //writeln(OutFile, 'M0'); // angle := CalculateAngle(CoilWidth/2, CurrentZ); angle := AngleBetweenRays/2; writeln(OutFile, 'G1 X', -1*CoilHeight/2:0:3, ' Y', -angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5, ' ;CurrentZ= ',CurrentZ:0:5); // Bottom Left Corner if MoveForward then CurrentZ:=CurrentZ+StatorParams.WireDiameter/4 else CurrentZ:=CurrentZ-StatorParams.WireDiameter/4; //writeln(OutFile, 'M0'); end; writeln(OutFile, 'M0'); // writeln(OutFile, 'G91'); // writeln(OutFile, 'G1 Y50'); // writeln(OutFile, 'G90'); CoilWidth:=CoilWidth+StatorParams.WireDiameter*2; MoveForward:= not MoveForward; writeln(OutFile,';MoveForward: ', MoveForward); end; end; except on E: Exception do begin writeln('Error writing to output file: ', E.Message); Halt(1); end; end; CloseFile(OutFile); EndTime := Now; ExecutionTime := EndTime - StartTime; writeln('G-code generated to: ', OutputFileName, ' in ', FormatFloat('0.000', ExecutionTime * 86400), ' seconds.'); writeln('Press Enter... '); Readln; end.