Phoenix 6 Arcade Drive Simulation in Python

I’m trying to update our tutorial code for 2024. I’ve updated to beta5 of Phoenix 6 which now has all the simulation classes, but I’m getting to a roadblock where the TalonFXSimState object doesn’t seem to actually produce voltage when you call set_supply_voltage(). Meaning, after calling set_supply_voltage applying the inputs to the DifferentialDriveSim passing the left and right voltages, nothing happens due to the left and right voltages constantly sitting at 0.

I was using the ArcadeDrive Phoenix 6 example code, and trying to port it to Python.

Full repository is here.

From the physics.py file, in the update_sim method, this is how I was proceeding:

def update_sim(self, now: float, tm_diff: float) -> None:
        """
        Called when the simulation parameters for the program need to be
        updated.
        :param now: The current time as a float
        :param tm_diff: The amount of time that has passed since the last
                        time that this function was called
        """

        # CTRE simulation is low-level, it ignores some of the things like motor
        # motor invresion etc.  WPILib wants +v to be forward.
        # Start the motor simulation work flow by passing robot battery voltage to sim motors
        self._l_lead_motor.set_supply_voltage(
            wpilib.RobotController.getBatteryVoltage()
        )
        ....

        # Apply the motor inputs to the simulation
        self._drivesim.setInputs(
            self._l_lead_motor.motor_voltage,
            self._r_lead_motor.motor_voltage,
        )

        # advance the simulation model a timing loop
        self._drivesim.update(tm_diff)

        ....

        # Update the gyro simulation
        # -> FRC gyros are positive clockwise, but the returned pose is positive
        #    counter-clockwise
        pose = self._drivesim.getPose()
        self.navx_yaw.set(-self._drivesim.getHeading().degrees())
        # self.navx_yaw.set(-pose.rotation().degrees())

        self.physics_controller.field.setRobotPose(pose) 

I have confirmed that the drivetrain method is being called, and updating the DutyCycleOutput objects like this:

def drive_manually(self, forward: float, turn: float) -> None:
        self._left_duty_cyle.output = forward + turn
        self._right_duty_cycle.output = forward - turn

        self._left_leader.set_control(self._left_duty_cyle)
        self._right_leader.set_control(self._right_duty_cycle)

Has anyone else gotten CTRE simulation in Python with Phoenix 6?

It looks like you’re missing the feed_enable method to enable the devices in sim.
We have a fancy feature in Java/C++ where if the robot is enabled as reported by the Sim Driverstation, we automatically feed enable, but we haven’t implemented that yet in the Python API.
So for the moment you’ll need to manually feed the enable signal.

We’re still in progress updating our python examples, but you can see roughly what it would look like here:

Thanks for the pointer, I’m not sure I would have ever found that one just debugging in a reasonable amount of time. Trying to get this code into our repo before Christmas break and kickoff.