diff --git a/gcodegenerator/CHANGELOG.md b/gcodegenerator/CHANGELOG.md
new file mode 100644
index 0000000..d3e930d
--- /dev/null
+++ b/gcodegenerator/CHANGELOG.md
@@ -0,0 +1,13 @@
+# Change Log
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+## 2025-01-05
+### Добавлено
+
+### Изменено
+
+### Исправлено
+
diff --git a/gcodegenerator/TODO.md b/gcodegenerator/TODO.md
new file mode 100644
index 0000000..224205c
--- /dev/null
+++ b/gcodegenerator/TODO.md
@@ -0,0 +1,16 @@
+This file contains a list of tasks that need to be completed.
+
+# TODO
+## CRITICAL
+
+## HIGH
+
+## MEDIUM
+
+## LOW
+1. .
+2. .
+
+# IN PROGRESS
+
+# DONE
\ No newline at end of file
diff --git a/gcodegenerator/backup/gcodegenerator.lpi b/gcodegenerator/backup/gcodegenerator.lpi
new file mode 100644
index 0000000..1bee867
--- /dev/null
+++ b/gcodegenerator/backup/gcodegenerator.lpi
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
diff --git a/gcodegenerator/backup/gcodegenerator.lps b/gcodegenerator/backup/gcodegenerator.lps
new file mode 100644
index 0000000..c1a37e5
--- /dev/null
+++ b/gcodegenerator/backup/gcodegenerator.lps
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gcodegenerator/gcodegenerator.exe b/gcodegenerator/gcodegenerator.exe
new file mode 100644
index 0000000..5bccb89
Binary files /dev/null and b/gcodegenerator/gcodegenerator.exe differ
diff --git a/gcodegenerator/gcodegenerator_v5.pas b/gcodegenerator/gcodegenerator_v5.pas
new file mode 100644
index 0000000..fc9e412
--- /dev/null
+++ b/gcodegenerator/gcodegenerator_v5.pas
@@ -0,0 +1,816 @@
+program gcodegenerator_v5;
+
+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;
+ NeedleRigidity: 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;
+ StartX: double;
+ StartY: double;
+ StartZ: double;
+ CurrentX: double;
+ CurrentY: 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;
+ WindDirection:integer;
+ OperationMode:string;
+ xclearance,yclearance,zclearance: Double;
+ FixtureOffset: Double;
+ FixtureDiameter: Double;
+ FixtureTurns:integer;
+
+ 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;
+ 'needle_rigidity': begin
+ StatorParams.NeedleRigidity := StrToFloat(Value);
+ StatorParams.NeedleRigidity := StatorParams.NeedleRigidity/100;
+ writeln('Needle Rigidity: ', StatorParams.NeedleRigidity:8:2);
+ writeln();
+ end;
+
+ 'x_clearance': begin
+ xclearance := StrToFloat(Value);
+ writeln('X Clearance: ', xclearance:8:2);
+ writeln();
+ end;
+ 'y_clearance': begin
+ yclearance := StrToFloat(Value);
+ writeln('Y Clearance: ', yclearance:8:2);
+ writeln();
+ end;
+ 'z_clearance': begin
+ zclearance := StrToFloat(Value);
+ writeln('Z Clearance: ', zclearance:8:2);
+ writeln();
+ end;
+ 'fixture_offset': begin
+ FixtureOffset := StrToFloat(Value);
+ writeln('Fixture Offset: ', FixtureOffset:8:2);
+ writeln();
+ end;
+ 'fixture_dia': begin
+ FixtureDiameter := StrToFloat(Value);
+ writeln('Fixture Diameter: ', FixtureDiameter:8:2);
+ writeln();
+ end;
+ 'fixture_turns': begin
+ FixtureTurns := StrToInt(Value);
+ writeln('Fixture Turns: ', FixtureTurns);
+ 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:=yclearance*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(); // -
+ StringReplace(TrimmedLine, ',', '.', [rfReplaceAll]);
+ 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;
+
+ procedure StartSequence();
+begin
+ 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);
+ // Move to center of ray along Y axis and reset coordinate
+ writeln(OutFile, 'G1 X', StatorParams.RayCenterOffset:0:2, ' Y0.0');
+ writeln(OutFile, 'G92 X0 Y0');
+
+ //
+ CoilRadius:=(StatorParams.RayTopHeight/2+StatorParams.NeedleDiameter/2+yclearance);
+ CoilWidth:=(StatorParams.RayTopWidth+StatorParams.NeedleDiameter+yclearance*2);
+ CoilHeight:=(StatorParams.RayTopHeight+StatorParams.NeedleDiameter+xclearance*2);
+ writeln(OutFile, ';CoilRadius = ', CoilRadius:0:3);
+ writeln(OutFile, ';CoilWidth = ', CoilWidth:0:3);
+ writeln(OutFile, ';CoilHeight = ', CoilHeight:0:3);
+ StartX:=-1*CoilHeight/2;
+ StartY:=-1*AngleBetweenRays/2;
+ writeln(OutFile, 'G1 X', StartX:0:3, ' Y', StartY:0:3);
+
+ // .
+ CurrentZ:=(StatorParams.BaseDiameter/2)+zclearance;
+ writeln(OutFile, 'G1 Z', CurrentZ:0:2, ' F', StatorParams.WorkSpeed);
+ // ,
+ writeln(OutFile, 'M0');
+ // "" . , .
+ writeln(OutFile, 'G1 X', StartX:0:3, ' Y', -1*StartY:0:3);
+end;
+
+ procedure MakeCoil();
+begin
+ for j := 1 to CurrentCoilTurns do
+ begin
+ writeln(OutFile,';Coil = ',j);
+ writeln(OutFile,'M117 L',LayerNumber,'/C',j,'/S',CoilTurnsSum-CurrentCoilTurns+j);
+
+ //Move from -X,Y to X,Y
+ angle := WindDirection*AngleBetweenRays/2;
+ CurrentX :=CoilHeight/2+((CurrentZ-StatorParams.BaseRadius)*xclearance*StatorParams.NeedleRigidity);
+ writeln(OutFile, 'G1 X', CurrentX:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5,' F',StatorParams.WorkSpeed, ' ;Point 1 CurrentZ= ',CurrentZ:0:5, ' 2x_clear= ',+((CurrentZ-StatorParams.BaseRadius)*xclearance*StatorParams.NeedleRigidity):0:3); // Top Right Corner
+ if MoveForward then CurrentZ:=CurrentZ+StatorParams.WireDiameter/4 else CurrentZ:=CurrentZ-StatorParams.WireDiameter/4;
+
+ //Divide the path into 100 points
+ //Move from X,Y to X,-Y
+ for k := 1 to 100 do
+ begin
+ angle := AngleBetweenRays/2;
+ angle := WindDirection*(angle-(2*(angle/100*k)));
+ CurrentX :=CoilHeight/2+((CurrentZ-StatorParams.BaseRadius)*xclearance*StatorParams.NeedleRigidity);
+ writeln(OutFile, 'G1 X', CurrentX:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5,' F',round(1.2*StatorParams.WorkSpeed/StatorParams.BaseRadius*CurrentZ), ' ;Point 2 CurrentZ= ',CurrentZ:0:5, ' 3x_clear= ',+((CurrentZ-StatorParams.BaseRadius)*xclearance*StatorParams.NeedleRigidity):0:3); // Bottom Right Corner
+ end;
+ if MoveForward then CurrentZ:=CurrentZ+StatorParams.WireDiameter/4 else CurrentZ:=CurrentZ-StatorParams.WireDiameter/4;
+
+ //Move from X,-Y to -X,-Y
+ angle := -1*WindDirection*AngleBetweenRays/2;
+ CurrentX :=CoilHeight/2+((CurrentZ-StatorParams.BaseRadius)*xclearance*StatorParams.NeedleRigidity);
+ writeln(OutFile, 'G1 X', -1*CurrentX:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5,' F',StatorParams.WorkSpeed, ' ;Point 3 CurrentZ= ',CurrentZ:0:5, ' 4x_clear= ',+((CurrentZ-StatorParams.BaseRadius)*xclearance*StatorParams.NeedleRigidity):0:3); // Bottom Left Corner
+ if MoveForward then CurrentZ:=CurrentZ+StatorParams.WireDiameter/4 else CurrentZ:=CurrentZ-StatorParams.WireDiameter/4;
+
+ //Move from -X,-Y to -X,Y
+ //Divide the path into 100 points
+ for k := 1 to 100 do
+ begin
+ angle := AngleBetweenRays/2;
+ angle := -1*WindDirection*(angle-(2*(angle/100*k)));
+ CurrentX :=CoilHeight/2+((CurrentZ-StatorParams.BaseRadius)*xclearance*StatorParams.NeedleRigidity);
+ writeln(OutFile, 'G1 X', -1*CurrentX:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5,' F',round(1.2*StatorParams.WorkSpeed/StatorParams.BaseRadius*CurrentZ) , ' ;Point 4 CurrentZ= ',CurrentZ:0:5, ' 1x_clear= ',+((CurrentZ-StatorParams.BaseRadius*xclearance*StatorParams.NeedleRigidity)):0:3); // Top Left Corner
+ end;
+ if MoveForward then CurrentZ:=CurrentZ+StatorParams.WireDiameter/4 else CurrentZ:=CurrentZ-StatorParams.WireDiameter/4;
+
+ end;
+
+end;
+
+ procedure PairCoilWind(mode: string);
+ begin
+ if ((mode = 'Aa') or (mode = 'Bb') or (mode = 'Cc')) then
+ begin
+ WindDirection:=1;
+ end
+ else if ((mode = 'aA') or (mode = 'bB') or (mode = 'cC')) then
+ begin
+ WindDirection:=-1;
+ end
+ else
+ begin
+ Writeln('Wrong Pair Coil Pattern. (Aa, aA, Bb, bB, Cc, cC');
+ Readln;
+ Halt(1);
+ end;
+
+ 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);
+
+ WindDirection := 1;
+ MakeCoil();
+ writeln(OutFile, 'M300 S2500 P100');
+
+ CoilWidth:=CoilWidth+StatorParams.WireDiameter*2;
+ MoveForward:= not MoveForward;
+ writeln(OutFile,';MoveForward: ', MoveForward);
+ end;
+ writeln(OutFile, 'M300 S2500 P100');
+ writeln(OutFile, 'G4 P100');
+ writeln(OutFile, 'M300 S2500 P100');
+ writeln(OutFile, 'G4 P100');
+ writeln(OutFile, 'M300 S2500 P100');
+ writeln(OutFile, ';Coil Complete.');
+ writeln(OutFile, ';Changing coords.');
+ writeln(OutFile, 'G92 Y', -1*angle:0:5);
+ writeln(OutFile, ';Second coil');
+
+ 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);
+
+ WindDirection := -1;
+ MakeCoil();
+ writeln(OutFile, 'M300 S2500 P100');
+
+ CoilWidth:=CoilWidth+StatorParams.WireDiameter*2;
+ MoveForward:= not MoveForward;
+ writeln(OutFile,';MoveForward: ', MoveForward);
+ end;
+ writeln(OutFile, 'M300 S2500 P100');
+ writeln(OutFile, 'G4 P50');
+ writeln(OutFile, 'M300 S2500 P100');
+ writeln(OutFile, 'G4 P50');
+ writeln(OutFile, 'M300 S2500 P100');
+ writeln(OutFile, ';Coil Complete.');
+
+ end;
+
+ procedure MoveToNextPair();
+ begin
+ writeln(OutFile, ';Move To Next Pair');
+ writeln(OutFile, 'G92 Y0');
+ writeln(OutFile, 'G1 Y', 360/(StatorParams.NumberOfRays/3/2):0:5 ); // Top Left Corner
+ writeln(OutFile, ';Turn to next pair with ',360/(StatorParams.NumberOfRays/3/2):0:5,'.' );
+ writeln(OutFile, 'G92 Y',StartY:0:5);
+ end;
+
+ procedure CreateMotorPhase(pattern:string);
+ begin
+ PairCoilWind(pattern);
+ MoveToNextPair();
+ PairCoilWind(pattern);
+ MoveToNextPair();
+ PairCoilWind(pattern);
+ MoveToNextPair();
+ PairCoilWind(pattern);
+ end;
+
+ procedure MoveToFixture();
+ begin
+ writeln(OutFile, ';Move To Fixture');
+ writeln(OutFile, 'G1 X', FixtureOffset:0:3);
+ writeln(OutFile, 'M0'); //
+ end;
+
+ procedure AttachToFixture();
+ begin
+ writeln(OutFile, ';Attach To Fixture');
+ for j := 0 to FixtureTurns do
+ begin
+ for i := 0 to 360 do
+ begin
+ coords := CircleCoordinates(FixtureDiameter/2+xclearance, i+180);
+ angle := CalculateAngle(coords.Y, CurrentZ);
+ writeln(OutFile, 'G1 X', coords.X:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5);
+ CurrentZ:=CurrentZ+StatorParams.WireDiameter/360;
+ end;
+ end;
+ end;
+
+begin //Start Programm
+ // 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);
+ StartSequence();
+ // *** Your G-code generation logic here ***
+
+ 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+yclearance*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? ');
+
+ CreateMotorPhase('Aa');
+ MoveToFixture();
+ AttachToFixture();
+
+ 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.
diff --git a/gcodegenerator/lib/x86_64-win64/gcodegenerator.compiled b/gcodegenerator/lib/x86_64-win64/gcodegenerator.compiled
new file mode 100644
index 0000000..ce58246
--- /dev/null
+++ b/gcodegenerator/lib/x86_64-win64/gcodegenerator.compiled
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/gcodegenerator/lib/x86_64-win64/gcodegenerator.o b/gcodegenerator/lib/x86_64-win64/gcodegenerator.o
new file mode 100644
index 0000000..699707d
Binary files /dev/null and b/gcodegenerator/lib/x86_64-win64/gcodegenerator.o differ
diff --git a/src/3d_printed_parts/Rotary_spacer_for_72mm_plastic_stator_2.SLDPRT b/src/3d_printed_parts/Rotary_spacer_for_72mm_plastic_stator_2.SLDPRT
new file mode 100644
index 0000000..96dd645
Binary files /dev/null and b/src/3d_printed_parts/Rotary_spacer_for_72mm_plastic_stator_2.SLDPRT differ
diff --git a/src/3d_printed_parts/Second_tension_lever.SLDPRT b/src/3d_printed_parts/Second_tension_lever.SLDPRT
new file mode 100644
index 0000000..c1907f0
Binary files /dev/null and b/src/3d_printed_parts/Second_tension_lever.SLDPRT differ
diff --git a/src/3d_printed_parts/Second_tension_part.SLDPRT b/src/3d_printed_parts/Second_tension_part.SLDPRT
new file mode 100644
index 0000000..b8f16d1
Binary files /dev/null and b/src/3d_printed_parts/Second_tension_part.SLDPRT differ
diff --git a/src/3d_printed_parts/needle_holder_for_1,2mm_tube_tmp.SLDPRT b/src/3d_printed_parts/needle_holder_for_1,2mm_tube_tmp.SLDPRT
new file mode 100644
index 0000000..33ff1da
Binary files /dev/null and b/src/3d_printed_parts/needle_holder_for_1,2mm_tube_tmp.SLDPRT differ
diff --git a/src/3d_printed_parts/rubberband_reel.SLDPRT b/src/3d_printed_parts/rubberband_reel.SLDPRT
new file mode 100644
index 0000000..c2128fa
Binary files /dev/null and b/src/3d_printed_parts/rubberband_reel.SLDPRT differ
diff --git a/src/3d_printed_parts/small_pully.SLDPRT b/src/3d_printed_parts/small_pully.SLDPRT
new file mode 100644
index 0000000..094ca66
Binary files /dev/null and b/src/3d_printed_parts/small_pully.SLDPRT differ
diff --git a/src/Secondary_asms/_asm_chelnok_test.SLDASM b/src/Secondary_asms/_asm_chelnok_test.SLDASM
new file mode 100644
index 0000000..a422b73
Binary files /dev/null and b/src/Secondary_asms/_asm_chelnok_test.SLDASM differ
diff --git a/src/Tmp/Calculations/Calc.SLDPRT b/src/Tmp/Calculations/Calc.SLDPRT
new file mode 100644
index 0000000..40bed2f
Binary files /dev/null and b/src/Tmp/Calculations/Calc.SLDPRT differ
diff --git a/src/Tmp/Calculations/Test_003.SLDPRT b/src/Tmp/Calculations/Test_003.SLDPRT
new file mode 100644
index 0000000..e084fee
Binary files /dev/null and b/src/Tmp/Calculations/Test_003.SLDPRT differ
diff --git a/src/Tmp/Calculations/coils_calculator.SLDPRT b/src/Tmp/Calculations/coils_calculator.SLDPRT
new file mode 100644
index 0000000..efb1736
Binary files /dev/null and b/src/Tmp/Calculations/coils_calculator.SLDPRT differ