Ejemplo n.º 1
0
        public void Tick()
        {
            // track angle

            int a = this.Motor.Angle - _zero;

            if (a - this.Angle < -Circle.Limit / 2)
            {
                a += Circle.Limit;
            }
            if (a - this.Angle > Circle.Limit / 2)
            {
                a -= Circle.Limit;
            }
            this.Angle = a;

            _angleHistory.Add(this.Angle);

            if (!_on)
            {
                this.Motor.Torque = 0;
                return;
            }

            var f = _maxTorque;
            var m = _m;

            // target time and angle
            int now = Environment.TickCount;
            var t2  = _targetTime - now;
            var a2  = Circle.Distance2(_targetAngle, this.Angle);

            // calc actual current velocity

            var ago = _angleHistory.Get(2);
            var v   = (float)(this.Angle - ago.Angle) / (now - ago.TickCount);

            // calc minimum and maximum acceptable velocity
            // that will allow us to finish the trajectory

            // maximum acceptable time until breaking
            var maxT1 = Quadratic.Solve(f / m * 3 / 2, -2 * t2 * f / m, t2 * t2 * f / m / 2);
            var t1    = Math.Max(maxT1[0], maxT1[1]);

            // mininum acceptable velocity until breaking
            var minV = (t2 - t1) * f / m;

            // maximum acceptable velocity
            var maxV = t2 * f / m;

            // optimal velocity
            var optV = (minV + maxV) / 2;
        }
Ejemplo n.º 2
0
        public void Tick()
        {
            // track angle

            int a = this.Motor.Angle - _zero;

            if (a - this.Angle < -Circle.Limit / 2)
            {
                a += Circle.Limit;
            }
            if (a - this.Angle > Circle.Limit / 2)
            {
                a -= Circle.Limit;
            }
            this.Angle = a;

            //

            _recentBuffer.Add(this.Angle);

            if (!_on)
            {
                this.Motor.Torque = 0;
                return;
            }

            int   now      = Environment.TickCount;
            float fraction = (float)(now - _startTime) / (_targetTime - _startTime);

            if (fraction < 0)
            {
                fraction = 0;
            }
            if (fraction > 1)
            {
                fraction = 1;
            }
            var desiredAngle = Circle.Fraction(_startAngle, _targetAngle /*, _direction*/, fraction);

            var error = Circle.Distance2(this.Angle, desiredAngle);
            //error = (int)_ema.Calc(error);

            // proportional

            var proportionalTorque = error * _power;

            // integral

            var maxError = (int)((_maxTorque - proportionalTorque) / _integral);

            _integralTorque += (/*Sqrt(error)*/ error * _integral);
            if (_integralTorque + proportionalTorque > _maxTorque)
            {
                _integralTorque = _maxTorque - proportionalTorque;
            }
            if (_integralTorque + proportionalTorque < -_maxTorque)
            {
                _integralTorque = -_maxTorque + proportionalTorque;
            }

            // derivative

            var ago = _recentBuffer.Get(3);
            var d   = (float)(this.Angle - ago.Angle) / (now - ago.TickCount);
            var derivativeTorque = d * _derivative;

            _integralTorque += derivativeTorque;

            //

            if (_debug)
            {
                Debug.WriteLine("a={0}, da={1} | P={2}, I={3}, D={4} | err={5}, int-err={6}", this.Angle, desiredAngle, proportionalTorque, _integralTorque, derivativeTorque, error, _integralTorque);
            }
            var torque = (int)(proportionalTorque + _integralTorque);

            if (torque < -_maxTorque)
            {
                torque = -_maxTorque;
            }
            if (torque > _maxTorque)
            {
                torque = _maxTorque;
            }

            this.Motor.Torque = torque;
        }