diff --git a/bin/app.php b/bin/app.php index 97c362a..c024861 100644 --- a/bin/app.php +++ b/bin/app.php @@ -1,14 +1,16 @@ toolMemory->save(new Tool(1, 5500, 2)); -$machine->toolMemory->save(new Tool(2, 3000, 61379)); +$machine->TM->write(new ToolData(1, 5500, 2)); +$machine->TM->write(new ToolData(2, 3000, 61379)); (new ProgramLoader)->loadPrograms($machine); $machine->loadProgram(9002); -$machine->start(); +while ($machine->PPMC->ready()) { + $machine->step(); +} diff --git a/ref/block_structure.jpeg b/ref/block_structure.jpeg new file mode 100644 index 0000000..eb8f887 Binary files /dev/null and b/ref/block_structure.jpeg differ diff --git a/ref/program_code_1.jpeg b/ref/program_code_1.jpeg new file mode 100644 index 0000000..f5ea274 Binary files /dev/null and b/ref/program_code_1.jpeg differ diff --git a/ref/program_code_2.jpeg b/ref/program_code_2.jpeg new file mode 100644 index 0000000..5fbde8f Binary files /dev/null and b/ref/program_code_2.jpeg differ diff --git a/ref/program_code_3.jpeg b/ref/program_code_3.jpeg new file mode 100644 index 0000000..08386ca Binary files /dev/null and b/ref/program_code_3.jpeg differ diff --git a/ref/programmable_words.jpeg b/ref/programmable_words.jpeg new file mode 100644 index 0000000..9c771f9 Binary files /dev/null and b/ref/programmable_words.jpeg differ diff --git a/ref/spindle_speeds.jpeg b/ref/spindle_speeds.jpeg new file mode 100644 index 0000000..4be332f Binary files /dev/null and b/ref/spindle_speeds.jpeg differ diff --git a/src/Automata/Registers.php b/src/Automata/DataRegisters.php similarity index 55% rename from src/Automata/Registers.php rename to src/Automata/DataRegisters.php index 870521d..a59a876 100644 --- a/src/Automata/Registers.php +++ b/src/Automata/DataRegisters.php @@ -2,7 +2,7 @@ namespace Automata; -class Registers +class DataRegisters { public int $B = 0; // Traverse information public int $X = 0; // Dimension along X-axis @@ -17,5 +17,14 @@ class Registers public int $T = 0; // Tool number public int $H = 0; // Additional functions (unused) public int $M = 0; // Auxiliary functions - public int $E = 0; // Number of repetitions / multiple meanins + public int $E = 0; // Number of repetitions / multiple meanings + // Modals + public int $TM = 0; // Traverse (0, 1, 2, 3) + public int $PS = 18; // Plane Selection (18, 19, 20) + public int $RC = 40; // Radius Compensation + public int $DM = 90; // Dimension (90, 91) + public int $WC = 0; // Work Cycle (null, 81, 84, 85, 86) + public int $CM = 8; // Coolant (8, 9) + public int $SM = 5; // Spindle (3, 4, 5) + public int $TC = 10; // Table Clamping (10, 11) } diff --git a/src/Automata/InstructionSet.php b/src/Automata/InstructionSet.php new file mode 100644 index 0000000..a094953 --- /dev/null +++ b/src/Automata/InstructionSet.php @@ -0,0 +1,41 @@ +[] */ + private array $map; + + + public function __construct(Machine $machine) + { + $this->machine = $machine; + $this->map = []; + } + + + public function apply(Block $block): void + { + $words = $block->words; + while ($word = array_shift($words)) { + $method = "{$word}"; + if (!method_exists($this, $method)) { + continue; + } + $this->{$method}($block); + break; + } + } + + + public function G22(Block $block): void + { + $number = $block->valueOf('X'); + $this->machine->SPMC->loadProgram($number); + $this->machine->AMC = $this->machine->SPMC; + } +} diff --git a/src/Automata/Machine.php b/src/Automata/Machine.php index 344e216..3cadab1 100644 --- a/src/Automata/Machine.php +++ b/src/Automata/Machine.php @@ -2,79 +2,57 @@ namespace Automata; -use Automata\Storage\ProgramMemory; -use Automata\Storage\ToolMemory; -use Program\Block; -use Program\Program; -use Program\Word; -use RuntimeException; -use SplStack; +use Automata\Memory\MemoryController; +use Automata\Memory\ProgramMemory; +use Automata\Memory\ToolMemory; -/* - * executing a program: - * - load parts program - * - execute line by line - * - load sub program - * - execute lines from subprogram - * - back to parts program - */ class Machine { - public State $state; - public ToolMemory $toolMemory; - public ProgramMemory $subProgramMemory; - public ProgramMemory $partProgramMemory; - /** @var SplStack|Program[] */ - private SplStack $programStack; - private ?Program $activeProgram = null; - private Definitions $definitions; + public DataRegisters $DR; + public InstructionSet $IS; + public ToolMemory $TM; + public ProgramMemory $SPM; + public ProgramMemory $PPM; + public MemoryController $SPMC; + public MemoryController $PPMC; + public ?MemoryController $AMC; public function __construct() { - $this->state = new State(); - $this->definitions = new Definitions(); - $this->toolMemory = new ToolMemory(); - $this->subProgramMemory = new ProgramMemory(); - $this->partProgramMemory = new ProgramMemory(); - $this->programStack = new SplStack(); + $this->DR = new DataRegisters(); + $this->IS = new InstructionSet($this); + $this->TM = new ToolMemory(); + $this->SPM = new ProgramMemory(); + $this->PPM = new ProgramMemory(); + $this->SPMC = new MemoryController($this->SPM); + $this->PPMC = new MemoryController($this->PPM); + $this->AMC = $this->PPMC; } public function loadProgram(int $N): void { - $this->programStack = new SplStack(); - $program = $this->partProgramMemory->read($N); - $this->programStack->push($program); + $this->PPMC->loadProgram($N); + $this->AMC = $this->PPMC; } - public function start(): void + public function step(): void { - $this->activeProgram = $this->programStack->pop(); - if (is_null($this->activeProgram)) { - throw new RuntimeException('No program loaded'); - } - foreach ($this->activeProgram as $block) { - $this->executeBlock($block); - } - } - - private function executeBlock(Block $block): void - { - /** @var Word[] $words */ - $words = $block->words; - while ($word = array_shift($words)) { - $this->state->apply($word); - system('clear'); - dump($this->state); - readline(); + $block = $this->AMC->next(); + if (is_null($block) && $this->AMC === $this->SPMC) { + // SP ended, back to PP + $this->AMC = $this->PPMC; + $block = $this->AMC->next(); } + $this->IS->apply($block); } public function reset(): void { - $this->activeProgram = null; + $this->PPMC->reset(); + $this->SPMC->reset(); } } diff --git a/src/Automata/Memory/MemoryController.php b/src/Automata/Memory/MemoryController.php new file mode 100644 index 0000000..7e44363 --- /dev/null +++ b/src/Automata/Memory/MemoryController.php @@ -0,0 +1,66 @@ +memory = $memory; + $this->blocks = null; + } + + + public function loadProgram(int $N): void + { + $program = $this->memory->read($N); + if (!$program) { + throw new InvalidArgumentException("Program N{$N} not found"); + } + $this->blocks = $program->getIterator()->getArrayCopy(); + } + + + public function reset(): void + { + $this->blocks = null; + } + + + public function count() + { + return count($this->blocks); + } + + + public function next(): ?Block + { + $this->guardNoProgramLoaded(); + + return array_shift($this->blocks); + } + + + public function ready(): bool + { + return !empty($this->blocks); + } + + + private function guardNoProgramLoaded(): void + { + if (is_null($this->blocks)) { + throw new RuntimeException('No program loaded in memory'); + } + } +} diff --git a/src/Automata/Storage/ProgramMemory.php b/src/Automata/Memory/ProgramMemory.php similarity index 86% rename from src/Automata/Storage/ProgramMemory.php rename to src/Automata/Memory/ProgramMemory.php index 0261be1..dbece46 100644 --- a/src/Automata/Storage/ProgramMemory.php +++ b/src/Automata/Memory/ProgramMemory.php @@ -1,6 +1,6 @@ guardInvalidProgramNumber($program->N); $this->memory[$program->N] = $program; @@ -30,5 +30,4 @@ class ProgramMemory throw new InvalidArgumentException('Program number must be in range 9001 - 9998'); } } - } diff --git a/src/Automata/Storage/ToolMemory.php b/src/Automata/Memory/ToolMemory.php similarity index 70% rename from src/Automata/Storage/ToolMemory.php rename to src/Automata/Memory/ToolMemory.php index a94d145..0c5c0e1 100644 --- a/src/Automata/Storage/ToolMemory.php +++ b/src/Automata/Memory/ToolMemory.php @@ -1,24 +1,24 @@ guardInvalidToolNumber($tool->T); $this->memory[$tool->T] = $tool; } - public function read(int $T): ?Tool + public function read(int $T): ?ToolData { return @$this->memory[$T]; } @@ -30,5 +30,4 @@ class ToolMemory throw new InvalidArgumentException('Tool number must be in range 1 - 64'); } } - } diff --git a/src/Automata/State.php b/src/Automata/State.php deleted file mode 100644 index 215a4b5..0000000 --- a/src/Automata/State.php +++ /dev/null @@ -1,71 +0,0 @@ -registers = new Registers(); - $this->traverseMode = new TraverseMode(0); - $this->planeSelection = new PlaneSelection(17); - $this->radiusCompensation = new RadiusCompensation(40); - $this->dimensionMode = new DimensionMode(90); - $this->workCycleSelection = new WorkCycle(0); - - $this->coolantMode = new CoolantMode(9); - $this->spindleMode = new SpindleMode(5); - $this->tableClamping = new TableClampingMode(10); - } - - - public function apply(Word $word): void - { - if ($word->register === 'G') { - $this->traverseMode->apply($word->value); - $this->planeSelection->apply($word->value); - $this->radiusCompensation->apply($word->value); - $this->dimensionMode->apply($word->value); - $this->workCycleSelection->apply($word->value); - - // TODO Handle other G commands - - return; - } - if ($word->register === 'M') { - $this->coolantMode->apply($word->value); - $this->spindleMode->apply($word->value); - $this->tableClamping->apply($word->value); - - // TODO Handle other M commands - return; - } - - if (property_exists($this->registers, $word->register)) { - $this->registers->{$word->register} = $word->value; - } - } -} diff --git a/src/Automata/Tool.php b/src/Automata/ToolData.php similarity index 94% rename from src/Automata/Tool.php rename to src/Automata/ToolData.php index 6004806..be6cfe0 100644 --- a/src/Automata/Tool.php +++ b/src/Automata/ToolData.php @@ -2,7 +2,7 @@ namespace Automata; -class Tool +class ToolData { public int $T; // Tool number public int $X; // Radius in 0.001 mm diff --git a/src/Program/Block.php b/src/Program/Block.php index 9861a55..db9c5ac 100644 --- a/src/Program/Block.php +++ b/src/Program/Block.php @@ -2,6 +2,8 @@ namespace Program; +use RuntimeException; + class Block { public string $N; @@ -20,4 +22,27 @@ class Block { $this->words[] = $word; } + + + public function valueOf(string $register): int + { + foreach ($this->words as $word) { + if ($word->register === $register) { + return $word->value; + } + } + + throw new RuntimeException("No word in block for register '$register'"); + } + + + public function __toString() + { + $buffer = "$this->N\t"; + foreach ($this->words as $word) { + $buffer .= "$word\t"; + } + + return $buffer; + } } diff --git a/src/ProgramLoader.php b/src/ProgramLoader.php index 9749c3c..d615479 100644 --- a/src/ProgramLoader.php +++ b/src/ProgramLoader.php @@ -11,12 +11,12 @@ class ProgramLoader foreach (glob(__DIR__ . '/../programs/part/*') as $partProgramFile) { $partProgram = $parser->parseFile($partProgramFile); - $machine->partProgramMemory->save($partProgram); + $machine->PPM->write($partProgram); } foreach (glob(__DIR__ . '/../programs/sub/*') as $subProgramFile) { $subProgram = $parser->parseFile($subProgramFile); - $machine->subProgramMemory->save($subProgram); + $machine->SPM->write($subProgram); } } }