poteus
December 31, 2024, 4:28am
1
Dear Chief Delphi Community,
we are struggling implementing SysID in Python. We managed to make it work last season, but we get Failure to Test this year. The errors we get back point toward initializing controllers with the same can ID, which looks like it is a Test issue and not the real issue.
RuntimeError: A CANSparkMax instance has already been created with this device ID: 11
We were able to tune our steering motors (NEO with SparkMax). We are working on tuning the FF and PID controller for the forward motors (Kraken with TalonFX). All motors and controllers have been tested and work perfectly.
Here is the link to our repo. Any advice will be much appreciated.
Your real error can probably be found in the first failing test. There’s a known issue where when one pyfrc test fails, it doesn’t release the resources held by the robot, causing subsequent pyfrc tests to fail.
You can get the tests to stop immediately on fail with the following command, if it helps.
robotpy test -- --exitfirst
poteus
December 31, 2024, 1:22pm
3
It did exit after the first error. Helas, it gave us the same error. No sign of were is the real issue…
Debugging by commenting by chunks, it looks like the error comes when we are creating the Mechanism
self.sys_id_routine = SysIdRoutine(
SysIdRoutine.Config(recordState = lambda state: phoenix6.SignalLogger.write_string("state", SysIdRoutineLog.stateEnumToString(state))),
SysIdRoutine.Mechanism(sysidDrive, self.log, self),
)
Github source
poteus
December 31, 2024, 2:03pm
4
Here is full message of the error thrown back by pyfrc…
python -m robotpy test -- --exitfirst
08:01:32:323 WARNING : pyfrc.physics : Cannot enable physics support, F:\Drive\SHS\Clubs and Teams\First Robotics\Programmers\Reefscape6651\physics.py not found
============================================================================================== test session starts ===============================================================================================
platform win32 -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0
rootdir: F:\Drive\SHS\Clubs and Teams\First Robotics\Programmers\Reefscape6651
configfile: pyproject.toml
plugins: reraise-2.1.2, typeguard-4.3.0
collected 4 items
pyfrc_test.py .F
==================================================================================================== FAILURES ====================================================================================================
_________________________________________________________________________________________________ test_disabled __________________________________________________________________________________________________
item = <Function test_disabled>
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_call(item: Item):
result = yield
if hasattr(item, "funcargs") and "reraise" in item.funcargs:
reraise = item.funcargs["reraise"]
# Override any non-re-raised exception in the main thread by calling `reraise()`
if result.excinfo is None or not hasattr(
result.excinfo[1], "_is_from_pytest_reraise"
):
> reraise()
C:\Users\kpuma\AppData\Local\Programs\Python\Python312\Lib\site-packages\pytest_reraise\reraise.py:136:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Users\kpuma\AppData\Local\Programs\Python\Python312\Lib\site-packages\pytest_reraise\reraise.py:72: in __call__
raise e
C:\Users\kpuma\AppData\Local\Programs\Python\Python312\Lib\site-packages\pyfrc\test_support\controller.py:42: in _robot_thread
robot.startCompetition()
C:\Users\kpuma\AppData\Local\Programs\Python\Python312\Lib\site-packages\pyfrc\test_support\pytest_plugin.py:46: in robotInit
super().robotInit()
..\robot.py:22: in robotInit
self.container = robotcontainer.RobotContainer()
..\robotcontainer.py:27: in __init__
self.swerveSubsystem = SwerveSubsystem()
..\subsystems\SwerveSubsystem.py:26: in __init__
self.frontLeft = SwerveModule(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <subsystems.SwerveModule.SwerveModule object at 0x000002D381A9E690>, driveMotorID = 12, turningMotorID = 11, driveMotorReversed = False, turningMotorReversed = True, absoluteEncoderID = 13
absoluteEncoderOffset = -1.270136, absoluteEncoderReversed = False, drivePIDk = [0.1, 0, 0, 0.1, 2.3, 0.06]
def __init__(self, driveMotorID, turningMotorID, driveMotorReversed, turningMotorReversed,
absoluteEncoderID, absoluteEncoderOffset, absoluteEncoderReversed, drivePIDk):
''' Constructor for SwerveModule '''
self.absoluteEncoderOffsetRad = absoluteEncoderOffset
self.absoluteEncoderReversed = absoluteEncoderReversed
# Init of Absolute Encoder (CANCoder)
self.absoluteEncoder = phoenix6.hardware.CANcoder(absoluteEncoderID)
# Init of Drive Motor (TalonFX) for Kraken X.60
self.driveMotor = phoenix6.hardware.TalonFX(driveMotorID)
# Init of Turning Motor (SparkMax) for NEO v1.1
> self.turningMotor = rev.CANSparkMax(turningMotorID, rev.CANSparkLowLevel.MotorType.kBrushless)
E RuntimeError: A CANSparkMax instance has already been created with this device ID: 11
..\subsystems\SwerveModule.py:38: RuntimeError
--------------------------------------------------------------------------------------------- Captured stdout setup ----------------------------------------------------------------------------------------------
********** Robot program startup complete **********
Default frc::IterativeRobotBase::RobotPeriodic() method... Override me!
Default frc::IterativeRobotBase::SimulationPeriodic() method... Override me!
Not loading CameraServerShared
============================================================================================ short test summary info =============================================================================================
FAILED pyfrc_test.py::test_disabled - RuntimeError: A CANSparkMax instance has already been created with this device ID: 11
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================================================================== 1 failed, 1 passed in 0.67s ===========================================================================================
[phoenix-diagnostics] Server shutdown cleanly. (dur:0)
[phoenix] Library shutdown cleanly
Hopefully Use pytest-xdist to isolate tests by justinb4003 · Pull Request #236 · robotpy/pyfrc · GitHub will fix this test issue. Going to try to get it in for kickoff, but we’ll see what happens.
poteus
January 1, 2025, 2:44pm
6
Sorry, but that does not help much. We still have the same issue.
We are more interested on the code than the lack of feedback from pyfrc.
The error looks like it comes from creating sys_id_routine
SysConfig = SysIdRoutine.Config(
# This is the function that will be called to set the mechanism to a given state
recordState = lambda state: phoenix6.SignalLogger.write_string("state", SysIdRoutineLog.stateEnumToString(state)),
)
SysMechanism = SysIdRoutine.Mechanism(
sysidDrive,
None, #self.log,
self)
self.sys_id_routine = SysIdRoutine(
SysConfig,
SysMechanism
)
Packages installed
robotpy 2024.3.2.2
robotpy-apriltag 2024.3.2.1
robotpy-cli 2024.0.0
robotpy-commands-v2 2024.3.1
robotpy-cscore 2024.3.2.1
robotpy-ctre 2024.1.3
robotpy-hal 2024.3.2.1
robotpy-halsim-ds-socket 2024.3.2.1
robotpy-halsim-gui 2024.3.2.1
robotpy-halsim-ws 2024.3.2.1
robotpy-installer 2024.2.4
robotpy-navx 2024.1.1
robotpy-pathplannerlib 2024.2.7
robotpy-playingwithfusion 2024.2.0
robotpy-rev 2024.2.4
robotpy-romi 2024.3.2.1
robotpy-wpilib-utilities 2024.1.0
robotpy-wpimath 2024.3.2.1
robotpy-wpinet 2024.3.2.1
robotpy-wpiutil 2024.3.2.1
robotpy-xrp 2024.3.2.1
Any feedback is welcome.
poteus
January 1, 2025, 3:31pm
7
We forced the deploy to the roborio, and it ran the program with no problem. No errors or warnings on the console.
Warning 0 [phoenix-diagnostics] Server 2024.1.0 (Apr 30 2024, 17:31:56) running on port: 1250
Wed Jan 1 09:27:31 CST 2025 - Killing robot code in frcKillRobot.sh
09:27:34:964 INFO : faulthandler : registered SIGUSR2 for PID 3817
09:27:40:092 INFO : deploy-info : kpuma@Tron at 2025-01-01T09:27:22
09:27:40:093 INFO : deploy-info : - git info: 7c1bfa7-dirty (branch=SysID)
09:27:40:094 INFO : wpilib : RobotPy version 2024.3.2.2
09:27:40:095 INFO : wpilib : WPILib version 2024.3.2.1
09:27:40:117 INFO : nt : Listening on NT3 port 1735, NT4 port 5810
Camera Server Library Not Found
Warning 44003 FRC: No robot code is currently running. Driver Station
********** Robot program startup complete **********
Default RobotPeriodic() method... Override me!
Warning 0 [phoenix] Library initialization is complete.
Warning 0 [phoenix-diagnostics] Server 2024.1.0 (Apr 30 2024, 17:31:56) running on port: 1250
DataLog: Logging to '/home/lvuser/logs/FRC_TBD_0730a66f2e72fda7.wpilog' (2.7 GiB free space)
DataLog: Renamed log file from 'FRC_TBD_0730a66f2e72fda7.wpilog' to 'FRC_20250101_152758.wpilog'
pyfrc is raising issues where there is none. Bug?
It looks like we have the same issue with pathplannerlib. If you want us to upload info, let me know.
Did you try it? Given the list of packages you have installed… well, I can’t tell because it’s not in your list, but I don’t think the 2025 version of pyfrc works with 2024 libraries.
The core problem is that some vendors are really bad at cleaning up after their C++ objects because nothing else really needs it the way that Python’s tests (but not the on-robot code!) does – and this is true for probably all vendors to some degree. From that perspective it’s not surprising it fails in tests and works deploed.
The proposed fix I linked (which is for 2025) should make it such that each robot test runs in its own process, which should allow us to avoid depending on vendors to write correct code – but FWIW I haven’t personally tried it, so I can’t guarantee that the issue will be resolved. In any case, it’s not quite to where I would like it, and I’m sick and traveling today, so while my goal is for it to be in the 2025 release, it may slip.