Ejemplo n.º 1
0
    def __init__(self, joint_constraints_dict, hard_constraints_dict, soft_constraints_dict, controlled_joint_symbols,
                 free_symbols=None, path_to_functions=''):
        """
        :type joint_constraints_dict: dict
        :type hard_constraints_dict: dict
        :type soft_constraints_dict: dict
        :type controlled_joint_symbols: set
        :type free_symbols: set
        :param path_to_functions: location where the compiled functions can be safed.
        :type path_to_functions: str
        """
        if free_symbols is not None:
            warnings.warn(u'use of free_symbols deprecated', DeprecationWarning)
        assert (not len(controlled_joint_symbols) > len(joint_constraints_dict))
        assert (not len(controlled_joint_symbols) < len(joint_constraints_dict))
        assert (len(hard_constraints_dict) <= len(controlled_joint_symbols))
        self.path_to_functions = path_to_functions
        self.free_symbols = free_symbols
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints = controlled_joint_symbols
        self.make_matrices()

        self.shape1 = len(self.hard_constraints_dict) + len(self.soft_constraints_dict)
        self.shape2 = len(self.joint_constraints_dict) + len(self.soft_constraints_dict)

        self.qp_solver = QPSolver(len(self.hard_constraints_dict),
                                  len(self.joint_constraints_dict),
                                  len(self.soft_constraints_dict))
        self.lbAs = None  # for debugging purposes
Ejemplo n.º 2
0
    def __init__(self, joint_constraints_dict, hard_constraints_dict, soft_constraints_dict, controlled_joint_symbols,
                 path_to_functions=''):
        """
        :type joint_constraints_dict: dict
        :type hard_constraints_dict: dict
        :type soft_constraints_dict: dict
        :type controlled_joint_symbols: list
        :param path_to_functions: location where the compiled functions can be safed.
        :type path_to_functions: str
        """
        assert (not len(controlled_joint_symbols) > len(joint_constraints_dict))
        assert (not len(controlled_joint_symbols) < len(joint_constraints_dict))
        assert (len(hard_constraints_dict) <= len(controlled_joint_symbols))
        self.path_to_functions = path_to_functions
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints = controlled_joint_symbols
        self.construct_big_ass_M()
        self.compile_big_ass_M()

        self.shape1 = len(self.hard_constraints_dict) + len(self.soft_constraints_dict)
        self.shape2 = len(self.joint_constraints_dict) + len(self.soft_constraints_dict)

        self.num_hard_constraints = len(self.hard_constraints_dict)
        self.num_joint_constraints = len(self.joint_constraints_dict)
        self.num_soft_constraints = len(self.soft_constraints_dict)

        self.qp_solver = QPSolver()
        self.lbAs = None  # for debugging purposes
Ejemplo n.º 3
0
    def __init__(self, joint_constraints_dict, hard_constraints_dict,
                 soft_constraints_dict):
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints_strs = list(self.joint_constraints_dict.keys())
        self.controlled_joints = sp.sympify(self.controlled_joints_strs)
        self.make_sympy_matrices()

        self.qp_solver = QPSolver(self.H.shape[0], len(self.lbA))
Ejemplo n.º 4
0
def test_simple_problem():
    H = np.eye(2) * 2
    A = np.ones((1, 2))
    g = np.zeros(2)
    lba = np.array([10.])
    lb = np.array([-10., -10.])
    ub = np.array([10., 10.])

    qp = QPSolver()
    x = qp.solve(H, g, A, lb, ub, lba, lba)
    np.testing.assert_array_almost_equal(x, np.array([5, 5]), decimal=4)
Ejemplo n.º 5
0
def test_non_diagonal_H():
    H = np.array([[1, -0.5], [-1, -1]])
    A = np.ones((1, 2))
    g = np.zeros(2)
    lba = np.array([-10.])
    lb = np.array([-10., -10.])
    ub = np.array([10., 10.])

    qp = QPSolver()
    x = qp.solve(H, g, A, lb, ub, lba, lba)
    print(x)
    print(qp.qpProblem.getObjVal())
Ejemplo n.º 6
0
    def __init__(self,
                 joint_constraints_dict,
                 hard_constraints_dict,
                 soft_constraints_dict,
                 backend=None,
                 logging=print_wrapper):
        self.backend = backend
        self.logging = logging
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints_strs = list(self.joint_constraints_dict.keys())
        self.controlled_joints = [
            spw.Symbol(n) for n in self.controlled_joints_strs
        ]
        self.soft_constraint_indices = {}
        self.make_sympy_matrices()

        self.qp_solver = QPSolver(self.H.shape[0], len(self.lbA))
Ejemplo n.º 7
0
    def __init__(self,
                 joint_constraints_dict,
                 hard_constraints_dict,
                 soft_constraints_dict,
                 controlled_joint_symbols,
                 free_symbols=None,
                 path_to_functions=''):
        """
        :type joint_constraints_dict: dict
        :type hard_constraints_dict: dict
        :type soft_constraints_dict: dict
        :type controlled_joint_symbols: set
        :type free_symbols: set
        :param path_to_functions: location where the compiled functions can be safed.
        :type path_to_functions: str
        """
        assert (
            not len(controlled_joint_symbols) > len(joint_constraints_dict))
        assert (
            not len(controlled_joint_symbols) < len(joint_constraints_dict))
        assert (len(hard_constraints_dict) <= len(controlled_joint_symbols))
        self.path_to_functions = path_to_functions
        self.free_symbols = free_symbols
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints = controlled_joint_symbols
        self.make_matrices()

        self.shape1 = len(self.hard_constraints_dict) + len(
            self.soft_constraints_dict)
        self.shape2 = len(self.joint_constraints_dict) + len(
            self.soft_constraints_dict)

        self.qp_solver = QPSolver(
            len(self.joint_constraints_dict) + len(self.soft_constraints_dict),
            len(self.hard_constraints_dict) + len(self.soft_constraints_dict))
