A problem of FRC Solenoid

l have had a question recently . That’s when l new a single solenoid and l want to use robot simulation to see whether it works well . But the program just can’t run and the error is below.

********** Robot program starting **********
Error at edu.wpi.first.wpilibj.MotorSafety.check(MotorSafety.java:96): DifferentialDrive... Output not updated often enough.
Error at edu.wpi.first.wpilibj.MotorSafety.check(MotorSafety.java:96): DifferentialDrive... Output not updated often enough.
Error at frc.robot.Hardware.<init>(Hardware.java:148): Unhandled exception: edu.wpi.first.hal.util.UncleanStatusException:  Code: -1004. HAL: No available resources to allocate
        at edu.wpi.first.hal.SolenoidJNI.initializeSolenoidPort(Native Method)
        at edu.wpi.first.wpilibj.Solenoid.<init>(Solenoid.java:46)
        at edu.wpi.first.wpilibj.Solenoid.<init>(Solenoid.java:29)
        at frc.robot.Hardware.<init>(Hardware.java:148)
        at frc.robot.Robot.robotInit(Robot.java:68)
        at edu.wpi.first.wpilibj.TimedRobot.startCompetition(TimedRobot.java:94)
        at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:335)
        at edu.wpi.first.wpilibj.RobotBase.lambda$startRobot$0(RobotBase.java:387)
        at java.base/java.lang.Thread.run(Thread.java:834)

And the hardware.java:148 is below

m_solenoidleft = new Solenoid(Constants.Intake.Left_Solenoid_Port);
        m_solenoidrght = new Solenoid(Constants.Intake.Right_Solenoid_Port);

Constants:

  // solenoid
        public static final int Left_Solenoid_Port = 1;
        public static final int Right_Solenoid_Port = 2;

And what’s the right method to create a solenoid?

You’re using the correct method. The two ports are different, so the problem likely lies elsewhere. If it’s erroring on the first line, it’s probably due to one of two things: either you’re instantiating Hardware twice, or you have some other place in your code creating a Solenoid on the same port before it gets to creating Hardware. If you post your entire program somewhere we can see it (e.g. GitHub), that would make it easier for us to help you find the issue.

1 Like

Thanks a lot , when l change the solenoid port to 11 and 12 and it really works . So is there any limit to the port that l use in my robot?

Hmmm. I’ve never tried this:

Limits should match with the number of electrical ports on the PCM. However many ports exist there, that’s the range of what you should have in your code.

0-7 are the ports I expect to function.

Perhaps this is an artifact of simulation behaving differently than the real robot? I’m not sure.

I concur with Peter’s assessment for the two most likely root causes of the initial issue.

It’s important to remember that the error in your post is a symptom, not a root cause. When the error goes away, it does not necessarily imply that the root cause issue was fixed.

I realize this may not be the easiest due to location, but it would be worth investigating. A few hours spent investigating a solution here allowing others to view your complete codebase will allow for much more direct answers to these sorts of questions.

1 Like

It crashes in simulation for me when I create a solenoid with a channel of 11

Error at frc.robot.Robot.autonomousInit(Robot.java:75): Unhandled exception: java.lang.IllegalArgumentException: Requested solenoid channel is out of range. Minimum: 0, Maximum: 8, Requested: 11
        at edu.wpi.first.wpilibj.SensorUtil.checkSolenoidChannel(SensorUtil.java:165)
        at edu.wpi.first.wpilibj.Solenoid.<init>(Solenoid.java:43)
        at edu.wpi.first.wpilibj.Solenoid.<init>(Solenoid.java:29)
        at frc.robot.Robot.autonomousInit(Robot.java:75)
        at edu.wpi.first.wpilibj.IterativeRobotBase.loopFunc(IterativeRobotBase.java:232)
        at edu.wpi.first.wpilibj.TimedRobot.startCompetition(TimedRobot.java:117)
        at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:335)
        at edu.wpi.first.wpilibj.RobotBase.lambda$startRobot$0(RobotBase.java:387)
        at java.base/java.lang.Thread.run(Thread.java:834)

