Beispiel #1
0
    /// <summary>
    /// Tries assigning an extruder to the arcs.
    /// </summary>
    /// <returns>
    /// True if successful; false if another extruder
    /// has already been assigned.
    /// </returns>
    /// <param name='anExtruder'>
    /// The extruder to assign.
    /// </param>
    /// <param name='toRing'>
    /// The ring number we care about.
    /// </param>
    public bool TryAssigning(PrinterExtruder anExtruder)
    {
        int toRing = Mathf.Abs(anExtruder.relativeRing);

        foreach (Arc anArc in m_arcs[toRing])
        {
            if (anArc.material == anExtruder.materialNumber)
            {
                // If we find an arc with another motor assigned,
                // then we have to handle the conflicts.
                if (anArc.motor == null)
                {
                    anArc.motor = anExtruder;
                }
                else
                {
                    Contract.Assert((PrinterExtruder)anArc.motor != anExtruder,
                                    @"Arc's motor {0} same as tested extruder; TryAssigning() called multiple times for same ring {1}.",
                                    anArc.motor, toRing);
                    return(false);
                }
            }
        }

        // The arcs, if any, were successfully assigned.
        return(true);
    }
Beispiel #2
0
    /// <summary>
    /// Clones this instance.
    /// </summary>
    public override PrinterMotor Clone()
    {
        PrinterExtruder result = new PrinterExtruder();

        Populate(result);
        return(result);
    }
Beispiel #3
0
 /// <summary>
 /// Clones this instance.
 /// </summary>
 public void Populate(PrinterExtruder result)
 {
     base.Populate(result);
     result.ringNumber            = ringNumber;
     result.targetTemperatureC    = targetTemperatureC;
     result.firstLayerTemperature = firstLayerTemperature;
     result.materialNumber        = materialNumber;
 }
Beispiel #4
0
 public MotorRateMover(PrinterExtruder anExtruder, StepDirection aDirection,
                       StepSize aSize, int aRate, int aGlobalStepStart, int totalStepCount)
 {
     motor           = (PrinterMotor)anExtruder;
     direction       = aDirection;
     size            = aSize;
     stepRate        = aRate;
     globalStartStep = aGlobalStepStart;
     stepCount       = totalStepCount;
 }
Beispiel #5
0
    /// <summary>
    /// Fills the provided queue with normalized arcs for the
    /// provided extruder. Should be called after StartExtraction().
    /// </summary>
    /// <param name='anExtruder'>
    /// The extruder we're searching for.
    /// </param>
    /// <param name='destination'>
    /// The final arc location.
    /// </param>
    public void ExtractArcsFor(PrinterExtruder anExtruder, List <Arc>[] destination)
    {
        int atRing = Mathf.Abs(anExtruder.relativeRing);

        // We're done if it's more than the outer ring.
        if (atRing > m_outerRing)
        {
            return;
        }

        List <Arc> arcs = m_arcs[atRing];

        int initialArcCount = m_arcCount;

        for (int anArcId = 0; anArcId < arcs.Count; /* NOP */)
        {
            Arc anArc = arcs[anArcId];

            if (anArc.motor == anExtruder)
            {
                destination[anExtruder.id].Add(anArc);
                arcs.RemoveAt(anArcId);

                m_earliestStep = Mathf.Min(m_earliestStep, anArc.startStep);
                m_latestStep   = Mathf.Max(m_latestStep, anArc.endStep);
                --m_arcCount;
            }
            else
            {
                ++anArcId;
            }
        }

        Contract.Assert(m_arcCount == initialArcCount ? true : m_earliestStep <= m_latestStep,
                        @"Ring {0}: Earliest step ({1}) larger than latest step ({2})",
                        atRing, m_earliestStep, m_latestStep);

        // Did we empty a ring?
        if (m_arcCount < initialArcCount && arcs.Count == 0)
        {
            --m_ringCount;
        }
    }