Ejemplo n.º 8
0
class QProblemBuilder(object):
    """
    Wraps around QPOases. Builds the required matrices from constraints.
    """
    def __init__(self,
                 joint_constraints_dict,
                 hard_constraints_dict,
                 soft_constraints_dict,
                 controlled_joint_symbols,
                 path_to_functions=''):
        """
        :type joint_constraints_dict: dict
        :type hard_constraints_dict: dict
        :type soft_constraints_dict: dict
        :type controlled_joint_symbols: list
        :param path_to_functions: location where the compiled functions can be safed.
        :type path_to_functions: str
        """
        assert (
            not len(controlled_joint_symbols) > len(joint_constraints_dict))
        assert (
            not len(controlled_joint_symbols) < len(joint_constraints_dict))
        assert (len(hard_constraints_dict) <= len(controlled_joint_symbols))
        self.path_to_functions = path_to_functions
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints = controlled_joint_symbols
        self.construct_big_ass_M()
        self.compile_big_ass_M()

        self.shape1 = len(self.hard_constraints_dict) + len(
            self.soft_constraints_dict)
        self.shape2 = len(self.joint_constraints_dict) + len(
            self.soft_constraints_dict)

        self.num_hard_constraints = len(self.hard_constraints_dict)
        self.num_joint_constraints = len(self.joint_constraints_dict)
        self.num_soft_constraints = len(self.soft_constraints_dict)

        self.qp_solver = QPSolver()
        self.lbAs = None  # for debugging purposes

    def get_expr(self):
        return self.compiled_big_ass_M.str_params

    @profile
    def construct_big_ass_M(self):
        # TODO cpu intensive
        weights = []
        lb = []
        ub = []
        lbA = []
        ubA = []
        linear_weight = []
        soft_expressions = []
        hard_expressions = []
        for constraint_name, constraint in self.joint_constraints_dict.items():
            weights.append(constraint.weight)
            lb.append(constraint.lower)
            ub.append(constraint.upper)
            linear_weight.append(constraint.linear_weight)
        for constraint_name, constraint in self.hard_constraints_dict.items():
            lbA.append(constraint.lower)
            ubA.append(constraint.upper)
            hard_expressions.append(constraint.expression)
        for constraint_name, constraint in self.soft_constraints_dict.items(
        ):  # type: (str, SoftConstraint)
            weights.append(constraint.weight)
            lbA.append(constraint.lbA)
            ubA.append(constraint.ubA)
            lb.append(constraint.lower_slack_limit)
            ub.append(constraint.upper_slack_limit)
            linear_weight.append(constraint.linear_weight)
            assert not w.is_matrix(
                constraint.expression
            ), u'Matrices are not allowed as soft constraint expression'
            soft_expressions.append(constraint.expression)

        self.np_g = np.zeros(len(weights))

        logging.loginfo(
            u'constructing new controller with {} soft constraints...'.format(
                len(soft_expressions)))
        self.h = len(self.hard_constraints_dict)
        self.s = len(self.soft_constraints_dict)
        self.j = len(self.joint_constraints_dict)

        self.init_big_ass_M()

        self.set_weights(weights)

        self.construct_A_hard(hard_expressions)
        self.construct_A_soft(soft_expressions)

        self.set_lbA(w.Matrix(lbA))
        self.set_ubA(w.Matrix(ubA))
        self.set_lb(w.Matrix(lb))
        self.set_ub(w.Matrix(ub))
        self.set_linear_weights(w.Matrix(linear_weight))

    @profile
    def compile_big_ass_M(self):
        t = time()
        self.free_symbols = w.free_symbols(self.big_ass_M)
        self.compiled_big_ass_M = w.speed_up(self.big_ass_M, self.free_symbols)
        logging.loginfo(
            u'compiled symbolic expressions in {:.5f}s'.format(time() - t))

    def init_big_ass_M(self):
        """
        #        j           s       1      1     1
        #    |--------------------------------------|
        # h  | A hard    |   0    |       |     |   |
        #    | -------------------| lbA   | ubA | 0 |
        # s  | A soft    |identity|       |     |   |
        #    |--------------------------------------|
        # j+s| H                  | lb    | ub  | g |
        #    | -------------------------------------|
        """
        self.big_ass_M = w.zeros(self.h + self.s * 2 + self.j,
                                 self.j + self.s + 3)

    def construct_A_hard(self, hard_expressions):
        A_hard = w.Matrix(hard_expressions)
        A_hard = w.jacobian(A_hard, self.controlled_joints)
        self.set_A_hard(A_hard)

    def set_A_hard(self, A_hard):
        self.big_ass_M[:self.h, :self.j] = A_hard

    def construct_A_soft(self, soft_expressions):
        A_soft = w.zeros(self.s, self.j + self.s)
        t = time()
        A_soft[:, :self.j] = w.jacobian(w.Matrix(soft_expressions),
                                        self.controlled_joints)
        logging.loginfo(u'computed Jacobian in {:.5f}s'.format(time() - t))
        A_soft[:, self.j:] = w.eye(self.s)
        self.set_A_soft(A_soft)

    def set_A_soft(self, A_soft):
        self.big_ass_M[self.h:self.h + self.s, :self.j + self.s] = A_soft

    def set_lbA(self, lbA):
        self.big_ass_M[:self.h + self.s, self.j + self.s] = lbA

    def set_ubA(self, ubA):
        self.big_ass_M[:self.h + self.s, self.j + self.s + 1] = ubA

    def set_lb(self, lb):
        self.big_ass_M[self.h + self.s:, self.j + self.s] = lb

    def set_ub(self, ub):
        self.big_ass_M[self.h + self.s:, self.j + self.s + 1] = ub

    def set_linear_weights(self, linear_weights):
        self.big_ass_M[self.h + self.s:, self.j + self.s + 2] = linear_weights

    def set_weights(self, weights):
        self.big_ass_M[self.h + self.s:, :-3] = w.diag(*weights)

    def debug_print(self,
                    unfiltered_H,
                    A,
                    lb,
                    ub,
                    lbA,
                    ubA,
                    g,
                    xdot_full=None,
                    actually_print=False):
        import pandas as pd
        bA_mask, b_mask = make_filter_masks(unfiltered_H,
                                            self.num_joint_constraints,
                                            self.num_hard_constraints)
        b_names = []
        bA_names = []
        for iJ, k in enumerate(self.joint_constraints_dict.keys()):
            key = 'j -- ' + str(k)
            b_names.append(key)

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

        for iS, k in enumerate(self.soft_constraints_dict.keys()):
            key = 's -- ' + str(k)
            bA_names.append(key)
            b_names.append(key)

        b_names = np.array(b_names)
        filtered_b_names = b_names[b_mask]
        filtered_bA_names = np.array(bA_names)[bA_mask]
        filtered_H = unfiltered_H[b_mask][:, b_mask]

        p_lb = pd.DataFrame(lb, filtered_b_names, [u'data'],
                            dtype=float).sort_index()
        p_ub = pd.DataFrame(ub, filtered_b_names, [u'data'],
                            dtype=float).sort_index()
        p_g = pd.DataFrame(g, filtered_b_names, [u'data'],
                           dtype=float).sort_index()
        p_lbA = pd.DataFrame(lbA, filtered_bA_names, [u'data'],
                             dtype=float).sort_index()
        p_ubA = pd.DataFrame(ubA, filtered_bA_names, [u'data'],
                             dtype=float).sort_index()
        p_weights = pd.DataFrame(unfiltered_H.dot(
            np.ones(unfiltered_H.shape[0])),
                                 b_names, [u'data'],
                                 dtype=float).sort_index()
        if xdot_full is not None:
            p_xdot = pd.DataFrame(xdot_full,
                                  filtered_b_names, [u'data'],
                                  dtype=float).sort_index()
            Ax = np.dot(A, xdot_full)
            p_Ax = pd.DataFrame(Ax, filtered_bA_names, [u'data'],
                                dtype=float).sort_index()
            xH = np.dot((xdot_full**2).T, filtered_H)
            p_xH = pd.DataFrame(xH, filtered_b_names, [u'data'],
                                dtype=float).sort_index()
            p_xg = p_g * p_xdot
            xHx = np.dot(np.dot(xdot_full.T, filtered_H), xdot_full)
            x_soft = xdot_full[len(xdot_full) - len(lbA):]
            p_lbA_minus_x = pd.DataFrame(lbA - x_soft,
                                         filtered_bA_names, [u'data'],
                                         dtype=float).sort_index()
            p_ubA_minus_x = pd.DataFrame(ubA - x_soft,
                                         filtered_bA_names, [u'data'],
                                         dtype=float).sort_index()
        else:
            p_xdot = None

        p_A = pd.DataFrame(A, filtered_bA_names, filtered_b_names,
                           dtype=float).sort_index(1).sort_index(0)
        # if self.lbAs is None:
        #     self.lbAs = p_lbA
        # else:
        #     self.lbAs = self.lbAs.T.append(p_lbA.T, ignore_index=True).T
        # self.lbAs.T[[c for c in self.lbAs.T.columns if 'dist' in c]].plot()

        # self.save_all(p_weights, p_A, p_lbA, p_ubA, p_lb, p_ub, p_xdot)
        return p_weights, p_A, p_lbA, p_ubA, p_lb, p_ub

    def are_joint_limits_violated(self, p_lb, p_ub):
        violations = (p_ub - p_lb)[p_lb.data > p_ub.data]
        if len(violations) > 0:
            logging.logerr(
                u'The following joints are outside of their limits: \n {}'.
                format(violations))
            return True
        logging.loginfo(u'All joints are within limits')
        return False

    def save_all(self, weights, A, lbA, ubA, lb, ub, xdot=None):
        if xdot is not None:
            print_pd_dfs([weights, A, lbA, ubA, lb, ub, xdot],
                         ['weights', 'A', 'lbA', 'ubA', 'lb', 'ub', 'xdot'])
        else:
            print_pd_dfs([weights, A, lbA, ubA, lb, ub],
                         ['weights', 'A', 'lbA', 'ubA', 'lb', 'ub'])

    def is_nan_in_array(self, name, p_array):
        p_filtered = p_array.apply(
            lambda x: zip(x.index[x.isnull()].tolist(), x[x.isnull()]), 1)
        p_filtered = p_filtered[p_filtered.apply(lambda x: len(x)) > 0]
        if len(p_filtered) > 0:
            logging.logerr(u'{} has the following nans:'.format(name))
            self.print_pandas_array(p_filtered)
            return True
        logging.loginfo(u'{} has no nans'.format(name))
        return False

    def print_pandas_array(self, array):
        import pandas as pd
        if len(array) > 0:
            with pd.option_context('display.max_rows', None,
                                   'display.max_columns', None):
                print(array)

    def filter_zero_weight_constraints(self, H, A, lb, ub, lbA, ubA, g):
        bA_mask, b_mask = make_filter_masks(H, self.num_joint_constraints,
                                            self.num_hard_constraints)
        A = A[bA_mask][:, b_mask].copy()
        lbA = lbA[bA_mask]
        ubA = ubA[bA_mask]
        lb = lb[b_mask]
        ub = ub[b_mask]
        g = g[b_mask]
        H = H[b_mask][:, b_mask]
        return H, A, lb, ub, lbA, ubA, g

    @profile
    def get_cmd(self, substitutions, nWSR=None):
        """
        Uses substitutions for each symbol to compute the next commands for each joint.
        :param substitutions:
        :type substitutions: list
        :return: joint name -> joint command
        :rtype: dict
        """
        np_big_ass_M = self.compiled_big_ass_M.call2(substitutions)
        np_H = np_big_ass_M[self.shape1:, :-3].copy()
        np_A = np_big_ass_M[:self.shape1, :self.shape2].copy()
        np_lb = np_big_ass_M[self.shape1:, -3].copy()
        np_ub = np_big_ass_M[self.shape1:, -2].copy()
        np_g = np_big_ass_M[self.shape1:, -1].copy()
        np_lbA = np_big_ass_M[:self.shape1, -3].copy()
        np_ubA = np_big_ass_M[:self.shape1, -2].copy()
        H, A, lb, ub, lbA, ubA, g = self.filter_zero_weight_constraints(
            np_H, np_A, np_lb, np_ub, np_lbA, np_ubA, np_g)
        # self.debug_print(np_H, A, lb, ub, lbA, ubA)
        try:
            xdot_full = self.qp_solver.solve(H, g, A, lb, ub, lbA, ubA, nWSR)
        except QPSolverException as e:
            p_weights, p_A, p_lbA, p_ubA, p_lb, p_ub = self.debug_print(
                np_H, A, lb, ub, lbA, ubA, g, actually_print=True)
            if isinstance(e, InfeasibleException):
                if self.are_joint_limits_violated(p_lb, p_ub):
                    raise OutOfJointLimitsException(e)
                raise HardConstraintsViolatedException(e)
            if isinstance(e, QPSolverException):
                arrays = [(p_weights, u'H'), (p_A, u'A'), (p_lbA, u'lbA'),
                          (p_ubA, u'ubA'), (p_lb, u'lb'), (p_ub, u'ub')]
                any_nan = False
                for a, name in arrays:
                    any_nan |= self.is_nan_in_array(name, a)
                if any_nan:
                    raise e
            raise e
        if xdot_full is None:
            return None
        # TODO enable debug print in an elegant way, preferably without slowing anything down
        self.debug_print(np_H, A, lb, ub, lbA, ubA, g, xdot_full)
        return OrderedDict((observable, xdot_full[i]) for i, observable in enumerate(self.controlled_joints)), \
               np_H, np_A, np_lb, np_ub, np_lbA, np_ubA, xdot_full
