I have a python script that reads the input signal of a joystick via pygame and passes that input to a motor controller.
Now i would like to add a ramping function. let's say to ramp up to the input value with a given delay. if the input of the joystick is '100' it should only pass that value to the motor controller after the delay has passed and 'fade' in between.
Also, it would be a plus to define the ramp. (linear or logarithmic curve)
Is there a simple way of doing that? thanks for your help!
A simple class could look like this:
class RampUp:
def __init__(self):
self.value = 0
self.target = 0
self.next = self.__next__
self.calc = None
def __iter__(self):
return self
def __next__(self):
if self.value == self.target:
return self.value
else:
self.value = self.calc(self.value, self.target)
return self.value
this class simply holds a state, is iterable and calls a function that calculates a new value in every iteration.
A simple "ramp" function that simply increases the output value by a given delta could be:
def simple(value, target):
if value < target:
value = min(value + 1, target)
else:
value = max(value - 1, target)
return value
Example of usage:
gen = RampUp()
gen.calc = simple
gen.target = 20
for _ in xrange(100):
# that's the value you pass to your motor controller
print next(gen)
Another example ramp function that is more complex:
def smooth(value, target):
# maximum acceleration is 2
delta_max = 2
# minimun acceleration is 0.5
delta = max(0.5, (abs(target) - abs(target-value)) / 10.)
delta = min(delta, delta_max)
if value < target:
value = min(value + delta, target)
else:
value = max(value - delta, target)
return value
In response to your comment:
def with_step(step):
def simple(value, target):
if value < target:
value = min(value + step, target)
else:
value = max(value - step, target)
return value
return simple
gen = RampUp()
gen.target = 20
# you could move this line into the class
# reaches the target value in 12 steps
gen.calc = with_step((gen.target - gen.value)/12.)