# RILYBOT 4: Decaying Average Techniques

Decaying averages are used in several places in the RILYBOT 4 design. There are two fundamental ways they are used: interpreting impulse stimuli, and continuous decayed averaging as a substitute for integration.

## Interpreting Impulse Stimuli

An impulse stimulus is the type of input that jumps in value quickly and for a brief amount of time. The bumpers on RILYBOT 4 are a good example of this: they're touch sensors, which are always either on or off, and they typically are on for only a very short amount of time.

Most simple robot programs will react to such stimuli by immediately reversing direction and/or turning, moving at a constant speed for a fixed period of time, then switching immediately to some other constant speed. Such reactions are easy to program but rather mechanical in appearance.

A more graceful, "organic" reaction is achieved if the following rules are followed:

• Reaction to the stimulus involves a gradually changing speed and/or rotation rate.
• The reaction is greatest right after the stimulus happens, and gradually decreases in magnitude as time goes on.
• The reaction decreases quickly at first, then decreases more slowly.
• The reaction eventually reaches zero.
• The reaction is gradually replaced by the "non-stimulus behavior" in a smooth and seamless manner.

All of this can be accomplished easily if the on-or-off input stimulus is processed in the following way:

task input_decay { while (true) { if (raw_input == ON) { decayed_input = 100; } else { decayed_input = decayed_input * 0.95; // decrease by 5 percent }   Sleep(10); // wait a little while } }

This causes the value decayed_input to take on a value that ranges from 100 to 0. Each time the input goes on the value will jump immediately to 100, then when the input goes off the value will drop to 0, falling quickly at first and then more slowly.

Once the input is available in this form, the output speed (and other reactions) can be controlled in this way:

#define FORWARD_RATE 20 #define REVERSE_RATE -20   task motion { while (true) { speed = ( (decayed_input * REVERSE_RATE) + ((100 - decayed_input) * FORWARD_RATE) ) / 100; Sleep(10); } }

## Continuous Decayed Averaging and Integration

Decayed averaging is also used as a simple approximation to a numerical integral, useful for signal processing and analysis. The input signal is turned into an output signal by the following algorithm:

while (converting) { average = ((20 * average) + next_input_value ) / 21; next_output_value = average; }

Each time through the loop it takes the old average and averages it with the current input value, but it gives the old average 20 times as much weight as the new reading. That means that if the input suddenly changes, the average will only change a little — and the average will take a long time to move a significant distance.

This is used to achieve several different types of results, all of which are really the same thing but looked at in different ways:

Smoothing (to eliminate noise) and averaging. Sometimes an input value is unreliable, and many readings must be taken and averaged to get a reliable value. Continuous decayed averaging makes such an average available all the time, and the average continually adjusts to changes in the input. It adjusts itself as gradually or as quickly as you want (just change the constants 20 and 21)

RILYBOT 4 uses this technique to get reliable motor speed readings for the high and low light levels.

Filtering. Filtering separates high-frequency information from low-frequency information. The decayed average is the low-frequency information; to get a stream of values containing the high-frequency information subtract the averages from the raw input values. Filtering is used in signal processing applications; the decayed-average technique is notable for requiring very little computation, particularly when compared to Fourier and other complicated techniques.

Estimating the frequency of a sinewave. If a sinewave is processed via decayed-average filtering, and if its wavelength is less than the decay halflife, its frequency is nearly proportional to the amplitude of the original signal divided by the amplitude of the decayed-average signal. This even works for non-sinusoidal waveforms, although each different wave shape has a different ratio between the two amplitudes. If there is any unwanted noise in the input the estimate will be inaccurate.

This page was written in the "embarrassingly readable" markup language RHTF, and was last updated on 2018 Aug 27. s.11