예제 #1
0
void AnimationEffect::updateInheritedTime(double inheritedTime, TimingUpdateReason reason) const
{
    bool needsUpdate = m_needsUpdate || (m_lastUpdateTime != inheritedTime && !(isNull(m_lastUpdateTime) && isNull(inheritedTime))) || (animation() && animation()->effectSuppressed());
    m_needsUpdate = false;
    m_lastUpdateTime = inheritedTime;

    const double localTime = inheritedTime;
    double timeToNextIteration = std::numeric_limits<double>::infinity();
    if (needsUpdate) {
        const double activeDuration = this->activeDurationInternal();

        const Phase currentPhase = calculatePhase(activeDuration, localTime, m_timing);
        // FIXME: parentPhase depends on groups being implemented.
        const AnimationEffect::Phase parentPhase = AnimationEffect::PhaseActive;
        const double activeTime = calculateActiveTime(activeDuration, resolvedFillMode(m_timing.fillMode, isKeyframeEffect()), localTime, parentPhase, currentPhase, m_timing);

        double currentIteration;
        double progress;
        if (const double iterationDuration = this->iterationDuration()) {
            const double startOffset = multiplyZeroAlwaysGivesZero(m_timing.iterationStart, iterationDuration);
            ASSERT(startOffset >= 0);
            const double scaledActiveTime = calculateScaledActiveTime(activeDuration, activeTime, startOffset, m_timing);
            const double iterationTime = calculateIterationTime(iterationDuration, repeatedDuration(), scaledActiveTime, startOffset, m_timing);

            currentIteration = calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, m_timing);
            const double transformedTime = calculateTransformedTime(currentIteration, iterationDuration, iterationTime, m_timing);

            // The infinite iterationDuration case here is a workaround because
            // the specified behaviour does not handle infinite durations well.
            // There is an open issue against the spec to fix this:
            // https://github.com/w3c/web-animations/issues/142
            if (!std::isfinite(iterationDuration))
                progress = fmod(m_timing.iterationStart, 1.0);
            else
                progress = transformedTime / iterationDuration;

            if (!isNull(iterationTime)) {
                timeToNextIteration = (iterationDuration - iterationTime) / std::abs(m_timing.playbackRate);
                if (activeDuration - activeTime < timeToNextIteration)
                    timeToNextIteration = std::numeric_limits<double>::infinity();
            }
        } else {
            const double localIterationDuration = 1;
            const double localRepeatedDuration = localIterationDuration * m_timing.iterationCount;
            ASSERT(localRepeatedDuration >= 0);
            const double localActiveDuration = m_timing.playbackRate ? localRepeatedDuration / std::abs(m_timing.playbackRate) : std::numeric_limits<double>::infinity();
            ASSERT(localActiveDuration >= 0);
            const double localLocalTime = localTime < m_timing.startDelay ? localTime : localActiveDuration + m_timing.startDelay;
            const AnimationEffect::Phase localCurrentPhase = calculatePhase(localActiveDuration, localLocalTime, m_timing);
            const double localActiveTime = calculateActiveTime(localActiveDuration, resolvedFillMode(m_timing.fillMode, isKeyframeEffect()), localLocalTime, parentPhase, localCurrentPhase, m_timing);
            const double startOffset = m_timing.iterationStart * localIterationDuration;
            ASSERT(startOffset >= 0);
            const double scaledActiveTime = calculateScaledActiveTime(localActiveDuration, localActiveTime, startOffset, m_timing);
            const double iterationTime = calculateIterationTime(localIterationDuration, localRepeatedDuration, scaledActiveTime, startOffset, m_timing);

            currentIteration = calculateCurrentIteration(localIterationDuration, iterationTime, scaledActiveTime, m_timing);
            progress = calculateTransformedTime(currentIteration, localIterationDuration, iterationTime, m_timing);
        }

        m_calculated.currentIteration = currentIteration;
        m_calculated.progress = progress;

        m_calculated.phase = currentPhase;
        m_calculated.isInEffect = !isNull(activeTime);
        m_calculated.isInPlay = getPhase() == PhaseActive;
        m_calculated.isCurrent = getPhase() == PhaseBefore || isInPlay();
        m_calculated.localTime = m_lastUpdateTime;
    }

    // Test for events even if timing didn't need an update as the animation may have gained a start time.
    // FIXME: Refactor so that we can ASSERT(m_animation) here, this is currently required to be nullable for testing.
    if (reason == TimingUpdateForAnimationFrame && (!m_animation || m_animation->hasStartTime() || m_animation->paused())) {
        if (m_eventDelegate)
            m_eventDelegate->onEventCondition(*this);
    }

    if (needsUpdate)  {
        // FIXME: This probably shouldn't be recursive.
        updateChildrenAndEffects();
        m_calculated.timeToForwardsEffectChange = calculateTimeToEffectChange(true, localTime, timeToNextIteration);
        m_calculated.timeToReverseEffectChange = calculateTimeToEffectChange(false, localTime, timeToNextIteration);
    }
}
예제 #2
0
void spintronicsStateMachine()
{
    volatile _Q15 bridgeSample;
    volatile _Q15 coilSample;
    static unsigned char state = IDLE;
    static uint32_t timer;
    static uint8_t sensor;
    _Q15 cosOmega1T;//fractions of full-scale //aligned to compensate for ADCDAC_GROUP_DELAY
    _Q15 cosOmega2T;//fractions of full-scale //aligned to compensate for ADCDAC_GROUP_DELAY
    static _Q15 cosOmega1TTimeAligned;//fractions of full-scale
    static _Q15 cosOmega2TTimeAligned;//fractions of full-scale
    static _Q15 freqT[6];//array contents: 2*f1*t, 2*f2*t, 2*f1*(t + ADCDAC_GROUP_DELAY), 2*f2*(t + ADCDAC_GROUP_DELAY), 2*fdiff*(t + ADCDAC_GROUP_DELAY), 2*fsum*(t + ADCDAC_GROUP_DELAY)
    static int64_t cosAccumulator[5];
    static int64_t sinAccumulator[5];
    static _Q15 phaseAngle[5];//units are radians divided by PI
    static _Q15 amplitude[5];//fractions of full-scale
    static bool bridgeADCClipFlag;
    static bool coilADCClipFlag;
    static bool bridgeDigitalClipFlag;

#ifdef SIMULATION_MODE
    uint16_t RXBUF2 = rand();//only to give random stimulus during simulation
#endif


    if (RXBUF0 == 0x7FFF || RXBUF0 == 0x8000)
    {
        bridgeADCClipFlag = true;
    }
    if (RXBUF2 == 0x7FFF || RXBUF2 == 0x8000)
    {
        coilADCClipFlag = true;
    }
    bridgeSample = readBridgeSampleAndApplyGain(&bridgeDigitalClipFlag);
    coilSample = RXBUF2;

    if (GUIRequestingRun == false)
    {
        state = IDLE;
    }
    
    switch (state)
    {
    case IDLE:
            timer = 0;
            sensor = 0;
            configSensor(sensor);
            signalGenerator(RESET, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            cosAccumulator[0] = 0; cosAccumulator[1] = 0; cosAccumulator[2] = 0; cosAccumulator[3] = 0; cosAccumulator[4] = 0;
            sinAccumulator[0] = 0; sinAccumulator[1] = 0; sinAccumulator[2] = 0; sinAccumulator[3] = 0; sinAccumulator[4] = 0;
            phaseAngle[0] = 0; phaseAngle[1] = 0; phaseAngle[2] = 0; phaseAngle[3] = 0; phaseAngle[4] = 0;
            amplitude[0] = 0; amplitude[1] = 0; amplitude[2] = 0; amplitude[3] = 0; amplitude[4] = 0;
            bridgeADCClipFlag = false;
            coilADCClipFlag = false;
            bridgeDigitalClipFlag = false;

#ifdef CS4272_CONTROL_PORT_MODE
            state = CALIBRATE_ADC;
            enableADCHpf(true);//enable the hpf to calibrate for systematic DC offset
#else
            state = START_SIGNAL_GEN;
#endif

            break;

#ifdef CS4272_CONTROL_PORT_MODE
        case CALIBRATE_ADC:
            signalGenerator(RESET, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == ADC_CALIBRATION_TIME)
            {
                timer = 0;
                state = WAIT_FOR_HPF_DISABLE_MESSAGE_TX;
                enableADCHpf(false);//DC calibration complete; disable hpf
            }
            break;

         case WAIT_FOR_HPF_DISABLE_MESSAGE_TX:
            signalGenerator(RESET, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == CS4272_SPI_TX_LATENCY)
            {
                timer = 0;
                state = START_SIGNAL_GEN;
            }
            break;
#endif

        case START_SIGNAL_GEN:
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == SETUP_TIME)
            {
                timer = 0;
                state = MEASURE_PHASE;
            }
            break;            

        case MEASURE_PHASE:
            measurePhase(bridgeSample, coilSample, freqT, cosOmega1TTimeAligned, cosOmega2TTimeAligned, cosAccumulator, sinAccumulator);
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == phaseMeasurementTime)
            {
                timer = 0;
                state = CALCULATE_PHASE;
            }
            break;

        case CALCULATE_PHASE:
        {
            static uint8_t shiftAmt[5];
            if (timer < 5)
            {
                calculateShiftAmount(timer, cosAccumulator, sinAccumulator, shiftAmt);
            }
			else
            {
                calculatePhase(timer - 5, cosAccumulator, sinAccumulator, phaseAngle, shiftAmt);
            }
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == 10)
            {    
                cosAccumulator[0] = 0; cosAccumulator[1] = 0; cosAccumulator[2] = 0; cosAccumulator[3] = 0; cosAccumulator[4] = 0; 
                sinAccumulator[0] = 0; sinAccumulator[1] = 0; sinAccumulator[2] = 0; sinAccumulator[3] = 0; sinAccumulator[4] = 0; 
                timer = 0;
                state = MEASURE_AMPLITUDE;
            }
            break;
        }

        case MEASURE_AMPLITUDE:
            measureAmplitude(bridgeSample, coilSample, freqT, cosAccumulator, phaseAngle);
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == amplitudeMeasurementTime)
            {
                timer = 0;
                state = CALCULATE_AMPLITUDE;
            }
            break;

        case CALCULATE_AMPLITUDE:
            calculateAmplitude(timer, cosAccumulator, amplitude);
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;  
            if (timer == 5)
            {
                uint8_t index;
                uint8_t txSensor;//temporary variable to store the value for transmission
                _Q15 txPhaseAngle[5];//temporary array to store values for transmission
                _Q15 txAmplitude[5];//temporary array to store values for transmission
                bool txBridgeADCClipFlag;//temporary variable to store the flag for transmission
                bool txCoilADCClipFlag;//temporary variable to store the flag for transmission
                bool txBridgeDigitalClipFlag;//temporary variable to store the flag for transmission

                //store variables for transmission
                txSensor = sensor;
                for (index = 0; index < 5; ++index)
                {
                    txPhaseAngle[index] = phaseAngle[index];
                    txAmplitude[index] = amplitude[index];
                }
                txBridgeADCClipFlag = bridgeADCClipFlag;
                txCoilADCClipFlag = coilADCClipFlag;
                txBridgeDigitalClipFlag = bridgeDigitalClipFlag;

                //clear static variables for next iteration of the state machine
                cosAccumulator[0] = 0; cosAccumulator[1] = 0; cosAccumulator[2] = 0; cosAccumulator[3] = 0; cosAccumulator[4] = 0; 
                timer = 0;
                                bridgeADCClipFlag = false;
                                coilADCClipFlag = false;
                                bridgeDigitalClipFlag = false;

                state = START_SIGNAL_GEN;
                ++sensor;
                if (sensor == NUMBER_OF_SENSORS)
                {
                    sensor = 0;
                }
                configSensor(sensor);

                //transmit results
                transmitResults(txSensor, txPhaseAngle, txAmplitude, txBridgeADCClipFlag, txCoilADCClipFlag, txBridgeDigitalClipFlag);//don't do this until the state machine is ready for the next measurment period; transmitting results takes more than one sample period.
            }
            break;
            
        default:
            timer = 0;
            sensor = 0;
            configSensor(sensor);
            signalGenerator(RESET, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            cosAccumulator[0] = 0; cosAccumulator[1] = 0; cosAccumulator[2] = 0; cosAccumulator[3] = 0; cosAccumulator[4] = 0; 
            sinAccumulator[0] = 0; sinAccumulator[1] = 0; sinAccumulator[2] = 0; sinAccumulator[3] = 0; sinAccumulator[4] = 0; 
            phaseAngle[0] = 0; phaseAngle[1] = 0; phaseAngle[2] = 0; phaseAngle[3] = 0; phaseAngle[4] = 0;
            amplitude[0] = 0; amplitude[1] = 0; amplitude[2] = 0; amplitude[3] = 0; amplitude[4] = 0; 
            break;
    }
}
예제 #3
0
void AnimationNode::updateInheritedTime(double inheritedTime, TimingUpdateReason reason) const
{
    bool needsUpdate = m_needsUpdate || (m_lastUpdateTime != inheritedTime && !(isNull(m_lastUpdateTime) && isNull(inheritedTime)));
    m_needsUpdate = false;
    m_lastUpdateTime = inheritedTime;

    const double localTime = inheritedTime - m_startTime;
    double timeToNextIteration = std::numeric_limits<double>::infinity();
    if (needsUpdate) {
        const double activeDuration = this->activeDurationInternal();

        const Phase currentPhase = calculatePhase(activeDuration, localTime, m_timing);
        // FIXME: parentPhase depends on groups being implemented.
        const AnimationNode::Phase parentPhase = AnimationNode::PhaseActive;
        const double activeTime = calculateActiveTime(activeDuration, resolvedFillMode(m_timing.fillMode, isAnimation()), localTime, parentPhase, currentPhase, m_timing);

        double currentIteration;
        double timeFraction;
        if (const double iterationDuration = this->iterationDuration()) {
            const double startOffset = multiplyZeroAlwaysGivesZero(m_timing.iterationStart, iterationDuration);
            ASSERT(startOffset >= 0);
            const double scaledActiveTime = calculateScaledActiveTime(activeDuration, activeTime, startOffset, m_timing);
            const double iterationTime = calculateIterationTime(iterationDuration, repeatedDuration(), scaledActiveTime, startOffset, m_timing);

            currentIteration = calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, m_timing);
            timeFraction = calculateTransformedTime(currentIteration, iterationDuration, iterationTime, m_timing) / iterationDuration;

            if (!isNull(iterationTime)) {
                timeToNextIteration = (iterationDuration - iterationTime) / std::abs(m_timing.playbackRate);
                if (activeDuration - activeTime < timeToNextIteration)
                    timeToNextIteration = std::numeric_limits<double>::infinity();
            }
        } else {
            const double localIterationDuration = 1;
            const double localRepeatedDuration = localIterationDuration * m_timing.iterationCount;
            ASSERT(localRepeatedDuration >= 0);
            const double localActiveDuration = m_timing.playbackRate ? localRepeatedDuration / std::abs(m_timing.playbackRate) : std::numeric_limits<double>::infinity();
            ASSERT(localActiveDuration >= 0);
            const double localLocalTime = localTime < m_timing.startDelay ? localTime : localActiveDuration + m_timing.startDelay;
            const AnimationNode::Phase localCurrentPhase = calculatePhase(localActiveDuration, localLocalTime, m_timing);
            const double localActiveTime = calculateActiveTime(localActiveDuration, resolvedFillMode(m_timing.fillMode, isAnimation()), localLocalTime, parentPhase, localCurrentPhase, m_timing);
            const double startOffset = m_timing.iterationStart * localIterationDuration;
            ASSERT(startOffset >= 0);
            const double scaledActiveTime = calculateScaledActiveTime(localActiveDuration, localActiveTime, startOffset, m_timing);
            const double iterationTime = calculateIterationTime(localIterationDuration, localRepeatedDuration, scaledActiveTime, startOffset, m_timing);

            currentIteration = calculateCurrentIteration(localIterationDuration, iterationTime, scaledActiveTime, m_timing);
            timeFraction = calculateTransformedTime(currentIteration, localIterationDuration, iterationTime, m_timing);
        }

        m_calculated.currentIteration = currentIteration;
        m_calculated.timeFraction = timeFraction;

        m_calculated.phase = currentPhase;
        m_calculated.isInEffect = !isNull(activeTime);
        m_calculated.isInPlay = phase() == PhaseActive && (!m_parent || m_parent->isInPlay());
        m_calculated.isCurrent = phase() == PhaseBefore || isInPlay() || (m_parent && m_parent->isCurrent());
        m_calculated.localTime = m_lastUpdateTime - m_startTime;
    }

    // Test for events even if timing didn't need an update as the player may have gained a start time.
    // FIXME: Refactor so that we can ASSERT(m_player) here, this is currently required to be nullable for testing.
    if (reason == TimingUpdateForAnimationFrame && (!m_player || m_player->hasStartTime() || m_player->paused())) {
        if (m_eventDelegate)
            m_eventDelegate->onEventCondition(this);
    }

    if (needsUpdate)  {
        // FIXME: This probably shouldn't be recursive.
        updateChildrenAndEffects();
        m_calculated.timeToForwardsEffectChange = calculateTimeToEffectChange(true, localTime, timeToNextIteration);
        m_calculated.timeToReverseEffectChange = calculateTimeToEffectChange(false, localTime, timeToNextIteration);
    }
}