MotivationRacing vehicles often require precise as well as rapid control depending on the magnitude of the user input. User input is usually related to the output such as rotational speed by a function. For convenience such a function translating input to output from now on will be referred to as the response curve.
The most basic response curve can be exponential function. The shape of the exponential function can be determined by single parameter (exponent) and allows such mapping in which low-mid input values give precise changes in output, while higher input values result in more rapid response.
Disadvantage of such a basic exponential function is the limited number of shapes determined by a single parameter and usually too much flattened output for low input values. Attempts to remedy this can be found in different flight firmwares. BetaFlight implemented similar in shape to exponential but more parametrized SuperRate function with stepper low-mid input range properties. dRonin firmware implemented Expo-M using polynomials to allow user specifying desired rates at specific input ranges.
In this write-up I would like to introduce the concept of Bézier curves and discuss their potential applicability as an alternative response curve. More parametrized approach permits users to shape the response curve to their individual preferences more freely without as many limiting factors.
Bézier curve general representationBézier curves can be represented by a binomial polynomials with weights to control curvature.
The general Bézier curve forumla is
where
is the order of polynomial,
is the input variable and
are weights being just coordinate values that our function should have.
For example cubic Bézier curve which stars at (0, 0), is controlled by (0.2, 0.8 ) and (0.8, 0.2) and ends at (1,1) the following Bézier curve can be used
where series of coordinates are
and
.
ImplementationFor the cubic Bézier curve with star, end coordinates and two control points the following Python implementation demonstrates the shape of the curve.
import matplotlib.pyplot as plt
# t range must be between 0 and 1
t = [i/100 for i in range(0, 100)]
# Weights, start, end and two control points between
w = [(0, 0), # Start
(0.2, 0.8), # First control
(0.8, 0.2), # Second control
(1, 1)] # End
# Beizer cubic which can be implemented in firmware
def cubic(t):
t2 = t * t
t3 = t2 * t
mt = 1-t
mt2 = mt * mt
mt3 = mt2 * mt
x = w[0][0]*mt3 + 3*w[1][0]*mt2*t + 3*w[2][0]*mt*t2 + w[3][0]*t3
y = w[0][1]*mt3 + 3*w[1][1]*mt2*t + 3*w[2][1]*mt*t2 + w[3][1]*t3
return((x, y))
# For plotting unfold tuple of coordinates
xy = [cubic(i) for i in t]
x = [ix[0] for ix in xy]
y = [iy[1] for iy in xy]
plt.plot(x, y)
plt.draw()
plt.savefig(fname)
ApplicabilityInput from the user can be, and usually is scaled between
bound. Therefore, start
and end
points are fixed. The control coordinates are two tuning parameters which determine the shape of the curve and conveniently can serve to specify what is desirable output (rate) at two points between start and stop for given input.
Example of Qt 5.10 implementation in QML for the ground station can be found at
as a short visual demo.
DiscussionDiscussion is open, and basically why this post is here. Parametric function like this is not very complex to (see python code cubic(t)) to be implemented at flight-side, but does it make sense ?
Would any of pilots flying rate be happy with this additional flexibility of shaping/editing the curve with mouse by pulling and pushing control points ? There would be good default curve, but the question is, is this more useful than just basic expo curve ? Feedback would be nice.