Repository: stack-of-tasks/tsid (language: python)

Issue:
github action on OSX conda Release failing on osqp solver
Dear @fabinsch,
Currently unrelated PR #212 fails due to an error when testing the Oxford osqp solver on Linux /OS Conda Release.
See here for instance:
https://github.com/stack-of-tasks/tsid/actions/runs/6538220426/job/17753685229?pr=212

I suspect that this is related to an incompatibility or a release problem as the same test seems to work for Linux - ROS Noetic Debug , where as in PR #213 it was the reverse (i.e failing for Linux ROS Noetic Debug and fine for Linux/OS Conda Release).

As you authored the test, could you give an insight on how to fix the problem ?


Discussion / hints:
Hi @olivier-stasse,

it is correct that I added proxqp and osqp. In this test, we create random problems and then check if the solver can solve the problem up to `EPS=1e-3`.  We are not setting any accuracy for the solvers, which leads to  `epsAbs = 1e-5` for [osqp](https://github.com/stack-of-tasks/tsid/blob/master/src/solvers/solver-osqp.cpp#L35). We could try to increase the accuracy we ask for by doing `solver.set_epsilon_absolute(1e-5)` for example. Also, we can fix the random seed to be sure to always run on the same problem.

If you want, I can open another PR where I do this change, and we can check if the tests pass. If yes, we can rebase the open PRs.

Fix patch:
diff --git a/exercizes/notebooks/Installation process.ipynb b/exercizes/notebooks/Installation process.ipynb
index de8bd7cc..0923bcf9 100644
--- a/exercizes/notebooks/Installation process.ipynb
+++ b/exercizes/notebooks/Installation process.ipynb
@@ -1,5 +1,5 @@
 {
- "cells": [
+  "cells": [
   {
    "cell_type": "markdown",
    "metadata": {},
diff --git a/exercizes/notebooks/ex_0_joint_space_inverse_dynamics_arm.ipynb b/exercizes/notebooks/ex_0_joint_space_inverse_dynamics_arm.ipynb
index 1e1642e7..04eee69d 100644
--- a/exercizes/notebooks/ex_0_joint_space_inverse_dynamics_arm.ipynb
+++ b/exercizes/notebooks/ex_0_joint_space_inverse_dynamics_arm.ipynb
@@ -1,5 +1,5 @@
 {
- "cells": [
+  "cells": [
   {
    "cell_type": "markdown",
    "metadata": {},
diff --git a/exercizes/notebooks/ex_1_com_sin_track_talos.ipynb b/exercizes/notebooks/ex_1_com_sin_track_talos.ipynb
index a5e1f8c4..1d707a61 100644
--- a/exercizes/notebooks/ex_1_com_sin_track_talos.ipynb
+++ b/exercizes/notebooks/ex_1_com_sin_track_talos.ipynb
@@ -1,5 +1,5 @@
 {
- "cells": [
+  "cells": [
   {
    "cell_type": "markdown",
    "metadata": {},
diff --git a/exercizes/notebooks/ex_3_biped_balance_with_gui.ipynb b/exercizes/notebooks/ex_3_biped_balance_with_gui.ipynb
index f6db703c..c63fad6d 100644
--- a/exercizes/notebooks/ex_3_biped_balance_with_gui.ipynb
+++ b/exercizes/notebooks/ex_3_biped_balance_with_gui.ipynb
@@ -1,5 +1,5 @@
 {
- "cells": [
+  "cells": [
   {
    "cell_type": "code",
    "execution_count": null,


Test patch:
diff --git a/tests/python/test_Solvers.py b/tests/python/test_Solvers.py
index eb8e2896..646bc53f 100644
--- a/tests/python/test_Solvers.py
+++ b/tests/python/test_Solvers.py
@@ -5,6 +5,8 @@
 print("Test Solvers")
 print("")
 
+np.random.seed(0)
+
 EPS = 1e-3
 nTest = 100
 n = 60
@@ -38,6 +40,7 @@
 
 try:
     solver_proxqp = tsid.SolverProxQP("proxqp solver")
+    solver_proxqp.set_epsilon_absolute(1e-6)
     solver_proxqp.resize(n, neq, nin)
     solver_list.append(("proxqp", solver_proxqp))
     print("Adding proxqp to list of solvers to test")
@@ -47,6 +50,8 @@
 
 try:
     solver_osqp = tsid.SolverOSQP("osqp solver")
+    solver_osqp.set_epsilon_absolute(1e-6)
+    solver_osqp.set_maximum_iterations(10_000)
     solver_osqp.resize(n, neq, nin)
     solver_list.append(("osqp", solver_osqp))
     print("Adding osqp to list of solvers to test")
@@ -59,7 +64,8 @@
 b1 = np.random.rand(n)
 cost = tsid.ConstraintEquality("c1", A1, b1)
 
-x = np.linalg.inv(A1).dot(b1)
+x = np.linalg.solve(A1, b1)
+
 A_in = np.random.rand(nin, n)
 A_lb = np.random.rand(nin) * NORMAL_DISTR_VAR
 A_ub = np.random.rand(nin) * NORMAL_DISTR_VAR
@@ -110,6 +116,7 @@
 
         HQPoutput = solver.solve(HQPData)
 
+        assert HQPoutput.status == 0  # HQP_STATUS_OPTIMAL = 0
         assert np.linalg.norm(A_eq.dot(HQPoutput.x) - b_eq, 2) < EPS
         assert (A_in.dot(HQPoutput.x) <= A_ub + EPS).all()
         assert (A_in.dot(HQPoutput.x) > A_lb - EPS).all()