Ejemplo n.º 9
0
class QProblemBuilder(object):
    BACKEND = 'numpy'

    def __init__(self, joint_constraints_dict, hard_constraints_dict,
                 soft_constraints_dict):
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints_strs = list(self.joint_constraints_dict.keys())
        self.controlled_joints = sp.sympify(self.controlled_joints_strs)
        self.make_sympy_matrices()

        self.qp_solver = QPSolver(self.H.shape[0], len(self.lbA))

    # @profile
    def make_sympy_matrices(self):
        weights = []
        lb = []
        ub = []
        lbA = []
        ubA = []
        soft_expressions = []
        hard_expressions = []
        for jn in self.controlled_joints:
            c = self.joint_constraints_dict[str(jn)]
            weights.append(c.weight)
            lb.append(c.lower)
            ub.append(c.upper)
        for c in self.hard_constraints_dict.values():
            lbA.append(c.lower)
            ubA.append(c.upper)
            hard_expressions.append(c.expression)
        for c in self.soft_constraints_dict.values():
            weights.append(c.weight)
            lbA.append(c.lower)
            ubA.append(c.upper)
            lb.append(-1e9)
            ub.append(1e9)
            soft_expressions.append(c.expression)

        self.H = sp.diag(*weights)

        self.np_g = np.zeros(len(weights))

        self.lb = sp.Matrix(lb)
        self.ub = sp.Matrix(ub)

        # make A
        # hard part
        M_controlled_joints = sp.Matrix(self.controlled_joints)
        A_hard = sp.Matrix(hard_expressions)
        A_hard = A_hard.jacobian(M_controlled_joints)
        zerosHxS = sp.zeros(A_hard.shape[0], len(soft_expressions))
        A_hard = A_hard.row_join(zerosHxS)

        # soft part
        A_soft = sp.Matrix(soft_expressions)
        A_soft = A_soft.jacobian(M_controlled_joints)
        identity3x3 = sp.eye(A_soft.shape[0])
        A_soft = A_soft.row_join(identity3x3)

        # final A
        self.A = A_soft.row_insert(0, A_hard)

        self.lbA = sp.Matrix(lbA)
        self.ubA = sp.Matrix(ubA)

        self.cython_H = lambdify(list(self.H.free_symbols),
                                 self.H,
                                 self.BACKEND,
                                 dummify=False)
        self.H_symbols = [str(x) for x in self.H.free_symbols]

        self.cython_A = lambdify(list(self.A.free_symbols),
                                 self.A,
                                 self.BACKEND,
                                 dummify=False)
        self.A_symbols = [str(x) for x in self.A.free_symbols]

        self.cython_lb = lambdify(list(self.lb.free_symbols),
                                  self.lb,
                                  self.BACKEND,
                                  dummify=False)
        self.lb_symbols = [str(x) for x in self.lb.free_symbols]

        self.cython_ub = lambdify(list(self.ub.free_symbols),
                                  self.ub,
                                  self.BACKEND,
                                  dummify=False)
        self.ub_symbols = [str(x) for x in self.ub.free_symbols]

        self.cython_lbA = lambdify(list(self.lbA.free_symbols),
                                   self.lbA,
                                   self.BACKEND,
                                   dummify=False)
        self.lbA_symbols = [str(x) for x in self.lbA.free_symbols]

        self.cython_ubA = lambdify(list(self.ubA.free_symbols),
                                   self.ubA,
                                   self.BACKEND,
                                   dummify=False)
        self.ubA_symbols = [str(x) for x in self.ubA.free_symbols]

    def filter_observables(self, argument_names, observables_update):
        return {str(k): observables_update[k] for k in argument_names}

    # @profile
    def update_observables(self, observables_update):
        self.np_H = self.update_expression_matrix(self.cython_H,
                                                  self.H_symbols,
                                                  observables_update)
        self.np_A = self.update_expression_matrix(self.cython_A,
                                                  self.A_symbols,
                                                  observables_update)
        # for i in range(5):
        #     print(self.A[i,:])
        self.np_lb = self.update_expression_vector(self.cython_lb,
                                                   self.lb_symbols,
                                                   observables_update)
        self.np_ub = self.update_expression_vector(self.cython_ub,
                                                   self.ub_symbols,
                                                   observables_update)
        self.np_lbA = self.update_expression_vector(self.cython_lbA,
                                                    self.lbA_symbols,
                                                    observables_update)
        self.np_ubA = self.update_expression_vector(self.cython_ubA,
                                                    self.ubA_symbols,
                                                    observables_update)

        xdot_full = self.qp_solver.solve(self.np_H, self.np_g, self.np_A,
                                         self.np_lb, self.np_ub, self.np_lbA,
                                         self.np_ubA)
        if xdot_full is None:
            return None
        return OrderedDict(
            (observable, xdot_full[i])
            for i, observable in enumerate(self.controlled_joints_strs))

    # @profile
    def update_expression_matrix(self, matrix, argument_names, updates_dict):
        args = self.filter_observables(argument_names, updates_dict)
        if len(args) == 1:
            return matrix(args.values()[0])
        return matrix(**args).astype(float)

    def update_expression_vector(self, vector, argument_names, updates_dict):
        np_v = self.update_expression_matrix(vector, argument_names,
                                             updates_dict)
        return np_v.reshape(len(np_v))