Beispiel #6
0
    static void Extrude(Arc anArc, int atRate, int usingPlatformStepRate, List <TickProfile> forList)
    {
        Contract.Assert(atRate > 0, @"Expected positive extrusion rate, not {0}.", atRate);

        PrinterExtruder extruder = (PrinterExtruder)anArc.motor;

        if (!anArc.hasVariableStepRate)
        {
            extruder.stepsExtruded += anArc.length;

            // Scale small arc step rate by a constant.
            if (anArc.length < kSmallArcLimit)
            {
                atRate = Mathf.RoundToInt(atRate / kSmallArcRateScale);
            }

            TickProfile result = new TickProfile(anArc, usingPlatformStepRate, atRate);
            if (result.tickLength > 0)
            {
                forList.Add(result);
            }
        }
        else
        {
            extruder.stepsExtruded += anArc.variableStepLocations.Length;
            foreach (int singleArc in anArc.variableStepLocations)
            {
                Arc aNewArc = new Arc(anArc);
                aNewArc.startStep = anArc.startStep + singleArc;
                aNewArc.endStep   = aNewArc.startStep + 1;
                TickProfile result = new TickProfile(aNewArc, usingPlatformStepRate, usingPlatformStepRate);
                if (result.tickLength > 0)
                {
                    forList.Add(result);
                }
                else
                {
                    Text.Error("Came up with a tickprofile with no movement while processing arc " + aNewArc);
                }
                //Text.Log("For " + aNewArc + " we came up with profile " + result);
            }
        }
    }
Beispiel #7
0
    static int ApplyPressure(PrinterMotor forMotor, StepDirection inDirection,
                             int usingPressureSteps, int usingPlatformRotation, List <TickProfile> toList)
    {
        Contract.Assert(usingPressureSteps <= kPressureSteps,
                        @"Requested {0} pressure steps; maximum is {1}.",
                        usingPressureSteps, kPressureSteps);

        // NOTE: We don't know how many steps it'll take to
        // accelerate over usingPressureSteps. So we need
        // to treat everything as if it stepped from
        // [0, usingPressureSteps) and then scale the
        // resulting ticks by anArc.startingStep.
        Arc pressureArc = new Arc(forMotor, 0);

        pressureArc.startStep = 0;
        pressureArc.endStep   = usingPressureSteps;
        pressureArc.direction = inDirection;

        PrinterExtruder extruder = (PrinterExtruder)forMotor;

        if (inDirection == StepDirection.Ccw)
        {
            extruder.pressureRequired -= usingPressureSteps;

            Contract.Assert(extruder.pressureRequired >= 0,
                            @"Pressurized more than {0} steps.", kPressureSteps);
        }
        else
        {
            extruder.pressureRequired += usingPressureSteps;

            Contract.Assert(extruder.pressureRequired <= kPressureSteps,
                            @"Motor {0} required pressure of {1} exceeds max of {2}.",
                            extruder.id, extruder.pressureRequired, kPressureSteps);
        }

        int ticksTaken = Accelerate(pressureArc, usingPlatformRotation, toList);

        Contract.Assert(ticksTaken > 0, @"Non-positive ticks taken over {0} step{1}.",
                        ticksTaken, Text.S(ticksTaken));
        return(ticksTaken);
    }
