private void _stream(DriverCNC2 driver) { PlanStreamerContext intermContext = null; _context = new PlanStreamerContext(true); foreach (var part in PlanParts) { var s = part.StartPoint; var e = part.EndPoint; var segment = new ToolPathSegment(new Point3D(s.X, s.Y, s.Z), new Point3D(e.X, e.Y, e.Z), MotionMode.IsLinear); _context.AddSegment(segment); } var zeroCompatibleSpeed = Configuration.ReverseSafeSpeed.ToMetric(); var instructionBuffer = new Queue <InstructionCNC>(); var maxPlannedInstructionCount = 5; var currentContext = _context; while (!currentContext.IsComplete || intermContext != null) { if (intermContext != null && intermContext.IsComplete) { intermContext = null; currentContext = _context; continue; } while (_stop && _context.CurrentSpeed <= zeroCompatibleSpeed) { _isStreaming = false; Thread.Sleep(10); } _isStreaming = true; if (IsChangingPosition) { // create intermediate context which will transfer machine to the new position var np = CurrentStreamPosition.As3Dmm(); var cp = driver.CurrentState.As3Dstep().As3Dmm(); var cpTransition = new Point3Dmm(cp.X, cp.Y, _transitionLevel); var npTransition = new Point3Dmm(np.X, np.Y, _transitionLevel); intermContext = new PlanStreamerContext(false); intermContext.AddSegment(new ToolPathSegment(cp.As3D(), cpTransition.As3D(), MotionMode.IsLinear)); intermContext.AddSegment(new ToolPathSegment(cpTransition.As3D(), npTransition.As3D(), MotionMode.IsLinear)); intermContext.AddSegment(new ToolPathSegment(npTransition.As3D(), np.As3D(), MotionMode.IsLinear)); currentContext = intermContext; IsChangingPosition = false; } if (driver.IncompleteInstructionCount >= maxPlannedInstructionCount) { //wait some time so we are not spinning like crazy Thread.Sleep(1); continue; } do { double speed; lock (_L_speed) { speed = _stream_cuttingSpeed; } if (_stop) { speed = zeroCompatibleSpeed; } var instruction = currentContext.GenerateNextInstruction(speed, stopRemainingTimeLockstep: _stop); instructionBuffer.Enqueue(instruction); } while (driver.IncompleteInstructionCount == 0 && !currentContext.IsComplete && instructionBuffer.Count < maxPlannedInstructionCount); while (instructionBuffer.Count > 0) { var instruction = instructionBuffer.Dequeue(); if (!driver.SEND(instruction)) { throw new InvalidOperationException("Instruction was not accepted. (Probably over bounds?). Progress: " + Progress * 100); } } } while (driver.IncompleteInstructionCount > 0) { //wait until all instructions are completed Thread.Sleep(10); } StreamingIsComplete?.Invoke(); }
private void _stream(DriverCNC2 driver) { var context = new PlanStreamerContext(); foreach (var part in PlanParts) { var s = part.StartPoint; var e = part.EndPoint; var segment = new ToolPathSegment(new Point3D(s.X, s.Y, s.Z), new Point3D(e.X, e.Y, e.Z), MotionMode.IsLinear); context.AddSegment(segment); } var zeroCompatibleSpeed = Configuration.ReverseSafeSpeed.ToMetric(); var instructionBuffer = new Queue <InstructionCNC>(); var maxPlannedInstructionCount = 5; while (!context.IsComplete) { while (_stop && context.CurrentSpeed <= zeroCompatibleSpeed) { _isStreaming = false; Thread.Sleep(10); } _isStreaming = true; if (driver.IncompleteInstructionCount >= maxPlannedInstructionCount) { //wait some time so we are not spinning like crazy Thread.Sleep(1); continue; } do { double speed; lock (_L_speed) speed = _stream_cuttingSpeed; if (_stop) { speed = zeroCompatibleSpeed; } var instruction = context.GenerateNextInstruction(speed); instructionBuffer.Enqueue(instruction); } while (driver.IncompleteInstructionCount == 0 && !context.IsComplete && instructionBuffer.Count < maxPlannedInstructionCount); while (instructionBuffer.Count > 0) { var instruction = instructionBuffer.Dequeue(); driver.SEND(instruction); } } while (driver.IncompleteInstructionCount > 0) { //wait until all instructions are completed Thread.Sleep(10); } StreamingIsComplete?.Invoke(); }
private void _stream(DriverCNC2 driver) { var planStream = new PlanStream3D(_plan.ToArray()); var preloadTime = 0.05; var startTime = DateTime.Now; var lastTimeMeasure = startTime; var lastTotalSecondsRefreshTime = startTime; var lastCuttingSpeed = Speed.Zero; var currentlyQueuedTime = 0.0; var timeQueue = new Queue <double>(); while (!planStream.IsComplete) { var currentCuttingSpeed = _stream_cuttingSpeed; var currentTime = DateTime.Now; if ((currentTime - lastTotalSecondsRefreshTime).TotalSeconds > 5.0) { //force recalculation every few seconds lastCuttingSpeed = null; } if (lastCuttingSpeed != currentCuttingSpeed) { //recalculate totalSeconds lastCuttingSpeed = currentCuttingSpeed; var cuttingDistance = planStream.GetRemainingConstantDistance(); var rampTime = planStream.GetRemainingRampTime(); var totalElapsedTime = (currentTime - startTime).TotalSeconds; _totalSeconds = totalElapsedTime + rampTime + cuttingDistance / currentCuttingSpeed.ToMetric() + currentlyQueuedTime; lastTotalSecondsRefreshTime = currentTime; } var timeElapsed = (currentTime - lastTimeMeasure).TotalSeconds; lastTimeMeasure = currentTime; if (driver.IncompleteInstructionCount >= 3) { //wait some time so we are not spinning like crazy Thread.Sleep(5); continue; } if (timeQueue.Count > 0) { currentlyQueuedTime -= timeQueue.Dequeue(); } IEnumerable <InstructionCNC> nextInstructions; if (planStream.IsSpeedLimitedBy(Configuration.MaxCuttingSpeed)) { var lengthLimit = preloadTime * currentCuttingSpeed.ToMetric(); nextInstructions = planStream.ShiftByConstantSpeed(lengthLimit, currentCuttingSpeed); } else { nextInstructions = planStream.NextRampInstructions(); } driver.SEND(nextInstructions); var duration = nextInstructions.Select(i => i.CalculateTotalTime()); var timeToQueue = duration.Sum(d => (float)d) / Configuration.TimerFrequency; currentlyQueuedTime += timeToQueue; timeQueue.Enqueue(currentlyQueuedTime); } while (driver.IncompleteInstructionCount > 0) { Thread.Sleep(10); } StreamingIsComplete?.Invoke(); }