Hi all, I have a problem with allocating DIO ports for DigitalIput.
The error message is:
-
[phoenix] Initialization is complete.
-
Unhandled exception: edu.wpi.first.hal.util.UncleanStatusException: Code: -1029. HAL: Resource already allocated
-
Error at frc.robot.subsystems.ElevatorSys.<init>(ElevatorSys.java:18): Unhandled exception: edu.wpi.first.hal.util.UncleanStatusException: Code: -1029. HAL: Resource already allocated
-
at edu.wpi.first.hal.DIOJNI.initializeDIOPort(Native Method)
-
at edu.wpi.first.wpilibj.DigitalInput.<init>(DigitalInput.java:34)
-
at frc.robot.subsystems.ElevatorSys.<init>(ElevatorSys.java:18)
-
at frc.robot.commands.StopElevator.<init>(StopElevator.java:10)
-
at frc.robot.OI.<init>(OI.java:40)
-
at frc.robot.Robot.robotInit(Robot.java:39)
-
at edu.wpi.first.wpilibj.TimedRobot.startCompetition(TimedRobot.java:63)
-
at edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:263)
-
at frc.robot.Main.main(Main.java:27)
-
Robots should not quit, but yours did!
-
Warning at edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:274): Robots should not quit, but yours did!
-
The startCompetition() method (or methods called by it) should have handled the exception above.
-
Error at edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:276): The startCompetition() method (or methods called by it) should have handled the exception above.
-
[phoenix] Shutdown cleanly
When I try allocating a port that isn’t used by any other device it still comes up with this error…
Any idea on how to solve this?
Thank you from team 4661
I’ve only seen this error in the context of two calls to constructors which utilize the same port. Are you willing to post the full codebase for folks to inspect?
That is kind of a deal, I’ll have to ask my supervisor
Ok. Some possibly useful musings:
There are multiple types of things that could allocate digital IO ports (digital out, digital in, encoder, counter, button, etc.)
Is there any chance that ElevatorSys
is being instantiated more than once?
Yes I created two command that utilize this subsystem called ElevatorDown.java and ElevatorUp.java that control the motion of the elevaotr(Up or Down).
I also implement them in the OI
here is some OI code:
this.operatorButtons[2].whileHeld(new ElevatorDown(0.2));
this.operatorButtons[2].whenReleased(new StopElevator());
this.operatorButtons[3].whileHeld(new ElevatorUp(-0.5));
Gotcha. I may have to defer to someone more familiar with command based architecture. What I know is that by restriction of WPI, you can’t have two different java objects which allocate the same HAL DIO resource.
From my very weak understanding of command based architecture, I would say the DIO object should be created in the subsystem, not in the command. From looking at your stack trace though, I presume ElevatorSys
is the subsystem? If so, I am not sure why it would get instantiated twice.
Also in general, I try not to allocate and dealocate HAL resources at runtime.
ElevatorSys is a subsystem.
I can share some RobotMap code if that helps.
From my weak understading of how HAL works it sais that there are more than two devices allocated on the same port
RobotMap code:
package frc.robot;
public class RobotMap {
//CHASSIS
public static int CHASSIS_LEFT_FRONT = 10;//1
public static int CHASSIS_LEFT_REAR = 11;//2
public static int CHASSIS_RIGHT_FRONT = 12;//3
public static int CHASSIS_RIGHT_REAR = 13;//4
//BUTTONS
public static int BTN_3 = 3;
//JOYSTICK
public static int DRIVE_JOYSTICK_PORT = 0;
public static int OPERATOR_JOYSTICK_PORT = 1;
//PISTON
public static int SOLENOID_A_PORT = 1;
public static int SOLENOID_B_PORT = 2;
//ELIVATOR
public static int ELEVATOR_MOTOR_PORT = 14;//5
//FORKLIFT
public static int FORKLIFT_OC_MOTOR_PORT = 16;//7
//SUCTION
public static int SUCTION_MOTOR1_PORT = 17;//8
public static int SUCTION_MOTOR2_PORT = 18;//9
//CAMERA
public static int CAMERA_PORT = 3;
public static int VIDEO_SOURCE_PORT = 4;
//SOLENOID
//Digital Input
public static int ELEVATOR_DIGITAL_INPUT_A_PORT = 5;
public static int ELEVATOR_DIGITAL_INPUT_B_PORT = 6;
public static int FORKLIFT_DIGITAL_INPUT_A_PORT = 7;
public static int FORKLIFT_DIGITAL_INPUT_B_PORT = 8;
//Exterior Chassis
public static int ECHASSIS_DRUNKWHEEL_MOTOR_PORT = 15;//6
public static int ECHASSIS_OUTER_CHASSIS_WHEEL_MOTOR_A_PORT = 19;//10
//public static int ECHASSIS_OUTER_CHASSIS_WHEEL_MOTOR_B_PORT = 16;
}
I concur, 14 is used only once in that code snippet.
An issue we ran into this year: Someone accidentally hard coded the number for the IO port in the instantiation of the resource. A blind search through the codebase for all instances of DigitalInput(
was required to find it.
you mean the class of First
I have tried to narrow down the constructor calles
still comes up with an error, and as you can see the stop elevator command is called once:
-
[phoenix] Initialization is complete.
-
[!] Stopping Elevator!!!
-
Unhandled exception: edu.wpi.first.hal.util.UncleanStatusException: Code: -1029. HAL: Resource already allocated
-
Error at frc.robot.subsystems.ElevatorSys.<init>(ElevatorSys.java:15): Unhandled exception: edu.wpi.first.hal.util.UncleanStatusException: Code: -1029. HAL: Resource already allocated
-
at edu.wpi.first.hal.DIOJNI.initializeDIOPort(Native Method)
-
at edu.wpi.first.wpilibj.DigitalInput.<init>(DigitalInput.java:34)
-
at frc.robot.subsystems.ElevatorSys.<init>(ElevatorSys.java:15)
-
at frc.robot.commands.ElevatorUp.<init>(ElevatorUp.java:10)
-
at frc.robot.OI.<init>(OI.java:41)
-
at frc.robot.Robot.robotInit(Robot.java:39)
-
at edu.wpi.first.wpilibj.TimedRobot.startCompetition(TimedRobot.java:63)
-
at edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:263)
-
at f
-
Robots should not quit, but yours did!
-
Warning at edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:274): Robots should not quit, but yours did!
-
The startCompetition() method (or methods called by it) should have handled the exception above.
-
Error at edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:276): The startCompetition() method (or methods called by it) should have handled the exception above.
-
[phoenix] Shutdown cleanly
I agree, it appears you are somehow trying to create your DigitalInput
more than once, and based on the stacktrace, it appears each time your command executes, a new instance is created (explaining why the command only executes once before crashing).
I take it you are unable to post all of your code here, are you able to just post the ElevatorSys
subsystem and ElevatorUp
command?
Failing that, what is the method that creates the DigitalInput
(with what I would expect to be new DigitalInput(RobotMap.ELEVATOR_MOTOR_PORT)
).
Is it the constructor of ElevatorSys
or a different method?
I do agree with you,
I cant post my code here (my supervisor) deosnt allow it.
The constructor of ElevatorSys creates the DigitalInput
BTW I have no idea on how to solve the command calling problem
Are you by any chance instantiating a new ElevatorSys in your ElevatorUp command?
How are you accessing the subsystem within the command, perhaps it is creating a new instance each time?
Edit: Sniped
Then that is exactly the problem, instead instantiate the ElevatorSys
subsystem within Robot.java and access a static copy from there.
There’s the problem
You should instantiate only ONE instance of your ElevatorSys, and then reference that in all the commands. What it’s doing right now is creating a new ElevatorSys instance every time you call a command, thus running the constructor over and over again
Assuming the other two posts here are correct, and you are initializing an ElevatorSys in the command, then this is very much your issue.
The solution is to make one shared object that can be used by all your commands. This is typically done by creating one public static
variable for the subsystem in your Robot.java file and then accessing it in the commands using Robot.subsystemVariable
. You should also be passing this shared variable into the requires()
method call in the constructor of the commands.
I mean to say that searching the codebase for all usages of WPI classes that allocate HAL resources from the DIO bank on the RIO revealed a case where robotMap was not used to select the pin (rather it was hardcoded at that spot). This meant that inspecting our robotMap file did not show a problem, but the problem still existed.
To help debug the multi-instantiation problem, if you can’t post code: Put the following line in ElevatorSys.java on line 17 (right before the problematic line):
Thread.dumpStack();
I haven’t tried it yet to confirm, but this ought to print out the stack traces for every time your HAL resource is allocated. Using that info, you start to unravel if/why your subsystem code is getting double-instantiated.
EDIT: should have read before I hit submit, you covered this already. Never mind!
OP Bonus round time: Does it make sense why changing the pin used in elevator would not have changed the error?