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 @@ + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes> + <Item Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <Units> + <Unit> + <Filename Value="gcodegenerator_v5.pas"/> + <IsPartOfProject Value="True"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="gcodegenerator_v5"/> + </Target> + <SearchPaths> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + </Debugging> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <PathDelim Value="\"/> + <Version Value="12"/> + <BuildModes Active="Default"/> + <Units> + <Unit> + <Filename Value="gcodegenerator_v5.pas"/> + <IsPartOfProject Value="True"/> + <IsVisibleTab Value="True"/> + <TopLine Value="648"/> + <CursorPos X="25" Y="668"/> + <FoldState Value=" TC6B22 PPTB T3iV2{#5 piZmf2L1123]Rl3pQ2 T0yU4U0"/> + <UsageCount Value="220"/> + <Loaded Value="True"/> + </Unit> + </Units> + <JumpHistory HistoryIndex="19"> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="191" Column="51" TopLine="158"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="351" Column="28" TopLine="333"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="518" Column="74" TopLine="496"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="524" Column="47" TopLine="504"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="181" Column="56" TopLine="166"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="651" Column="71" TopLine="625"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="604" Column="42" TopLine="587"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="612" Column="91" TopLine="590"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="506" Column="32" TopLine="245"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="657" Column="139" TopLine="621"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="630" Column="26" TopLine="246"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="632" TopLine="610"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="671" Column="7" TopLine="615"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="532" Column="51" TopLine="493"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="542" Column="49" TopLine="515"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="580" Column="67" TopLine="313"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="507" Column="66" TopLine="72"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="222" Column="64" TopLine="198"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Column="11"/> + </Position> + <Position> + <Filename Value="gcodegenerator_v5.pas"/> + <Caret Line="668" Column="25" TopLine="636"/> + </Position> + </JumpHistory> + <RunParams> + <FormatVersion Value="2"/> + <Modes ActiveMode="default"> + <Mode Name="default"> + <local> + <CommandLineParams Value="input.txt output.gcode"/> + </local> + </Mode> + </Modes> + </RunParams> + <HistoryLists> + <List Name="LaunchingApplication" Type="File" Count="1"> + <Item1 Value="C:\Windows\system32\cmd.exe /C ${TargetCmdLine}"/> + </List> + <List Name="CommandLineParameters" Count="1"> + <Item1 Value="input.txt output.gcode"/> + </List> + </HistoryLists> + </ProjectSession> +</CONFIG> 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 <input_file.txt> <output_file.gcode> <coil_geometry.txt>'); + 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <Compiler Value="C:\lazarus\fpc\3.2.2\bin\x86_64-win64\fpc.exe" Date="1497193866"/> + <Params Value=" -MObjFPC -Scghi -O1 -gw3 -gl -l -vewnhibq -FuD:\Documents\GitHub\motor-wire-winder\gcodegenerator\ -FUD:\Documents\GitHub\motor-wire-winder\gcodegenerator\lib\x86_64-win64\ -FED:\Documents\GitHub\motor-wire-winder\gcodegenerator\ -oD:\Documents\GitHub\motor-wire-winder\gcodegenerator\gcodegenerator.exe gcodegenerator.pas"/> +</CONFIG> 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