Beispiel #1
0
    def on_run(self,
               offset,
               desire_setter,
               current,
               default_error,
               error=None,
               modulo_error=False,
               *args,
               **kwargs):
        """
        Note: This does not 0 the desire when completed.

        :param offset: A Number or function that when called with no arguments returns a Number that represents the
        value to be targeted. This offset will be added to the current value.
        :param desire_setter: A SHM variable (object with a set method) that will be called with a single argument to
        target.
        :param current: A Number or function that when called with no arguments returns the current value as a Number.
        :param error: A Number representing the allowed error before a wrapper is finished.
        :param modulo_error: a Boolean that is true only if the error calculated should be with respect to modulo 360.
        """
        if error is None:
            error = default_error

        offset, current = call_if_function(offset), call_if_function(current)

        desire_setter(current + offset)
        if within_deadband(current + offset,
                           current,
                           error,
                           use_mod_error=modulo_error):
            self.finish()
Beispiel #2
0
    def on_run(self, velocity, desire_setter, current, target=None, error=-1, modulo_error=False, *args, **kwargs):
        """
        Note: This does not 0 the desire when completed.

        :param velocity: A Number or function that when called with no arguments returns a Number that represents the
        value to be targeted. This target will be multiplied with the time in seconds from the last call and be added to
        the current value.
        :param desire_setter: A SHM variable (object with a set method) that will be called with a single argument to
        target.
        :param current: A Number or function that when called with no arguments returns the current value as a Number.
        :param target: A Number (or function) that represents the target velocity (units/second).
        :param error: A Number representing the allowed error before a wrapper is finished.
        :param modulo_error: a Boolean that is true only if the error calculated should be with respect to modulo 360.
        """

        velocity, current, target = call_if_function(velocity), call_if_function(current), call_if_function(target)

        target_for_velocity = velocity * (self.this_run_time - self.last_run_time)

        self.relative_to_current_setter.on_run(offset=target_for_velocity, desire_setter=desire_setter, current=current,
                                               error=error, modulo_error=modulo_error)

        if target is not None or within_deadband(target, current, error, use_mod_error=modulo_error):
            self.finish()
        else:
            desire_setter()
Beispiel #3
0
    def on_run(self, input_value, output_function, target=0, modulo_error=False, deadband=1, p=1, d=0, i=0,
               negate=False, *args, **kwargs):
        # TODO: minimum_output too?
        input_value = call_if_function(input_value)
        target = call_if_function(target)

        output = self.pid.tick(value=input_value, desired=target, p=p, d=d, i=i)
        output_function(-output if negate else output)

        if within_deadband(input_value, target, deadband=deadband, use_mod_error=modulo_error):
            # TODO: Should this zero on finish? Or set to I term?
            self.finish()
Beispiel #4
0
    def run(self,
            input_value,
            output_function,
            p=0.2,
            d=0,
            i=0,
            target=0,
            deadband=0,
            modulo_error=False,
            negate=False,
            debug=False,
            min_out=None):
        input_value = evaluate_or_call(input_value)

        # Don't do anything if the current value (input_value) is within the deadband of the target.
        if within_deadband(input_value,
                           target,
                           deadband,
                           use_mod_error=modulo_error):
            # TODO: Should we set the output to the target as we don't know what the current target is?
            self._finish()
            return

        err = (-1 if negate else 1) * (target - input_value)
        self.error = err
        # P, I and D loops
        output_value = p * err

        self.total_error += err * (self.this_run - self.last_run)
        output_value += i * self.total_error

        output_value += d * (self.last_value - input_value) / (self.this_run -
                                                               self.last_run)

        if debug:
            print(output_value)
            print()

        if min_out is not None and output_value < min_out:
            output_function(min_out * (-1 if output_value < 0 else 1))
        else:
            output_function(output_value)

        self.log({
            'p': p,
            'i': i,
            'd': d,
            'in': input_value,
            'out': output_value,
            'negate': negate
        })
Beispiel #5
0
    def run(self, value, variable, current, error=0, modulo_error=False):
        """
        :param value: A Number that represents the value to be targeted.
        :param variable: A SHM variable (object with a set method) that will be called with a single argument to target.
        :param current: A function that when called with no arguments returns the current value as a Number.
        :param error: A Number representing the allowed error before a wrapper is finished.
        :param modulo_error: a Boolean that is true only if the error calculated should be with respect to modulo 360.
        """

        value, current = evaluate_or_call(value), evaluate_or_call(current)
        variable.set(value)

        if within_deadband(value, current, error, use_mod_error=modulo_error):
            self._finish()
Beispiel #6
0
    def on_run(self,
               velocity,
               desire_setter,
               current,
               default_error,
               target=None,
               error=None,
               modulo_error=False,
               min_target=None,
               max_target=None,
               *args,
               **kwargs):
        """
        Note: This does not 0 the desire when completed.

        :param velocity: A Number or function that when called with no arguments returns a Number that represents the
        value to be targeted. This target will be multiplied with the time in seconds from the last call and be added to
        the current value.
        :param desire_setter: A SHM variable (object with a set method) that will be called with a single argument to
        target.
        :param current: A Number or function that when called with no arguments returns the current value as a Number.
        :param target: A Number (or function) that represents the target velocity (units/second).
        :param error: A Number representing the allowed error before a wrapper is finished.
        :param modulo_error: a Boolean that is true only if the error calculated should be with respect to modulo 360.
        """
        if error is None:
            error = default_error

        velocity, current, target = call_if_function(
            velocity), call_if_function(current), call_if_function(target)

        target_for_velocity = velocity * (self.this_run_time -
                                          self.last_run_time)

        self.relative_to_current_setter.on_run(offset=target_for_velocity,
                                               desire_setter=desire_setter,
                                               current=current,
                                               error=error,
                                               modulo_error=modulo_error,
                                               min_target=min_target,
                                               max_target=max_target)

        if target is not None or within_deadband(
                target, current, error, use_mod_error=modulo_error):
            if target is not None:
                desire_setter()

            self.finish()
        else:
            desire_setter()
Beispiel #7
0
    def on_run(self, input_value, output_function, target=0, modulo_error=False, deadband=1, p=1, d=0, i=0,
               negate=False, max_out=None, *args, **kwargs):
        # TODO: minimum_output too?
        input_value = call_if_function(input_value)
        target = call_if_function(target)
        if max_out is None:
            max_out = float('inf')

        output = self.pid.tick(value=input_value, desired=target, p=p, d=d, i=i)
        output = math.copysign(min(abs(output), max_out), output)
        output_function(-output if negate else output)

        if within_deadband(input_value, target, deadband=deadband, use_mod_error=modulo_error):
            # TODO: Should this zero on finish? Or set to I term?
            self.finish()
Beispiel #8
0
    def on_run(self, offset, desire_setter, current, error=-1, modulo_error=False, *args, **kwargs):
        """
        Note: This does not 0 the desire when completed.

        :param offset: A Number or function that when called with no arguments returns a Number that represents the
        value to be targeted. This offset will be added to the current value on the first run.
        :param desire_setter: A SHM variable (object with a set method) that will be called with a single argument to target.
        :param current: A Number or function that when called with no arguments returns the current value as a Number.
        :param error: A Number representing the allowed error before a wrapper is finished.
        :param modulo_error: a Boolean that is true only if the error calculated should be with respect to modulo 360.
        """

        offset, current = call_if_function(offset), call_if_function(current)

        if within_deadband(self.initial_value + offset, current, error, use_mod_error=modulo_error):
            self.finish()
        else:
            desire_setter(self.initial_value + offset)