v5-rc2
Все изменения в CHANGELOG.md
This commit is contained in:
parent
766bb1a985
commit
ae07549e1b
32 changed files with 118162 additions and 33235 deletions
24
CHANGELOG.md
24
CHANGELOG.md
|
@ -4,10 +4,26 @@ 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/).
|
||||
|
||||
## [v5-rc2] Намотчик - 2025-01-05
|
||||
|
||||
### Добавлено
|
||||
- Начата работа над программой-генератором g-code. Эта программа необходима для автоматического расчета траекторий движения конца иголки, в процессе намотки.
|
||||
- Детали чтобы использовать трубочку диаметром 0.9мм, вместо иглы.
|
||||
- Добавлена кнопка аварийного останова.
|
||||
- Экспериментальная система, подтягивающая проволку назад, призванная сохранять натяжение во время провисания провода.
|
||||
|
||||
### Изменено
|
||||
- Изменен дизайн системы натяжения
|
||||
- Дизайн каретки, чтобы при стягивании деталей, держащих иголку, резьба вкручивалась в металлическую гайку, а не в пластик.
|
||||
- Также изменена высота каретки, чтобы можно было менять высоту иглы.
|
||||
- Небольшие изменения в раме станка. (Удалил лишние построения, для старого держателя катушки)
|
||||
|
||||
### Исправлено
|
||||
|
||||
|
||||
## [v5-rc1] Намотчик - 2024-11-11
|
||||
|
||||
### Добавлено
|
||||
|
||||
- Тормоз для катушки
|
||||
- Проставки под плату вместо металлических стоек
|
||||
- Отверстия для крепления RAMPS
|
||||
|
@ -16,18 +32,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- Сделана спецификация с временем печати и расходом пластика для каждой детали
|
||||
|
||||
### Изменено
|
||||
|
||||
- Отредактирована крышка. Добавлены прорези под провода
|
||||
- Рельсы заменены с MGN12 на MGN9
|
||||
- Удалены все мелкие скругления
|
||||
- Увеличил пространство для гайки М8, которая одевается шпильку
|
||||
- Увеличено пространство для гайки М8, которая одевается шпильку
|
||||
- Перепроектирован стенд для дисплея
|
||||
- Упрощена деталь Organizer
|
||||
- Увеличена глубина борозды под провод на колесе
|
||||
- Оптимизированы детали для печати. Там где это возможно, печатаются без поддержек.
|
||||
|
||||
### Исправлено
|
||||
|
||||
### Исправлено
|
||||
- Удалены все лишние плоскости, которые очень мешают, если включить их отображение. Кроме того, в некоторых эскизах были привязки не к плоскостям или граням, а к этим самым плоскостям. То есть, удаление или смещение плоскости, привело бы к непредсказуемому изменению модели.
|
||||
- Исправены ошибки и "костыли". В некоторых деталях встречались случаи, когда, например, была сделана вытяжка, а потом эта вытяжка удалялась вырезом.
|
||||
Или наоборот, делался вырез, который потом заполнялся вытяжкой. Что перегружало дерево. Некоторые детали были сделаны из "заготовок", что лишало возможности редактировать геометрию. Этот инструмент хорош для быстрой прикидки, но не стоит его оставлять в конечной версии проекта.
|
||||
|
|
|
@ -9,18 +9,22 @@
|
|||
<Filename Value="gcodegenerator_v3.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<IsVisibleTab Value="True"/>
|
||||
<TopLine Value="442"/>
|
||||
<CursorPos X="141" Y="459"/>
|
||||
<FoldState Value=" TC6B2 T3iD2{i5 piZm02K T0p34U^"/>
|
||||
<TopLine Value="69"/>
|
||||
<CursorPos X="60" Y="95"/>
|
||||
<FoldState Value=" TC6B22 PQUB T3lU2L5 PiYj]KT0pO4UR"/>
|
||||
<UsageCount Value="220"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
<JumpHistory>
|
||||
<JumpHistory HistoryIndex="1">
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v3.pas"/>
|
||||
<Caret Line="417" Column="42" TopLine="393"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v3.pas"/>
|
||||
<Caret Line="529" Column="59" TopLine="493"/>
|
||||
</Position>
|
||||
</JumpHistory>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
|
|
|
@ -10,6 +10,7 @@ type
|
|||
|
||||
type
|
||||
TStatorParams = record
|
||||
StatorName: String;
|
||||
BaseDiameter: Double;
|
||||
BaseRadius: Double;
|
||||
NumberOfRays: Integer;
|
||||
|
@ -32,7 +33,15 @@ type
|
|||
WorkSpeed :integer;
|
||||
end;
|
||||
|
||||
type
|
||||
TLayer = record
|
||||
Turns: Integer; // Êîëè÷åñòâî âèòêîâ
|
||||
StartX: double; // Íà÷àëüíàÿ êîîðäèíàòà
|
||||
EndX: double; // Êîíå÷íàÿ êîîðäèíàòà
|
||||
end;
|
||||
|
||||
var
|
||||
StartTime, EndTime, ExecutionTime: TDateTime;
|
||||
InputFileName, OutputFileName: string;
|
||||
StatorParams: TStatorParams;
|
||||
InFile, OutFile: TextFile;
|
||||
|
@ -41,6 +50,7 @@ var
|
|||
CurrentZ: double;
|
||||
coords: TPoint;
|
||||
normalizecoords: TPoint;
|
||||
Layers: array[1..10] of TLayer;
|
||||
i, j, k: Integer;
|
||||
CoilLength :double;
|
||||
CurrentCoilTurns, CoilTurnsSum :Integer;
|
||||
|
@ -51,7 +61,7 @@ var
|
|||
angle :double;
|
||||
MaxDepth,MaxPath :double;
|
||||
MoveForward:boolean;
|
||||
|
||||
OperationMode:string;
|
||||
|
||||
|
||||
function ParseLine(Line: string): Boolean;
|
||||
|
@ -69,13 +79,22 @@ var
|
|||
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;
|
||||
'stator_name': begin
|
||||
OperationMode := Value;
|
||||
writeln('Operation Mode: ', OperationMode);
|
||||
writeln();
|
||||
end;
|
||||
'base_dia': begin
|
||||
StatorParams.BaseDiameter := StrToFloat(Value);
|
||||
writeln('Base Diameter: ', StatorParams.BaseDiameter:8:2);
|
||||
|
@ -293,6 +312,7 @@ end;
|
|||
|
||||
begin
|
||||
// Command line argument handling
|
||||
StartTime := Now;
|
||||
if ParamCount < 2 then
|
||||
begin
|
||||
Writeln('Usage: GCodeGenerator <input_file.txt> <output_file.gcode>');
|
||||
|
@ -308,6 +328,7 @@ begin
|
|||
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');
|
||||
|
@ -412,7 +433,7 @@ begin
|
|||
writeln(OutFile,'; NewZ=',CurrentZ:0:5);
|
||||
//Íà÷èíàåì ìîòàòü.
|
||||
writeln(OutFile, ';We make ',CurrentCoilTurns, ' turns on ', LayerNumber, ' layer.' );
|
||||
for j := 0 to CurrentCoilTurns do
|
||||
for j := 1 to CurrentCoilTurns do
|
||||
begin
|
||||
writeln(OutFile,';Coil¹ = ',j);
|
||||
writeln(OutFile,'M117 ',j);
|
||||
|
@ -515,8 +536,9 @@ begin
|
|||
end;
|
||||
end;
|
||||
CloseFile(OutFile);
|
||||
|
||||
writeln('G-code generated to: ', OutputFileName);
|
||||
EndTime := Now;
|
||||
ExecutionTime := EndTime - StartTime;
|
||||
writeln('G-code generated to: ', OutputFileName, ' in ', FormatFloat('0.000', ExecutionTime * 86400), ' seconds.');
|
||||
writeln('Press Enter... ');
|
||||
Readln;
|
||||
end.
|
||||
|
|
62
gcode/Generator/backup/gcodegenerator_v4.lpi
Normal file
62
gcode/Generator/backup/gcodegenerator_v4.lpi
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="gcodegenerator_v4"/>
|
||||
<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_v4.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="gcodegenerator_v4"/>
|
||||
</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>
|
160
gcode/Generator/backup/gcodegenerator_v4.lps
Normal file
160
gcode/Generator/backup/gcodegenerator_v4.lps
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectSession>
|
||||
<PathDelim Value="\"/>
|
||||
<Version Value="12"/>
|
||||
<BuildModes Active="Default"/>
|
||||
<Units>
|
||||
<Unit>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<IsVisibleTab Value="True"/>
|
||||
<TopLine Value="538"/>
|
||||
<CursorPos X="11" Y="582"/>
|
||||
<FoldState Value=" TC6B21 PMUB T3iN2{r5 piZm92L]NiejM2 T0tN4U0"/>
|
||||
<UsageCount Value="220"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
<JumpHistory HistoryIndex="29">
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="419" Column="18" TopLine="281"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="422" Column="40" TopLine="398"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="418" Column="18" TopLine="398"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="419" Column="20" TopLine="400"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="291" Column="12" TopLine="247"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="419" Column="66" TopLine="400"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="420" Column="18" TopLine="400"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="419" Column="18" TopLine="400"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="432" Column="22" TopLine="403"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="418" Column="62" TopLine="398"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="422" Column="72" TopLine="403"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="409" Column="32" TopLine="375"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="291" Column="12" TopLine="247"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="507" Column="20" TopLine="487"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="446" Column="34" TopLine="412"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="421" Column="63" TopLine="404"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="427" Column="71" TopLine="411"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="424" Column="42" TopLine="405"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="426" Column="52" TopLine="408"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="291" Column="12" TopLine="247"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="425" Column="157" TopLine="406"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="440" Column="48" TopLine="416"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="436" Column="42" TopLine="417"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="437" Column="42" TopLine="417"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="446" Column="69" TopLine="415"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="439" Column="55" TopLine="418"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="382" Column="23" TopLine="361"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="407" Column="11" TopLine="394"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="445" Column="87" TopLine="419"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="582" Column="3" TopLine="621"/>
|
||||
</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>
|
668
gcode/Generator/backup/gcodegenerator_v4.pas
Normal file
668
gcode/Generator/backup/gcodegenerator_v4.pas
Normal file
|
@ -0,0 +1,668 @@
|
|||
program gcodegenerator_v4;
|
||||
|
||||
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 <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);
|
||||
// *** 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;
|
||||
|
||||
// writeln(OutFile, 'G1 X', -1*CoilHeight/2:0:3, ' Y', angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5); // Top Left Corner
|
||||
// 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', 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;
|
||||
|
||||
// angle := CalculateAngle(-1*CoilWidth/2, CurrentZ);
|
||||
// writeln(OutFile, 'G1 X', CoilHeight/2:0:3, ' Y', -angle:0:5,' Z', NormalizeZ(CurrentZ, angle):0:5); // Bottom Right Corner
|
||||
// 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); *)
|
||||
//Inc(LayerNumber);
|
||||
end;
|
||||
|
||||
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// *** Your G-code generation logic here ***
|
||||
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.
|
Binary file not shown.
|
@ -9,18 +9,26 @@
|
|||
<Filename Value="gcodegenerator_v3.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<IsVisibleTab Value="True"/>
|
||||
<TopLine Value="403"/>
|
||||
<CursorPos X="19" Y="415"/>
|
||||
<FoldState Value=" TC6B2 T3iD2{i5 piZm02K T0p34U^"/>
|
||||
<TopLine Value="74"/>
|
||||
<CursorPos X="10" Y="93"/>
|
||||
<FoldState Value=" TC6B22 PQUB T3lU2L5 PiYj]KT0pO4UR"/>
|
||||
<UsageCount Value="220"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
<JumpHistory>
|
||||
<JumpHistory HistoryIndex="2">
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v3.pas"/>
|
||||
<Caret Line="417" Column="42" TopLine="393"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v3.pas"/>
|
||||
<Caret Line="529" Column="59" TopLine="493"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v3.pas"/>
|
||||
<Caret Line="95" Column="60" TopLine="69"/>
|
||||
</Position>
|
||||
</JumpHistory>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
|
|
|
@ -10,6 +10,7 @@ type
|
|||
|
||||
type
|
||||
TStatorParams = record
|
||||
StatorName: String;
|
||||
BaseDiameter: Double;
|
||||
BaseRadius: Double;
|
||||
NumberOfRays: Integer;
|
||||
|
@ -32,7 +33,15 @@ type
|
|||
WorkSpeed :integer;
|
||||
end;
|
||||
|
||||
type
|
||||
TLayer = record
|
||||
Turns: Integer; // Êîëè÷åñòâî âèòêîâ
|
||||
StartX: double; // Íà÷àëüíàÿ êîîðäèíàòà
|
||||
EndX: double; // Êîíå÷íàÿ êîîðäèíàòà
|
||||
end;
|
||||
|
||||
var
|
||||
StartTime, EndTime, ExecutionTime: TDateTime;
|
||||
InputFileName, OutputFileName: string;
|
||||
StatorParams: TStatorParams;
|
||||
InFile, OutFile: TextFile;
|
||||
|
@ -41,6 +50,7 @@ var
|
|||
CurrentZ: double;
|
||||
coords: TPoint;
|
||||
normalizecoords: TPoint;
|
||||
Layers: array[1..10] of TLayer;
|
||||
i, j, k: Integer;
|
||||
CoilLength :double;
|
||||
CurrentCoilTurns, CoilTurnsSum :Integer;
|
||||
|
@ -51,7 +61,7 @@ var
|
|||
angle :double;
|
||||
MaxDepth,MaxPath :double;
|
||||
MoveForward:boolean;
|
||||
|
||||
OperationMode:string;
|
||||
|
||||
|
||||
function ParseLine(Line: string): Boolean;
|
||||
|
@ -69,13 +79,22 @@ var
|
|||
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);
|
||||
|
@ -293,6 +312,7 @@ end;
|
|||
|
||||
begin
|
||||
// Command line argument handling
|
||||
StartTime := Now;
|
||||
if ParamCount < 2 then
|
||||
begin
|
||||
Writeln('Usage: GCodeGenerator <input_file.txt> <output_file.gcode>');
|
||||
|
@ -308,6 +328,7 @@ begin
|
|||
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');
|
||||
|
@ -515,8 +536,9 @@ begin
|
|||
end;
|
||||
end;
|
||||
CloseFile(OutFile);
|
||||
|
||||
writeln('G-code generated to: ', OutputFileName);
|
||||
EndTime := Now;
|
||||
ExecutionTime := EndTime - StartTime;
|
||||
writeln('G-code generated to: ', OutputFileName, ' in ', FormatFloat('0.000', ExecutionTime * 86400), ' seconds.');
|
||||
writeln('Press Enter... ');
|
||||
Readln;
|
||||
end.
|
||||
|
|
BIN
gcode/Generator/gcodegenerator_v4.exe
Normal file
BIN
gcode/Generator/gcodegenerator_v4.exe
Normal file
Binary file not shown.
62
gcode/Generator/gcodegenerator_v4.lpi
Normal file
62
gcode/Generator/gcodegenerator_v4.lpi
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="gcodegenerator_v4"/>
|
||||
<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_v4.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="gcodegenerator_v4"/>
|
||||
</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>
|
160
gcode/Generator/gcodegenerator_v4.lps
Normal file
160
gcode/Generator/gcodegenerator_v4.lps
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectSession>
|
||||
<PathDelim Value="\"/>
|
||||
<Version Value="12"/>
|
||||
<BuildModes Active="Default"/>
|
||||
<Units>
|
||||
<Unit>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<IsVisibleTab Value="True"/>
|
||||
<TopLine Value="615"/>
|
||||
<CursorPos X="7" Y="639"/>
|
||||
<FoldState Value=" TC6B21 PMUB T3iN2{r5 piZm92L]NiejM2 T0tN4U0"/>
|
||||
<UsageCount Value="220"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
<JumpHistory HistoryIndex="29">
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="419" Column="18" TopLine="281"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="422" Column="40" TopLine="398"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="418" Column="18" TopLine="398"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="419" Column="20" TopLine="400"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="291" Column="12" TopLine="247"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="419" Column="66" TopLine="400"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="420" Column="18" TopLine="400"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="419" Column="18" TopLine="400"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="432" Column="22" TopLine="403"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="418" Column="62" TopLine="398"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="422" Column="72" TopLine="403"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="409" Column="32" TopLine="375"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="291" Column="12" TopLine="247"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="507" Column="20" TopLine="487"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="446" Column="34" TopLine="412"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="421" Column="63" TopLine="404"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="427" Column="71" TopLine="411"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="424" Column="42" TopLine="405"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="426" Column="52" TopLine="408"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="291" Column="12" TopLine="247"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="425" Column="157" TopLine="406"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="440" Column="48" TopLine="416"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="436" Column="42" TopLine="417"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="437" Column="42" TopLine="417"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="446" Column="69" TopLine="415"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="439" Column="55" TopLine="418"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="382" Column="23" TopLine="361"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="407" Column="11" TopLine="394"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="445" Column="87" TopLine="419"/>
|
||||
</Position>
|
||||
<Position>
|
||||
<Filename Value="gcodegenerator_v4.pas"/>
|
||||
<Caret Line="582" Column="3" TopLine="621"/>
|
||||
</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>
|
654
gcode/Generator/gcodegenerator_v4.pas
Normal file
654
gcode/Generator/gcodegenerator_v4.pas
Normal file
|
@ -0,0 +1,654 @@
|
|||
program gcodegenerator_v4;
|
||||
|
||||
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 <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);
|
||||
// *** 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.
|
Binary file not shown.
|
@ -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\gcode\Generator\ -FUD:\Documents\GitHub\motor-wire-winder\gcode\Generator\lib\x86_64-win64\ -FED:\Documents\GitHub\motor-wire-winder\gcode\Generator\ -oD:\Documents\GitHub\motor-wire-winder\gcode\Generator\gcodegenerator_v4.exe gcodegenerator_v4.pas"/>
|
||||
</CONFIG>
|
BIN
gcode/Generator/lib/x86_64-win64/gcodegenerator_v4.o
Normal file
BIN
gcode/Generator/lib/x86_64-win64/gcodegenerator_v4.o
Normal file
Binary file not shown.
25
gcode/Generator/trident_coil.txt
Normal file
25
gcode/Generator/trident_coil.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
;Lair:1 <--
|
||||
39 19.04500 28.01500
|
||||
|
||||
;Lair:2 -->
|
||||
37 27.67 19.16
|
||||
|
||||
;Lair:3 <--
|
||||
32 20.425 27.7850
|
||||
|
||||
;Lair:4 -->
|
||||
26 27.67 21.69
|
||||
|
||||
;Lair:5 <--
|
||||
19 23.415 27.7850
|
||||
|
||||
;Lair:6 -->
|
||||
13 27.67 24.68
|
||||
|
||||
;Lair:7 <--
|
||||
5 26.635 27.7850
|
||||
|
||||
;Lair:8 -->
|
||||
38 27.67 18.93
|
||||
|
||||
;CoilTurnsSum: 209
|
15
gcode/Generator/trident_coil2.txt
Normal file
15
gcode/Generator/trident_coil2.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
;Ñalculations resulted in MaxLayers=8 because it is even, MaxLayers=MaxLayers-1 and equal 7
|
||||
;Lair:1 have 9.00000mm 39 Turns NewStartZ=19.04500 EndZ=28.01500
|
||||
|
||||
;Lair:2 have 9.00000mm 39 Turns NewStartZ=27.78500 EndZ=18.81500
|
||||
|
||||
;Lair:3 have 8.94590mm 39 Turns NewStartZ=19.04500 EndZ=28.01500
|
||||
|
||||
;Lair:4 have 7.19888mm 31 Turns NewStartZ=27.78500 EndZ=20.65500
|
||||
|
||||
;Lair:5 have 5.45185mm 24 Turns NewStartZ=22.49500 EndZ=28.01500
|
||||
|
||||
;Lair:6 have 3.70483mm 16 Turns NewStartZ=27.78500 EndZ=24.10500
|
||||
|
||||
;Lair:7 have 1.95781mm 9 Turns NewStartZ=25.94500 EndZ=28.01500
|
||||
|
19
gcode/Generator/trident_coil3.txt
Normal file
19
gcode/Generator/trident_coil3.txt
Normal file
|
@ -0,0 +1,19 @@
|
|||
;Ñalculations resulted in MaxLayers=8 because it is even, MaxLayers=MaxLayers-1 and equal 7
|
||||
;Lair:1 have 9.00000mm 39 Turns NewStartZ=19.04500 EndZ=28.01500
|
||||
;39 19.04500 28.01500
|
||||
39 19.04500 28.01500
|
||||
;Lair:2 have 9.00000mm 39 Turns NewStartZ=27.78500 EndZ=18.81500
|
||||
;39 27.78500 18.81500
|
||||
39 27.78500 18.81500
|
||||
;Lair:3 have 8.18632mm 36 Turns NewStartZ=19.73500 EndZ=28.01500
|
||||
36 19.73500 28.01500
|
||||
;Lair:4 have 6.43930mm 28 Turns NewStartZ=27.78500 EndZ=21.34500
|
||||
28 27.78500 21.34500
|
||||
;Lair:5 have 4.69228mm 20 Turns NewStartZ=23.41500 EndZ=28.01500
|
||||
20 23.41500 28.01500
|
||||
;Lair:6 have 2.94525mm 13 Turns NewStartZ=27.78500 EndZ=24.79500
|
||||
13 27.78500 24.79500
|
||||
;Lair:7 have 1.19823mm 5 Turns NewStartZ=26.86500 EndZ=28.01500
|
||||
6 26.86500 28.01500
|
||||
|
||||
;CoilTurnsSum: 180
|
|
@ -1,3 +1,7 @@
|
|||
# Èìÿ ñòàòîðà
|
||||
stator_name=Plastic_72mm
|
||||
# Ðåæèì ðàáîòû (auto, manual)
|
||||
Operation_Mode=manual
|
||||
# диаметр основания статора
|
||||
base_dia=37,8
|
||||
# количество лучей статора
|
||||
|
@ -33,7 +37,7 @@ wire_diameter=0,23
|
|||
needle_diameter=1,25
|
||||
|
||||
# зазор пути
|
||||
path_clearance=0,4
|
||||
path_clearance=0,2
|
||||
|
||||
# скорость намотки
|
||||
work_speed=500
|
||||
|
|
File diff suppressed because it is too large
Load diff
33569
gcode/Generator/trident_output3.gcode
Normal file
33569
gcode/Generator/trident_output3.gcode
Normal file
File diff suppressed because it is too large
Load diff
40295
gcode/Generator/trident_output4.gcode
Normal file
40295
gcode/Generator/trident_output4.gcode
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1 +1 @@
|
|||
gcodegenerator_v3.exe trident_input.txt trident_output.gcode
|
||||
gcodegenerator_v4.exe trident_input.txt trident_output.gcode trident_coil.txt
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue