コード例 #1
0
ファイル: TickProfile.cs プロジェクト: njpatter/Radiant-Li
    /// <summary>
    /// Does nothing, as even distances don't require additional patterns.
    /// </summary>
    /// <returns>
    /// The number of new patterns added.
    /// </returns>
    /// <param name='forList'>
    /// THe list to add new patterns to if required.
    /// </param>
    /// <param name='totalTicksWaited'>
    /// The total number of ticks we've waited thus far.
    /// </param>
    static void HandleEvenPattern(List <TickProfile> forList, ref int totalTicksWaited)
    {
        // Instead of having two additional tick profiles, just make one longer one.
        TickProfile lastProfile = forList[forList.Count - 1];

        totalTicksWaited       += lastProfile.tickLength;
        lastProfile.tickLength *= 2;
    }
コード例 #2
0
ファイル: TickProfile.cs プロジェクト: njpatter/Radiant-Li
    /// <summary>
    /// Inserts the extra required step for odd distances.
    /// </summary>
    /// <returns>
    /// The number of new patterns added.
    /// </returns>
    /// <param name='forList'>
    /// The list to add new patterns to if required.
    /// </param>
    /// <param name='totalTicksWaited'>
    /// The total number of ticks we've waited thus far.
    /// </param>
    static void HandleOddPattern(List <TickProfile> forList, ref int totalTicksWaited)
    {
        // Step rate is one more in the future; we also create a gap
        // for the odd value, below.
        TickProfile lastProfile = forList[forList.Count - 1];

        int additionalTicks = lastProfile.tickLength + lastProfile.stepRate;

        lastProfile.tickLength += additionalTicks;
        totalTicksWaited       += additionalTicks;
    }
コード例 #3
0
ファイル: TickProfile.cs プロジェクト: njpatter/Radiant-Li
    /// <summary>
    /// Optionally accelerates the specified arc using the provided platform step rate
    /// to calculate the initial tick location. Results are added to the provided list.
    /// If the arc is small, an unaccelerated TickProfile is added to the list instead.
    /// </summary>
    /// <param name='anArc'>
    /// An arc to accelerate.
    /// </param>
    /// <param name='usingPlatformStepRate'>
    /// The platform's step-rate.
    /// </param>
    /// <param name='forList'>
    /// The list to update.
    /// </param>
    static int Accelerate(Arc anArc, int usingPlatformStepRate, List <TickProfile> forList)
    {
        Contract.Assert(usingPlatformStepRate > 0,
                        @"Expected a positive platform step rate, not {0}.", usingPlatformStepRate);

        TickProfile constantTick = new TickProfile(anArc, usingPlatformStepRate, PrinterExtruder.kDefaultTickRate);

        if (constantTick.tickLength > 0)
        {
            forList.Add(constantTick);
        }
        return(constantTick.tickLength);
    }
コード例 #4
0
ファイル: TickProfile.cs プロジェクト: njpatter/Radiant-Li
    public TickProfile(TickProfile source, int aStartTick)
    {
        motor     = source.motor;
        size      = source.size;
        direction = source.direction;
        stepRate  = source.stepRate;

        startTick  = aStartTick;
        tickLength = source.tickLength;

        // NOTE: Negative tick profiles are OK
        // when pressurizing, so we don't
        // check for negative start ticks.
        Contract.Assert(tickLength >= 0, @"Negative tick length.");
        Contract.Assert(motor != null, @"No motor assigned to tick profile.");
        Contract.Assert(direction != StepDirection.Unknown, @"Unknown step direction.");
    }
コード例 #5
0
ファイル: TickProfile.cs プロジェクト: njpatter/Radiant-Li
    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);
            }
        }
    }
コード例 #6
0
ファイル: TickProfile.cs プロジェクト: njpatter/Radiant-Li
    /// <summary>
    /// Converts the queue of arcs into a list of tick profiles
    /// using the provided platform step-rate for conversion and
    /// optionally with acceleration.
    /// </summary>
    /// <param name='arcs'>
    /// The arc source.
    /// </param>
    /// <param name='toList'>
    /// The target list.
    /// </param>
    /// <param name='usingPlatformStepRate'>
    /// The platform step rate.
    /// </param>
    /// <param name='withAcceleration'>
    /// True for acceleration, false for a constant speed.
    /// </param>
    public static void Convert(List <Arc> fromArcs, List <TickProfile> toList,
                               int usingPlatformStepRate)
    {
        toList.Clear();

        // NOTE(kevin): Could try merging arcs, but this is low
        // priority.
        for (int aI = 0; aI < fromArcs.Count; aI++)
        {
            Arc a = fromArcs[aI];
            if (a.length == 0)
            {
                continue;
            }

            Contract.Assert(a.motor != null, @"No motor assigned for arc {0}.", a);
            TickProfile result = new TickProfile(a, usingPlatformStepRate, usingPlatformStepRate);
            toList.Add(result);
        }

        fromArcs.Clear();
    }