Ejemplo n.º 10
0
class QProblemBuilder(object):
    """
    Wraps around QPOases. Builds the required matrices from constraints.
    """
    def __init__(self,
                 joint_constraints_dict,
                 hard_constraints_dict,
                 soft_constraints_dict,
                 controlled_joint_symbols,
                 free_symbols=None,
                 path_to_functions=''):
        """
        :type joint_constraints_dict: dict
        :type hard_constraints_dict: dict
        :type soft_constraints_dict: dict
        :type controlled_joint_symbols: set
        :type free_symbols: set
        :param path_to_functions: location where the compiled functions can be safed.
        :type path_to_functions: str
        """
        assert (
            not len(controlled_joint_symbols) > len(joint_constraints_dict))
        assert (
            not len(controlled_joint_symbols) < len(joint_constraints_dict))
        assert (len(hard_constraints_dict) <= len(controlled_joint_symbols))
        self.path_to_functions = path_to_functions
        self.free_symbols = free_symbols
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints = controlled_joint_symbols
        self.make_matrices()

        self.shape1 = len(self.hard_constraints_dict) + len(
            self.soft_constraints_dict)
        self.shape2 = len(self.joint_constraints_dict) + len(
            self.soft_constraints_dict)

        self.qp_solver = QPSolver(
            len(self.joint_constraints_dict) + len(self.soft_constraints_dict),
            len(self.hard_constraints_dict) + len(self.soft_constraints_dict))

    # @profile
    def make_matrices(self):
        """
        Turns constrains into a function that computes the matrices needed for QPOases.
        """
        # TODO split this into smaller functions to increase readability
        t_total = time()
        # TODO cpu intensive
        weights = []
        lb = []
        ub = []
        lbA = []
        ubA = []
        soft_expressions = []
        hard_expressions = []
        for k, c in self.joint_constraints_dict.items():
            weights.append(c.weight)
            lb.append(c.lower)
            ub.append(c.upper)
        for k, c in self.hard_constraints_dict.items():
            lbA.append(c.lower)
            ubA.append(c.upper)
            hard_expressions.append(c.expression)
        for k, c in self.soft_constraints_dict.items():
            weights.append(c.weight)
            lbA.append(c.lower)
            ubA.append(c.upper)
            lb.append(-BIG_NUMBER)
            ub.append(BIG_NUMBER)
            assert not isinstance(
                c.expression, spw.Matrix
            ), u'Matrices are not allowed as soft constraint expression'
            soft_expressions.append(c.expression)

        self.cython_big_ass_M = load_compiled_function(self.path_to_functions)
        self.np_g = np.zeros(len(weights))

        if self.cython_big_ass_M is None:
            print(u'new controller requested; compiling')
            self.H = spw.diag(*weights)

            self.lb = spw.Matrix(lb)
            self.ub = spw.Matrix(ub)

            # make A
            # hard part
            M_controlled_joints = spw.Matrix(self.controlled_joints)
            A_hard = spw.Matrix(hard_expressions)
            A_hard = A_hard.jacobian(M_controlled_joints)
            zerosHxS = spw.zeros(A_hard.shape[0], len(soft_expressions))
            A_hard = A_hard.row_join(zerosHxS)

            # soft part
            A_soft = spw.Matrix(soft_expressions)
            t = time()
            A_soft = A_soft.jacobian(M_controlled_joints)
            print(u'jacobian took {}'.format(time() - t))
            identity = spw.eye(A_soft.shape[0])
            A_soft = A_soft.row_join(identity)

            # final A
            self.A = A_hard.col_join(A_soft)

            self.lbA = spw.Matrix(lbA)
            self.ubA = spw.Matrix(ubA)

            big_ass_M_A = self.A.row_join(self.lbA).row_join(self.ubA)
            big_ass_M_H = self.H.row_join(self.lb).row_join(self.ub)
            # putting everything into one big matrix to take full advantage of cse in speed_up()
            self.big_ass_M = big_ass_M_A.col_join(big_ass_M_H)

            t = time()
            if self.free_symbols is None:
                self.free_symbols = self.big_ass_M.free_symbols
            self.cython_big_ass_M = spw.speed_up(self.big_ass_M,
                                                 self.free_symbols,
                                                 backend=BACKEND)
            if self.path_to_functions is not None:
                safe_compiled_function(self.cython_big_ass_M,
                                       self.path_to_functions)
            print(u'autowrap took {}'.format(time() - t))
        else:
            print(u'controller loaded {}'.format(self.path_to_functions))
        print(u'controller ready {}s'.format(time() - t_total))

    def save_pickle(self, hash, f):
        with open(u'/tmp/{}'.format(hash), u'w') as file:
            pickle.dump(f, file)

    def load_pickle(self, hash):
        return pickle.load(hash)

    def debug_print(self,
                    np_H,
                    np_A,
                    np_lb,
                    np_ub,
                    np_lbA,
                    np_ubA,
                    xdot_full=None):
        import pandas as pd
        lb = []
        ub = []
        lbA = []
        ubA = []
        weights = []
        xdot = []
        for iJ, k in enumerate(self.joint_constraints_dict.keys()):
            key = 'j -- ' + str(k)
            lb.append(key)
            ub.append(key)
            weights.append(key)
            xdot.append(key)

        for iH, k in enumerate(self.hard_constraints_dict.keys()):
            key = 'h -- ' + str(k)
            lbA.append(key)
            ubA.append(key)

        for iS, k in enumerate(self.soft_constraints_dict.keys()):
            key = 's -- ' + str(k)
            lbA.append(key)
            ubA.append(key)
            weights.append(key)
            xdot.append(key)
        p_lb = pd.DataFrame(np_lb[:-len(self.soft_constraints_dict)], lb)
        p_ub = pd.DataFrame(np_ub[:-len(self.soft_constraints_dict)], ub)
        p_lbA = pd.DataFrame(np_lbA, lbA)
        p_ubA = pd.DataFrame(np_ubA, ubA)
        p_weights = pd.DataFrame(np_H.dot(np.ones(np_H.shape[0])), weights)
        if xdot_full is not None:
            p_xdot = pd.DataFrame(xdot_full, xdot)
        p_A = pd.DataFrame(np_A, lbA, weights)
        pass

    def get_cmd(self, substitutions, nWSR=None):
        """
        Uses substitutions for each symbol to compute the next commands for each joint.
        :param substitutions: symbol -> value
        :type substitutions: dict
        :return: joint name -> joint command
        :rtype: dict
        """
        np_big_ass_M = self.cython_big_ass_M(**substitutions)
        # TODO create functions to extract the different matrices.
        np_H = np.array(np_big_ass_M[self.shape1:, :-2])
        np_A = np.array(np_big_ass_M[:self.shape1, :self.shape2])
        np_lb = np.array(np_big_ass_M[self.shape1:, -2])
        np_ub = np.array(np_big_ass_M[self.shape1:, -1])
        np_lbA = np.array(np_big_ass_M[:self.shape1, -2])
        np_ubA = np.array(np_big_ass_M[:self.shape1, -1])
        # self.debug_print(np_H, np_A, np_lb, np_ub, np_lbA, np_ubA)
        xdot_full = self.qp_solver.solve(np_H, self.np_g, np_A, np_lb, np_ub,
                                         np_lbA, np_ubA, nWSR)
        if xdot_full is None:
            return None
        # TODO enable debug print in an elegant way, preferably without slowing anything down
        # self.debug_print(np_H, np_A, np_lb, np_ub, np_lbA, np_ubA, xdot_full)
        return OrderedDict(
            (observable, xdot_full[i])
            for i, observable in enumerate(self.controlled_joints))
