Exemple #1
0
 def compile(self):
     a = ''.join(str(x) for x in sorted(chain([(x,) for x in self.soft_constraints.keys()],
                                              self.hard_constraints.keys(),
                                              self.joint_constraints.keys())))
     function_hash = hashlib.md5((a + self.robot.get_urdf_str()).encode('utf-8')).hexdigest()
     path_to_functions = self.path_to_functions + function_hash
     self.qp_problem_builder = QProblemBuilder(self.joint_constraints,
                                               self.hard_constraints,
                                               self.soft_constraints,
                                               list(self.joint_to_symbols_str.values()),
                                               path_to_functions)
Exemple #2
0
 def compile(self):
     a = ''.join(
         str(x) for x in sorted(
             chain(self.soft_constraints.keys(), self.hard_constraints.keys(
             ), self.joint_constraints.keys())))
     function_hash = hashlib.md5(a + self.robot.get_hash()).hexdigest()
     path_to_functions = self.path_to_functions + function_hash
     self.qp_problem_builder = QProblemBuilder(
         self.joint_constraints,
         self.hard_constraints, self.soft_constraints,
         self.joint_to_symbols_str.values(), self.free_symbols,
         path_to_functions)
Exemple #3
0
class QPController(Controller):
    def __init__(self, robot, builder_backend=None, logging=print_wrapper):
        self.builder_backend = builder_backend
        self.logging = logging
        super(QPController, self).__init__(robot)

    def init(self):
        self._controllable_constraints = OrderedDict()
        self._hard_constraints = OrderedDict()
        self._soft_constraints = OrderedDict()

        self.add_inputs(self.get_robot())
        self.make_constraints(self.get_robot())
        self.build_builder()

    def add_inputs(self, robot):
        raise (NotImplementedError)

    def make_constraints(self, robot):
        self._controllable_constraints = self.get_robot().joint_constraints
        self._hard_constraints = self.get_robot().hard_constraints

    def build_builder(self):
        self.qp_problem_builder = QProblemBuilder(
            self._controllable_constraints, self._hard_constraints,
            self._soft_constraints, self.builder_backend, self.logging)

    def get_next_command(self):
        # TODO add dt parameter and return next state + cmds instead of only cmds
        self.update_observables(self.get_robot().get_state())
        return self.qp_problem_builder.update_observables(self.get_state())
Exemple #4
0
 def build_builder(self):
     self.qp_problem_builder = QProblemBuilder(
         self._controllable_constraints, self._hard_constraints,
         self._soft_constraints, self.builder_backend, self.logging)
Exemple #5
0
 def test_differentiation_speed_cython(self):
     builder = QProblemBuilder(self.robot.joint_constraints,
                               self.robot.hard_constraints, self.s_dict)
Exemple #6
0
class InstantaneousController(object):
    """
    This class handles constraints and computes joint commands using symengine and qpOases.
    """

    # TODO should anybody who uses this class know about constraints?

    def __init__(self, robot, path_to_functions):
        """
        :type robot: Robot
        :param path_to_functions: location where compiled functions are stored
        :type: str
        """
        self.path_to_functions = path_to_functions
        self.robot = robot
        self.controlled_joints = []
        self.hard_constraints = {}
        self.joint_constraints = {}
        self.soft_constraints = {}
        self.free_symbols = None
        self.qp_problem_builder = None

    def set_controlled_joints(self, joint_names):
        """
        :type joint_names: set
        """
        self.controlled_joints = joint_names
        self.joint_to_symbols_str = OrderedDict(
            (x, self.robot.get_joint_position_symbol(x))
            for x in self.controlled_joints)
        self.joint_constraints = OrderedDict(
            ((self.robot.get_name(), k), self.robot._joint_constraints[k])
            for k in self.controlled_joints)
        self.hard_constraints = OrderedDict(
            ((self.robot.get_name(), k), self.robot._hard_constraints[k])
            for k in self.controlled_joints
            if k in self.robot._hard_constraints)

    def get_qpdata_key_map(self):
        b_keys = []
        weights_keys = []
        xdot_keys = []
        bA_keys = []
        for iJ, k in enumerate(self.joint_constraints.keys()):
            key = u'j -- ' + str(k)
            b_keys.append(key)
            weights_keys.append(key)
            xdot_keys.append(key)

        for iH, k in enumerate(self.hard_constraints.keys()):
            key = u'h -- ' + str(k)
            bA_keys.append(key)

        for iS, k in enumerate(self.soft_constraints.keys()):
            key = str(k)
            bA_keys.append(key)
            weights_keys.append(key)
            xdot_keys.append(key)
        return weights_keys, b_keys, bA_keys, xdot_keys

    def update_soft_constraints(self, soft_constraints, free_symbols=None):
        """
        Triggers a recompile if the number of soft constraints has changed.
        :type soft_constraints: dict
        :type free_symbols: set
        """
        if free_symbols is not None:
            warnings.warn(u'use of free_symbols deprecated',
                          DeprecationWarning)
        # TODO bug if soft constraints get replaced, actual amount does not change.
        last_number_of_constraints = len(self.soft_constraints)
        if free_symbols is not None:
            if self.free_symbols is None:
                self.free_symbols = set()
            self.free_symbols.update(free_symbols)
        self.soft_constraints.update(soft_constraints)
        if last_number_of_constraints != len(self.soft_constraints):
            self.qp_problem_builder = None

    def compile(self):
        a = ''.join(
            str(x) for x in sorted(
                chain(self.soft_constraints.keys(), self.hard_constraints.keys(
                ), self.joint_constraints.keys())))
        function_hash = hashlib.md5(a + self.robot.get_urdf_str()).hexdigest()
        path_to_functions = self.path_to_functions + function_hash
        self.qp_problem_builder = QProblemBuilder(
            self.joint_constraints,
            self.hard_constraints, self.soft_constraints,
            self.joint_to_symbols_str.values(), self.free_symbols,
            path_to_functions)

    def get_cmd(self, substitutions, nWSR=None):
        """
        Computes joint commands that satisfy constrains given substitutions.
        :param substitutions: maps symbol names as str to floats.
        :type substitutions: dict
        :param nWSR: magic number, if None throws errors, increase this until it stops.
        :type nWSR: int
        :return: maps joint names to command
        :rtype: dict
        """
        next_cmd, H, A, lb, ub, lbA, ubA, xdot_full = self.qp_problem_builder.get_cmd(
            substitutions, nWSR)
        if next_cmd is None:
            pass
        return {name: next_cmd[symbol] for name, symbol in self.joint_to_symbols_str.items()}, \
               H, A, lb, ub, lbA, ubA, xdot_full

    def get_expr(self):
        return self.qp_problem_builder.get_expr()
