Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- private class ThrottleCalculator
- {
- private readonly int _throttle;
- private DateTime _lastCalculation = DateTime.Now;
- private int _count = 0;
- private int _interval = 0;
- public ThrottleCalculator(int throttle)
- {
- this._throttle = throttle;
- }
- public async Task CalculateThrottle()
- {
- this._count += 1;
- var elapsed = DateTime.Now.Subtract(this._lastCalculation).TotalMilliseconds;
- var tick = 50;
- if (elapsed > tick)
- {
- this._lastCalculation = DateTime.Now;
- int projection = this._count * (1000 / tick);
- var errorTerm = this._throttle - projection;
- this._interval = this._interval - errorTerm;
- if (this._interval < 0)
- this._interval = 0;
- // this is often several thousand, so I have to limit.
- if (this._interval > 100)
- this._interval = 100;
- await Task.Delay(this._interval);
- this._count = 0;
- }
- }
- }
- var throttle = new ThrottleCalculator(600); // 600/s
- while (message = getMessage())
- {
- ... // do stuff with message.
- if (throttle != null)
- await throttle.CalculateThrottle();
- private class ThrottleCalculator
- {
- private readonly int _throttle;
- private DateTime _lastCalculationTime;
- private double _measured = 0;
- private double _totalError = 0;
- private double _integral = 0;
- private double _lastError = 0;
- public ThrottleCalculator(int throttle)
- {
- this._throttle = throttle;
- this._lastCalculationTime = DateTime.MinValue;
- }
- public async Task CalculateThrottle()
- {
- var kp = -.1d; // proportional gain
- var ki = -.1d; // integral gain
- var kd = -.1d; // derivative gain
- var dt = 30d; // rate of change of time. calculcations every ms;
- this._measured += 1;
- if (this._lastCalculationTime == DateTime.MinValue)
- this._lastCalculationTime = DateTime.Now;
- var elapsed = (double)DateTime.Now.Subtract(this._lastCalculationTime)
- .TotalMilliseconds;
- if (elapsed > dt)
- {
- this._lastCalculationTime = DateTime.Now;
- var error = ((double)this._throttle / (1000d / dt)) - this._measured;
- this._totalError += error;
- var integral = this._totalError;
- var derivative = (error - this._lastError) / elapsed;
- var actual = (kp * error) + (ki * integral) + (kd * derivative);
- var output = actual;
- if (output < 1)
- output = 0;
- // i don't like this, but it seems necessary
- // so that wild wait values are never used.
- if (output > dt * 4)
- output = dt * 4;
- if (output > 0)
- await Task.Delay((int)output);
- this._measured = 0;
- this._lastError = error;
- }
- }
- }
- Actual: 19.2000 Output: 19.2000 Integral: -209 Derivative: .0000 Error: 17
- Actual: 17.5000 Output: 17.5000 Integral: -192 Derivative: .0000 Error: 17
- Actual: 15.8000 Output: 15.8000 Integral: -175 Derivative: .0000 Error: 17
- Actual: 33.8104 Output: 33.8104 Integral: -255 Derivative: -3.1040 Error: -80
- Actual: 21.8931 Output: 21.8931 Integral: -238 Derivative: 2.0686 Error: 17
- Actual: 20.4000 Output: 20.4000 Integral: -221 Derivative: .0000 Error: 17
- Actual: 18.7000 Output: 18.7000 Integral: -204 Derivative: .0000 Error: 17
- Actual: 17.0000 Output: 17.0000 Integral: -187 Derivative: .0000 Error: 17
- Actual: 15.3000 Output: 15.3000 Integral: -170 Derivative: .0000 Error: 17
- Actual: 31.0752 Output: 31.0752 Integral: -239 Derivative: -2.7520 Error: -69
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement