Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/python_package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ jobs:
run: |
pip install pybind11-stubgen
pip install .
mkdir -p stubs_temp
pybind11-stubgen dqrobotics --output-dir stubs_temp
python regenerate_stubs.py
cp -r stubs_temp/dqrobotics/dqrobotics/ dqrobotics-stubs
rm -r stubs_temp
pip uninstall dqrobotics -y
- name: Compile
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dqrobotics/_dqrobotics/
1 change: 0 additions & 1 deletion dqrobotics-stubs/README.md

This file was deleted.

2 changes: 1 addition & 1 deletion dqrobotics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
#
# ################################################################
"""
from dqrobotics._dqrobotics import *
from ._dqrobotics import *

2 changes: 1 addition & 1 deletion dqrobotics/interfaces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@
#
# ################################################################
"""
from dqrobotics._dqrobotics._interfaces import *
from .._dqrobotics._interfaces import *
26 changes: 0 additions & 26 deletions dqrobotics/interfaces/coppeliasim/__init__.py

This file was deleted.

2 changes: 1 addition & 1 deletion dqrobotics/interfaces/json11/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@
#
# ################################################################
"""
from dqrobotics._dqrobotics._interfaces._json11 import *
from ..._dqrobotics._interfaces._json11 import *
26 changes: 0 additions & 26 deletions dqrobotics/interfaces/vrep/__init__.py

This file was deleted.

26 changes: 0 additions & 26 deletions dqrobotics/interfaces/vrep/robots/__init__.py

This file was deleted.

Empty file added dqrobotics/py.typed
Empty file.
2 changes: 1 addition & 1 deletion dqrobotics/robot_control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@
#
# ################################################################
"""
from dqrobotics._dqrobotics._robot_control import *
from .._dqrobotics._robot_control import *
2 changes: 1 addition & 1 deletion dqrobotics/robot_modeling/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@
#
# ################################################################
"""
from dqrobotics._dqrobotics._robot_modeling import *
from .._dqrobotics._robot_modeling import *
2 changes: 1 addition & 1 deletion dqrobotics/robots/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@
#
# ################################################################
"""
from dqrobotics._dqrobotics._robots import *
from .._dqrobotics._robots import *
6 changes: 3 additions & 3 deletions dqrobotics/solvers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
#
# ################################################################
"""
from dqrobotics._dqrobotics._solvers import *
from .._dqrobotics._solvers import *

try:
from dqrobotics.solvers._dq_quadprog_solver import DQ_QuadprogSolver
from dqrobotics.solvers._dq_quadprog_solver import DQ_QuadprogSolver as DQ_QuadprogSolver
except:
pass

try:
from dqrobotics.solvers._dq_cplex_solver import DQ_CPLEXSolver
from dqrobotics.solvers._dq_cplex_solver import DQ_CPLEXSolver as DQ_CPLEXSolver
except:
pass
15 changes: 12 additions & 3 deletions dqrobotics/solvers/_dq_cplex_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,30 @@
#
# ################################################################
"""
from __future__ import annotations
from dqrobotics._dqrobotics._solvers import DQ_QuadraticProgrammingSolver
import numpy as np
from numpy.typing import NDArray
import cplex

# https://github.com/dqrobotics/python/issues/24
class DQ_CPLEXSolver(DQ_QuadraticProgrammingSolver):
def __init__(self):
def __init__(self) -> None:
DQ_QuadraticProgrammingSolver.__init__(self)
# Make and set a solver instance
self.P = cplex.Cplex()
self.P: cplex.Cplex = cplex.Cplex()
self.P.objective.set_sense(self.P.objective.sense.minimize)
self.P.set_problem_type(self.P.problem_type.QP)
self.P.set_results_stream(results_file=None)

def solve_quadratic_program(self, H, f, A, b, Aeq, beq):
# Narrower than the base class's ArrayLike: this implementation requires numpy arrays.
def solve_quadratic_program(self, # type: ignore[override]
H: NDArray[np.float64],
f: NDArray[np.float64],
A: NDArray[np.float64],
b: NDArray[np.float64],
Aeq: NDArray[np.float64],
beq: NDArray[np.float64]) -> NDArray[np.float64]:
problem_size = H.shape[0]
inequality_constraint_size = b.shape[0]
equality_constraint_size = beq.shape[0]
Expand Down
45 changes: 30 additions & 15 deletions dqrobotics/solvers/_dq_quadprog_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,41 @@
#
# ################################################################
"""
from __future__ import annotations
from typing import Optional
from dqrobotics._dqrobotics._solvers import DQ_QuadraticProgrammingSolver
import numpy as np
from numpy.typing import NDArray
import quadprog

class DQ_QuadprogSolver(DQ_QuadraticProgrammingSolver):
def __init__(self):
def __init__(self) -> None:
DQ_QuadraticProgrammingSolver.__init__(self)
self.equality_constraints_tolerance = 0 # default of np.finfo(np.float64).eps is already included in the solver
self.equality_constraints_tolerance: float = 0 # default of np.finfo(np.float64).eps is already included in the solver
pass

def set_equality_constraints_tolerance(self, tolerance):
def set_equality_constraints_tolerance(self, tolerance: float) -> None:
"""
Set allowed tolerance for the equality constraints
:param tolerance: Tolerance allowed for equality constraints
"""
self.equality_constraints_tolerance = tolerance

def get_equality_constraints_tolerance(self):
def get_equality_constraints_tolerance(self) -> float:
"""
Get allowed tolerance for the equality constraints
:return: Current tolerance
"""
return self.equality_constraints_tolerance

def solve_quadratic_program(self, H, f, A, b, Aeq, beq):
# Narrower than the base class's ArrayLike: this implementation requires numpy arrays.
def solve_quadratic_program(self, # type: ignore[override]
H: NDArray[np.float64],
f: NDArray[np.float64],
A: Optional[NDArray[np.float64]],
b: Optional[NDArray[np.float64]],
Aeq: Optional[NDArray[np.float64]],
beq: Optional[NDArray[np.float64]]) -> NDArray[np.float64]:
"""
Solves the following quadratic program
min(x) 0.5*x'Hx + f'x
Expand Down Expand Up @@ -81,24 +91,29 @@ def solve_quadratic_program(self, H, f, A, b, Aeq, beq):
# Turn equality into a bounded inequality
## Aeq.x <= beq + delta
## Aeq.x >= beq - delta ==> -Aeq.x <= -beq + delta
if Aeq is not None: # beq is None already checked by the ValueError
if Aeq is not None:
assert beq is not None # Already checked by the ValueError
Aeq = np.vstack([Aeq, -Aeq])
beq = beq.reshape(-1)
beq = np.concatenate([beq + self.equality_constraints_tolerance, -beq + self.equality_constraints_tolerance])

# Use (A,b), (Aeq,beq), or both.
if Aeq is None:
# Use (A,b), (Aeq,beq), or both. The asserts were already checked by the ValueError.
A_internal: NDArray[np.float64]
b_internal: NDArray[np.float64]
if A is not None and Aeq is not None:
assert b is not None and beq is not None
A_internal = np.vstack([A, Aeq])
b_internal = np.concatenate([b.reshape(-1), beq])
elif A is not None:
assert b is not None
A_internal = A
b_internal = b
if A is None:
elif Aeq is not None:
assert beq is not None
A_internal = Aeq
b_internal = beq
if Aeq is not None and A is not None:
A_internal = np.vstack([A, Aeq])
b_internal = np.concatenate([b.reshape(-1), beq])

# Solve for the unconstrained case. quadprog does not accept None, so we add a dummy constraint.
if A is None and b is None and Aeq is None and beq is None:
else:
# Solve for the unconstrained case. quadprog does not accept None, so we add a dummy constraint.
A_internal = np.zeros((1, H.shape[0]))
b_internal = np.zeros(1)

Expand Down
2 changes: 1 addition & 1 deletion dqrobotics/utils/DQ_LinearAlgebra/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@
#
# ################################################################
"""
from dqrobotics._dqrobotics._utils._DQ_LinearAlgebra import *
from ..._dqrobotics._utils._DQ_LinearAlgebra import *
2 changes: 1 addition & 1 deletion dqrobotics/utils/DQ_Math/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from dqrobotics._dqrobotics._utils._DQ_Math import *
from ..._dqrobotics._utils._DQ_Math import *
2 changes: 1 addition & 1 deletion dqrobotics/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@
#
# ################################################################
"""
from dqrobotics._dqrobotics._utils import *
from .._dqrobotics._utils import *
8 changes: 7 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,10 @@ Issues = "https://github.com/dqrobotics/python/issues"
enabled = true
# https://stackoverflow.com/questions/73605607/how-to-use-setuptools-scm
dev_template = "{tag}.a{ccount}"
dirty_template = "{tag}.a{ccount}"
dirty_template = "{tag}.a{ccount}"

[tool.mypy]
# The optional solver backends of dqrobotics.solvers ship no type information.
[[tool.mypy.overrides]]
module = ["quadprog", "cplex"]
ignore_missing_imports = true
Loading
Loading