Exemple #7
0
class SymEngineController(object):
    """
    This class handles constraints and computes joint commands using symengine and qpOases.
    """

    # TODO should anybody how uses this card know about constrains?

    def __init__(self, robot, path_to_functions):
        """
        :type robot: Robot
        :param path_to_functions: location where compiled functions are stored
        :type: str
        """
        self.path_to_functions = path_to_functions
        self.robot = robot
        self.controlled_joints = []
        self.hard_constraints = {}
        self.joint_constraints = {}
        self.soft_constraints = {}
        self.free_symbols = set()
        self.qp_problem_builder = None

    def set_controlled_joints(self, joint_names):
        """
        :type joint_names: set
        """
        self.controlled_joints = joint_names
        self.joint_to_symbols_str = OrderedDict(
            (x, self.robot.get_joint_symbol(x))
            for x in self.controlled_joints)
        self.joint_constraints = OrderedDict(
            ((self.robot.get_name(), k), self.robot.joint_constraints[k])
            for k in self.controlled_joints)
        self.hard_constraints = OrderedDict(
            ((self.robot.get_name(), k), self.robot.hard_constraints[k])
            for k in self.controlled_joints
            if k in self.robot.hard_constraints)

    def update_soft_constraints(self, soft_constraints, free_symbols):
        """
        Triggers a recompile if the number of soft constraints has changed.
        :type soft_constraints: dict
        :type free_symbols: set
        """
        # TODO bug if soft constraints get replaced, actual amount does not change.
        last_number_of_constraints = len(self.soft_constraints)
        self.free_symbols.update(free_symbols)
        self.soft_constraints.update(soft_constraints)
        if last_number_of_constraints != len(self.soft_constraints):
            self.qp_problem_builder = None

    def compile(self):
        a = ''.join(
            str(x) for x in sorted(
                chain(self.soft_constraints.keys(), self.hard_constraints.keys(
                ), self.joint_constraints.keys())))
        function_hash = hashlib.md5(a + self.robot.get_hash()).hexdigest()
        path_to_functions = self.path_to_functions + function_hash
        self.qp_problem_builder = QProblemBuilder(
            self.joint_constraints,
            self.hard_constraints, self.soft_constraints,
            self.joint_to_symbols_str.values(), self.free_symbols,
            path_to_functions)

    def get_cmd(self, substitutions, nWSR=None):
        """
        Computes joint commands that satisfy constrains given substitutions.
        :param substitutions: maps symbol names as str to floats.
        :type substitutions: dict
        :param nWSR: magic number, if None throws errors, increase this until it stops.
        :type nWSR: int
        :return: maps joint names to command
        :rtype: dict
        """
        try:
            next_cmd = self.qp_problem_builder.get_cmd(substitutions, nWSR)
            if next_cmd is None:
                pass
            return {
                name: next_cmd[symbol]
                for name, symbol in self.joint_to_symbols_str.items()
            }
        except AttributeError:
            self.compile()
            return self.get_cmd(substitutions, nWSR)