Ejemplo n.º 11
0
class QProblemBuilder(object):
    """
    Wraps around QPOases. Builds the required matrices from constraints.
    """

    def __init__(self, joint_constraints_dict, hard_constraints_dict, soft_constraints_dict, controlled_joint_symbols,
                 free_symbols=None, path_to_functions=''):
        """
        :type joint_constraints_dict: dict
        :type hard_constraints_dict: dict
        :type soft_constraints_dict: dict
        :type controlled_joint_symbols: set
        :type free_symbols: set
        :param path_to_functions: location where the compiled functions can be safed.
        :type path_to_functions: str
        """
        if free_symbols is not None:
            warnings.warn(u'use of free_symbols deprecated', DeprecationWarning)
        assert (not len(controlled_joint_symbols) > len(joint_constraints_dict))
        assert (not len(controlled_joint_symbols) < len(joint_constraints_dict))
        assert (len(hard_constraints_dict) <= len(controlled_joint_symbols))
        self.path_to_functions = path_to_functions
        self.free_symbols = free_symbols
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints = controlled_joint_symbols
        self.make_matrices()

        self.shape1 = len(self.hard_constraints_dict) + len(self.soft_constraints_dict)
        self.shape2 = len(self.joint_constraints_dict) + len(self.soft_constraints_dict)

        self.qp_solver = QPSolver(len(self.hard_constraints_dict),
                                  len(self.joint_constraints_dict),
                                  len(self.soft_constraints_dict))
        self.lbAs = None  # for debugging purposes

    def get_expr(self):
        return self.cython_big_ass_M.str_params

    def make_matrices(self):
        """
        Turns constrains into a function that computes the matrices needed for QPOases.
        """
        # TODO split this into smaller functions to increase readability
        t_total = time()
        # TODO cpu intensive
        weights = []
        lb = []
        ub = []
        lbA = []
        ubA = []
        soft_expressions = []
        hard_expressions = []
        for k, c in self.joint_constraints_dict.items():
            weights.append(c.weight)
            lb.append(c.lower)
            ub.append(c.upper)
        for k, c in self.hard_constraints_dict.items():
            lbA.append(c.lower)
            ubA.append(c.upper)
            hard_expressions.append(c.expression)
        for k, c in self.soft_constraints_dict.items():
            weights.append(c.weight)
            lbA.append(c.lower)
            ubA.append(c.upper)
            lb.append(-BIG_NUMBER)
            ub.append(BIG_NUMBER)
            assert not w.is_matrix(c.expression), u'Matrices are not allowed as soft constraint expression'
            soft_expressions.append(c.expression)

        self.cython_big_ass_M = w.load_compiled_function(self.path_to_functions)
        self.np_g = np.zeros(len(weights))

        if self.cython_big_ass_M is None:
            logging.loginfo(u'new controller with {} constraints requested; compiling'.format(len(soft_expressions)))
            h = len(self.hard_constraints_dict)
            s = len(self.soft_constraints_dict)
            c = len(self.joint_constraints_dict)

            #       c           s       1      1
            #   |----------------------------------
            # h | A hard    |   0    |       |
            #   | -------------------| lbA   | ubA
            # s | A soft    |identity|       |
            #   |-----------------------------------
            #c+s| H                  | lb    | ub
            #   | ----------------------------------
            self.big_ass_M = w.zeros(h+s+s+c, c+s+2)

            self.big_ass_M[h+s:,:-2] = w.diag(*weights)

            self.lb = w.Matrix(lb)
            self.ub = w.Matrix(ub)

            # make A
            # hard part
            A_hard = w.Matrix(hard_expressions)
            A_hard = w.jacobian(A_hard, self.controlled_joints)
            self.big_ass_M[:h, :c] = A_hard

            # soft part
            A_soft = w.Matrix(soft_expressions)
            t = time()
            A_soft = w.jacobian(A_soft, self.controlled_joints)
            logging.loginfo(u'jacobian took {}'.format(time() - t))
            identity = w.eye(A_soft.shape[0])
            self.big_ass_M[h:h+s, :c] = A_soft
            self.big_ass_M[h:h+s, c:c+s] = identity


            self.lbA = w.Matrix(lbA)
            self.ubA = w.Matrix(ubA)

            self.big_ass_M[:h+s, c+s] = self.lbA
            self.big_ass_M[:h+s, c+s+1] = self.ubA
            self.big_ass_M[h+s:, c+s] = self.lb
            self.big_ass_M[h+s:, c+s+1] = self.ub

            t = time()
            if self.free_symbols is None:
                self.free_symbols = w.free_symbols(self.big_ass_M)
            self.cython_big_ass_M = w.speed_up(self.big_ass_M,
                                               self.free_symbols)
            if self.path_to_functions is not None:
                # safe_compiled_function(self.cython_big_ass_M, self.path_to_functions)
                logging.loginfo(u'autowrap took {}'.format(time() - t))
        else:
            logging.loginfo(u'controller loaded {}'.format(self.path_to_functions))
            logging.loginfo(u'controller ready {}s'.format(time() - t_total))

    def save_pickle(self, hash, f):
        with open(u'/tmp/{}'.format(hash), u'w') as file:
            pickle.dump(f, file)

    def load_pickle(self, hash):
        return pickle.load(hash)

    def debug_print(self, np_H, np_A, np_lb, np_ub, np_lbA, np_ubA, xdot_full=None):
        import pandas as pd
        lb = []
        lbA = []
        weights = []
        xdot = []
        # if xdot_full is not None:
        #     A_dot_x = np_A.dot(xdot_full)
        for iJ, k in enumerate(self.joint_constraints_dict.keys()):
            key = 'j -- ' + str(k)
            lb.append(key)
            weights.append(key)
            xdot.append(key)

        for iH, k in enumerate(self.hard_constraints_dict.keys()):
            key = 'h -- ' + str(k)
            lbA.append(key)
            upper_bound = np_ubA[iH]
            lower_bound = np_lbA[iH]
            if np.sign(upper_bound) == np.sign(lower_bound):
                logging.logwarn(u'{} out of bounds'.format(k))
                if upper_bound > 0:
                    logging.logwarn(u'{} value below lower bound by {}'.format(k, lower_bound))
                    vel = np_ub[iH]
                    if abs(vel) < abs(lower_bound):
                        logging.logerr(u'joint vel of {} to low to get back into bound in one iteration'.format(vel))
                else:
                    logging.logwarn(u'{} value above upper bound by {}'.format(k, abs(upper_bound)))
                    vel = np_lb[iH]
                    if abs(vel) < abs(lower_bound):
                        logging.logerr(u'joint vel of {} to low to get back into bound in one iteration'.format(vel))

        for iS, k in enumerate(self.soft_constraints_dict.keys()):
            key = 's -- ' + str(k)
            lbA.append(key)
            weights.append(key)
            # xdot.append(key)
        p_lb = pd.DataFrame(np_lb[:-len(self.soft_constraints_dict)], lb).sort_index()
        p_ub = pd.DataFrame(np_ub[:-len(self.soft_constraints_dict)], lb).sort_index()
        p_lbA = pd.DataFrame(np_lbA, lbA).sort_index()
        # if xdot_full is not None:
        #     p_A_dot_x = pd.DataFrame(A_dot_x, lbA).sort_index()
        p_ubA = pd.DataFrame(np_ubA, lbA).sort_index()
        p_weights = pd.DataFrame(np_H.dot(np.ones(np_H.shape[0])), weights).sort_index()
        if xdot_full is not None:
            p_xdot = pd.DataFrame(xdot_full[:len(xdot)], xdot).sort_index()
        p_A = pd.DataFrame(np_A, lbA, weights).sort_index(1).sort_index(0)
        if self.lbAs is None:
            self.lbAs = p_lbA
        else:
            self.lbAs = self.lbAs.T.append(p_lbA.T, ignore_index=True).T
            # self.lbAs.T[[c for c in self.lbAs.T.columns if 'dist' in c]].plot()
        # arrays = [(p_weights, u'H'),
        #           (p_A, u'A'),
        #           (p_lbA, u'lbA'),
        #           (p_ubA, u'ubA'),
        #           (p_lb, u'lb'),
        #           (p_ub, u'ub')]
        # for a, name in arrays:
        #     self.check_for_nan(name, a)
        #     self.check_for_big_numbers(name, a)
        pass

    def check_for_nan(self, name, p_array):
        p_filtered = p_array.apply(lambda x: zip(x.index[x.isnull()].tolist(), x[x.isnull()]), 1)
        p_filtered = p_filtered[p_filtered.apply(lambda x: len(x)) > 0]
        if len(p_filtered) > 0:
            logging.logwarn(u'{} has the following nans:'.format(name))
            self.print_pandas_array(p_filtered)
        else:
            logging.loginfo(u'no nans')

    def check_for_big_numbers(self, name, p_array, big=1e5):
        # FIXME fails if condition is true on first entry
        p_filtered = p_array.apply(lambda x: zip(x.index[abs(x) > big].tolist(), x[x > big]), 1)
        p_filtered = p_filtered[p_filtered.apply(lambda x: len(x)) > 0]
        if len(p_filtered) > 0:
            logging.logwarn(u'{} has the following big numbers:'.format(name))
            self.print_pandas_array(p_filtered)
        else:
            logging.loginfo(u'no big numbers')

    def print_pandas_array(self, array):
        import pandas as pd
        if len(array) > 0:
            with pd.option_context('display.max_rows', None, 'display.max_columns', None):
                print(array)

    def get_cmd(self, substitutions, nWSR=None):
        """
        Uses substitutions for each symbol to compute the next commands for each joint.
        :param substitutions: symbol -> value
        :type substitutions: dict
        :return: joint name -> joint command
        :rtype: dict
        """
        np_big_ass_M = self.cython_big_ass_M.call2(substitutions)
        np_H = np_big_ass_M[self.shape1:, :-2].copy()
        np_A = np_big_ass_M[:self.shape1, :self.shape2].copy()
        np_lb = np_big_ass_M[self.shape1:, -2].copy()
        np_ub = np_big_ass_M[self.shape1:, -1].copy()
        np_lbA = np_big_ass_M[:self.shape1, -2].copy()
        np_ubA = np_big_ass_M[:self.shape1, -1].copy()
        # self.debug_print(np_H, np_A, np_lb, np_ub, np_lbA, np_ubA)
        try:
            xdot_full = self.qp_solver.solve(np_H, self.np_g, np_A, np_lb, np_ub, np_lbA, np_ubA, nWSR)
        except QPSolverException as e:
            self.debug_print(np_H, np_A, np_lb, np_ub, np_lbA, np_ubA)
            raise e
        if xdot_full is None:
            return None
        # TODO enable debug print in an elegant way, preferably without slowing anything down
        # self.debug_print(np_H, np_A, np_lb, np_ub, np_lbA, np_ubA, xdot_full)
        return OrderedDict((observable, xdot_full[i]) for i, observable in enumerate(self.controlled_joints)), \
               np_H, np_A, np_lb, np_ub, np_lbA, np_ubA, xdot_full