Beispiel #8
0
    void Extrude(PrinterExtruder anExtruder)
    {
        List <Vector4> points    = extrudedPoints[anExtruder.id];
        int            prevIndex = points.Count - 1;

        int pressureDelta = anExtruder.stepDirection == StepDirection.Ccw ? 1 : -1;

        anExtruder.pressureRequired = Mathf.Clamp(anExtruder.pressureRequired - pressureDelta,
                                                  0, TickProfile.kPressureSteps);

        if (onlyCollectExtruded && anExtruder.pressureRequired > 0)
        {
            if (prevIndex >= 0 && points[prevIndex] != gap)
            {
                points.Add(gap);
            }
            return;
        }

        float relativePosition = -(m_simulation.platformRadiusInMm - (float)m_simulation.horizTrack.position);
        float distFromCenter   = anExtruder.DistanceFromPlatCenterInMm(relativePosition);
        float angleInRad       = m_simulation.platform.rotationInDegrees * Mathf.Deg2Rad;

        float colorIndex = ((anExtruder.id - kExtruderBase) * 2)
                           + ((anExtruder.stepDirection == StepDirection.Ccw) ? 0 : 1);

        Vector4 point = new Vector4(distFromCenter * Mathf.Cos(angleInRad) + m_simulation.platformRadiusInMm,
                                    m_trans.position.y,
                                    distFromCenter * Mathf.Sin(angleInRad),
                                    colorIndex);

        /*
         * if (points.Count > 1
         *      && (points[prevIndex].w == point.w)
         *      && ((Vector3)(point - points[prevIndex])).sqrMagnitude < kSqrThreshold) return;
         */
        extrudedPoints[anExtruder.id].Add(point);
    }
Beispiel #9
0
    void StepMotors()
    {
        //Text.Log(string.Format("Steps remaining: {0}, {1}", m_motorSteps[0], m_motorSteps[1]));
        for (int aMotorId = 0; aMotorId < m_motors.Length; ++aMotorId)
        {
            PrinterMotor aMotor = m_motors[aMotorId];
            if (aMotor.stepRate == 0)
            {
                continue;
            }

            --aMotor.stepCounter;
            if (aMotor.stepCounter == 0)
            {
                aMotor.stepCounter     = aMotor.stepRate;
                m_motorSteps[aMotorId] = 1;
            }
        }
        bool hasMoved = false;

        for (int aMotorId = 0; aMotorId < kExtruderBase; ++aMotorId)
        {
            if (m_motorSteps[aMotorId] > 0)
            {
                m_motors[aMotorId].Step();
                --m_motorSteps[aMotorId];
                hasMoved = true;
            }
        }
        for (int aMotorId = kExtruderBase; aMotorId < m_motorSteps.Length; ++aMotorId)
        {
            if (m_motorSteps[aMotorId] > 0)
            {
                m_motors[aMotorId].Step();
                --m_motorSteps[aMotorId];
                Extrude((PrinterExtruder)m_motors[aMotorId]);
                hasMoved = false;
            }
        }

        if (hasMoved && !onlyCollectExtruded)
        {
            PrinterExtruder anExtruder       = (PrinterExtruder)m_motors[4];
            float           relativePosition = m_simulation.platformRadiusInMm - (float)m_simulation.horizTrack.position;
            float           distFromCenter   = anExtruder.DistanceFromPlatCenterInMm(relativePosition);
            float           angleInRad       = m_simulation.platform.rotationInDegrees * Mathf.Deg2Rad;

            Vector4 point = new Vector4(distFromCenter * Mathf.Cos(angleInRad) + m_simulation.platformRadiusInMm,
                                        -m_trans.position.y,
                                        distFromCenter * Mathf.Sin(angleInRad),
                                        4);
            movementWithoutExtrusion.Add(point);
        }

        m_globalSteps = (m_globalSteps + 1) & 0xFFFFFFFF;

        Vector3 platformPosition = new Vector3(-(float)m_simulation.horizTrack.position,
                                               (float)m_simulation.vertTrack[0].position, 0);

        m_trans.position = platformPosition;
        m_trans.rotation = Quaternion.Euler(0, m_simulation.platform.rotationInDegrees, 0);
    }
Beispiel #10
0
 public Vector3 GetExtruderCartesianPosition(PrinterExtruder anExtruder)
 {
     return(MathUtil.PolarToCartesian(GetExtruderPolarPosition(anExtruder)));
 }
