As the title says, we’re new to robotpy. I’m the programming mentor for 6343 and we’ve historically used C++ but our team is basically all freshman with familiarity to python so we decided to make the switch. We are using a command based framework as we would with C++. The error that we see reminds me of the nullptr error you’d see with joystick issues and C++.
Thanks for taking a look and offering some suggestions.
When we use “py -3 robot.py deploy”, the code deploys successfully but we get the “No Robot Code” issue on the driverstation.
We’ve never used the simulation and I don’t think we’re quite there yet to create it.
When we use “py -3 robot.py --skip-tests” we get the “watchdog not fed” error.
When we use “py -3 robot.py --nc” the stack trace gives a few lines from the files (noted below).
Here is the stacktrace:
[44.92] 12:35:07:671 INFO : wpilib : WPILib version 2022.2.1.1
[44.92] 12:35:07:673 INFO : wpilib : HAL version 2022.2.1.0
[44.92] 12:35:07:674 INFO : wpilib : robotpy-wpiutil version 2022.2.1.0
[44.93] 12:35:07:676 INFO : wpilib : robotpy-wpimath version 2022.2.1.1
[44.93] 12:35:07:680 INFO : wpilib : robotpy-rev version 2022.0.0
[44.93] 12:35:07:681 INFO : wpilib : robotpy-playingwithfusion version 2022.0.3
[44.93] 12:35:07:682 INFO : wpilib : robotpy-photonvision version 2022.0.2
[44.93] 12:35:07:683 INFO : wpilib : robotpy-navx version 2022.0.0
[44.93] 12:35:07:683 INFO : wpilib : robotpy-ctre version 2022.0.2
[44.93] 12:35:07:684 INFO : wpilib : robotpy-commands-v2 version 2022.2.1.0
[44.93] 12:35:07:685 INFO : wpilib : robotpy-commands-v1 version 2022.2.1.0
[44.93] 12:35:07:686 INFO : wpilib : pyntcore version 2022.2.1.0
[44.94] 12:35:07:688 INFO : faulthandler : registered SIGUSR2 for PID 2830
[44.95] Camera Server Library Not Found
[44.96] Fatal Python error: Segmentation fault
[44.96]
[44.96] Thread 0xb3187470 (most recent call first):
[44.96] File "/usr/local/lib/python3.10/site-packages/_pyntcore/_logutil.py", line 60 in _logging_thread
[44.96] File "/usr/local/lib/python3.10/threading.py", line 946 in run
[44.96] File "/usr/local/lib/python3.10/threading.py", line 1009 in _bootstrap_inner
[44.97] File "/usr/local/lib/python3.10/threading.py", line 966 in _bootstrap
[44.97]
[44.97] Current thread 0xb6f66210 (most recent call first):
[44.97] File "/home/lvuser/py/subsystems/drivetrain.py", line 19 in __init__
[44.97] File "/home/lvuser/py/robotcontainer.py", line 32 in __init__
[44.97] File "/home/lvuser/py/robot.py", line 16 in robotInit
[44.97] File "/usr/local/lib/python3.10/site-packages/wpilib/_impl/start.py", line 124 in _start
[44.97] File "/usr/local/lib/python3.10/site-packages/wpilib/_impl/start.py", line 58 in start
[44.97] File "/usr/local/lib/python3.10/site-packages/wpilib/_impl/start.py", line 54 in run
[44.97] File "/usr/local/lib/python3.10/site-packages/wpilib/_impl/start.py", line 19 in run
[44.97] File "/usr/local/lib/python3.10/site-packages/wpilib/_impl/main.py", line 193 in run
[44.97] File "/home/lvuser/py/robot.py", line 56 in <module>
Link to our github:
OR
Here are our files:
Command drivewithjoystick.py:
import commands2
from subsystems.drivetrain import Drivetrain
class DrivewithJoystick(commands2.CommandBase):
def init(self, drive: Drivetrain, left_axis: float, right_axis: float) -> None:
super().__init__()
self.drive = drive
self.left_axis = left_axis
self.right_axis = right_axis
self.addRequirements(self.drive)
def execute(self) -> None:
self.drive.userDrive(self.left_axis(), self.right_axis())
def end(self, interrupted: bool) -> None:
self.drive.stopMotors()
def isFinished(self) -> bool:
return False
Subsystem drivetrain.py:
import commands2
import ctre
import constants
class Drivetrain(commands2.SubsystemBase):
def __init__(self) -> None:
super().__init__()
#initalize motors
self.frontLeft = ctre.TalonFX(constants.kfrontLeft)
self.backLeft = ctre.TalonFX(constants.kbackLeft)
self.frontRight = ctre.TalonFX(constants.kfrontRight)
self.backRight = ctre.TalonFX(constants.kbackRight)
#set followers
self.backLeft.follow(self.frontLeft)
self.backRight.follow(self.frontRight)
#reverse sensors
self.frontLeft.setSensorPhase(False)
self.frontRight.setSensorPhase(False)
#invert motors on right side
self.frontRight.setInverted(True)
self.backRight.setInverted(True)
#configure encoders
self.frontRight.configSelectedFeedbackSensor(ctre.FeedbackDevice.QuadEncoder, 0, constants.ktimeoutMs)
self.frontLeft.configSelectedFeedbackSensor(ctre.FeedbackDevice.QuadEncoder, 0, constants.ktimeoutMs)
#set motors to brake mode
self.frontLeft.setNeutralMode(ctre.NeutralMode.Brake)
self.backLeft.setNeutralMode(ctre.NeutralMode.Brake)
self.frontRight.setNeutralMode(ctre.NeutralMode.Brake)
self.backLeft.setNeutralMode(ctre.NeutralMode.Brake)
def userDrive(self, left: float, right: float) -> None:
self.frontLeft.set(ctre.ControlMode.PercentOutput, left)
self.frontRight.set(ctre.ControlMode.PercentOutput, right)
def stopMotors(self, left: float, right: float) -> None:
self.frontLeft.set(0.0)
self.frontRight.set(0.0)
Our constants.py file:
import math
#Controller ports
kdriverControllerPort = 0
kfunctionsControllerPort = 1
#Motors
kfrontLeft = 0
kbackLeft = 1
kfrontRight = 2
kbackRight = 3
#Encoders
ktimeoutMs = 10
#Physical constants
robot.py:
import commands2
import wpilib
from robotcontainer import RobotContainer
class MyRobot(commands2.TimedCommandRobot):
def robotInit(self) -> None:
#This function is run when the robot is first started up and should be used for any
#initialization code.
# Instantiate our RobotContainer. This will perform all our button bindings, and put our
# autonomous chooser on the dashboard.
self.container = RobotContainer()
def disabledInit(self) -> None:
#This function is called once each time the robot enters Disabled mode.
def disabledPeriodic(self) -> None:
#This function is called periodically when disabled
def autonomousInit(self) -> None:
#This autonomous runs the autonomous command selected by your RobotContainer class.
self.autonomousCommand = self.container.getAutonomousCommand()
if self.autonomousCommand:
self.autonomousCommand.schedule()
def autonomousPeriodic(self) -> None:
#This function is called periodically during autonomous
def teleopInit(self) -> None:
#This makes sure that the autonomous stops running when
#teleop starts running. If you want the autonomous to
#continue until interrupted by another command, remove
#this line or comment it out.
if self.autonomousCommand:
self.autonomousCommand.cancel()
def teleopPeriodic(self) -> None:
#This function is called periodically during operator control
def testInit(self) -> None:
# Cancels all running commands at the start of test mode
commands2.CommandScheduler.getInstance().cancelAll()
if __name__ == "__main__":
wpilib.run(MyRobot)
robotcontainer.py:
import wpilib
import commands2
import constants
import ctre
from wpilib import XboxController
from commands.drivewithjoystick import DrivewithJoystick
from subsystems.drivetrain import Drivetrain
class RobotContainer:
#This class is where the bulk of the robot should be declared. Since Command-based is a
#"declarative" paradigm, very little robot logic should actually be handled in the :class:`.Robot`
#periodic methods (other than the scheduler calls). Instead, the structure of the robot (including
#subsystems, commands, and button mappings) should be declared here.
def __init__(self) -> None:
# The driver's controller
self.driverController = XboxController(constants.kdriverControllerPort)
#self.functionsController = XboxController(constants.kfunctionsControllerPort)
self.frontLeft = ctre.TalonFX(constants.kfrontLeft)
self.backLeft = ctre.TalonFX(constants.kbackLeft)
self.frontRight = ctre.TalonFX(constants.kfrontRight)
self.backRight = ctre.TalonFX(constants.kbackRight)
# The robot's subsystems
self.drivetrain = Drivetrain()
# Autonomous routines
#self.AUTOCOMMANDHERE = COMMAND()
# Chooser
self.chooser = wpilib.SendableChooser()
# Add commands to the autonomous command chooser
#self.chooser.setDefaultOption("Simple Auto", self.simpleAuto)
#self.chooser.addOption("Complex Auto", self.complexAuto)
# Put the chooser on the dashboard
#wpilib.SmartDashboard.putData("Autonomous", self.chooser)
self.configureButtonBindings()
# set up default drive command
self.drivetrain.setDefaultCommand(DrivewithJoystick(self.drivetrain,lambda: -self.driverController.getLeftY(), lambda: -self.driverController.getRightY()))
def configureButtonBindings(self):
#Use this method to define your button->command mappings. Buttons can be created by
#instantiating a :GenericHID or one of its subclasses (Joystick or XboxController),
#and then passing it to a JoystickButton.
def getAutonomousCommand(self) -> commands2.Command:
return self.chooser.getSelected()