Ejemplo n.º 12
0
def test_simple_problem_split():
    cw1 = 10.
    cw2 = 1000.
    H = np.diag([1, 1, cw1, cw2])
    A = np.array([[1., 1, 1, 0], [1, 1, 0, 1]])
    g = np.zeros(4)
    lba = np.array([10., 5.])
    lb = np.array([-10., -10., -1e9, -1e9])
    ub = np.array([10., 10., 1e9, 1e9])

    qp = QPSolver()
    x1 = qp.solve(H, g, A, lb, ub, lba, lba)
    print(x1)

    H = np.diag([1, 1, cw1])
    A = np.array([[1., 1, 1]])
    g = np.zeros(3)
    lba = np.array([10.])
    lb = np.array([-10., -10., -1e9])
    ub = np.array([10., 10., 1e9])

    qp = QPSolver()
    x2 = qp.solve(H, g, A, lb, ub, lba, lba)
    print(x2)

    H = np.diag([1, 1, cw2])
    A = np.array([[1., 1, 1]])
    g = np.zeros(3)
    lba = np.array([5.])
    lb = np.array([-10., -10., -1e9])
    ub = np.array([10., 10., 1e9])

    qp = QPSolver()
    x3 = qp.solve(H, g, A, lb, ub, lba, lba)
    print(x3)

    H = np.diag([1., 1, cw1, cw1, cw2, cw2])
    A = np.array([[1., 0, 1, 0, 0, 0], [0., 1, 0, 1, 0, 0],
                  [1., 0, 0, 0, 1, 0], [0., 1, 0, 0, 0, 1]])
    g = np.zeros(H.shape[0])
    lba = np.array([
        x2[0],
        x2[1],
        x3[0],
        x3[1],
    ])
    lb = np.array([-10., -10., -1e9, -1e9, -1e9, -1e9])
    ub = np.array([10., 10., 1e9, 1e9, 1e9, 1e9])

    qp = QPSolver()
    x4 = qp.solve(H, g, A, lb, ub, lba, lba)
    print(x4)

    H = np.diag([1., 1, cw1, cw2, cw1, cw2])
    A = np.array([[1., 0, 1, 0, 0, 0], [0., 1, 1, 0, 0, 0],
                  [1., 0, 0, 1, 0, 0], [0., 1, 0, 1, 0, 0]])
    g = np.zeros(H.shape[0])
    lba = np.array([
        x2[0],
        x2[1],
        x3[0],
        x3[1],
    ])
    lb = np.array([-10., -10., -1e9, -1e9, -1e9, -1e9])
    ub = np.array([10., 10., 1e9, 1e9, 1e9, 1e9])

    qp = QPSolver()
    x5 = qp.solve(H, g, A, lb, ub, lba, lba)
    print(x5)
    print((x2[:2] + x3[:2]) / 2)
    print(np.sqrt((x1[:2]**2 + x2[:2]**2)) / 2)
