robotpy/robotpy-commands-v2

Impossible to diagnose issue with functional commands

Closed this issue · 2 comments

Easy reproducer:

>>> import commands2.cmd
>>> r = commands2.cmd.run(None, [])
>>> r.execute()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: bad_function_call

The actual situation where this occurred was when one of our examples called a function instead of using a lambda:

@@ -56,13 +56,13 @@ class RobotContainer:
 
         # Move the arm to 2 radians above horizontal when the 'A' button is pressed.
         self.driver_controller.A().onTrue(
-            commands2.cmd.run(self.moveArm(2), [self.robot_arm])
+            commands2.cmd.run(lambda: self.moveArm(2), [self.robot_arm])
         )
 
         # Move the arm to neutral position when the 'B' button is pressed
         self.driver_controller.B().onTrue(
             commands2.cmd.run(
-                self.moveArm(constants.ArmConstants.kArmOffsetRads), [self.robot_arm]
+                lambda: self.moveArm(constants.ArmConstants.kArmOffsetRads), [self.robot_arm]
             )
         )

FWIW, I don't exactly understand why this is possible. The type caster for std::function doesn't... oh, the problem is that it accepts None as a valid argument and converts it to an empty function. Womp.

Here's how we do it: https://pybind11.readthedocs.io/en/stable/advanced/functions.html#allow-prohibiting-none-arguments. It is a weird footgun that it allows None by default.

Fixed in 2023.3.2.2