Search code examples
pythonjupyter-notebookdrake

RuntimeError: You should not call `__bool__` / `__nonzero__` on `Formula`


I am working on Exercise 3.9 (virtual wall) from Russ Tedrake's Robotic Manipulation course, and I'm receiving the runtime error above when attempting to add the end-effector position constraint. I've been stuck on this almost all day, so I caved and decided to post. Another post had a similar error, but it wasn't enough for me to see what's going wrong. I'll try to give as little information as necessary to avoid showing my solution to the problem.

Here is the code with some lines missing.

prog = MathematicalProgram()
      v = prog.NewContinuousVariables(7, 'joint_velocities')
      v_max = 3.0 # do not modify
      h = 4e-3 # do not modify
      lower_bound = np.array([-0.3, -1.0, -1.0]) # do not modify
      upper_bound = np.array([0.3, 1.0, 1.0]) # do not modify

In the following, 'p' is an array of symbolic expressions that depend on elements of 'v'.

  for i in range(p.shape[0]):
    prog.AddConstraint(le(lower_bound[i], p[i]))
    prog.AddConstraint(ge(upper_bound[i], p[i]))

  solver = SnoptSolver()
  result = solver.Solve(prog)
    
  if not (result.is_success()):
    raise ValueError("Could not find the optimal solution.")

  v_solution = result.GetSolution(v)
  return v_solution

And here is the error message. The first line in the for loop is where the error occurs.

RuntimeError                              Traceback (most recent call last)
<ipython-input-108-b73c5373ad6c> in <module>()
      1 V_d = np.array([0.0, 0., 0., 0.1, 0.05, 0])
----> 2 simulator = BuildAndSimulate(DiffIKQP_Wall, V_d)

5 frames
/usr/local/lib/python3.7/dist-packages/numpy/lib/function_base.py in _get_ufunc_and_otypes(self, func, args)
   2144 
   2145             inputs = [arg.flat[0] for arg in args]
-> 2146             outputs = func(*inputs)
   2147 
   2148             # Performance note: profiling indicates that -- for simple

RuntimeError: You should not call `__bool__` / `__nonzero__` on `Formula`. If you are trying to make a map with `Variable`, `Expression`, or `Polynomial` as keys (and then access the map in Python), please use pydrake.common.containers.EqualToDict`.

Please let me know if have any suggestions or you need more information.

Thanks!

Edit:

I thought this information might be helpful. Running

print(type(lower_bound[i]))
print(type(p[i]))

returns

<class 'numpy.float64'>
<class 'pydrake.symbolic.Expression'>

Solution

  • Well... i'm embarassed. But I think you've found a bug in our python bindings.

    from pydrake.all import Variable, le, ge
    x = Variable("x")
    
    print(2 <= x**2)
    print(x**2 <= 2)
    print(le(x**2, 2))
    #print(le(2, x**2))  <== this crashes
    
    print(ge(x**2, 2))
    #print(ge(2, x**2))  <== this too.
    

    I've opened: https://github.com/RobotLocomotion/drake/issues/15549

    But for now, please pick any of the other ways to write the same constraint?