コード例 #7
0
    IEnumerator TestRoutine()
    {
        while (!startAngleTest && !startRotationTest)
        {
            yield return(null);
        }
        Init();
        yield return(null);

        if (startAngleTest)
        {
            int stepDirection = -1;
            int targetAngle   = smallAngle;
            for (int testCount = 0; testCount < 10000000; testCount++)
            {
                stepDirection = -stepDirection;
                targetAngle   = targetAngle == smallAngle ? largeAngle : smallAngle;
                if (true)                  //!shouldUseAccel) {
                {
                    pc.MoveMotorAtSteprateForTicks(workingPrinter, workingPrinter.platform, StepSize.Quarter,
                                                   (StepDirection)stepDirection,
                                                   stepRate, stepRate * numStepsPerRot * targetAngle / 360);
                }

                /*
                 * else {
                 *      TickProfile aProfile;
                 *      for(int i = 0; i < rates.Length - 1; i++) {
                 *              aProfile = new TickProfile(workingPrinter.platform,
                 *                                                     StepSize.Quarter,
                 *                                                     (StepDirection)stepDirection,
                 *                                                     rates[i],
                 *                                                     0,
                 *                                                     rates[i]);
                 *              pc.AddTickProfileForMotorAndSend(workingPrinter, workingPrinter.platform, aProfile);
                 *      }
                 *      aProfile = new TickProfile(workingPrinter.platform,
                 *                                 StepSize.Quarter,
                 *                                 (StepDirection)stepDirection,
                 *                                 rates[rates.Length - 1],
                 *                                 0,
                 *                                 rates[rates.Length - 1] * numStepsPerRot * targetAngle / 360);
                 *      pc.AddTickProfileForMotorAndSend(workingPrinter, workingPrinter.platform, aProfile);
                 *
                 *      for(int i = rates.Length - 2; i > -1; i--) {
                 *              aProfile = new TickProfile(workingPrinter.platform,
                 *                                         StepSize.Quarter,
                 *                                         (StepDirection)stepDirection,
                 *                                         rates[i],
                 *                                         0,
                 *                                         rates[i]);
                 *              pc.AddTickProfileForMotorAndSend(workingPrinter, workingPrinter.platform, aProfile);
                 *      }
                 * }
                 */
                yield return(null);

                if (targetAngle == smallAngle)
                {
                    smallAngleCount++;
                }
                else
                {
                    largeAngleCount++;
                }
                yield return(Scheduler.StartCoroutine(pc.WaitUntilDoneMoving()));
            }
        }
        else if (startRotationTest)
        {
            for (int testCount = 0; testCount < 1000000000; testCount++)
            {
                TickProfile aProfile = new TickProfile(workingPrinter.platform,
                                                       StepSize.Quarter,
                                                       StepDirection.Ccw,
                                                       stepRate,
                                                       0,
                                                       stepRate * numStepsPerRot);
                pc.AddTickProfileForMotorAndSend(workingPrinter, workingPrinter.platform, aProfile);

                yield return(new WaitSeconds(2.2f));

                //yield return Scheduler.StartCoroutine(pc.WaitUntilDoneMoving());
                largeAngleCount++;
            }
        }
    }
コード例 #8
0
ファイル: Printer.cs プロジェクト: njpatter/Radiant-Li
    public int UpdateState(TickProfile fromProfile, List <TxPacket> forList)
    {
        int          targetMotorId = fromProfile.motor.id;
        PrinterMotor targetMotor   = targetMotorId < kBaseMotors
                        ? GetBaseMotor(targetMotorId) : extruders[targetMotorId - kBaseMotors];

        Contract.Assert(targetMotor.id == targetMotorId, @"Found motor {0} but id isn't {1}.",
                        targetMotor, targetMotorId);

        bool shouldSendDirection = targetMotor.stepDirection != fromProfile.direction;
        bool shouldSendStepSize  = targetMotor.stepSize != fromProfile.size;
        bool shouldSendStepRate  = targetMotor.stepRate != fromProfile.stepRate;

        if (shouldSendDirection || shouldSendStepSize || shouldSendStepRate)
        {
            if (currentMotorId != targetMotorId)
            {
                // Select the motor; note that we don't change the stack.
                if (lastEnqueuedPacket != null && lastEnqueuedPacket.aCmd == GanglionCommand.StepRate)
                {
                    lastEnqueuedPacket.aCmd = kStepRateMotor[targetMotorId];
                }
                else
                {
                    lastEnqueuedPacket = new TxPacket(kMotorToCommand[targetMotorId]);
                    forList.Add(lastEnqueuedPacket);
                }
                currentMotorId = targetMotorId;
            }
            Contract.Assert(currentMotorId == targetMotor.id,
                            @"Motor id mismatch: {0} != {1}", currentMotorId, targetMotor.id);

            if (shouldSendDirection)
            {
                lastEnqueuedPacket = new TxPacket(fromProfile.direction == StepDirection.Ccw
                                                                  ? GanglionCommand.CounterClockwise
                                                                  : GanglionCommand.Clockwise);
                forList.Add(lastEnqueuedPacket);
                targetMotor.stepDirection = fromProfile.direction;
            }
            if (shouldSendStepSize)
            {
                int ganglionSize = kStepConversion[fromProfile.size];
                lastEnqueuedPacket = new TxPacket(GanglionCommand.Value, ganglionSize);
                forList.Add(lastEnqueuedPacket);

                lastEnqueuedPacket = new TxPacket(GanglionCommand.StepSize);
                forList.Add(lastEnqueuedPacket);
                targetMotor.stepSize = fromProfile.size;

                m_lastNumberSent = ganglionSize;
            }
            if (shouldSendStepRate)
            {
                if (fromProfile.stepRate == 0)
                {
                    if (lastEnqueuedPacket != null && kMotorStop.ContainsKey(lastEnqueuedPacket.aCmd))
                    {
                        lastEnqueuedPacket.aCmd = kMotorStop[lastEnqueuedPacket.aCmd];
                    }
                    else
                    {
                        lastEnqueuedPacket = new TxPacket(GanglionCommand.Stop);
                        forList.Add(lastEnqueuedPacket);
                    }
                }
                else
                {
                    if (m_lastNumberSent != fromProfile.stepRate)
                    {
                        lastEnqueuedPacket = new TxPacket(GanglionCommand.Value, fromProfile.stepRate);
                        forList.Add(lastEnqueuedPacket);
                        m_lastNumberSent = fromProfile.stepRate;
                    }
                    lastEnqueuedPacket = new TxPacket(GanglionCommand.StepRate);
                    forList.Add(lastEnqueuedPacket);
                }
                targetMotor.stepRate = fromProfile.stepRate;
            }
        }

        Contract.Assert(targetMotor.stepDirection == fromProfile.direction,
                        @"Direction mismatch: {0} != {1}.", targetMotor.stepDirection, fromProfile.direction);
        Contract.Assert(targetMotor.stepSize == fromProfile.size,
                        @"Step size mismatch: {0} != {1}", targetMotor.stepSize, fromProfile.size);
        Contract.Assert(targetMotor.stepRate == fromProfile.stepRate,
                        @"Step rate mismatch: {0} != {1}.", targetMotor.stepRate, fromProfile.stepRate);

        return(m_lastNumberSent);
    }