Ejemplo n.º 13
0
class QProblemBuilder(object):
    def __init__(self,
                 joint_constraints_dict,
                 hard_constraints_dict,
                 soft_constraints_dict,
                 backend=None,
                 logging=print_wrapper):
        self.backend = backend
        self.logging = logging
        self.joint_constraints_dict = joint_constraints_dict
        self.hard_constraints_dict = hard_constraints_dict
        self.soft_constraints_dict = soft_constraints_dict
        self.controlled_joints_strs = list(self.joint_constraints_dict.keys())
        self.controlled_joints = [
            spw.Symbol(n) for n in self.controlled_joints_strs
        ]
        self.soft_constraint_indices = {}
        self.make_sympy_matrices()

        self.qp_solver = QPSolver(self.H.shape[0], len(self.lbA))

    # @profile
    def make_sympy_matrices(self):
        weights = []
        lb = []
        ub = []
        lbA = []
        ubA = []
        soft_expressions = []
        hard_expressions = []
        for jn in self.controlled_joints:
            c = self.joint_constraints_dict[str(jn)]
            weights.append(c.weight)
            lb.append(c.lower)
            ub.append(c.upper)
        for c in self.hard_constraints_dict.values():
            lbA.append(c.lower)
            ubA.append(c.upper)
            hard_expressions.append(c.expression)
        for scname, c in self.soft_constraints_dict.items():
            self.soft_constraint_indices[scname] = len(lbA)
            weights.append(c.weight)
            lbA.append(c.lower)
            ubA.append(c.upper)
            lb.append(-BIG_NUMBER)
            ub.append(BIG_NUMBER)
            soft_expressions.append(c.expression)

        self.H = spw.diag(*weights)

        self.np_g = np.zeros(len(weights))

        self.lb = spw.Matrix(lb)
        self.ub = spw.Matrix(ub)

        # make A
        # hard part
        M_controlled_joints = spw.Matrix(self.controlled_joints)
        A_hard = spw.Matrix(hard_expressions)
        A_hard = A_hard.jacobian(M_controlled_joints)
        zerosHxS = spw.zeros(A_hard.shape[0], len(soft_expressions))
        A_hard = A_hard.row_join(zerosHxS)

        # soft part
        A_soft = spw.Matrix(soft_expressions)
        t = time()
        A_soft = A_soft.jacobian(M_controlled_joints)
        self.logging('jacobian took {}'.format(time() - t))
        identity = spw.eye(A_soft.shape[0])
        A_soft = A_soft.row_join(identity)

        # final A
        self.A = A_hard.col_join(A_soft)

        self.lbA = spw.Matrix(lbA)
        self.ubA = spw.Matrix(ubA)

        t = time()
        try:
            self.cython_H = spw.speed_up(self.H, self.H.free_symbols)
        except Exception as e:
            raise Exception(
                'Error while wrapping weight matrix! Error: {}\n'.format(e))

        try:
            self.cython_A = spw.speed_up(self.A, self.A.free_symbols)
        except Exception as e:
            raise Exception(
                'Error while wrapping jacobian! Error: {}\n'.format(e))

        try:
            self.cython_lb = spw.speed_up(self.lb, self.lb.free_symbols)
        except Exception as e:
            raise Exception(
                'Error while wrapping lower bounds! Error: {}\n'.format(e))

        try:
            self.cython_ub = spw.speed_up(self.ub, self.ub.free_symbols)
        except Exception as e:
            raise Exception(
                'Error while wrapping upper bounds! Error: {}\n'.format(e))

        try:
            self.cython_lbA = spw.speed_up(self.lbA, self.lbA.free_symbols)
        except Exception as e:
            raise Exception(
                'Error while wrapping jacobian lower bounds! Error: {}\n'.
                format(e))

        try:
            self.cython_ubA = spw.speed_up(self.ubA, self.ubA.free_symbols)
        except Exception as e:
            raise Exception(
                'Error while wrapping jacobian upper bounds! Error: {}\n'.
                format(e))

        self.logging('autowrap took {}'.format(time() - t))

        # Strings for printing
        col_names = self.controlled_joints_strs + ['slack'
                                                   ] * len(soft_expressions)
        row_names = self.hard_constraints_dict.keys(
        ) + self.soft_constraints_dict.keys()

        self.str_A = pretty_matrix_format_str(col_names, row_names)
        self.str_b = pretty_matrix_format_str(
            ['lb', 'ub'],
            self.controlled_joints_strs + self.soft_constraints_dict.keys())
        self.str_bA = pretty_matrix_format_str(
            ['lbA', 'ubA'],
            self.hard_constraints_dict.keys() +
            self.soft_constraints_dict.keys())

    # @profile
    def update_observables(self, observables_update):
        #        print('Evaluating H')
        self.np_H = self.cython_H(**observables_update)
        #        print('Evaluating A')
        self.np_A = self.cython_A(**observables_update)
        #        print('Evaluating ctrl lb')
        self.np_lb = self.cython_lb(**observables_update).reshape(
            self.lb.shape[0])
        #print('Evaluating ctrl ub')
        self.np_ub = self.cython_ub(**observables_update).reshape(
            self.ub.shape[0])
        #print('Evaluating A lb')
        self.np_lbA = self.cython_lbA(**observables_update).reshape(
            self.lbA.shape[0])
        #print('Evaluating A ub')
        self.np_ubA = self.cython_ubA(**observables_update).reshape(
            self.ubA.shape[0])

        xdot_full = self.qp_solver.solve(self.np_H, self.np_g, self.np_A,
                                         self.np_lb, self.np_ub, self.np_lbA,
                                         self.np_ubA)
        if xdot_full is None:
            return None
        return OrderedDict(
            (observable, xdot_full[i])
            for i, observable in enumerate(self.controlled_joints_strs))

    def constraints_met(self, lbThreshold=0.01, ubThreshold=-0.01, names=None):
        if names == None:
            for x in range(len(self.np_lbA)):
                if self.np_lbA[x] > lbThreshold or self.np_ubA[x] < ubThreshold:
                    return False
        else:
            for name in names:
                x = self.soft_constraint_indices[name]
                if self.np_lbA[x] > lbThreshold or self.np_ubA[x] < ubThreshold:
                    return False
        return True

    def str_jacobian(self):
        return format_matrix(self.np_A, self.str_A)

    def str_lb_ub(self):
        return format_matrix(
            np.concatenate((self.np_lb.reshape(len(
                self.np_lb), 1), self.np_ub.reshape(len(self.np_ub), 1)),
                           axis=1), self.str_b)

    def str_lbA_ubA(self):
        return format_matrix(
            np.concatenate((self.np_lbA.reshape(len(
                self.np_lbA), 1), self.np_ubA.reshape(len(self.np_lbA), 1)),
                           axis=1), self.str_bA)

    def log_jacobian(self):
        self.logging('Matrix A: \n{}'.format(self.str_jacobian()))

    def log_lb_ub(self):
        self.logging('Matrix lb, ub: \n{}'.format(self.str_lb_ub()))

    def log_lbA_ubA(self):
        self.logging('Matrix lbA, ubA: \n{}'.format(self.str_lbA_ubA()))

    def reset_solver(self):
        self.qp_solver = QPSolver(self.H.shape[0], len(self.lbA))
Ejemplo n.º 14
0
 def reset_solver(self):
     self.qp_solver = QPSolver(self.H.shape[0], len(self.lbA))