Beispiel #11
0
 public Vector3 GetExtruderPolarPosition(PrinterExtruder anExtruder)
 {
     return(PolarPosition + new Vector3(PrinterExtruder.kStandardNozzleWidth * anExtruder.ringNumber, 0, 0));
 }
Beispiel #12
0
    /// <summary>
    /// Assign the specified extruder to arcs if the relative
    /// ring matches; otherwise, uses the existing extruder.
    /// </summary>
    /// <param name='forSecondExtruder'>
    /// The extruder we're trying to assign.
    /// </param>
    /// <param name='usingStepsPerRotation'>
    /// Steps required for 1 platform rotation (excluding step-rate).
    /// </param>
    public void ResolveAssignments(PrinterExtruder forSecondExtruder, int usingStepsPerRotation)
    {
        PrinterExtruder firstExtruder = (PrinterExtruder)m_arcs[Mathf.Abs(forSecondExtruder.relativeRing)][0].motor;

        Contract.Assert(firstExtruder.materialNumber == forSecondExtruder.materialNumber,
                        @"Extruder materials differ (#{0}: {1}; #{2}: {3}).",
                        firstExtruder.id, firstExtruder.materialNumber,
                        forSecondExtruder.id, forSecondExtruder.materialNumber);

        PrinterExtruder positiveExtruder = (firstExtruder.relativeRing < 0) ? forSecondExtruder : firstExtruder;
        PrinterExtruder negativeExtruder = (firstExtruder.relativeRing < 0) ? firstExtruder  : forSecondExtruder;

        Contract.Assert(positiveExtruder != negativeExtruder,
                        @"Extruder ids {0} and {1} are identical.", firstExtruder.id, forSecondExtruder.id);
        Contract.Assert(positiveExtruder.relativeRing > 0,
                        @"Relative ring ({0}) isn't positive for extruder {1}.",
                        positiveExtruder.relativeRing, positiveExtruder.id);
        Contract.Assert(negativeExtruder.relativeRing < 0,
                        @"Relative ring ({0}) isn't negative for extruder {1}.",
                        negativeExtruder.relativeRing, negativeExtruder.id);
        Contract.Assert(positiveExtruder.relativeRing == -negativeExtruder.relativeRing,
                        @"Extruder {0}'s relative ring ({1}) doesn't match extruder {2}'s -relative ring ({3}).",
                        positiveExtruder.id, positiveExtruder.relativeRing,
                        negativeExtruder.id, negativeExtruder.relativeRing);


        List <Arc> arcs = m_arcs[positiveExtruder.relativeRing];
        int        stepsPerHalfRotation = usingStepsPerRotation / 2;

        for (int arcId = 0; arcId < arcs.Count; ++arcId)
        {
            Arc anArc = arcs[arcId];
            // Skip arcs if they are for different materials.
            if (anArc.material != positiveExtruder.materialNumber)
            {
                continue;
            }

            if (anArc.startStep < stepsPerHalfRotation && anArc.endStep < stepsPerHalfRotation)
            {
                // Case 1: Everything happens before 180°, so use the positive extruder.
                anArc.motor = positiveExtruder;
            }
            else if (anArc.startStep >= stepsPerHalfRotation && anArc.endStep >= stepsPerHalfRotation)
            {
                // Case 2: Everything happens after 180°, so use the negative extruder.
                anArc.motor = negativeExtruder;
            }
            else
            {
                // Case 3: The arc straddles the 180° line; split it into two.
                Arc secondHalf = new Arc(anArc);

                // NOTE: We can't normalize the arcs yet because arcs
                // assigned to a single extruder with a negative
                // relative ring also need to get normalized.
                secondHalf.startStep = stepsPerHalfRotation;
                secondHalf.motor     = negativeExtruder;

                anArc.endStep = stepsPerHalfRotation;
                anArc.motor   = positiveExtruder;
                arcs.Insert(arcId + 1, secondHalf);

                // Skip the arc we just added.
                ++arcId;
            }
        }
    }