コード例 #9
0
ファイル: TickProfile.cs プロジェクト: njpatter/Radiant-Li
    public static void ConvertExtruder(List <Arc> arcs, List <TickProfile> toList,
                                       int usingPlatformStepRate, int stepsPerPlatformRotation,
                                       int withInitialPressureSteps, int withLastPlatformStep,
                                       out int shiftInTicksRequired, out int depressureRequested)
    {
        Contract.Assert(arcs.Count > 0, @"Called with empty arcs; should be handled prior.");

        int extrusionRate = ((PrinterExtruder)
                             (arcs[0].motor)).SetExtrusionRate(stepsPerPlatformRotation
                                                               * usingPlatformStepRate,
                                                               arcs.Count);

        // How far before the initial tick do we start?
        int initialPressureTick = 0;

        if (withInitialPressureSteps > 0)
        {
            initialPressureTick = Pressurize(arcs[0], withInitialPressureSteps, usingPlatformStepRate, toList);
        }
        shiftInTicksRequired = Mathf.Max(-initialPressureTick, 0);

        Extrude(arcs[0], extrusionRate, usingPlatformStepRate, toList);
        for (int i = 1; i < arcs.Count; ++i)
        {
            Arc lastArc = arcs[i - 1];
            Arc thisArc = arcs[i];

            int halfSpaceAvailable = (thisArc.startStep - lastArc.endStep) / 2;
            int pressureSteps      = Mathf.Min(halfSpaceAvailable, kPressureSteps);
            Contract.Assert(pressureSteps >= 0, @"Expected positive pressure steps, not {0}, between {1} and {2}.",
                            pressureSteps, lastArc, thisArc);
            Contract.Assert(pressureSteps <= kPressureSteps,
                            @"Pressure steps too large: {0}.", pressureSteps);

            if (lastArc.hasVariableStepRate && thisArc.hasVariableStepRate)
            {
                pressureSteps = 0;
            }

            if (pressureSteps > 0)
            {
                Depressurize(lastArc, pressureSteps, usingPlatformStepRate, toList);
                Pressurize(thisArc, pressureSteps, usingPlatformStepRate, toList);
            }

            Extrude(thisArc, extrusionRate, usingPlatformStepRate, toList);
        }
        Arc finalArc            = arcs[arcs.Count - 1];
        int depressureAvailable = Mathf.Min(kPressureSteps,
                                            Mathf.Max(withLastPlatformStep - finalArc.endStep, 0));

        if (depressureAvailable > 0)
        {
            Depressurize(arcs[arcs.Count - 1], depressureAvailable,
                         usingPlatformStepRate, toList);
        }

        // Return the untaken depressure steps.
        depressureRequested = kPressureSteps - depressureAvailable;

#if UNITY_EDITOR
        for (int i = 1; i < toList.Count; ++i)
        {
            TickProfile p0 = toList[i - 1];
            TickProfile p1 = toList[i];

            Contract.Assert(p0.endTick <= p1.startTick,
                            @"Created overlapping profiles {0} and {1}", p0, p1);
        }
#endif
    }