Warning at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:350): Robots should not quit, but yours did!
1 Like

Hmmmmm. I’d say OP has something pretty interesting going on.

1 Like

Where does the maximum of 8 come from? Is it not 7?

It’s due to the way we currently generate the error message (it’s a closed/open range like for loop bounds often are). I agree it would be less confusing if it reported 7 instead; we are improving error messages in various ways for 2022 and plan to fix this as part of those changes.

1 Like

Back when I originally translated those error messages to Python (back when RobotPy was pure Python) I actually decided to use interval notation [0,8).

Now, whilst it agree it may be initially confusing to those who haven’t seen that notation before, it’s clear and explicit for those that are familiar, and it’s common enough that it’d be a useful learning discussion. (Hopefully most teams have a mentor with some maths background!)

l test the code after l set the port to 11 and 12 , the error is the same .
Below is my whole code . 2021FRC.zip (34.6 MB)

I just took the zip file, changed the ports back to 1 and 2 in Constants.java, and uncommented the two lines in Hardware.java, and ran gradlew build and gradlew simulateJava and it worked fine. Maybe try a gradlew clean?

And how to try a gradlew clean /

l run the “Simulate the Robot code on Desktop” command.
It seems to work well now .
Thanks a lot .

Do l need to write the code for PCM and how to write it?

I’m not sure what you mean. Solenoid uses the PCM under the hood.

Oh , l only need to set solenoid to true or false . Thank you a lot .
And l have another question and can l help me optimize my limelight code.
My limelight code are below

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package frc.robot.subsystems.limelight;

import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.CommandBase;
import frc.robot.Robot;
import frc.robot.util.Constants;
import frc.robot.util.RobotContainer;

public class limelighton extends CommandBase {
  static double test = 0;
  /** Creates a new limelight. */
  public limelighton() {
    // Use addRequirements() here to declare subsystem dependencies.
    addRequirements(RobotContainer.m_Drive);
  }

  // Called when the command is initially scheduled.
  @Override
  public void initialize() {
  }

  // Called every time the scheduler runs while the command is scheduled.
  @Override
  public void execute() {

    // Get tx 
    double lime_tx = RobotContainer.m_Drive.Get_tx();

    //  Set the parameters
    double heading_error = - RobotContainer.m_Drive.Get_tx();
    // You need to reset the cross_hair in order to use this method . Unless you will need to calculate the current distance.
    double distance_error = - RobotContainer.m_Drive.Get_ty(); 

    // Package the parameters
    double KpAim = Constants.Limelight.KpAim;
    double KpDistance = Constants.Limelight.KpDistance;

    // Package the degree of drive
    double min_command = Constants.Limelight.min_command;

    // Set some crucial parameters
    double steering_adjust = 0.0;
    double left_command = 0.0;
    double rght_command = 0.0;
    double distance_adjust = 0.0;

    if(lime_tx>1.0){
      steering_adjust = KpAim * heading_error - min_command;
    }
    else if(lime_tx < 1.0){
      steering_adjust = KpAim * heading_error + min_command;
    }

    distance_adjust = KpDistance * distance_error;

    left_command += steering_adjust + distance_adjust;
    rght_command += steering_adjust + distance_adjust;

    Robot.hardware.m_diffDrive.tankDrive(left_command, rght_command);
    test ++;
    SmartDashboard.putNumber("test",test);

  }

  // Called once the command ends or is interrupted.
  @Override
  public void end(boolean interrupted) {
  }

  // Returns true when the command should end.
  @Override
  public boolean isFinished() {
    return false;
  }
}

This seems like a different issue so I would create a new topic for it. That way when people search for that problem they can find that discussion.

What are you looking to optimize? Not sure I understand why you have min_command.


        // Set PID parameters.
        public static final double KpAim = -0.1;
        public static final double KpDistance = -0.1;

        public static final double min_command = 0.05;

Can you send a perfect limelight example to me or teach me how to adjust my code ?

Please continue the limelight discussion in your other thread. The optimization of Limelight

2 Likes

l also want to know how to test my auto mode without the robot?