Ejemplo n.º 1
0
        internal void AddSegment(ToolPathSegment segment)
        {
            if (_lastAddedSegment != null)
            {
                var edgeLimit = PathSpeedLimitCalculator.CalculateEdgeLimit(_lastAddedSegment, segment);
                _edgeLimits[segment] = edgeLimit;
            }

            _lastAddedSegment = segment;

            var segmentInfo = new SegmentPlanningInfo(segment);

            _workSegments.Enqueue(segmentInfo);

            foreach (var limitCalculator in _openLimitCalculators)
            {
                limitCalculator.AddLookaheadSegments(new[] { segment }, _edgeLimits);
            }

            _openLimitCalculators.Add(segmentInfo.LimitCalculator);
            foreach (var limitCalculator in _openLimitCalculators.ToArray())
            {
                if (!limitCalculator.NeedsMoreFollowingSegments)
                {
                    _openLimitCalculators.Remove(limitCalculator);
                }
            }
        }
Ejemplo n.º 2
0
        internal InstructionCNC GenerateNextInstruction(double desiredSpeed)
        {
            if (_currentSlicer == null || _currentSlicer.IsComplete)
            {
                if (_currentSlicer != null)
                {
                    _completedLength += _currentSlicer.CompletedLength;
                }

                _currentSegmentInfo    = _workSegments[_nextWorkSegmentIndex];
                _currentSlicer         = new ToolPathSegmentSlicer(_currentSegmentInfo.Segment);
                _nextWorkSegmentIndex += 1;
            }

            var limitCalculator    = _currentSegmentInfo.LimitCalculator;
            var currentSegment     = _currentSegmentInfo.Segment;
            var smoothingLookahead = 5.0 / currentSegment.Length;
            var speedLimit         = limitCalculator.GetLimit(_currentSlicer.SliceProgress);

            double speedLimitLookahead;

            if (_currentSpeed < speedLimit)
            {
                // lookahead is useful to prevent short term accelerations - call it only when acceleration is possible
                speedLimitLookahead = limitCalculator.GetLimit(Math.Min(1.0, _currentSlicer.SliceProgress + smoothingLookahead));
            }
            else
            {
                speedLimitLookahead = speedLimit;
            }

            var targetSpeed = Math.Min(desiredSpeed, speedLimit);

            if (_currentSpeed < speedLimitLookahead)
            {
                //allow acceleration only when limit is far enough
                _currentSpeed = PathSpeedLimitCalculator.TransitionSpeedTo(_currentSpeed, targetSpeed);
            }

            var newSpeed = Math.Min(_currentSpeed, speedLimit); //speed limits are valid (acceleration limits accounted)

            _currentSpeed = newSpeed;

            return(_currentSlicer.Slice(_currentSpeed, PathSpeedLimitCalculator.TimeGrain));
        }
Ejemplo n.º 3
0
        internal void MoveToCompletedLength(double targetLength)
        {
            --_nextWorkSegmentIndex;

            if (_nextWorkSegmentIndex < 1)
            {
                _completedLength      = 0;
                _nextWorkSegmentIndex = 0;
            }


            while (_completedLength > targetLength)
            {
                --_nextWorkSegmentIndex;
                _currentSegmentInfo = _workSegments[_nextWorkSegmentIndex];
                _completedLength   -= _currentSegmentInfo.Segment.Length;
            }

            while (_completedLength < targetLength && _nextWorkSegmentIndex < _workSegments.Length)
            {
                _currentSegmentInfo = _workSegments[_nextWorkSegmentIndex];
                if (_completedLength + _currentSegmentInfo.Segment.Length >= targetLength)
                {
                    // we found the correct segment
                    break;
                }

                ++_nextWorkSegmentIndex;
                _completedLength += _currentSegmentInfo.Segment.Length;
            }

            _currentSegmentInfo = _workSegments[_nextWorkSegmentIndex];
            _currentSlicer      = new ToolPathSegmentSlicer(_currentSegmentInfo.Segment);
            ++_nextWorkSegmentIndex;
            while (_currentSlicer.SliceProgress * _currentSlicer.Segment.Length + _completedLength < targetLength)
            {
                _currentSlicer.Slice(_currentSpeed, PathSpeedLimitCalculator.TimeGrain);

                if (_currentSlicer.IsComplete)
                {
                    break;
                }
            }
        }